1- const DIGIT_REGEXP = / ^ \[ ? \d + ] ?$ / ;
2-
3- /**
4- * Extract the target path and string key from a path with numeric segments.
5- * E.g. "this.list.0.name" → ["this.list", "0.name"]
6- * E.g. "this.list.[0]" → ["this.list", "0"]
7- * E.g. "@foo.0.bar" → ["@foo", "0.bar"]
8- *
9- * @param {string } original The original path string
10- * @returns {[string, string] } A tuple of [targetPath, stringKey]
11- */
12- function getHelperParams ( original ) {
13- const parts = original . split ( '.' ) ;
14- const firstDigitIndex = parts . findIndex ( ( part ) => DIGIT_REGEXP . test ( part ) ) ;
15-
16- if ( firstDigitIndex === - 1 ) {
17- return null ;
18- }
19-
20- const targetPath = parts . slice ( 0 , firstDigitIndex ) . join ( '.' ) ;
21- // Strip brackets from digit segments: [0] → 0
22- const keyParts = parts . slice ( firstDigitIndex ) . map ( ( part ) => part . replace ( / ^ \[ ( \d + ) ] $ / , '$1' ) ) ;
23- const stringKey = keyParts . join ( '.' ) ;
24-
25- return [ targetPath , stringKey ] ;
26- }
27-
281/** @type {import('eslint').Rule.RuleModule } */
292module . exports = {
303 meta : {
@@ -35,7 +8,6 @@ module.exports = {
358 url : 'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/template-no-obscure-array-access.md' ,
369 templateMode : 'both' ,
3710 } ,
38- fixable : 'code' ,
3911 schema : [ ] ,
4012 messages : {
4113 noObscureArrayAccess :
@@ -54,7 +26,7 @@ module.exports = {
5426 GlimmerPathExpression ( node ) {
5527 const path = node . original ;
5628 const sourcePath = context . sourceCode . getText ( node ) ;
57- // Check for @each or [] in paths — these are structural and not autofixable
29+ // Check for @each or [] in paths
5830 if ( path && ( path . includes ( '.@each.' ) || path . includes ( '.[].' ) ) ) {
5931 context . report ( {
6032 node,
@@ -65,57 +37,13 @@ module.exports = {
6537 }
6638 // Check for numeric path segments (e.g., foo.0.bar) or bracket notation (e.g., foo.[0])
6739 if ( node . tail && node . tail . some ( ( segment ) => / ^ \d + $ / . test ( segment ) ) ) {
68- const params = getHelperParams ( path ) ;
6940 context . report ( {
7041 node,
7142 messageId : 'noObscureArrayAccess' ,
7243 data : { path : sourcePath } ,
73- fix : params ? buildFix ( context , node , params ) : undefined ,
7444 } ) ;
7545 }
7646 } ,
7747 } ;
7848 } ,
7949} ;
80-
81- /**
82- * Build a fix function for a numeric path expression.
83- *
84- * @param {import('eslint').Rule.RuleContext } context
85- * @param {import('estree').Node } node The GlimmerPathExpression node
86- * @param {[string, string] } params The [targetPath, stringKey] tuple
87- * @returns {(fixer: import('eslint').Rule.RuleFixer) => import('eslint').Rule.Fix }
88- */
89- function buildFix ( context , node , params ) {
90- const [ target , key ] = params ;
91- const parent = node . parent ;
92-
93- // Case 1: PathExpression is the path of a MustacheStatement (e.g., {{this.list.0.name}})
94- // Replace the entire mustache inner content with: get target "key"
95- if (
96- parent &&
97- parent . type === 'GlimmerMustacheStatement' &&
98- parent . path === node &&
99- parent . params . length === 0 &&
100- ( ! parent . hash || parent . hash . pairs . length === 0 )
101- ) {
102- return ( fixer ) => {
103- // The mustache is {{path}} — replace just the path portion
104- // The source text of the MustacheStatement includes {{ and }}
105- const mustacheSource = context . sourceCode . getText ( parent ) ;
106- const isTriple = mustacheSource . startsWith ( '{{{' ) ;
107- const openLen = isTriple ? 3 : 2 ;
108- const closeLen = isTriple ? 3 : 2 ;
109- const innerStart = parent . range [ 0 ] + openLen ;
110- const innerEnd = parent . range [ 1 ] - closeLen ;
111-
112- return fixer . replaceTextRange ( [ innerStart , innerEnd ] , `get ${ target } "${ key } "` ) ;
113- } ;
114- }
115-
116- // Case 2: PathExpression is a param or hash value or any other context
117- // Wrap with (get target "key")
118- return ( fixer ) => {
119- return fixer . replaceText ( node , `(get ${ target } "${ key } ")` ) ;
120- } ;
121- }
0 commit comments