Skip to content

Commit 6762a3f

Browse files
authored
Fix: update fixer-return rule to handle arrow function expressions (#144)
1 parent 7bf777b commit 6762a3f

File tree

2 files changed

+147
-42
lines changed

2 files changed

+147
-42
lines changed

lib/rules/fixer-return.js

+30-9
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,17 @@ module.exports = {
4747
* If not, report the function as a violation.
4848
*
4949
* @param {ASTNode} node - A node to check.
50+
* @param {Location} loc - Optional location to report violation on.
5051
* @returns {void}
5152
*/
52-
function checkLastSegment (node) {
53+
function ensureFunctionReturnedFix (node, loc = (node.id || node).loc.start) {
5354
if (
54-
funcInfo.shouldCheck &&
55-
(
56-
(node.generator && !funcInfo.hasYieldWithFixer) || // Generator function never yielded a fix
57-
(!node.generator && !funcInfo.hasReturnWithFixer) // Non-generator function never returned a fix
58-
)
55+
(node.generator && !funcInfo.hasYieldWithFixer) || // Generator function never yielded a fix
56+
(!node.generator && !funcInfo.hasReturnWithFixer) // Non-generator function never returned a fix
5957
) {
6058
context.report({
6159
node,
62-
loc: (node.id || node).loc.start,
60+
loc,
6361
messageId: 'missingFix',
6462
});
6563
}
@@ -103,7 +101,7 @@ module.exports = {
103101
const parent = node.parent;
104102

105103
// Whether we are inside the fixer function we care about.
106-
const shouldCheck = node.type === 'FunctionExpression' &&
104+
const shouldCheck = ['FunctionExpression', 'ArrowFunctionExpression'].includes(node.type) &&
107105
parent.parent.type === 'ObjectExpression' &&
108106
parent.parent.parent.type === 'CallExpression' &&
109107
contextIdentifiers.has(parent.parent.parent.callee.object) &&
@@ -140,7 +138,30 @@ module.exports = {
140138
},
141139

142140
// Ensure the current fixer function returned or yielded a fix.
143-
'FunctionExpression:exit': checkLastSegment,
141+
'FunctionExpression:exit' (node) {
142+
if (funcInfo.shouldCheck) {
143+
ensureFunctionReturnedFix(node);
144+
}
145+
},
146+
147+
// Ensure the current (arrow) fixer function returned a fix.
148+
'ArrowFunctionExpression:exit' (node) {
149+
if (funcInfo.shouldCheck) {
150+
const loc = context.getSourceCode().getTokenBefore(node.body).loc; // Show violation on arrow (=>).
151+
if (node.expression) {
152+
// When the return is implied (no curly braces around the body), we have to check the single body node directly.
153+
if (!isFix(node.body)) {
154+
context.report({
155+
node,
156+
loc,
157+
messageId: 'missingFix',
158+
});
159+
}
160+
} else {
161+
ensureFunctionReturnedFix(node, loc);
162+
}
163+
}
164+
},
144165
};
145166
},
146167
};

tests/lib/rules/fixer-return.js

+117-33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* @fileoverview enforces always return from a fixer function
2+
* @fileoverview Require fixer function to return a fix
33
* @author 薛定谔的猫<[email protected]>
44
*/
55

@@ -12,8 +12,6 @@
1212
const rule = require('../../../lib/rules/fixer-return');
1313
const RuleTester = require('eslint').RuleTester;
1414

15-
const ERROR = { messageId: 'missingFix', type: 'FunctionExpression' };
16-
1715
// ------------------------------------------------------------------------------
1816
// Tests
1917
// ------------------------------------------------------------------------------
@@ -46,6 +44,38 @@ ruleTester.run('fixer-return', rule, {
4644
}
4745
};
4846
`,
47+
// Not the right fix function.
48+
`
49+
module.exports = {
50+
create: function(context) {
51+
context.report( {
52+
notFix: function(fixer) {
53+
}
54+
});
55+
}
56+
};
57+
`,
58+
// Not the right fix function (arrow function with implied return)
59+
`
60+
module.exports = {
61+
create: function(context) {
62+
context.report( {
63+
notFix: fixer => undefined
64+
});
65+
}
66+
};
67+
`,
68+
// Not the right fix function (arrow function)
69+
`
70+
module.exports = {
71+
create: function(context) {
72+
context.report( {
73+
notFix: fixer => {}
74+
});
75+
}
76+
};
77+
`,
78+
// Arrow function (expression)
4979
`
5080
module.exports = {
5181
create: function(context) {
@@ -55,6 +85,17 @@ ruleTester.run('fixer-return', rule, {
5585
}
5686
};
5787
`,
88+
// Arrow function (with return)
89+
`
90+
module.exports = {
91+
create: function(context) {
92+
context.report({
93+
fix: fixer => {return fixer.foo();}
94+
});
95+
}
96+
};
97+
`,
98+
// Generator
5899
`
59100
module.exports = {
60101
create: function (context) {
@@ -196,7 +237,50 @@ ruleTester.run('fixer-return', rule, {
196237
}
197238
};
198239
`,
199-
errors: [ERROR],
240+
errors: [{ messageId: 'missingFix', type: 'FunctionExpression', line: 5, column: 24 }],
241+
},
242+
{
243+
// Fix but missing return (arrow function, report on arrow)
244+
code: `
245+
module.exports = {
246+
create: function(context) {
247+
context.report({
248+
fix: (fixer) => {
249+
fixer.foo();
250+
}
251+
});
252+
}
253+
};
254+
`,
255+
errors: [{ messageId: 'missingFix', type: 'ArrowFunctionExpression', line: 5, endLine: 5, column: 34, endColumn: 36 }],
256+
},
257+
{
258+
// With no autofix (arrow function, explicit return, report on arrow)
259+
code: `
260+
module.exports = {
261+
create: function(context) {
262+
context.report({
263+
fix: (fixer) => {
264+
return undefined;
265+
}
266+
});
267+
}
268+
};
269+
`,
270+
errors: [{ messageId: 'missingFix', type: 'ArrowFunctionExpression', line: 5, endLine: 5, column: 34, endColumn: 36 }],
271+
},
272+
{
273+
// With no autofix (arrow function, implied return, report on arrow)
274+
code: `
275+
module.exports = {
276+
create: function(context) {
277+
context.report( {
278+
fix: fixer => undefined
279+
});
280+
}
281+
};
282+
`,
283+
errors: [{ messageId: 'missingFix', type: 'ArrowFunctionExpression', line: 5, endLine: 5, column: 32, endColumn: 34 }],
200284
},
201285
{
202286
// Fix but missing yield (generator)
@@ -211,22 +295,22 @@ ruleTester.run('fixer-return', rule, {
211295
}
212296
};
213297
`,
214-
errors: [ERROR],
298+
errors: [{ messageId: 'missingFix', type: 'FunctionExpression', line: 5, column: 25 }],
215299
},
216300
{
217301
// With no autofix (only yield undefined)
218302
code: `
219-
module.exports = {
220-
create: function(context) {
221-
context.report({
222-
*fix(fixer) {
223-
yield undefined;
224-
}
225-
});
226-
}
227-
};
228-
`,
229-
errors: [ERROR],
303+
module.exports = {
304+
create: function(context) {
305+
context.report({
306+
*fix(fixer) {
307+
yield undefined;
308+
}
309+
});
310+
}
311+
};
312+
`,
313+
errors: [{ messageId: 'missingFix', type: 'FunctionExpression', line: 5, column: 25 }],
230314
},
231315
{
232316
// With no autofix (only return null)
@@ -241,7 +325,7 @@ ruleTester.run('fixer-return', rule, {
241325
}
242326
};
243327
`,
244-
errors: [ERROR],
328+
errors: [{ messageId: 'missingFix', type: 'FunctionExpression', line: 5, column: 26 }],
245329
},
246330
{
247331
// With no autofix (only return undefined)
@@ -256,23 +340,23 @@ ruleTester.run('fixer-return', rule, {
256340
}
257341
};
258342
`,
259-
errors: [ERROR],
343+
errors: [{ messageId: 'missingFix', type: 'FunctionExpression', line: 5, column: 26 }],
260344
},
261345
{
262346
// With no autofix (only return undefined, but in variable)
263347
code: `
264-
module.exports = {
265-
create: function(context) {
266-
context.report( {
267-
fix: function(fixer) {
268-
const returnValue = undefined;
269-
return returnValue;
270-
}
271-
});
272-
}
273-
};
274-
`,
275-
errors: [ERROR],
348+
module.exports = {
349+
create: function(context) {
350+
context.report( {
351+
fix: function(fixer) {
352+
const returnValue = undefined;
353+
return returnValue;
354+
}
355+
});
356+
}
357+
};
358+
`,
359+
errors: [{ messageId: 'missingFix', type: 'FunctionExpression', line: 5, column: 26 }],
276360
},
277361
{
278362
// With no autofix (only return implicit undefined)
@@ -287,7 +371,7 @@ ruleTester.run('fixer-return', rule, {
287371
}
288372
};
289373
`,
290-
errors: [ERROR],
374+
errors: [{ messageId: 'missingFix', type: 'FunctionExpression', line: 5, column: 26 }],
291375
},
292376
{
293377
// With no autofix (only return empty array)
@@ -302,7 +386,7 @@ ruleTester.run('fixer-return', rule, {
302386
}
303387
};
304388
`,
305-
errors: [ERROR],
389+
errors: [{ messageId: 'missingFix', type: 'FunctionExpression', line: 5, column: 26 }],
306390
},
307391
{
308392
// With no autofix (no return, empty function)
@@ -316,7 +400,7 @@ ruleTester.run('fixer-return', rule, {
316400
}
317401
};
318402
`,
319-
errors: [ERROR],
403+
errors: [{ messageId: 'missingFix', type: 'FunctionExpression', line: 5, column: 26 }],
320404
},
321405
],
322406
});

0 commit comments

Comments
 (0)