Skip to content

Commit dc2406a

Browse files
Merge pull request #2676 from johanrd/night_fix/template-no-obsolete-elements
Post-merge-review: use scope manager for block-param tracking in template-no-obsolete-elements
2 parents 367ee0b + 0c5ea45 commit dc2406a

2 files changed

Lines changed: 28 additions & 14 deletions

File tree

lib/rules/template-no-obsolete-elements.js

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ const OBSOLETE = [
2929
'tt',
3030
'xmp',
3131
];
32+
33+
function hasBindingInScopeChain(scope, name) {
34+
for (let s = scope; s; s = s.upper) {
35+
if (s.set && s.set.has(name)) {
36+
return true;
37+
}
38+
}
39+
return false;
40+
}
41+
3242
/** @type {import('eslint').Rule.RuleModule} */
3343
module.exports = {
3444
meta: {
@@ -50,26 +60,21 @@ module.exports = {
5060
},
5161
create(context) {
5262
const obsolete = new Set(OBSOLETE);
53-
const blockParamsInScope = [];
63+
const sourceCode = context.sourceCode;
5464

5565
return {
56-
GlimmerBlockStatement(node) {
57-
const params = node.program?.blockParams || [];
58-
blockParamsInScope.push(...params);
59-
},
60-
'GlimmerBlockStatement:exit'(node) {
61-
const params = node.program?.blockParams || [];
62-
for (let i = 0; i < params.length; i++) {
63-
blockParamsInScope.pop();
64-
}
65-
},
6666
GlimmerElementNode(node) {
67-
if (blockParamsInScope.includes(node.tag)) {
67+
if (!obsolete.has(node.tag)) {
6868
return;
6969
}
70-
if (obsolete.has(node.tag)) {
71-
context.report({ node, messageId: 'obsolete', data: { element: node.tag } });
70+
// Use the parent's scope so that the element's own `as |x|` params
71+
// (which attach a block scope to this node) don't shadow its own tag
72+
// name. e.g. `<marquee as |marquee|>` must still flag the outer tag.
73+
const scope = sourceCode.getScope(node.parent);
74+
if (hasBindingInScopeChain(scope, node.tag)) {
75+
return;
7276
}
77+
context.report({ node, messageId: 'obsolete', data: { element: node.tag } });
7378
},
7479
};
7580
},

tests/lib/rules/template-no-obsolete-elements.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,22 @@ ruleTester.run('template-no-obsolete-elements', rule, {
1111
`<template>{{#let (component 'whatever-here') as |plaintext|}}
1212
<plaintext />
1313
{{/let}}</template>`,
14+
// Element-level block params (<Comp as |...|>) are now tracked
15+
'<template><Comp as |plaintext|><plaintext /></Comp></template>',
16+
'<template><Outer as |marquee|><marquee /></Outer></template>',
1417
],
1518
invalid: [
1619
{
1720
code: '<template><marquee></marquee></template>',
1821
output: null,
1922
errors: [{ messageId: 'obsolete' }],
2023
},
24+
// Element's own block params must not shadow its own tag name.
25+
{
26+
code: '<template><marquee as |marquee|></marquee></template>',
27+
output: null,
28+
errors: [{ messageId: 'obsolete', data: { element: 'marquee' } }],
29+
},
2130
],
2231
});
2332

0 commit comments

Comments
 (0)