Skip to content

Post-merge-review: use scope manager for block-param tracking in template-no-obsolete-elements#2676

Merged
NullVoxPopuli merged 8 commits intoember-cli:masterfrom
johanrd:night_fix/template-no-obsolete-elements
Apr 19, 2026
Merged

Post-merge-review: use scope manager for block-param tracking in template-no-obsolete-elements#2676
NullVoxPopuli merged 8 commits intoember-cli:masterfrom
johanrd:night_fix/template-no-obsolete-elements

Conversation

@johanrd
Copy link
Copy Markdown
Contributor

@johanrd johanrd commented Apr 13, 2026

Summary

Replaces the manual block-param stack with sourceCode.getScope(node.parent) + a walk up the scope chain. Uses the parent scope rather than the element's own scope so an element's own as |x| params don't shadow its own tag — e.g. <marquee as |marquee|> must still flag the outer <marquee>.

Upstream dependency

Requires ember-tooling/ember-eslint-parser#189 (merged, released as 0.10.0), which populates block-param scope in the hbs-parser. Without it, .hbs files ran against an empty scope manager and the scope check had no effect. Bumped ember-eslint-parser to ^0.10.0 in this PR.

Test plan

  • GTS: <plaintext> / <marquee> flagged
  • GTS: {{#let ... as |plaintext|}}<plaintext /> not flagged (scope sees the block param)
  • GTS: <Comp as |plaintext|><plaintext /> not flagged (element-level block params)
  • GTS: <marquee as |marquee|> still flagged (parent scope trick)
  • HBS: {{#let ... as |plaintext|}}<plaintext /> not flagged (now that the hbs-parser registers scope)
  • HBS: <marquee>, <acronym>, etc. flagged

The rule suppressed obsolete-element reports when the tag name shadows a
block param from a GlimmerBlockStatement (e.g. {{#let (...) as |marquee|}}).
It did not track element-level block params (<Comp as |marquee|>), so
inside an angle-bracket component the shadowing was ignored and the tag
was falsely reported. Push element block params on enter and pop on exit,
mirroring the existing GlimmerBlockStatement handling.
@johanrd johanrd force-pushed the night_fix/template-no-obsolete-elements branch from 511b615 to 029c2c0 Compare April 13, 2026 10:01
@johanrd johanrd marked this pull request as ready for review April 13, 2026 10:34
// Element-level block params (e.g. `<Comp as |param|>`) are scoped to
// the children, so push them after the obsolete check. Pop on exit.
const elementParams = node.blockParams || [];
blockParamsInScope.push(...elementParams);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be the responsibility of the scope manager?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a clarification above blockParamsInScope now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kinda seems like we should fix that rather than add a work-around here, ya?

Copy link
Copy Markdown
Contributor Author

@johanrd johanrd Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, maybe, although I'm not sure how to approach that.

To my understanding, getScope() runs into two problems:

HBS mode: ember-eslint-parser's HBS path creates an intentionally empty scope manager — Glimmer block params from {{#let ... as |x|}} and <Comp as |x|> are not registered, so getScope() sees nothing.

GTS mode: at the GlimmerElementNode visitor, the element's own as |x| params are already visible in scope. So getScope() at <marquee as |marquee|> test would find marquee in scope and incorrectly suppress the flag. The push-after-check ordering handles this: the element is checked against outer params only, then its own are pushed for its children.

or were you thinking something else completely? upstream to ember-eslint-parser? thanks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to scope-manager (getScope(node.parent) + chain walk) as suggested. 36/37 tests pass; the one failing HBS test is blocked on ember-tooling/ember-eslint-parser#189

johanrd added 3 commits April 13, 2026 20:50
…params

Replaces the manual block-param stack with sourceCode.getScope(node.parent)
+ a walk up the scope chain. GTS templates work today (36/37 tests pass).

BLOCKED BY UPSTREAM: ember-tooling/ember-eslint-parser#189. The HBS parser
currently builds an empty scope manager, so Glimmer block params aren't
registered for .hbs files. The failing test
`{{#let ... as |plaintext|}}<plaintext />` documents this gap and will
start passing once PR 189 is merged and consumed here.

Uses getScope(node.parent) rather than getScope(node) so an element's
own `as |x|` params (attached to that element's block scope) don't
shadow its own tag — e.g. `<marquee as |marquee|>` must still flag the
outer <marquee>.
@johanrd johanrd force-pushed the night_fix/template-no-obsolete-elements branch from 3a7cb52 to 6189818 Compare April 15, 2026 19:52
@johanrd johanrd changed the title Post-merge-review: Fix template-no-obsolete-elements: track element-level block params Post-merge-review: use scope manager for block-param tracking in template-no-obsolete-elements Apr 15, 2026
@johanrd johanrd requested a review from NullVoxPopuli April 15, 2026 19:54
@johanrd johanrd marked this pull request as draft April 15, 2026 20:31
Unblocks the HBS valid-case test

    {{#let (component 'whatever-here') as |plaintext|}}
      <plaintext />
    {{/let}}

which relies on ember-tooling/ember-eslint-parser#189 populating block-
param scope in the hbs-parser. All 37 tests (GTS + HBS) pass.
@johanrd johanrd marked this pull request as ready for review April 19, 2026 18:46
@NullVoxPopuli NullVoxPopuli merged commit dc2406a into ember-cli:master Apr 19, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants