eslint 3.18.0 → 3.19.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 +39 -0
- package/README.md +1 -0
- package/lib/config/config-rule.js +14 -10
- package/lib/config/plugins.js +19 -8
- package/lib/eslint.js +6 -5
- package/lib/formatters/codeframe.js +4 -9
- package/lib/rules/arrow-body-style.js +2 -2
- package/lib/rules/arrow-parens.js +9 -3
- package/lib/rules/comma-dangle.js +3 -2
- package/lib/rules/comma-spacing.js +4 -14
- package/lib/rules/comma-style.js +8 -14
- package/lib/rules/curly.js +2 -2
- package/lib/rules/dot-notation.js +12 -6
- package/lib/rules/lines-around-directive.js +1 -1
- package/lib/rules/new-parens.js +7 -21
- package/lib/rules/no-cond-assign.js +4 -17
- package/lib/rules/no-else-return.js +6 -3
- package/lib/rules/no-extra-parens.js +47 -103
- package/lib/rules/no-extra-semi.js +3 -2
- package/lib/rules/no-implicit-coercion.js +21 -8
- package/lib/rules/no-native-reassign.js +1 -1
- package/lib/rules/no-negated-in-lhs.js +1 -1
- package/lib/rules/no-param-reassign.js +8 -1
- package/lib/rules/no-restricted-syntax.js +33 -6
- package/lib/rules/no-sequences.js +2 -2
- package/lib/rules/no-unsafe-negation.js +1 -1
- package/lib/rules/no-useless-computed-key.js +12 -1
- package/lib/rules/object-curly-spacing.js +2 -2
- package/lib/rules/object-shorthand.js +8 -2
- package/lib/rules/operator-assignment.js +20 -3
- package/lib/rules/prefer-const.js +1 -1
- package/lib/rules/quotes.js +1 -0
- package/lib/rules/semi-spacing.js +2 -15
- package/lib/rules/semi.js +4 -12
- package/lib/rules/space-before-function-paren.js +53 -77
- package/lib/rules/space-in-parens.js +4 -8
- package/lib/util/glob-util.js +1 -1
- package/package.json +29 -29
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,42 @@
|
|
1
|
+
v3.19.0 - March 31, 2017
|
2
|
+
|
3
|
+
* e09132f Fix: no-extra-parens false positive with exports and object literals (#8359) (Teddy Katz)
|
4
|
+
* 91baed4 Update: allow custom messages in no-restricted-syntax (fixes #8298) (#8357) (Vitor Balocco)
|
5
|
+
* 35c93e6 Fix: prevent space-before-function-paren from checking type annotations (#8349) (Teddy Katz)
|
6
|
+
* 3342e9f Fix: don't modify operator precedence in operator-assignment autofixer (#8358) (Teddy Katz)
|
7
|
+
* f88375f Docs: clarify that no-unsafe-negation is in eslint:recommended (#8371) (Teddy Katz)
|
8
|
+
* 02f0d27 Docs: Add soda0289 to Development Team (#8367) (Kai Cataldo)
|
9
|
+
* 155424c Fix: ignore empty path in patterns (fixes #8362) (#8364) (alberto)
|
10
|
+
* 27616a8 Fix: prefer-const false positive with object spread (fixes #8187) (#8297) (Vitor Balocco)
|
11
|
+
* 8569a90 Docs: add note about git's linebreak handling to linebreak-style docs (#8361) (Teddy Katz)
|
12
|
+
* 5878593 Chore: fix invalid syntax in no-param-reassign test (#8360) (Teddy Katz)
|
13
|
+
* 1b1046b Fix: don't classify plugins that throw errors as "missing" (fixes #6874) (#8323) (Teddy Katz)
|
14
|
+
* 29f4ba5 Fix: no-useless-computed-key invalid autofix for getters and setters (#8335) (Teddy Katz)
|
15
|
+
* 0541eaf Fix: no-implicit-coercion invalid autofix with consecutive identifiers (#8340) (Teddy Katz)
|
16
|
+
* 41b9786 Fix: no-extra-parens false positive with objects following arrows (#8339) (Teddy Katz)
|
17
|
+
* 3146167 Fix: `eslint.verify` should not mutate config argument (fixes #8329) (#8334) (alberto)
|
18
|
+
* 927de90 Fix: dot-notation autofix produces invalid syntax for integer properties (#8332) (Teddy Katz)
|
19
|
+
* a9d1bea Fix: comma-style autofix produces errors on parenthesized elements (#8331) (Teddy Katz)
|
20
|
+
* d52173f Fix: don't generate invalid options in config-rule (#8326) (Teddy Katz)
|
21
|
+
* 6eda3b5 Fix: no-extra-parens invalid autofix in for-of statements (#8337) (Teddy Katz)
|
22
|
+
* 6c819d8 Fix: dot-notation autofix produces errors on parenthesized computed keys (#8330) (Teddy Katz)
|
23
|
+
* 2d883d7 Fix: object-shorthand autofix produces errors on parenthesized functions (#8328) (Teddy Katz)
|
24
|
+
* cd9b774 Fix: quotes false positive with backtick option in method names (#8327) (Teddy Katz)
|
25
|
+
* d064ba2 Fix: no-else-return false positive for ifs in single-statement position (#8338) (Teddy Katz)
|
26
|
+
* 6a718ba Chore: enable max-statements-per-line on ESLint codebase (#8321) (Teddy Katz)
|
27
|
+
* 614b62e Chore: update sinon calls to deprecated API. (#8310) (alberto)
|
28
|
+
* 0491572 Chore: use precalculated counts in codeframe formatter (#8296) (Vitor Balocco)
|
29
|
+
* 8733e6a Chore: Fix incorrect error location properties in tests (#8307) (alberto)
|
30
|
+
* c4ffb49 Chore: Fix typos in test option assertions (#8305) (Teddy Katz)
|
31
|
+
* 79a97cb Upgrade: devDependencies (#8303) (alberto)
|
32
|
+
* e4da200 Upgrade: Mocha to 3.2.0 (#8299) (Ilya Volodin)
|
33
|
+
* 2f144ca Fix: operator-assignment autofix errors with parentheses (fixes #8293) (#8294) (Teddy Katz)
|
34
|
+
* 7521cd5 Chore: update token logic in rules to use ast-utils (#8288) (Teddy Katz)
|
35
|
+
* 9b509ce Chore: refactor space-before-function-paren rule (#8284) (Teddy Katz)
|
36
|
+
* ddc6350 Fix: no-param-reassign false positive on destructuring (fixes #8279) (#8281) (Teddy Katz)
|
37
|
+
* f8176b3 Chore: improve test coverage for node-event-generator (#8287) (Teddy Katz)
|
38
|
+
* 602e9c2 Docs: fix incorrect selector examples (#8278) (Teddy Katz)
|
39
|
+
|
1
40
|
v3.18.0 - March 17, 2017
|
2
41
|
|
3
42
|
* 85f74ca Fix: broken code path of direct nested loops (fixes #8248) (#8274) (Toru Nagashima)
|
package/README.md
CHANGED
@@ -130,6 +130,7 @@ These folks keep the project moving and are resources for help.
|
|
130
130
|
* Kevin Partington ([@platinumazure](https://github.com/platinumazure))
|
131
131
|
* Vitor Balocco ([@vitorbal](https://github.com/vitorbal))
|
132
132
|
* James Henry ([@JamesHenry](https://github.com/JamesHenry))
|
133
|
+
* Reyad Attiyat ([@soda0289](https://github.com/soda0289))
|
133
134
|
|
134
135
|
## Releases
|
135
136
|
|
@@ -223,7 +223,7 @@ class RuleConfigSet {
|
|
223
223
|
/**
|
224
224
|
* Add rule configurations from a schema object
|
225
225
|
* @param {Object} obj Schema item with type === "object"
|
226
|
-
* @returns {
|
226
|
+
* @returns {boolean} true if at least one schema for the object could be generated, false otherwise
|
227
227
|
*/
|
228
228
|
addObject(obj) {
|
229
229
|
const objectConfigSet = {
|
@@ -258,7 +258,10 @@ class RuleConfigSet {
|
|
258
258
|
|
259
259
|
if (objectConfigSet.objectConfigs.length > 0) {
|
260
260
|
this.ruleConfigs = this.ruleConfigs.concat(combineArrays(this.ruleConfigs, objectConfigSet.objectConfigs));
|
261
|
+
return true;
|
261
262
|
}
|
263
|
+
|
264
|
+
return false;
|
262
265
|
}
|
263
266
|
}
|
264
267
|
|
@@ -271,20 +274,21 @@ function generateConfigsFromSchema(schema) {
|
|
271
274
|
const configSet = new RuleConfigSet();
|
272
275
|
|
273
276
|
if (Array.isArray(schema)) {
|
274
|
-
|
277
|
+
for (const opt of schema) {
|
275
278
|
if (opt.enum) {
|
276
279
|
configSet.addEnums(opt.enum);
|
277
|
-
}
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
}
|
280
|
+
} else if (opt.type && opt.type === "object") {
|
281
|
+
if (!configSet.addObject(opt)) {
|
282
|
+
break;
|
283
|
+
}
|
282
284
|
|
283
|
-
|
285
|
+
// TODO (IanVS): support oneOf
|
286
|
+
} else {
|
284
287
|
|
285
|
-
//
|
288
|
+
// If we don't know how to fill in this option, don't fill in any of the following options.
|
289
|
+
break;
|
286
290
|
}
|
287
|
-
}
|
291
|
+
}
|
288
292
|
}
|
289
293
|
configSet.addErrorSeverity();
|
290
294
|
return configSet.ruleConfigs;
|
package/lib/config/plugins.js
CHANGED
@@ -127,14 +127,25 @@ module.exports = {
|
|
127
127
|
if (!plugins[shortName]) {
|
128
128
|
try {
|
129
129
|
plugin = require(longName);
|
130
|
-
} catch (
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
130
|
+
} catch (pluginLoadErr) {
|
131
|
+
try {
|
132
|
+
|
133
|
+
// Check whether the plugin exists
|
134
|
+
require.resolve(longName);
|
135
|
+
} catch (missingPluginErr) {
|
136
|
+
|
137
|
+
// If the plugin can't be resolved, display the missing plugin error (usually a config or install error)
|
138
|
+
debug(`Failed to load plugin ${longName}.`);
|
139
|
+
missingPluginErr.message = `Failed to load plugin ${pluginName}: ${missingPluginErr.message}`;
|
140
|
+
missingPluginErr.messageTemplate = "plugin-missing";
|
141
|
+
missingPluginErr.messageData = {
|
142
|
+
pluginName: longName
|
143
|
+
};
|
144
|
+
throw missingPluginErr;
|
145
|
+
}
|
146
|
+
|
147
|
+
// Otherwise, the plugin exists and is throwing on module load for some reason, so print the stack trace.
|
148
|
+
throw pluginLoadErr;
|
138
149
|
}
|
139
150
|
|
140
151
|
this.define(pluginName, plugin);
|
package/lib/eslint.js
CHANGED
@@ -778,17 +778,18 @@ module.exports = (function() {
|
|
778
778
|
// search and apply "eslint-env *".
|
779
779
|
const envInFile = findEslintEnv(text || textOrSourceCode.text);
|
780
780
|
|
781
|
+
config = Object.assign({}, config);
|
782
|
+
|
781
783
|
if (envInFile) {
|
782
|
-
if (
|
783
|
-
config = Object.assign({}, config || {}, { env: envInFile });
|
784
|
-
} else {
|
785
|
-
config = Object.assign({}, config);
|
784
|
+
if (config.env) {
|
786
785
|
config.env = Object.assign({}, config.env, envInFile);
|
786
|
+
} else {
|
787
|
+
config.env = envInFile;
|
787
788
|
}
|
788
789
|
}
|
789
790
|
|
790
791
|
// process initial config to make it safe to extend
|
791
|
-
config = prepareConfig(config
|
792
|
+
config = prepareConfig(config);
|
792
793
|
|
793
794
|
// only do this for text
|
794
795
|
if (text !== null) {
|
@@ -101,15 +101,10 @@ module.exports = function(results) {
|
|
101
101
|
const resultsWithMessages = results.filter(result => result.messages.length > 0);
|
102
102
|
|
103
103
|
let output = resultsWithMessages.reduce((resultsOutput, result) => {
|
104
|
-
const messages = result.messages.map(message => {
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
warnings++;
|
109
|
-
}
|
110
|
-
|
111
|
-
return `${formatMessage(message, result)}\n\n`;
|
112
|
-
});
|
104
|
+
const messages = result.messages.map(message => `${formatMessage(message, result)}\n\n`);
|
105
|
+
|
106
|
+
errors += result.errorCount;
|
107
|
+
warnings += result.warningCount;
|
113
108
|
|
114
109
|
return resultsOutput.concat(messages);
|
115
110
|
}, []).join("\n");
|
@@ -100,7 +100,7 @@ module.exports = {
|
|
100
100
|
const firstValueToken = sourceCode.getTokenAfter(returnKeyword);
|
101
101
|
let lastValueToken = sourceCode.getLastToken(blockBody[0]);
|
102
102
|
|
103
|
-
if (
|
103
|
+
if (astUtils.isSemicolonToken(lastValueToken)) {
|
104
104
|
|
105
105
|
/* The last token of the returned value is the last token of the ReturnExpression (if
|
106
106
|
* the ReturnExpression has no semicolon), or the second-to-last token (if the ReturnExpression
|
@@ -120,7 +120,7 @@ module.exports = {
|
|
120
120
|
const textBeforeReturn = sourceText.slice(arrowBody.range[0] + 1, returnKeyword.range[0]);
|
121
121
|
const textBetweenReturnAndValue = sourceText.slice(returnKeyword.range[1], firstValueToken.range[0]);
|
122
122
|
const rawReturnValueText = sourceText.slice(firstValueToken.range[0], lastValueToken.range[1]);
|
123
|
-
const returnValueText = firstValueToken
|
123
|
+
const returnValueText = astUtils.isOpeningBraceToken(firstValueToken) ? `(${rawReturnValueText})` : rawReturnValueText;
|
124
124
|
const textAfterValue = sourceText.slice(lastValueToken.range[1], blockBody[0].range[1] - 1);
|
125
125
|
const textAfterReturnStatement = sourceText.slice(blockBody[0].range[1], arrowBody.range[1] - 1);
|
126
126
|
|
@@ -4,6 +4,12 @@
|
|
4
4
|
*/
|
5
5
|
"use strict";
|
6
6
|
|
7
|
+
//------------------------------------------------------------------------------
|
8
|
+
// Requirements
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
|
11
|
+
const astUtils = require("../ast-utils");
|
12
|
+
|
7
13
|
//------------------------------------------------------------------------------
|
8
14
|
// Rule Definition
|
9
15
|
//------------------------------------------------------------------------------
|
@@ -62,7 +68,7 @@ module.exports = {
|
|
62
68
|
node.body.type !== "BlockStatement" &&
|
63
69
|
!node.returnType
|
64
70
|
) {
|
65
|
-
if (
|
71
|
+
if (astUtils.isOpeningParenToken(token)) {
|
66
72
|
context.report({
|
67
73
|
node,
|
68
74
|
message: requireForBlockBodyMessage,
|
@@ -84,7 +90,7 @@ module.exports = {
|
|
84
90
|
requireForBlockBody &&
|
85
91
|
node.body.type === "BlockStatement"
|
86
92
|
) {
|
87
|
-
if (
|
93
|
+
if (!astUtils.isOpeningParenToken(token)) {
|
88
94
|
context.report({
|
89
95
|
node,
|
90
96
|
message: requireForBlockBodyNoParensMessage,
|
@@ -103,7 +109,7 @@ module.exports = {
|
|
103
109
|
!node.params[0].typeAnnotation &&
|
104
110
|
!node.returnType
|
105
111
|
) {
|
106
|
-
if (
|
112
|
+
if (astUtils.isOpeningParenToken(token)) {
|
107
113
|
context.report({
|
108
114
|
node,
|
109
115
|
message: asNeededMessage,
|
@@ -10,6 +10,7 @@
|
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
12
|
const lodash = require("lodash");
|
13
|
+
const astUtils = require("../ast-utils");
|
13
14
|
|
14
15
|
//------------------------------------------------------------------------------
|
15
16
|
// Helpers
|
@@ -178,7 +179,7 @@ module.exports = {
|
|
178
179
|
default: {
|
179
180
|
const nextToken = sourceCode.getTokenAfter(lastItem);
|
180
181
|
|
181
|
-
if (nextToken
|
182
|
+
if (astUtils.isCommaToken(nextToken)) {
|
182
183
|
return nextToken;
|
183
184
|
}
|
184
185
|
return sourceCode.getLastToken(lastItem);
|
@@ -224,7 +225,7 @@ module.exports = {
|
|
224
225
|
|
225
226
|
const trailingToken = getTrailingToken(node, lastItem);
|
226
227
|
|
227
|
-
if (trailingToken
|
228
|
+
if (astUtils.isCommaToken(trailingToken)) {
|
228
229
|
context.report({
|
229
230
|
node: lastItem,
|
230
231
|
loc: trailingToken.loc.start,
|
@@ -53,16 +53,6 @@ module.exports = {
|
|
53
53
|
// list of comma tokens to ignore for the check of leading whitespace
|
54
54
|
const commaTokensToIgnore = [];
|
55
55
|
|
56
|
-
/**
|
57
|
-
* Determines if a given token is a comma operator.
|
58
|
-
* @param {ASTNode} token The token to check.
|
59
|
-
* @returns {boolean} True if the token is a comma, false if not.
|
60
|
-
* @private
|
61
|
-
*/
|
62
|
-
function isComma(token) {
|
63
|
-
return !!token && (token.type === "Punctuator") && (token.value === ",");
|
64
|
-
}
|
65
|
-
|
66
56
|
/**
|
67
57
|
* Reports a spacing error with an appropriate message.
|
68
58
|
* @param {ASTNode} node The binary expression node to report.
|
@@ -147,7 +137,7 @@ module.exports = {
|
|
147
137
|
if (element === null) {
|
148
138
|
token = sourceCode.getTokenAfter(previousToken);
|
149
139
|
|
150
|
-
if (
|
140
|
+
if (astUtils.isCommaToken(token)) {
|
151
141
|
commaTokensToIgnore.push(token);
|
152
142
|
}
|
153
143
|
} else {
|
@@ -166,7 +156,7 @@ module.exports = {
|
|
166
156
|
"Program:exit"() {
|
167
157
|
tokensAndComments.forEach((token, i) => {
|
168
158
|
|
169
|
-
if (!
|
159
|
+
if (!astUtils.isCommaToken(token)) {
|
170
160
|
return;
|
171
161
|
}
|
172
162
|
|
@@ -179,8 +169,8 @@ module.exports = {
|
|
179
169
|
|
180
170
|
validateCommaItemSpacing({
|
181
171
|
comma: token,
|
182
|
-
left:
|
183
|
-
right:
|
172
|
+
left: astUtils.isCommaToken(previousToken) || commaTokensToIgnore.indexOf(token) > -1 ? null : previousToken,
|
173
|
+
right: astUtils.isCommaToken(nextToken) ? null : nextToken
|
184
174
|
}, token);
|
185
175
|
});
|
186
176
|
},
|
package/lib/rules/comma-style.js
CHANGED
@@ -63,16 +63,6 @@ module.exports = {
|
|
63
63
|
// Helpers
|
64
64
|
//--------------------------------------------------------------------------
|
65
65
|
|
66
|
-
/**
|
67
|
-
* Determines if a given token is a comma operator.
|
68
|
-
* @param {ASTNode} token The token to check.
|
69
|
-
* @returns {boolean} True if the token is a comma, false if not.
|
70
|
-
* @private
|
71
|
-
*/
|
72
|
-
function isComma(token) {
|
73
|
-
return !!token && (token.type === "Punctuator") && (token.value === ",");
|
74
|
-
}
|
75
|
-
|
76
66
|
/**
|
77
67
|
* Modified text based on the style
|
78
68
|
* @param {string} styleType Style type
|
@@ -192,7 +182,7 @@ module.exports = {
|
|
192
182
|
tokenBeforeComma = sourceCode.getTokenBefore(commaToken);
|
193
183
|
|
194
184
|
// Check if previous token is wrapped in parentheses
|
195
|
-
if (tokenBeforeComma && tokenBeforeComma
|
185
|
+
if (tokenBeforeComma && astUtils.isClosingParenToken(tokenBeforeComma)) {
|
196
186
|
previousItemToken = tokenBeforeComma;
|
197
187
|
}
|
198
188
|
|
@@ -210,12 +200,16 @@ module.exports = {
|
|
210
200
|
* All comparisons are done based on these tokens directly, so
|
211
201
|
* they are always valid regardless of an undefined item.
|
212
202
|
*/
|
213
|
-
if (
|
203
|
+
if (astUtils.isCommaToken(commaToken)) {
|
214
204
|
validateCommaItemSpacing(previousItemToken, commaToken,
|
215
205
|
currentItemToken, reportItem);
|
216
206
|
}
|
217
207
|
|
218
|
-
|
208
|
+
if (item) {
|
209
|
+
const tokenAfterItem = sourceCode.getTokenAfter(item, astUtils.isNotClosingParenToken);
|
210
|
+
|
211
|
+
previousItemToken = tokenAfterItem ? sourceCode.getTokenBefore(tokenAfterItem) : sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1];
|
212
|
+
}
|
219
213
|
});
|
220
214
|
|
221
215
|
/*
|
@@ -229,7 +223,7 @@ module.exports = {
|
|
229
223
|
const lastToken = sourceCode.getLastToken(node),
|
230
224
|
nextToLastToken = sourceCode.getTokenBefore(lastToken);
|
231
225
|
|
232
|
-
if (
|
226
|
+
if (astUtils.isCommaToken(nextToLastToken)) {
|
233
227
|
validateCommaItemSpacing(
|
234
228
|
sourceCode.getTokenBefore(nextToLastToken),
|
235
229
|
nextToLastToken,
|
package/lib/rules/curly.js
CHANGED
@@ -76,7 +76,7 @@ module.exports = {
|
|
76
76
|
function isCollapsedOneLiner(node) {
|
77
77
|
const before = sourceCode.getTokenBefore(node);
|
78
78
|
const last = sourceCode.getLastToken(node);
|
79
|
-
const lastExcludingSemicolon =
|
79
|
+
const lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last;
|
80
80
|
|
81
81
|
return before.loc.start.line === lastExcludingSemicolon.loc.end.line;
|
82
82
|
}
|
@@ -174,7 +174,7 @@ module.exports = {
|
|
174
174
|
const tokenAfter = sourceCode.getTokenAfter(closingBracket);
|
175
175
|
const lastBlockNode = sourceCode.getNodeByRangeIndex(tokenBefore.range[0]);
|
176
176
|
|
177
|
-
if (tokenBefore
|
177
|
+
if (astUtils.isSemicolonToken(tokenBefore)) {
|
178
178
|
|
179
179
|
// If the last statement already has a semicolon, don't add another one.
|
180
180
|
return false;
|
@@ -4,6 +4,12 @@
|
|
4
4
|
*/
|
5
5
|
"use strict";
|
6
6
|
|
7
|
+
//------------------------------------------------------------------------------
|
8
|
+
// Requirements
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
|
11
|
+
const astUtils = require("../ast-utils");
|
12
|
+
|
7
13
|
//------------------------------------------------------------------------------
|
8
14
|
// Rule Definition
|
9
15
|
//------------------------------------------------------------------------------
|
@@ -64,20 +70,20 @@ module.exports = {
|
|
64
70
|
propertyValue: JSON.stringify(node.property.value)
|
65
71
|
},
|
66
72
|
fix(fixer) {
|
67
|
-
const leftBracket = sourceCode.
|
68
|
-
const rightBracket = sourceCode.
|
69
|
-
const textBeforeProperty = sourceCode.text.slice(leftBracket.range[1], node.property.range[0]);
|
70
|
-
const textAfterProperty = sourceCode.text.slice(node.property.range[1], rightBracket.range[0]);
|
73
|
+
const leftBracket = sourceCode.getTokenAfter(node.object, astUtils.isOpeningBracketToken);
|
74
|
+
const rightBracket = sourceCode.getLastToken(node);
|
71
75
|
|
72
|
-
if (
|
76
|
+
if (sourceCode.getFirstTokenBetween(leftBracket, rightBracket, { includeComments: true, filter: astUtils.isCommentToken })) {
|
73
77
|
|
74
78
|
// Don't perform any fixes if there are comments inside the brackets.
|
75
79
|
return null;
|
76
80
|
}
|
77
81
|
|
82
|
+
const textBeforeDot = astUtils.isDecimalInteger(node.object) ? " " : "";
|
83
|
+
|
78
84
|
return fixer.replaceTextRange(
|
79
85
|
[leftBracket.range[0], rightBracket.range[1]],
|
80
|
-
|
86
|
+
`${textBeforeDot}.${node.property.value}`
|
81
87
|
);
|
82
88
|
}
|
83
89
|
});
|
@@ -74,7 +74,7 @@ module.exports = {
|
|
74
74
|
const lastToken = sourceCode.getLastToken(node);
|
75
75
|
const secondToLastToken = sourceCode.getTokenBefore(lastToken);
|
76
76
|
|
77
|
-
return
|
77
|
+
return astUtils.isSemicolonToken(lastToken) && lastToken.loc.start.line > secondToLastToken.loc.end.line
|
78
78
|
? secondToLastToken
|
79
79
|
: lastToken;
|
80
80
|
}
|
package/lib/rules/new-parens.js
CHANGED
@@ -6,28 +6,14 @@
|
|
6
6
|
"use strict";
|
7
7
|
|
8
8
|
//------------------------------------------------------------------------------
|
9
|
-
//
|
9
|
+
// Requirements
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
|
-
|
13
|
-
* Checks whether the given token is an opening parenthesis or not.
|
14
|
-
*
|
15
|
-
* @param {Token} token - The token to check.
|
16
|
-
* @returns {boolean} `true` if the token is an opening parenthesis.
|
17
|
-
*/
|
18
|
-
function isOpeningParen(token) {
|
19
|
-
return token.type === "Punctuator" && token.value === "(";
|
20
|
-
}
|
12
|
+
const astUtils = require("../ast-utils");
|
21
13
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
* @param {Token} token - The token to check.
|
26
|
-
* @returns {boolean} `true` if the token is an closing parenthesis.
|
27
|
-
*/
|
28
|
-
function isClosingParen(token) {
|
29
|
-
return token.type === "Punctuator" && token.value === ")";
|
30
|
-
}
|
14
|
+
//------------------------------------------------------------------------------
|
15
|
+
// Helpers
|
16
|
+
//------------------------------------------------------------------------------
|
31
17
|
|
32
18
|
//------------------------------------------------------------------------------
|
33
19
|
// Rule Definition
|
@@ -56,8 +42,8 @@ module.exports = {
|
|
56
42
|
}
|
57
43
|
|
58
44
|
const lastToken = sourceCode.getLastToken(node);
|
59
|
-
const hasLastParen = lastToken &&
|
60
|
-
const hasParens = hasLastParen &&
|
45
|
+
const hasLastParen = lastToken && astUtils.isClosingParenToken(lastToken);
|
46
|
+
const hasParens = hasLastParen && astUtils.isOpeningParenToken(sourceCode.getTokenBefore(lastToken));
|
61
47
|
|
62
48
|
if (!hasParens) {
|
63
49
|
context.report({
|
@@ -66,19 +66,6 @@ module.exports = {
|
|
66
66
|
return null;
|
67
67
|
}
|
68
68
|
|
69
|
-
/**
|
70
|
-
* Check whether the code represented by an AST node is enclosed in parentheses.
|
71
|
-
* @param {!Object} node The node to test.
|
72
|
-
* @returns {boolean} `true` if the code is enclosed in parentheses; otherwise, `false`.
|
73
|
-
*/
|
74
|
-
function isParenthesised(node) {
|
75
|
-
const previousToken = sourceCode.getTokenBefore(node),
|
76
|
-
nextToken = sourceCode.getTokenAfter(node);
|
77
|
-
|
78
|
-
return previousToken.value === "(" && previousToken.range[1] <= node.range[0] &&
|
79
|
-
nextToken.value === ")" && nextToken.range[0] >= node.range[1];
|
80
|
-
}
|
81
|
-
|
82
69
|
/**
|
83
70
|
* Check whether the code represented by an AST node is enclosed in two sets of parentheses.
|
84
71
|
* @param {!Object} node The node to test.
|
@@ -88,9 +75,9 @@ module.exports = {
|
|
88
75
|
const previousToken = sourceCode.getTokenBefore(node, 1),
|
89
76
|
nextToken = sourceCode.getTokenAfter(node, 1);
|
90
77
|
|
91
|
-
return isParenthesised(node) &&
|
92
|
-
|
93
|
-
nextToken
|
78
|
+
return astUtils.isParenthesised(sourceCode, node) &&
|
79
|
+
astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] &&
|
80
|
+
astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1];
|
94
81
|
}
|
95
82
|
|
96
83
|
/**
|
@@ -102,7 +89,7 @@ module.exports = {
|
|
102
89
|
if (node.test &&
|
103
90
|
(node.test.type === "AssignmentExpression") &&
|
104
91
|
(node.type === "ForStatement"
|
105
|
-
? !isParenthesised(node.test)
|
92
|
+
? !astUtils.isParenthesised(sourceCode, node.test)
|
106
93
|
: !isParenthesisedTwice(node.test)
|
107
94
|
)
|
108
95
|
) {
|
@@ -9,6 +9,7 @@
|
|
9
9
|
// Requirements
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
|
+
const astUtils = require("../ast-utils");
|
12
13
|
const FixTracker = require("../util/fix-tracker");
|
13
14
|
|
14
15
|
//------------------------------------------------------------------------------
|
@@ -199,9 +200,11 @@ module.exports = {
|
|
199
200
|
let consequents,
|
200
201
|
alternate;
|
201
202
|
|
202
|
-
|
203
|
-
|
204
|
-
|
203
|
+
/*
|
204
|
+
* Fixing this would require splitting one statement into two, so no error should
|
205
|
+
* be reported if this node is in a position where only one statement is allowed.
|
206
|
+
*/
|
207
|
+
if (!astUtils.STATEMENT_LIST_PARENTS.has(parent.type)) {
|
205
208
|
return;
|
206
209
|
}
|
207
210
|
|