@@ -113,6 +113,13 @@ function getThisExpressions(nodeLogicalExpression) {
113
113
return arrayOfThisExpressions . reverse ( ) ;
114
114
}
115
115
116
+ function makeFix ( nodeToReplace , macro , macroArgs ) {
117
+ const isDecoratorUsage = types . isMethodDefinition ( nodeToReplace ) ;
118
+ const prefix = isDecoratorUsage ? '@' : '' ; // Decorator usage has @ symbol prefixing computed()
119
+ const suffix = isDecoratorUsage ? ` ${ nodeToReplace . key . name } ` : '' ; // Decorator usage has property name as suffix.
120
+ return `${ prefix } computed.${ macro } (${ macroArgs } )${ suffix } ` ;
121
+ }
122
+
116
123
module . exports = {
117
124
meta : {
118
125
type : 'suggestion' ,
@@ -124,7 +131,18 @@ module.exports = {
124
131
'https://github.com/ember-cli/eslint-plugin-ember/tree/master/docs/rules/require-computed-macros.md' ,
125
132
} ,
126
133
fixable : 'code' ,
127
- schema : [ ] ,
134
+ schema : [
135
+ {
136
+ type : 'object' ,
137
+ properties : {
138
+ includeNativeGetters : {
139
+ type : 'boolean' ,
140
+ default : false ,
141
+ } ,
142
+ } ,
143
+ additionalProperties : false ,
144
+ } ,
145
+ ] ,
128
146
} ,
129
147
130
148
ERROR_MESSAGE_READS ,
@@ -146,7 +164,10 @@ module.exports = {
146
164
message : makeErrorMessage ( macro ) ,
147
165
fix ( fixer ) {
148
166
const text = propertyGetterUtils . nodeToDependentKey ( nodeWithThisExpression , context ) ;
149
- return fixer . replaceText ( nodeComputedProperty , `computed.${ macro } ('${ text } ')` ) ;
167
+ return fixer . replaceText (
168
+ nodeComputedProperty ,
169
+ makeFix ( nodeComputedProperty , macro , `'${ text } '` )
170
+ ) ;
150
171
} ,
151
172
} ) ;
152
173
}
@@ -164,7 +185,7 @@ module.exports = {
164
185
const textRight = sourceCode . getText ( nodeBinaryExpression . right ) ;
165
186
return fixer . replaceText (
166
187
nodeComputedProperty ,
167
- `computed. ${ macro } ( '${ textLeft } ', ${ textRight } )`
188
+ makeFix ( nodeComputedProperty , macro , ` '${ textLeft } ', ${ textRight } ` )
168
189
) ;
169
190
} ,
170
191
} ) ;
@@ -178,7 +199,10 @@ module.exports = {
178
199
const text = getThisExpressions ( nodeLogicalExpression )
179
200
. map ( ( node ) => propertyGetterUtils . nodeToDependentKey ( node , context ) )
180
201
. join ( "', '" ) ;
181
- return fixer . replaceText ( nodeComputedProperty , `computed.${ macro } ('${ text } ')` ) ;
202
+ return fixer . replaceText (
203
+ nodeComputedProperty ,
204
+ makeFix ( nodeComputedProperty , macro , `'${ text } '` )
205
+ ) ;
182
206
} ,
183
207
} ) ;
184
208
}
@@ -196,7 +220,7 @@ module.exports = {
196
220
const restOfArgs = nodeCallExpression . arguments . map ( ( arg ) => sourceCode . getText ( arg ) ) ;
197
221
return fixer . replaceText (
198
222
nodeComputedProperty ,
199
- `computed. ${ macro } ( '${ arg1 } ', ${ restOfArgs . join ( ', ' ) } )`
223
+ makeFix ( nodeComputedProperty , macro , ` '${ arg1 } ', ${ restOfArgs . join ( ', ' ) } ` )
200
224
) ;
201
225
} ,
202
226
} ) ;
@@ -209,24 +233,42 @@ module.exports = {
209
233
return ;
210
234
}
211
235
212
- if ( node . arguments . length === 0 ) {
213
- return ;
214
- }
236
+ // Options:
237
+ const includeNativeGetters = context . options [ 0 ] && context . options [ 0 ] . includeNativeGetters ;
215
238
216
- const lastArg = node . arguments [ node . arguments . length - 1 ] ;
217
- if ( ! types . isFunctionExpression ( lastArg ) ) {
239
+ let getterBody ;
240
+ let nodeToReport ;
241
+ if (
242
+ node . arguments . length > 0 &&
243
+ types . isFunctionExpression ( node . arguments [ node . arguments . length - 1 ] )
244
+ ) {
245
+ // Example: computed('dependentKey', function() { return this.x })
246
+ getterBody = node . arguments [ node . arguments . length - 1 ] . body . body ;
247
+ nodeToReport = node ;
248
+ } else if (
249
+ includeNativeGetters &&
250
+ types . isDecorator ( node . parent ) &&
251
+ types . isMethodDefinition ( node . parent . parent ) &&
252
+ node . parent . parent . decorators . length === 1 &&
253
+ node . parent . parent . kind === 'get' &&
254
+ types . isFunctionExpression ( node . parent . parent . value )
255
+ ) {
256
+ // Example: @computed () get someProp() { return this.x; }
257
+ getterBody = node . parent . parent . value . body . body ;
258
+ nodeToReport = node . parent . parent ;
259
+ } else {
218
260
return ;
219
261
}
220
262
221
- if ( lastArg . body . body . length !== 1 ) {
263
+ if ( getterBody . length !== 1 ) {
222
264
return ;
223
265
}
224
266
225
- if ( ! types . isReturnStatement ( lastArg . body . body [ 0 ] ) ) {
267
+ if ( ! types . isReturnStatement ( getterBody [ 0 ] ) ) {
226
268
return ;
227
269
}
228
270
229
- const statement = lastArg . body . body [ 0 ] . argument ;
271
+ const statement = getterBody [ 0 ] . argument ;
230
272
if ( ! statement ) {
231
273
return ;
232
274
}
@@ -236,35 +278,35 @@ module.exports = {
236
278
statement . operator === '!' &&
237
279
propertyGetterUtils . isSimpleThisExpression ( statement . argument )
238
280
) {
239
- reportSingleArg ( node , statement . argument , 'not' ) ;
281
+ reportSingleArg ( nodeToReport , statement . argument , 'not' ) ;
240
282
} else if ( types . isLogicalExpression ( statement ) ) {
241
283
if ( isSimpleThisExpressionsInsideLogicalExpression ( statement , '&&' ) ) {
242
- reportLogicalExpression ( node , statement , 'and' ) ;
284
+ reportLogicalExpression ( nodeToReport , statement , 'and' ) ;
243
285
} else if ( isSimpleThisExpressionsInsideLogicalExpression ( statement , '||' ) ) {
244
- reportLogicalExpression ( node , statement , 'or' ) ;
286
+ reportLogicalExpression ( nodeToReport , statement , 'or' ) ;
245
287
}
246
288
} else if (
247
289
types . isBinaryExpression ( statement ) &&
248
290
types . isLiteral ( statement . right ) &&
249
291
propertyGetterUtils . isSimpleThisExpression ( statement . left )
250
292
) {
251
293
if ( statement . operator === '===' ) {
252
- reportBinaryExpression ( node , statement , 'equal' ) ;
294
+ reportBinaryExpression ( nodeToReport , statement , 'equal' ) ;
253
295
} else if ( statement . operator === '>' ) {
254
- reportBinaryExpression ( node , statement , 'gt' ) ;
296
+ reportBinaryExpression ( nodeToReport , statement , 'gt' ) ;
255
297
} else if ( statement . operator === '>=' ) {
256
- reportBinaryExpression ( node , statement , 'gte' ) ;
298
+ reportBinaryExpression ( nodeToReport , statement , 'gte' ) ;
257
299
} else if ( statement . operator === '<' ) {
258
- reportBinaryExpression ( node , statement , 'lt' ) ;
300
+ reportBinaryExpression ( nodeToReport , statement , 'lt' ) ;
259
301
} else if ( statement . operator === '<=' ) {
260
- reportBinaryExpression ( node , statement , 'lte' ) ;
302
+ reportBinaryExpression ( nodeToReport , statement , 'lte' ) ;
261
303
}
262
304
} else if ( propertyGetterUtils . isSimpleThisExpression ( statement ) ) {
263
- reportSingleArg ( node , statement , 'reads' ) ;
305
+ reportSingleArg ( nodeToReport , statement , 'reads' ) ;
264
306
} else if ( isThisPropertyFunctionCall ( statement , 'filterBy' ) ) {
265
- reportFunctionCall ( node , statement , 'filterBy' ) ;
307
+ reportFunctionCall ( nodeToReport , statement , 'filterBy' ) ;
266
308
} else if ( isThisPropertyFunctionCall ( statement , 'mapBy' ) ) {
267
- reportFunctionCall ( node , statement , 'mapBy' ) ;
309
+ reportFunctionCall ( nodeToReport , statement , 'mapBy' ) ;
268
310
}
269
311
} ,
270
312
} ;
0 commit comments