eslint 5.0.1 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/README.md +1 -1
- package/lib/code-path-analysis/code-path-analyzer.js +1 -1
- package/lib/config/config-validator.js +13 -6
- package/lib/formatters/stylish.js +1 -1
- package/lib/rules/no-catch-shadow.js +4 -1
- package/lib/rules/no-debugger.js +2 -10
- package/lib/rules/prefer-const.js +1 -1
- package/lib/rules/prefer-object-spread.js +147 -196
- package/lib/rules/sort-keys.js +1 -1
- package/lib/rules/wrap-regex.js +8 -4
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
v5.1.0 - July 8, 2018
|
2
|
+
|
3
|
+
* 7328f99 Build: package.json update for eslint-config-eslint release (ESLint Jenkins)
|
4
|
+
* b161f6b Build: Include prerelease install info in release blog post (#10463) (Kevin Partington)
|
5
|
+
* b2df738 Fix: prefer-object-spread duplicated comma (fixes #10512, fixes #10532) (#10524) (Toru Nagashima)
|
6
|
+
* d8c3a25 Fix: wrap-regex doesn't work in some expression(fixes #10573) (#10576) (薛定谔的猫)
|
7
|
+
* 114f42e Docs: Clarify option defaults in max-lines-per-function docs (#10569) (Chris Harwood)
|
8
|
+
* 63f36f7 Fix: sort-keys in an object that contains spread (fixes #10261) (#10495) (katerberg)
|
9
|
+
* 601a5c4 Fix: Prefer-const rule crashing on array destructuring (fixes #10520) (#10527) (Michael Mason)
|
10
|
+
* 143890a Update: Adjust grammar of error/warnings fixable (#10546) (Matt Mischuk)
|
11
|
+
* 8ee39c5 Chore: small refactor config-validator (#10565) (薛定谔的猫)
|
12
|
+
* 100f1be Docs: add note about release issues to readme (#10572) (Teddy Katz)
|
13
|
+
* 02efeac Fix: do not fail on nested unknown operators (#10561) (Rubén Norte)
|
14
|
+
* 92b19ca Chore: use eslintrc overrides(dogfooding) (#10566) (薛定谔的猫)
|
15
|
+
* 076a6b6 Docs: add actionable fix to no-irregular-whitespace (#10558) (Matteo Collina)
|
16
|
+
* de663ec Docs: Only successfully linted files are cached (fixes #9802) (#10557) (Kevin Partington)
|
17
|
+
* f0e22fc Upgrade: globals@11.7.0 (#10497) (薛定谔的猫)
|
18
|
+
* 8a2ff2c Docs: adding a section about disable rules for some files (#10536) (Wellington Soares)
|
19
|
+
* f22a3f8 Docs: fix a word in no-implied-eval (#10539) (Dan Homola)
|
20
|
+
* 20d8bbd Docs: add missing paragraph about "custom parsers" (#10547) (Pig Fang)
|
21
|
+
* b7addf6 Update: deprecate no-catch-shadow (fixes #10466) (#10526) (Toru Nagashima)
|
22
|
+
* e862dc3 Fix: Remove autofixer for no-debugger (fixes #10242) (#10509) (Teddy Katz)
|
23
|
+
|
1
24
|
v5.0.1 - June 25, 2018
|
2
25
|
|
3
26
|
* 196c102 Fix: valid-jsdoc should allow optional returns for async (fixes #10386) (#10480) (Mark Banner)
|
package/README.md
CHANGED
@@ -157,7 +157,7 @@ Join our [Mailing List](https://groups.google.com/group/eslint) or [Chatroom](ht
|
|
157
157
|
|
158
158
|
## Releases
|
159
159
|
|
160
|
-
We have scheduled releases every two weeks on Friday or Saturday.
|
160
|
+
We have scheduled releases every two weeks on Friday or Saturday. You can follow a [release issue](https://github.com/eslint/eslint/issues?q=is%3Aopen+is%3Aissue+label%3Arelease) for updates about the scheduling of any particular release.
|
161
161
|
|
162
162
|
## Semantic Versioning Policy
|
163
163
|
|
@@ -23,10 +23,15 @@ const ruleValidators = new WeakMap();
|
|
23
23
|
let validateSchema;
|
24
24
|
|
25
25
|
// Defitions for deprecation warnings.
|
26
|
-
const deprecationWarningMessages =
|
26
|
+
const deprecationWarningMessages = {
|
27
27
|
ESLINT_LEGACY_ECMAFEATURES: "The 'ecmaFeatures' config file property is deprecated, and has no effect.",
|
28
28
|
ESLINT_LEGACY_OBJECT_REST_SPREAD: "The 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' option is deprecated. Use 'parserOptions.ecmaVersion' instead."
|
29
|
-
}
|
29
|
+
};
|
30
|
+
const severityMap = {
|
31
|
+
error: 2,
|
32
|
+
warn: 1,
|
33
|
+
off: 0
|
34
|
+
};
|
30
35
|
|
31
36
|
/**
|
32
37
|
* Gets a complete options schema for a rule.
|
@@ -65,12 +70,14 @@ function getRuleOptionsSchema(rule) {
|
|
65
70
|
*/
|
66
71
|
function validateRuleSeverity(options) {
|
67
72
|
const severity = Array.isArray(options) ? options[0] : options;
|
73
|
+
const normSeverity = typeof severity === "string" ? severityMap[severity.toLowerCase()] : severity;
|
68
74
|
|
69
|
-
if (
|
70
|
-
|
75
|
+
if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) {
|
76
|
+
return normSeverity;
|
71
77
|
}
|
72
78
|
|
73
|
-
|
79
|
+
throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util.inspect(severity).replace(/'/g, "\"").replace(/\n/g, "")}').\n`);
|
80
|
+
|
74
81
|
}
|
75
82
|
|
76
83
|
/**
|
@@ -116,7 +123,7 @@ function validateRuleOptions(rule, ruleId, options, source) {
|
|
116
123
|
try {
|
117
124
|
const severity = validateRuleSeverity(options);
|
118
125
|
|
119
|
-
if (severity !== 0
|
126
|
+
if (severity !== 0) {
|
120
127
|
validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []);
|
121
128
|
}
|
122
129
|
} catch (err) {
|
@@ -89,7 +89,7 @@ module.exports = function(results) {
|
|
89
89
|
|
90
90
|
if (fixableErrorCount > 0 || fixableWarningCount > 0) {
|
91
91
|
output += chalk[summaryColor].bold([
|
92
|
-
" ", fixableErrorCount, pluralize(" error", fixableErrorCount), "
|
92
|
+
" ", fixableErrorCount, pluralize(" error", fixableErrorCount), " and ",
|
93
93
|
fixableWarningCount, pluralize(" warning", fixableWarningCount),
|
94
94
|
" potentially fixable with the `--fix` option.\n"
|
95
95
|
].join(""));
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Rule to flag variable leak in CatchClauses in IE 8 and earlier
|
3
3
|
* @author Ian Christian Myers
|
4
|
+
* @deprecated in ESLint v5.1.0
|
4
5
|
*/
|
5
6
|
|
6
7
|
"use strict";
|
@@ -21,8 +22,10 @@ module.exports = {
|
|
21
22
|
description: "disallow `catch` clause parameters from shadowing variables in the outer scope",
|
22
23
|
category: "Variables",
|
23
24
|
recommended: false,
|
24
|
-
url: "https://eslint.org/docs/rules/no-catch-shadow"
|
25
|
+
url: "https://eslint.org/docs/rules/no-catch-shadow",
|
26
|
+
replacedBy: ["no-shadow"]
|
25
27
|
},
|
28
|
+
deprecated: true,
|
26
29
|
|
27
30
|
schema: [],
|
28
31
|
|
package/lib/rules/no-debugger.js
CHANGED
@@ -5,8 +5,6 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
-
const astUtils = require("../ast-utils");
|
9
|
-
|
10
8
|
//------------------------------------------------------------------------------
|
11
9
|
// Rule Definition
|
12
10
|
//------------------------------------------------------------------------------
|
@@ -19,7 +17,7 @@ module.exports = {
|
|
19
17
|
recommended: true,
|
20
18
|
url: "https://eslint.org/docs/rules/no-debugger"
|
21
19
|
},
|
22
|
-
fixable:
|
20
|
+
fixable: null,
|
23
21
|
schema: [],
|
24
22
|
messages: {
|
25
23
|
unexpected: "Unexpected 'debugger' statement."
|
@@ -32,13 +30,7 @@ module.exports = {
|
|
32
30
|
DebuggerStatement(node) {
|
33
31
|
context.report({
|
34
32
|
node,
|
35
|
-
messageId: "unexpected"
|
36
|
-
fix(fixer) {
|
37
|
-
if (astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) {
|
38
|
-
return fixer.remove(node);
|
39
|
-
}
|
40
|
-
return null;
|
41
|
-
}
|
33
|
+
messageId: "unexpected"
|
42
34
|
});
|
43
35
|
}
|
44
36
|
};
|
@@ -170,7 +170,7 @@ function getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign) {
|
|
170
170
|
const elements = leftNode.elements;
|
171
171
|
|
172
172
|
hasOuterVariables = elements
|
173
|
-
.map(element => element.name)
|
173
|
+
.map(element => element && element.name)
|
174
174
|
.some(name => isOuterVariableInDestructing(name, variable.scope));
|
175
175
|
}
|
176
176
|
if (hasOuterVariables) {
|
@@ -6,21 +6,15 @@
|
|
6
6
|
|
7
7
|
"use strict";
|
8
8
|
|
9
|
-
const
|
9
|
+
const { CALL, ReferenceTracker } = require("eslint-utils");
|
10
|
+
const {
|
11
|
+
isCommaToken,
|
12
|
+
isOpeningParenToken,
|
13
|
+
isClosingParenToken,
|
14
|
+
isParenthesised
|
15
|
+
} = require("../ast-utils");
|
10
16
|
|
11
|
-
|
12
|
-
* Helper that checks if the node is an Object.assign call
|
13
|
-
* @param {ASTNode} node - The node that the rule warns on
|
14
|
-
* @returns {boolean} - Returns true if the node is an Object.assign call
|
15
|
-
*/
|
16
|
-
function isObjectAssign(node) {
|
17
|
-
return (
|
18
|
-
node.callee &&
|
19
|
-
node.callee.type === "MemberExpression" &&
|
20
|
-
node.callee.object.name === "Object" &&
|
21
|
-
node.callee.property.name === "assign"
|
22
|
-
);
|
23
|
-
}
|
17
|
+
const ANY_SPACE = /\s/;
|
24
18
|
|
25
19
|
/**
|
26
20
|
* Helper that checks if the Object.assign call has array spread
|
@@ -35,15 +29,12 @@ function hasArraySpread(node) {
|
|
35
29
|
* Helper that checks if the node needs parentheses to be valid JS.
|
36
30
|
* The default is to wrap the node in parentheses to avoid parsing errors.
|
37
31
|
* @param {ASTNode} node - The node that the rule warns on
|
32
|
+
* @param {Object} sourceCode - in context sourcecode object
|
38
33
|
* @returns {boolean} - Returns true if the node needs parentheses
|
39
34
|
*/
|
40
|
-
function needsParens(node) {
|
35
|
+
function needsParens(node, sourceCode) {
|
41
36
|
const parent = node.parent;
|
42
37
|
|
43
|
-
if (!parent || !node.type) {
|
44
|
-
return true;
|
45
|
-
}
|
46
|
-
|
47
38
|
switch (parent.type) {
|
48
39
|
case "VariableDeclarator":
|
49
40
|
case "ArrayExpression":
|
@@ -51,180 +42,168 @@ function needsParens(node) {
|
|
51
42
|
case "CallExpression":
|
52
43
|
case "Property":
|
53
44
|
return false;
|
45
|
+
case "AssignmentExpression":
|
46
|
+
return parent.left === node && !isParenthesised(sourceCode, node);
|
54
47
|
default:
|
55
|
-
return
|
48
|
+
return !isParenthesised(sourceCode, node);
|
56
49
|
}
|
57
50
|
}
|
58
51
|
|
59
52
|
/**
|
60
53
|
* Determines if an argument needs parentheses. The default is to not add parens.
|
61
54
|
* @param {ASTNode} node - The node to be checked.
|
55
|
+
* @param {Object} sourceCode - in context sourcecode object
|
62
56
|
* @returns {boolean} True if the node needs parentheses
|
63
57
|
*/
|
64
|
-
function argNeedsParens(node) {
|
65
|
-
if (!node.type) {
|
66
|
-
return false;
|
67
|
-
}
|
68
|
-
|
58
|
+
function argNeedsParens(node, sourceCode) {
|
69
59
|
switch (node.type) {
|
70
60
|
case "AssignmentExpression":
|
71
61
|
case "ArrowFunctionExpression":
|
72
62
|
case "ConditionalExpression":
|
73
|
-
return
|
63
|
+
return !isParenthesised(sourceCode, node);
|
74
64
|
default:
|
75
65
|
return false;
|
76
66
|
}
|
77
67
|
}
|
78
68
|
|
79
69
|
/**
|
80
|
-
*
|
81
|
-
*
|
82
|
-
* @param {
|
83
|
-
* @
|
70
|
+
* Get the parenthesis tokens of a given ObjectExpression node.
|
71
|
+
* This incldues the braces of the object literal and enclosing parentheses.
|
72
|
+
* @param {ASTNode} node The node to get.
|
73
|
+
* @param {Token} leftArgumentListParen The opening paren token of the argument list.
|
74
|
+
* @param {SourceCode} sourceCode The source code object to get tokens.
|
75
|
+
* @returns {Token[]} The parenthesis tokens of the node. This is sorted by the location.
|
84
76
|
*/
|
85
|
-
function
|
86
|
-
const
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
const commentEnd = arr[1];
|
103
|
-
|
104
|
-
if (insertIndex < commentStart || insertIndex > commentEnd) {
|
105
|
-
validWhitespaceMatches.push(insertIndex);
|
106
|
-
}
|
107
|
-
});
|
108
|
-
});
|
109
|
-
const insertPos = Math.max(...validWhitespaceMatches);
|
110
|
-
const regex = new RegExp(`^((?:.|[^/s/S]){${insertPos}}) *`);
|
77
|
+
function getParenTokens(node, leftArgumentListParen, sourceCode) {
|
78
|
+
const parens = [sourceCode.getFirstToken(node), sourceCode.getLastToken(node)];
|
79
|
+
let leftNext = sourceCode.getTokenBefore(node);
|
80
|
+
let rightNext = sourceCode.getTokenAfter(node);
|
81
|
+
|
82
|
+
// Note: don't include the parens of the argument list.
|
83
|
+
while (
|
84
|
+
leftNext &&
|
85
|
+
rightNext &&
|
86
|
+
leftNext.range[0] > leftArgumentListParen.range[0] &&
|
87
|
+
isOpeningParenToken(leftNext) &&
|
88
|
+
isClosingParenToken(rightNext)
|
89
|
+
) {
|
90
|
+
parens.push(leftNext, rightNext);
|
91
|
+
leftNext = sourceCode.getTokenBefore(leftNext);
|
92
|
+
rightNext = sourceCode.getTokenAfter(rightNext);
|
93
|
+
}
|
111
94
|
|
112
|
-
return
|
95
|
+
return parens.sort((a, b) => a.range[0] - b.range[0]);
|
113
96
|
}
|
114
97
|
|
115
98
|
/**
|
116
|
-
*
|
117
|
-
* @param {
|
118
|
-
* @param {
|
119
|
-
* @
|
120
|
-
* @param {array} comments - comments inside checked node
|
121
|
-
* @returns {string} - formatted argument
|
99
|
+
* Get the range of a given token and around whitespaces.
|
100
|
+
* @param {Token} token The token to get range.
|
101
|
+
* @param {SourceCode} sourceCode The source code object to get tokens.
|
102
|
+
* @returns {number} The end of the range of the token and around whitespaces.
|
122
103
|
*/
|
123
|
-
function
|
124
|
-
const text = sourceCode.
|
125
|
-
|
126
|
-
const spread = arg.type === "SpreadElement" ? "" : "...";
|
127
|
-
|
128
|
-
if (arg.type === "ObjectExpression" && arg.properties.length === 0) {
|
129
|
-
return "";
|
130
|
-
}
|
104
|
+
function getStartWithSpaces(token, sourceCode) {
|
105
|
+
const text = sourceCode.text;
|
106
|
+
let start = token.range[0];
|
131
107
|
|
132
|
-
|
108
|
+
// If the previous token is a line comment then skip this step to avoid commenting this token out.
|
109
|
+
{
|
110
|
+
const prevToken = sourceCode.getTokenBefore(token, { includeComments: true });
|
133
111
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
* having multiple spaces around the object expression depending on how the object properties are spaced.
|
138
|
-
*/
|
139
|
-
const formattedObjectLiteral = text.replace(/^(.*){ */, "$1").replace(/ *}([^}]*)$/, "$1");
|
140
|
-
|
141
|
-
return isLast ? formattedObjectLiteral : addComma(formattedObjectLiteral, comments);
|
112
|
+
if (prevToken && prevToken.type === "Line") {
|
113
|
+
return start;
|
114
|
+
}
|
142
115
|
}
|
143
116
|
|
144
|
-
|
145
|
-
|
117
|
+
// Detect spaces before the token.
|
118
|
+
while (ANY_SPACE.test(text[start - 1] || "")) {
|
119
|
+
start -= 1;
|
146
120
|
}
|
147
121
|
|
148
|
-
return
|
122
|
+
return start;
|
149
123
|
}
|
150
124
|
|
151
125
|
/**
|
152
|
-
*
|
153
|
-
* @param {
|
154
|
-
* @param {
|
155
|
-
* @returns {
|
126
|
+
* Get the range of a given token and around whitespaces.
|
127
|
+
* @param {Token} token The token to get range.
|
128
|
+
* @param {SourceCode} sourceCode The source code object to get tokens.
|
129
|
+
* @returns {number} The start of the range of the token and around whitespaces.
|
156
130
|
*/
|
157
|
-
function
|
158
|
-
|
159
|
-
|
160
|
-
const firstArg = args[0];
|
161
|
-
const lastArg = args[args.length - 1];
|
162
|
-
const parens = needsParens(node);
|
163
|
-
const comments = sourceCode.getCommentsInside(node);
|
164
|
-
const replaceObjectAssignStart = fixer.replaceTextRange(
|
165
|
-
[node.range[0], firstArg.range[0]],
|
166
|
-
`${parens ? "({" : "{"}`
|
167
|
-
);
|
131
|
+
function getEndWithSpaces(token, sourceCode) {
|
132
|
+
const text = sourceCode.text;
|
133
|
+
let end = token.range[1];
|
168
134
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
const insertBody = fixer.replaceTextRange([firstArg.range[0], lastArg.range[1]], handleArgs.join(""));
|
174
|
-
const replaceObjectAssignEnd = fixer.replaceTextRange([lastArg.range[1], node.range[1]], `${parens ? "})" : "}"}`);
|
135
|
+
// Detect spaces after the token.
|
136
|
+
while (ANY_SPACE.test(text[end] || "")) {
|
137
|
+
end += 1;
|
138
|
+
}
|
175
139
|
|
176
|
-
|
177
|
-
replaceObjectAssignStart,
|
178
|
-
insertBody,
|
179
|
-
replaceObjectAssignEnd
|
180
|
-
];
|
181
|
-
};
|
140
|
+
return end;
|
182
141
|
}
|
183
142
|
|
184
143
|
/**
|
185
|
-
* Autofixes the Object.assign call
|
144
|
+
* Autofixes the Object.assign call to use an object spread instead.
|
186
145
|
* @param {ASTNode|null} node - The node that the rule warns on, i.e. the Object.assign call
|
187
146
|
* @param {string} sourceCode - sourceCode of the Object.assign call
|
188
|
-
* @returns {Function} autofixer - replaces the Object.assign with a object
|
147
|
+
* @returns {Function} autofixer - replaces the Object.assign with a spread object.
|
189
148
|
*/
|
190
|
-
function
|
191
|
-
return fixer
|
192
|
-
const
|
193
|
-
const
|
149
|
+
function defineFixer(node, sourceCode) {
|
150
|
+
return function *(fixer) {
|
151
|
+
const leftParen = sourceCode.getTokenAfter(node.callee, isOpeningParenToken);
|
152
|
+
const rightParen = sourceCode.getLastToken(node);
|
153
|
+
|
154
|
+
// Remove the callee `Object.assign`
|
155
|
+
yield fixer.remove(node.callee);
|
156
|
+
|
157
|
+
// Replace the parens of argument list to braces.
|
158
|
+
if (needsParens(node, sourceCode)) {
|
159
|
+
yield fixer.replaceText(leftParen, "({");
|
160
|
+
yield fixer.replaceText(rightParen, "})");
|
161
|
+
} else {
|
162
|
+
yield fixer.replaceText(leftParen, "{");
|
163
|
+
yield fixer.replaceText(rightParen, "}");
|
164
|
+
}
|
194
165
|
|
195
|
-
|
196
|
-
|
197
|
-
|
166
|
+
// Process arguments.
|
167
|
+
for (const argNode of node.arguments) {
|
168
|
+
const innerParens = getParenTokens(argNode, leftParen, sourceCode);
|
169
|
+
const left = innerParens.shift();
|
170
|
+
const right = innerParens.pop();
|
198
171
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
* @returns {boolean} - true if node is an assignment, variable declaration, or import statement
|
203
|
-
*/
|
204
|
-
function isModifier(node) {
|
205
|
-
if (!node.type) {
|
206
|
-
return false;
|
207
|
-
}
|
172
|
+
if (argNode.type === "ObjectExpression") {
|
173
|
+
const maybeTrailingComma = sourceCode.getLastToken(argNode, 1);
|
174
|
+
const maybeArgumentComma = sourceCode.getTokenAfter(right);
|
208
175
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
176
|
+
/*
|
177
|
+
* Make bare this object literal.
|
178
|
+
* And remove spaces inside of the braces for better formatting.
|
179
|
+
*/
|
180
|
+
for (const innerParen of innerParens) {
|
181
|
+
yield fixer.remove(innerParen);
|
182
|
+
}
|
183
|
+
yield fixer.removeRange([left.range[0], getEndWithSpaces(left, sourceCode)]);
|
184
|
+
yield fixer.removeRange([getStartWithSpaces(right, sourceCode), right.range[1]]);
|
213
185
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
186
|
+
// Remove the comma of this argument if it's duplication.
|
187
|
+
if (
|
188
|
+
(argNode.properties.length === 0 || isCommaToken(maybeTrailingComma)) &&
|
189
|
+
isCommaToken(maybeArgumentComma)
|
190
|
+
) {
|
191
|
+
yield fixer.remove(maybeArgumentComma);
|
192
|
+
}
|
193
|
+
} else {
|
194
|
+
|
195
|
+
// Make spread.
|
196
|
+
if (argNeedsParens(argNode, sourceCode)) {
|
197
|
+
yield fixer.insertTextBefore(left, "...(");
|
198
|
+
yield fixer.insertTextAfter(right, ")");
|
199
|
+
} else {
|
200
|
+
yield fixer.insertTextBefore(left, "...");
|
201
|
+
}
|
202
|
+
}
|
203
|
+
}
|
204
|
+
};
|
225
205
|
}
|
226
206
|
|
227
|
-
|
228
207
|
module.exports = {
|
229
208
|
meta: {
|
230
209
|
docs: {
|
@@ -242,61 +221,33 @@ module.exports = {
|
|
242
221
|
}
|
243
222
|
},
|
244
223
|
|
245
|
-
create
|
224
|
+
create(context) {
|
246
225
|
const sourceCode = context.getSourceCode();
|
247
|
-
const scope = context.getScope();
|
248
|
-
const objectVariable = scope.variables.filter(variable => variable.name === "Object");
|
249
|
-
const moduleReferences = scope.childScopes.filter(childScope => {
|
250
|
-
const varNamedObject = childScope.variables.filter(variable => variable.name === "Object");
|
251
|
-
|
252
|
-
return childScope.type === "module" && varNamedObject.length;
|
253
|
-
});
|
254
|
-
const references = [].concat(...objectVariable.map(variable => variable.references || []));
|
255
226
|
|
256
227
|
return {
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
node,
|
279
|
-
|
280
|
-
fix: autofixObjectLiteral(node, sourceCode)
|
281
|
-
});
|
282
|
-
}
|
283
|
-
|
284
|
-
/*
|
285
|
-
* The condition below warns on `Object.assign` calls that that have
|
286
|
-
* an object literal as the first argument and have a second argument
|
287
|
-
* that can be spread. e.g `Object.assign({ foo: bar }, baz)`
|
288
|
-
*/
|
289
|
-
if (
|
290
|
-
node.arguments.length > 1 &&
|
291
|
-
node.arguments[0].type === "ObjectExpression" &&
|
292
|
-
isObjectAssign(node) &&
|
293
|
-
!hasArraySpread(node)
|
294
|
-
) {
|
295
|
-
context.report({
|
296
|
-
node,
|
297
|
-
messageId: "useSpreadMessage",
|
298
|
-
fix: autofixSpread(node, sourceCode)
|
299
|
-
});
|
228
|
+
Program() {
|
229
|
+
const scope = context.getScope();
|
230
|
+
const tracker = new ReferenceTracker(scope);
|
231
|
+
const trackMap = {
|
232
|
+
Object: {
|
233
|
+
assign: { [CALL]: true }
|
234
|
+
}
|
235
|
+
};
|
236
|
+
|
237
|
+
// Iterate all calls of `Object.assign` (only of the global variable `Object`).
|
238
|
+
for (const { node } of tracker.iterateGlobalReferences(trackMap)) {
|
239
|
+
if (
|
240
|
+
node.arguments.length >= 1 &&
|
241
|
+
node.arguments[0].type === "ObjectExpression" &&
|
242
|
+
!hasArraySpread(node)
|
243
|
+
) {
|
244
|
+
const messageId = node.arguments.length === 1
|
245
|
+
? "useLiteralMessage"
|
246
|
+
: "useSpreadMessage";
|
247
|
+
const fix = defineFixer(node, sourceCode);
|
248
|
+
|
249
|
+
context.report({ node, messageId, fix });
|
250
|
+
}
|
300
251
|
}
|
301
252
|
}
|
302
253
|
};
|
package/lib/rules/sort-keys.js
CHANGED
package/lib/rules/wrap-regex.js
CHANGED
@@ -20,7 +20,10 @@ module.exports = {
|
|
20
20
|
|
21
21
|
schema: [],
|
22
22
|
|
23
|
-
fixable: "code"
|
23
|
+
fixable: "code",
|
24
|
+
messages: {
|
25
|
+
requireParens: "Wrap the regexp literal in parens to disambiguate the slash."
|
26
|
+
}
|
24
27
|
},
|
25
28
|
|
26
29
|
create(context) {
|
@@ -33,15 +36,16 @@ module.exports = {
|
|
33
36
|
nodeType = token.type;
|
34
37
|
|
35
38
|
if (nodeType === "RegularExpression") {
|
36
|
-
const
|
39
|
+
const beforeToken = sourceCode.getTokenBefore(node);
|
40
|
+
const afterToken = sourceCode.getTokenAfter(node);
|
37
41
|
const ancestors = context.getAncestors();
|
38
42
|
const grandparent = ancestors[ancestors.length - 1];
|
39
43
|
|
40
44
|
if (grandparent.type === "MemberExpression" && grandparent.object === node &&
|
41
|
-
(
|
45
|
+
!(beforeToken && beforeToken.value === "(" && afterToken && afterToken.value === ")")) {
|
42
46
|
context.report({
|
43
47
|
node,
|
44
|
-
|
48
|
+
messageId: "requireParens",
|
45
49
|
fix: fixer => fixer.replaceText(node, `(${sourceCode.getText(node)})`)
|
46
50
|
});
|
47
51
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "5.0
|
3
|
+
"version": "5.1.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -42,6 +42,7 @@
|
|
42
42
|
"debug": "^3.1.0",
|
43
43
|
"doctrine": "^2.1.0",
|
44
44
|
"eslint-scope": "^4.0.0",
|
45
|
+
"eslint-utils": "^1.3.1",
|
45
46
|
"eslint-visitor-keys": "^1.0.0",
|
46
47
|
"espree": "^4.0.0",
|
47
48
|
"esquery": "^1.0.1",
|
@@ -49,7 +50,7 @@
|
|
49
50
|
"file-entry-cache": "^2.0.0",
|
50
51
|
"functional-red-black-tree": "^1.0.1",
|
51
52
|
"glob": "^7.1.2",
|
52
|
-
"globals": "^11.
|
53
|
+
"globals": "^11.7.0",
|
53
54
|
"ignore": "^3.3.3",
|
54
55
|
"imurmurhash": "^0.1.4",
|
55
56
|
"inquirer": "^5.2.0",
|