@@ -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 } */
3343module . 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 } ,
0 commit comments