diff --git a/lib/rules/template-no-obsolete-elements.js b/lib/rules/template-no-obsolete-elements.js index af82f4e007..31f97a07e3 100644 --- a/lib/rules/template-no-obsolete-elements.js +++ b/lib/rules/template-no-obsolete-elements.js @@ -29,6 +29,16 @@ const OBSOLETE = [ 'tt', 'xmp', ]; + +function hasBindingInScopeChain(scope, name) { + for (let s = scope; s; s = s.upper) { + if (s.set && s.set.has(name)) { + return true; + } + } + return false; +} + /** @type {import('eslint').Rule.RuleModule} */ module.exports = { meta: { @@ -50,26 +60,21 @@ module.exports = { }, create(context) { const obsolete = new Set(OBSOLETE); - const blockParamsInScope = []; + const sourceCode = context.sourceCode; return { - GlimmerBlockStatement(node) { - const params = node.program?.blockParams || []; - blockParamsInScope.push(...params); - }, - 'GlimmerBlockStatement:exit'(node) { - const params = node.program?.blockParams || []; - for (let i = 0; i < params.length; i++) { - blockParamsInScope.pop(); - } - }, GlimmerElementNode(node) { - if (blockParamsInScope.includes(node.tag)) { + if (!obsolete.has(node.tag)) { return; } - if (obsolete.has(node.tag)) { - context.report({ node, messageId: 'obsolete', data: { element: node.tag } }); + // Use the parent's scope so that the element's own `as |x|` params + // (which attach a block scope to this node) don't shadow its own tag + // name. e.g. `` must still flag the outer tag. + const scope = sourceCode.getScope(node.parent); + if (hasBindingInScopeChain(scope, node.tag)) { + return; } + context.report({ node, messageId: 'obsolete', data: { element: node.tag } }); }, }; }, diff --git a/package.json b/package.json index 719f475e7f..37304b14f7 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "aria-query": "^5.3.2", "css-tree": "^3.0.1", "editorconfig": "^3.0.2", - "ember-eslint-parser": "^0.9.0", + "ember-eslint-parser": "^0.10.0", "ember-rfc176-data": "^0.3.18", "eslint-utils": "^3.0.0", "estraverse": "^5.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 17861ed207..b45cc046a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,8 +21,8 @@ importers: specifier: ^3.0.2 version: 3.0.2 ember-eslint-parser: - specifier: ^0.9.0 - version: 0.9.0(@typescript-eslint/parser@8.58.1(eslint@8.57.1)(typescript@5.9.3))(typescript@5.9.3) + specifier: ^0.10.0 + version: 0.10.0(@typescript-eslint/parser@8.58.1(eslint@8.57.1)(typescript@5.9.3))(typescript@5.9.3) ember-rfc176-data: specifier: ^0.3.18 version: 0.3.18 @@ -1778,8 +1778,8 @@ packages: electron-to-chromium@1.5.335: resolution: {integrity: sha512-q9n5T4BR4Xwa2cwbrwcsDJtHD/enpQ5S1xF1IAtdqf5AAgqDFmR/aakqH3ChFdqd/QXJhS3rnnXFtexU7rax6Q==} - ember-eslint-parser@0.9.0: - resolution: {integrity: sha512-/Z/eoBmkeVdS+UjrocxKuLP4HG9K7XxZgpVvFjDBZ+o3gXYpbnvWkL+wYjaxzySXm3cuuCvnGW5NppIh9Vl/ig==} + ember-eslint-parser@0.10.0: + resolution: {integrity: sha512-oq37TDYDBqR4fTGhJy/Yecw5VHlPJrSCd26KkwCKlhzAHMCzac+/HSln99COihKei2mMaaob17IrV3I9XL83YQ==} engines: {node: '>=16.0.0'} peerDependencies: '@typescript-eslint/parser': '*' @@ -5652,7 +5652,7 @@ snapshots: electron-to-chromium@1.5.335: {} - ember-eslint-parser@0.9.0(@typescript-eslint/parser@8.58.1(eslint@8.57.1)(typescript@5.9.3))(typescript@5.9.3): + ember-eslint-parser@0.10.0(@typescript-eslint/parser@8.58.1(eslint@8.57.1)(typescript@5.9.3))(typescript@5.9.3): dependencies: '@glimmer/syntax': 0.95.0 '@typescript-eslint/tsconfig-utils': 8.58.1(typescript@5.9.3) diff --git a/tests/lib/rules/template-no-obsolete-elements.js b/tests/lib/rules/template-no-obsolete-elements.js index 5c995da69b..16221c7ee6 100644 --- a/tests/lib/rules/template-no-obsolete-elements.js +++ b/tests/lib/rules/template-no-obsolete-elements.js @@ -11,6 +11,9 @@ ruleTester.run('template-no-obsolete-elements', rule, { `