Skip to content

Commit 9ae3226

Browse files
committed
wip
update
1 parent b6ba741 commit 9ae3226

File tree

2 files changed

+75
-32
lines changed

2 files changed

+75
-32
lines changed

lib/rules/fixer-return.js

+73-27
Original file line numberDiff line numberDiff line change
@@ -5,50 +5,96 @@
55

66
'use strict';
77

8-
const utils = require('../utils');
8+
// ------------------------------------------------------------------------------
9+
// Requirements
10+
// ------------------------------------------------------------------------------
911

12+
// const utils = require('../utils');
13+
const astUtils = require('../ast-utils.js');
1014
// ------------------------------------------------------------------------------
1115
// Rule Definition
1216
// ------------------------------------------------------------------------------
1317

1418
module.exports = {
1519
meta: {
1620
docs: {
17-
description: 'enforces fixer function always return a value',
18-
category: 'Rules',
21+
description: 'Expected fixer function to always return a value.',
22+
category: 'Possible Errors',
1923
recommended: false,
2024
},
21-
fixable: null, // or "code" or "whitespace"
22-
schema: [],
25+
fixable: null,
2326
},
2427

2528
create (context) {
26-
// ----------------------------------------------------------------------
27-
// Public
28-
// ----------------------------------------------------------------------
29-
const message = 'fixer function is expected to return a value.';
30-
const sourceCode = context.getSourceCode();
29+
const message = 'Expected fixer function to always return a value.';
30+
let funcInfo = {
31+
upper: null,
32+
codePath: null,
33+
hasReturn: false,
34+
shouldCheck: false,
35+
node: null,
36+
};
37+
38+
/**
39+
* Checks whether or not the last code path segment is reachable.
40+
* Then reports this function if the segment is reachable.
41+
*
42+
* If the last code path segment is reachable, there are paths which are not
43+
* returned or thrown.
44+
*
45+
* @param {ASTNode} node - A node to check.
46+
* @returns {void}
47+
*/
48+
function checkLastSegment (node) {
49+
if (funcInfo.shouldCheck && funcInfo.codePath.currentSegments.some(segment => segment.reachable)) {
50+
context.report({
51+
node,
52+
loc: (node.id || node).loc.start,
53+
message,
54+
});
55+
}
56+
}
3157

3258
return {
33-
Program (ast) {
34-
utils.getTestInfo(context, ast).forEach(testRun => {
35-
[testRun.valid, testRun.invalid].forEach(tests => {
36-
const cache = Object.create(null);
37-
// to avoid tests being null
38-
(tests || []).forEach(test => {
39-
const testCode = sourceCode.getText(test);
40-
if (cache[testCode]) {
41-
context.report({
42-
node: test,
43-
message,
44-
});
45-
} else {
46-
cache[testCode] = true;
47-
}
59+
60+
// Stacks this function's information.
61+
onCodePathStart (codePath, node) {
62+
const parent = node.parent;
63+
64+
funcInfo = {
65+
upper: funcInfo,
66+
codePath,
67+
hasReturn: false,
68+
shouldCheck:
69+
node.type === 'FunctionExpression' &&
70+
node.body.type === 'BlockStatement' &&
71+
// check if it is naming fix
72+
astUtils.getStaticPropertyName(parent) === 'fix',
73+
node,
74+
};
75+
},
76+
77+
// Pops this function's information.
78+
onCodePathEnd () {
79+
funcInfo = funcInfo.upper;
80+
},
81+
82+
// Checks the return statement is valid.
83+
ReturnStatement (node) {
84+
if (funcInfo.shouldCheck) {
85+
funcInfo.hasReturn = true;
86+
87+
if (!node.argument) {
88+
context.report({
89+
node,
90+
message,
4891
});
49-
});
50-
});
92+
}
93+
}
5194
},
95+
96+
// Reports a given function if the last path is reachable.
97+
'FunctionExpression:exit': checkLastSegment,
5298
};
5399
},
54100
};

tests/lib/rules/fixer-return.js

+2-5
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,19 @@
1212
const rule = require('../../../lib/rules/fixer-return');
1313
const RuleTester = require('eslint').RuleTester;
1414

15-
const ERROR = { message: 'fixer function is expected to return a value.' };
15+
const ERROR = { message: 'Expected fixer function to always return a value.' };
1616

1717
// ------------------------------------------------------------------------------
1818
// Tests
1919
// ------------------------------------------------------------------------------
2020

21-
const ruleTester = new RuleTester();
21+
const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
2222
ruleTester.run('fixer-return', rule, {
2323
valid: [
2424
`
2525
module.exports = {
2626
create: function(context) {
2727
context.report( {
28-
node,
2928
fix: function(fixer) {
3029
return fixer.foo();
3130
}
@@ -37,7 +36,6 @@ ruleTester.run('fixer-return', rule, {
3736
module.exports = {
3837
create: function(context) {
3938
context.report({
40-
node,
4139
fix: fixer => fixer.foo()
4240
});
4341
}
@@ -51,7 +49,6 @@ ruleTester.run('fixer-return', rule, {
5149
module.exports = {
5250
create: function(context) {
5351
context.report({
54-
node,
5552
fix(fixer) {
5653
fixer.foo();
5754
}

0 commit comments

Comments
 (0)