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
@@ -60,6 +60,7 @@ module.exports = {
|
|
60
60
|
create(context) {
|
61
61
|
const sourceCode = context.getSourceCode();
|
62
62
|
|
63
|
+
const tokensToIgnore = new WeakSet();
|
63
64
|
const isParenthesised = astUtils.isParenthesised.bind(astUtils, sourceCode);
|
64
65
|
const precedence = astUtils.getPrecedence;
|
65
66
|
const ALL_NODES = context.options[0] !== "functions";
|
@@ -116,8 +117,8 @@ module.exports = {
|
|
116
117
|
nextToken = sourceCode.getTokenAfter(node, 1);
|
117
118
|
|
118
119
|
return isParenthesised(node) && previousToken && nextToken &&
|
119
|
-
|
120
|
-
nextToken
|
120
|
+
astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] &&
|
121
|
+
astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1];
|
121
122
|
}
|
122
123
|
|
123
124
|
/**
|
@@ -179,7 +180,7 @@ module.exports = {
|
|
179
180
|
const lastToken = sourceCode.getLastToken(newExpression);
|
180
181
|
const penultimateToken = sourceCode.getTokenBefore(lastToken);
|
181
182
|
|
182
|
-
return newExpression.arguments.length > 0 ||
|
183
|
+
return newExpression.arguments.length > 0 || astUtils.isOpeningParenToken(penultimateToken) && astUtils.isClosingParenToken(lastToken);
|
183
184
|
}
|
184
185
|
|
185
186
|
/**
|
@@ -238,69 +239,6 @@ module.exports = {
|
|
238
239
|
return hasDoubleExcessParens(node);
|
239
240
|
}
|
240
241
|
|
241
|
-
/**
|
242
|
-
* Checks whether or not a given node is located at the head of ExpressionStatement.
|
243
|
-
* @param {ASTNode} node - A node to check.
|
244
|
-
* @returns {boolean} `true` if the node is located at the head of ExpressionStatement.
|
245
|
-
*/
|
246
|
-
function isHeadOfExpressionStatement(node) {
|
247
|
-
let parent = node.parent;
|
248
|
-
|
249
|
-
while (parent) {
|
250
|
-
switch (parent.type) {
|
251
|
-
case "SequenceExpression":
|
252
|
-
if (parent.expressions[0] !== node || isParenthesised(node)) {
|
253
|
-
return false;
|
254
|
-
}
|
255
|
-
break;
|
256
|
-
|
257
|
-
case "UnaryExpression":
|
258
|
-
case "UpdateExpression":
|
259
|
-
if (parent.prefix || isParenthesised(node)) {
|
260
|
-
return false;
|
261
|
-
}
|
262
|
-
break;
|
263
|
-
|
264
|
-
case "BinaryExpression":
|
265
|
-
case "LogicalExpression":
|
266
|
-
if (parent.left !== node || isParenthesised(node)) {
|
267
|
-
return false;
|
268
|
-
}
|
269
|
-
break;
|
270
|
-
|
271
|
-
case "ConditionalExpression":
|
272
|
-
if (parent.test !== node || isParenthesised(node)) {
|
273
|
-
return false;
|
274
|
-
}
|
275
|
-
break;
|
276
|
-
|
277
|
-
case "CallExpression":
|
278
|
-
if (parent.callee !== node || isParenthesised(node)) {
|
279
|
-
return false;
|
280
|
-
}
|
281
|
-
break;
|
282
|
-
|
283
|
-
case "MemberExpression":
|
284
|
-
if (parent.object !== node || isParenthesised(node)) {
|
285
|
-
return false;
|
286
|
-
}
|
287
|
-
break;
|
288
|
-
|
289
|
-
case "ExpressionStatement":
|
290
|
-
return true;
|
291
|
-
|
292
|
-
default:
|
293
|
-
return false;
|
294
|
-
}
|
295
|
-
|
296
|
-
node = parent;
|
297
|
-
parent = parent.parent;
|
298
|
-
}
|
299
|
-
|
300
|
-
/* istanbul ignore next */
|
301
|
-
throw new Error("unreachable");
|
302
|
-
}
|
303
|
-
|
304
242
|
/**
|
305
243
|
* Determines whether a node should be preceded by an additional space when removing parens
|
306
244
|
* @param {ASTNode} node node to evaluate; must be surrounded by parentheses
|
@@ -318,7 +256,7 @@ module.exports = {
|
|
318
256
|
}
|
319
257
|
|
320
258
|
// If the parens are preceded by a keyword (e.g. `typeof(0)`), a space should be inserted (`typeof 0`)
|
321
|
-
const
|
259
|
+
const precededByIdentiferPart = esUtils.code.isIdentifierPartES6(tokenBeforeLeftParen.value.slice(-1).charCodeAt(0));
|
322
260
|
|
323
261
|
// However, a space should not be inserted unless the first character of the token is an identifier part
|
324
262
|
// e.g. `typeof([])` should be fixed to `typeof[]`
|
@@ -331,7 +269,7 @@ module.exports = {
|
|
331
269
|
const startsWithUnaryPlus = firstToken.type === "Punctuator" && firstToken.value === "+";
|
332
270
|
const startsWithUnaryMinus = firstToken.type === "Punctuator" && firstToken.value === "-";
|
333
271
|
|
334
|
-
return (
|
272
|
+
return (precededByIdentiferPart && startsWithIdentifierPart) ||
|
335
273
|
(precededByUnaryPlus && startsWithUnaryPlus) ||
|
336
274
|
(precededByUnaryMinus && startsWithUnaryMinus);
|
337
275
|
}
|
@@ -346,6 +284,10 @@ module.exports = {
|
|
346
284
|
const leftParenToken = sourceCode.getTokenBefore(node);
|
347
285
|
const rightParenToken = sourceCode.getTokenAfter(node);
|
348
286
|
|
287
|
+
if (tokensToIgnore.has(sourceCode.getFirstToken(node)) && !isParenthesisedTwice(node)) {
|
288
|
+
return;
|
289
|
+
}
|
290
|
+
|
349
291
|
context.report({
|
350
292
|
node,
|
351
293
|
loc: leftParenToken.loc.start,
|
@@ -466,6 +408,34 @@ module.exports = {
|
|
466
408
|
}
|
467
409
|
}
|
468
410
|
|
411
|
+
/**
|
412
|
+
* Checks the parentheses for an ExpressionStatement or ExportDefaultDeclaration
|
413
|
+
* @param {ASTNode} node The ExpressionStatement.expression or ExportDefaultDeclaration.declaration node
|
414
|
+
* @returns {void}
|
415
|
+
*/
|
416
|
+
function checkExpressionOrExportStatement(node) {
|
417
|
+
const firstToken = isParenthesised(node) ? sourceCode.getTokenBefore(node) : sourceCode.getFirstToken(node);
|
418
|
+
const secondToken = sourceCode.getTokenAfter(firstToken, astUtils.isNotOpeningParenToken);
|
419
|
+
|
420
|
+
if (
|
421
|
+
astUtils.isOpeningParenToken(firstToken) &&
|
422
|
+
(
|
423
|
+
astUtils.isOpeningBraceToken(secondToken) ||
|
424
|
+
secondToken.type === "Keyword" && (
|
425
|
+
secondToken.value === "function" ||
|
426
|
+
secondToken.value === "class" ||
|
427
|
+
secondToken.value === "let" && astUtils.isOpeningBracketToken(sourceCode.getTokenAfter(secondToken))
|
428
|
+
)
|
429
|
+
)
|
430
|
+
) {
|
431
|
+
tokensToIgnore.add(secondToken);
|
432
|
+
}
|
433
|
+
|
434
|
+
if (hasExcessParens(node)) {
|
435
|
+
report(node);
|
436
|
+
}
|
437
|
+
}
|
438
|
+
|
469
439
|
return {
|
470
440
|
ArrayExpression(node) {
|
471
441
|
[].forEach.call(node.elements, e => {
|
@@ -481,13 +451,13 @@ module.exports = {
|
|
481
451
|
}
|
482
452
|
|
483
453
|
if (node.body.type !== "BlockStatement") {
|
484
|
-
|
485
|
-
|
486
|
-
return;
|
487
|
-
}
|
454
|
+
const firstBodyToken = sourceCode.getFirstToken(node.body, astUtils.isNotOpeningParenToken);
|
455
|
+
const tokenBeforeFirst = sourceCode.getTokenBefore(firstBodyToken);
|
488
456
|
|
489
|
-
|
490
|
-
|
457
|
+
if (astUtils.isOpeningParenToken(tokenBeforeFirst) && astUtils.isOpeningBraceToken(firstBodyToken)) {
|
458
|
+
tokensToIgnore.add(firstBodyToken);
|
459
|
+
}
|
460
|
+
if (hasExcessParens(node.body) && precedence(node.body) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) {
|
491
461
|
report(node.body);
|
492
462
|
}
|
493
463
|
}
|
@@ -530,27 +500,8 @@ module.exports = {
|
|
530
500
|
}
|
531
501
|
},
|
532
502
|
|
533
|
-
|
534
|
-
|
535
|
-
const firstTokens = sourceCode.getFirstTokens(node.expression, 2);
|
536
|
-
const firstToken = firstTokens[0];
|
537
|
-
const secondToken = firstTokens[1];
|
538
|
-
|
539
|
-
if (
|
540
|
-
!firstToken ||
|
541
|
-
firstToken.value !== "{" &&
|
542
|
-
firstToken.value !== "function" &&
|
543
|
-
firstToken.value !== "class" &&
|
544
|
-
(
|
545
|
-
firstToken.value !== "let" ||
|
546
|
-
!secondToken ||
|
547
|
-
secondToken.value !== "["
|
548
|
-
)
|
549
|
-
) {
|
550
|
-
report(node.expression);
|
551
|
-
}
|
552
|
-
}
|
553
|
-
},
|
503
|
+
ExportDefaultDeclaration: node => checkExpressionOrExportStatement(node.declaration),
|
504
|
+
ExpressionStatement: node => checkExpressionOrExportStatement(node.expression),
|
554
505
|
|
555
506
|
ForInStatement(node) {
|
556
507
|
if (hasExcessParens(node.right)) {
|
@@ -593,18 +544,11 @@ module.exports = {
|
|
593
544
|
(
|
594
545
|
node.computed ||
|
595
546
|
!(
|
596
|
-
(node.object
|
597
|
-
typeof node.object.value === "number" &&
|
598
|
-
astUtils.isDecimalInteger(node.object)) ||
|
547
|
+
astUtils.isDecimalInteger(node.object) ||
|
599
548
|
|
600
549
|
// RegExp literal is allowed to have parens (#1589)
|
601
550
|
(node.object.type === "Literal" && node.object.regex)
|
602
551
|
)
|
603
|
-
) &&
|
604
|
-
!(
|
605
|
-
(node.object.type === "FunctionExpression" || node.object.type === "ClassExpression") &&
|
606
|
-
isHeadOfExpressionStatement(node) &&
|
607
|
-
!hasDoubleExcessParens(node.object)
|
608
552
|
)
|
609
553
|
) {
|
610
554
|
report(node.object);
|
@@ -10,6 +10,7 @@
|
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
12
|
const FixTracker = require("../util/fix-tracker");
|
13
|
+
const astUtils = require("../ast-utils");
|
13
14
|
|
14
15
|
//------------------------------------------------------------------------------
|
15
16
|
// Rule Definition
|
@@ -60,10 +61,10 @@ module.exports = {
|
|
60
61
|
*/
|
61
62
|
function checkForPartOfClassBody(firstToken) {
|
62
63
|
for (let token = firstToken;
|
63
|
-
token.type === "Punctuator" && token
|
64
|
+
token.type === "Punctuator" && !astUtils.isClosingBraceToken(token);
|
64
65
|
token = sourceCode.getTokenAfter(token)
|
65
66
|
) {
|
66
|
-
if (token
|
67
|
+
if (astUtils.isSemicolonToken(token)) {
|
67
68
|
report(token);
|
68
69
|
}
|
69
70
|
}
|
@@ -6,6 +6,7 @@
|
|
6
6
|
"use strict";
|
7
7
|
|
8
8
|
const astUtils = require("../ast-utils");
|
9
|
+
const esUtils = require("esutils");
|
9
10
|
|
10
11
|
//------------------------------------------------------------------------------
|
11
12
|
// Helpers
|
@@ -197,19 +198,31 @@ module.exports = {
|
|
197
198
|
*/
|
198
199
|
function report(node, recommendation, shouldFix) {
|
199
200
|
shouldFix = typeof shouldFix === "undefined" ? true : shouldFix;
|
200
|
-
|
201
|
+
|
202
|
+
context.report({
|
201
203
|
node,
|
202
204
|
message: "use `{{recommendation}}` instead.",
|
203
205
|
data: {
|
204
206
|
recommendation
|
207
|
+
},
|
208
|
+
fix(fixer) {
|
209
|
+
if (!shouldFix) {
|
210
|
+
return null;
|
211
|
+
}
|
212
|
+
|
213
|
+
const tokenBefore = sourceCode.getTokenBefore(node);
|
214
|
+
|
215
|
+
if (
|
216
|
+
tokenBefore &&
|
217
|
+
tokenBefore.range[1] === node.range[0] &&
|
218
|
+
esUtils.code.isIdentifierPartES6(tokenBefore.value.slice(-1).charCodeAt(0)) &&
|
219
|
+
esUtils.code.isIdentifierPartES6(recommendation.charCodeAt(0))
|
220
|
+
) {
|
221
|
+
return fixer.replaceText(node, ` ${recommendation}`);
|
222
|
+
}
|
223
|
+
return fixer.replaceText(node, recommendation);
|
205
224
|
}
|
206
|
-
};
|
207
|
-
|
208
|
-
if (shouldFix) {
|
209
|
-
reportObj.fix = fixer => fixer.replaceText(node, recommendation);
|
210
|
-
}
|
211
|
-
|
212
|
-
context.report(reportObj);
|
225
|
+
});
|
213
226
|
}
|
214
227
|
|
215
228
|
return {
|
@@ -18,18 +18,45 @@ module.exports = {
|
|
18
18
|
|
19
19
|
schema: {
|
20
20
|
type: "array",
|
21
|
-
items: [{
|
21
|
+
items: [{
|
22
|
+
oneOf: [
|
23
|
+
{
|
24
|
+
type: "string"
|
25
|
+
},
|
26
|
+
{
|
27
|
+
type: "object",
|
28
|
+
properties: {
|
29
|
+
selector: { type: "string" },
|
30
|
+
message: { type: "string" }
|
31
|
+
},
|
32
|
+
required: ["selector"],
|
33
|
+
additionalProperties: false
|
34
|
+
}
|
35
|
+
]
|
36
|
+
}],
|
22
37
|
uniqueItems: true,
|
23
38
|
minItems: 0
|
24
39
|
}
|
25
40
|
},
|
26
41
|
|
27
42
|
create(context) {
|
28
|
-
return context.options.reduce((result,
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
43
|
+
return context.options.reduce((result, selectorOrObject) => {
|
44
|
+
const isStringFormat = (typeof selectorOrObject === "string");
|
45
|
+
const hasCustomMessage = !isStringFormat && Boolean(selectorOrObject.message);
|
46
|
+
|
47
|
+
const selector = isStringFormat ? selectorOrObject : selectorOrObject.selector;
|
48
|
+
const message = hasCustomMessage ? selectorOrObject.message : "Using '{{selector}}' is not allowed.";
|
49
|
+
|
50
|
+
return Object.assign(result, {
|
51
|
+
[selector](node) {
|
52
|
+
context.report({
|
53
|
+
node,
|
54
|
+
message,
|
55
|
+
data: hasCustomMessage ? {} : { selector }
|
56
|
+
});
|
57
|
+
}
|
58
|
+
});
|
59
|
+
}, {});
|
33
60
|
|
34
61
|
}
|
35
62
|
};
|
@@ -76,8 +76,8 @@ module.exports = {
|
|
76
76
|
nextToken = sourceCode.getTokenAfter(node, 1);
|
77
77
|
|
78
78
|
return isParenthesised(node) && previousToken && nextToken &&
|
79
|
-
|
80
|
-
nextToken
|
79
|
+
astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] &&
|
80
|
+
astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1];
|
81
81
|
}
|
82
82
|
|
83
83
|
return {
|
@@ -9,6 +9,7 @@
|
|
9
9
|
//------------------------------------------------------------------------------
|
10
10
|
|
11
11
|
const astUtils = require("../ast-utils");
|
12
|
+
const esUtils = require("esutils");
|
12
13
|
|
13
14
|
//------------------------------------------------------------------------------
|
14
15
|
// Rule Definition
|
@@ -55,7 +56,17 @@ module.exports = {
|
|
55
56
|
// If there are comments between the brackets and the property name, don't do a fix.
|
56
57
|
return null;
|
57
58
|
}
|
58
|
-
|
59
|
+
|
60
|
+
const tokenBeforeLeftBracket = sourceCode.getTokenBefore(leftSquareBracket);
|
61
|
+
|
62
|
+
// Insert a space before the key to avoid changing identifiers, e.g. ({ get[2]() {} }) to ({ get2() {} })
|
63
|
+
const needsSpaceBeforeKey = tokenBeforeLeftBracket.range[1] === leftSquareBracket.range[0] &&
|
64
|
+
esUtils.code.isIdentifierPartES6(tokenBeforeLeftBracket.value.slice(-1).charCodeAt(0)) &&
|
65
|
+
esUtils.code.isIdentifierPartES6(key.raw.charCodeAt(0));
|
66
|
+
|
67
|
+
const replacementKey = (needsSpaceBeforeKey ? " " : "") + key.raw;
|
68
|
+
|
69
|
+
return fixer.replaceTextRange([leftSquareBracket.range[0], rightSquareBracket.range[1]], replacementKey);
|
59
70
|
}
|
60
71
|
});
|
61
72
|
}
|
@@ -171,8 +171,8 @@ module.exports = {
|
|
171
171
|
|
172
172
|
if (astUtils.isTokenOnSameLine(penultimate, last)) {
|
173
173
|
const shouldCheckPenultimate = (
|
174
|
-
options.arraysInObjectsException && penultimate
|
175
|
-
options.objectsInObjectsException && penultimate
|
174
|
+
options.arraysInObjectsException && astUtils.isClosingBracketToken(penultimate) ||
|
175
|
+
options.objectsInObjectsException && astUtils.isClosingBraceToken(penultimate)
|
176
176
|
);
|
177
177
|
const penultimateType = shouldCheckPenultimate && sourceCode.getNodeByRangeIndex(penultimate.start).type;
|
178
178
|
|
@@ -230,7 +230,10 @@ module.exports = {
|
|
230
230
|
const functionToken = sourceCode.getTokens(node.value).find(token => token.type === "Keyword" && token.value === "function");
|
231
231
|
const tokenBeforeParams = node.value.generator ? sourceCode.getTokenAfter(functionToken) : functionToken;
|
232
232
|
|
233
|
-
return fixer.replaceTextRange(
|
233
|
+
return fixer.replaceTextRange(
|
234
|
+
[firstKeyToken.range[0], node.range[1]],
|
235
|
+
keyPrefix + keyText + sourceCode.text.slice(tokenBeforeParams.range[1], node.value.range[1])
|
236
|
+
);
|
234
237
|
}
|
235
238
|
const arrowToken = sourceCode.getTokens(node.value).find(token => token.value === "=>");
|
236
239
|
const tokenBeforeArrow = sourceCode.getTokenBefore(arrowToken);
|
@@ -238,7 +241,10 @@ module.exports = {
|
|
238
241
|
const oldParamText = sourceCode.text.slice(sourceCode.getFirstToken(node.value, node.value.async ? 1 : 0).range[0], tokenBeforeArrow.range[1]);
|
239
242
|
const newParamText = hasParensAroundParameters ? oldParamText : `(${oldParamText})`;
|
240
243
|
|
241
|
-
return fixer.replaceTextRange(
|
244
|
+
return fixer.replaceTextRange(
|
245
|
+
[firstKeyToken.range[0], node.range[1]],
|
246
|
+
keyPrefix + keyText + newParamText + sourceCode.text.slice(arrowToken.range[1], node.value.range[1])
|
247
|
+
);
|
242
248
|
|
243
249
|
}
|
244
250
|
|
@@ -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
|
// Helpers
|
9
15
|
//------------------------------------------------------------------------------
|
@@ -135,7 +141,7 @@ module.exports = {
|
|
135
141
|
const equalsToken = getOperatorToken(node);
|
136
142
|
const operatorToken = getOperatorToken(expr);
|
137
143
|
const leftText = sourceCode.getText().slice(node.range[0], equalsToken.range[0]);
|
138
|
-
const rightText = sourceCode.getText().slice(operatorToken.range[1],
|
144
|
+
const rightText = sourceCode.getText().slice(operatorToken.range[1], node.right.range[1]);
|
139
145
|
|
140
146
|
return fixer.replaceText(node, `${leftText}${expr.operator}=${rightText}`);
|
141
147
|
}
|
@@ -171,9 +177,20 @@ module.exports = {
|
|
171
177
|
if (canBeFixed(node.left)) {
|
172
178
|
const operatorToken = getOperatorToken(node);
|
173
179
|
const leftText = sourceCode.getText().slice(node.range[0], operatorToken.range[0]);
|
174
|
-
const
|
180
|
+
const newOperator = node.operator.slice(0, -1);
|
181
|
+
let rightText;
|
182
|
+
|
183
|
+
// If this change would modify precedence (e.g. `foo *= bar + 1` => `foo = foo * (bar + 1)`), parenthesize the right side.
|
184
|
+
if (
|
185
|
+
astUtils.getPrecedence(node.right) <= astUtils.getPrecedence({ type: "BinaryExpression", operator: newOperator }) &&
|
186
|
+
!astUtils.isParenthesised(sourceCode, node.right)
|
187
|
+
) {
|
188
|
+
rightText = `${sourceCode.text.slice(operatorToken.range[1], node.right.range[0])}(${sourceCode.getText(node.right)})`;
|
189
|
+
} else {
|
190
|
+
rightText = sourceCode.text.slice(operatorToken.range[1], node.range[1]);
|
191
|
+
}
|
175
192
|
|
176
|
-
return fixer.replaceText(node, `${leftText}= ${leftText}${
|
193
|
+
return fixer.replaceText(node, `${leftText}= ${leftText}${newOperator}${rightText}`);
|
177
194
|
}
|
178
195
|
return null;
|
179
196
|
}
|
@@ -9,7 +9,7 @@
|
|
9
9
|
// Helpers
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
|
-
const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|Property)$/;
|
12
|
+
const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/;
|
13
13
|
const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/;
|
14
14
|
const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/;
|
15
15
|
|
package/lib/rules/quotes.js
CHANGED
@@ -105,20 +105,7 @@ module.exports = {
|
|
105
105
|
function isBeforeClosingParen(token) {
|
106
106
|
const nextToken = sourceCode.getTokenAfter(token);
|
107
107
|
|
108
|
-
return (
|
109
|
-
nextToken &&
|
110
|
-
nextToken.type === "Punctuator" &&
|
111
|
-
(nextToken.value === "}" || nextToken.value === ")")
|
112
|
-
);
|
113
|
-
}
|
114
|
-
|
115
|
-
/**
|
116
|
-
* Checks if the given token is a semicolon.
|
117
|
-
* @param {Token} token The token to check.
|
118
|
-
* @returns {boolean} Whether or not the given token is a semicolon.
|
119
|
-
*/
|
120
|
-
function isSemicolon(token) {
|
121
|
-
return token.type === "Punctuator" && token.value === ";";
|
108
|
+
return (nextToken && astUtils.isClosingBraceToken(nextToken) || astUtils.isClosingParenToken(nextToken));
|
122
109
|
}
|
123
110
|
|
124
111
|
/**
|
@@ -128,7 +115,7 @@ module.exports = {
|
|
128
115
|
* @returns {void}
|
129
116
|
*/
|
130
117
|
function checkSemicolonSpacing(token, node) {
|
131
|
-
if (
|
118
|
+
if (astUtils.isSemicolonToken(token)) {
|
132
119
|
const location = token.loc.start;
|
133
120
|
|
134
121
|
if (hasLeadingSpace(token)) {
|
package/lib/rules/semi.js
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
//------------------------------------------------------------------------------
|
10
10
|
|
11
11
|
const FixTracker = require("../util/fix-tracker");
|
12
|
+
const astUtils = require("../ast-utils");
|
12
13
|
|
13
14
|
//------------------------------------------------------------------------------
|
14
15
|
// Rule Definition
|
@@ -110,15 +111,6 @@ module.exports = {
|
|
110
111
|
|
111
112
|
}
|
112
113
|
|
113
|
-
/**
|
114
|
-
* Checks whether a token is a semicolon punctuator.
|
115
|
-
* @param {Token} token The token.
|
116
|
-
* @returns {boolean} True if token is a semicolon punctuator.
|
117
|
-
*/
|
118
|
-
function isSemicolon(token) {
|
119
|
-
return (token.type === "Punctuator" && token.value === ";");
|
120
|
-
}
|
121
|
-
|
122
114
|
/**
|
123
115
|
* Check if a semicolon is unnecessary, only true if:
|
124
116
|
* - next token is on a new line and is not one of the opt-out tokens
|
@@ -127,7 +119,7 @@ module.exports = {
|
|
127
119
|
* @returns {boolean} whether the semicolon is unnecessary.
|
128
120
|
*/
|
129
121
|
function isUnnecessarySemicolon(lastToken) {
|
130
|
-
if (!
|
122
|
+
if (!astUtils.isSemicolonToken(lastToken)) {
|
131
123
|
return false;
|
132
124
|
}
|
133
125
|
|
@@ -140,7 +132,7 @@ module.exports = {
|
|
140
132
|
const lastTokenLine = lastToken.loc.end.line;
|
141
133
|
const nextTokenLine = nextToken.loc.start.line;
|
142
134
|
const isOptOutToken = OPT_OUT_PATTERN.test(nextToken.value) && nextToken.value !== "++" && nextToken.value !== "--";
|
143
|
-
const isDivider = (nextToken
|
135
|
+
const isDivider = (astUtils.isClosingBraceToken(nextToken) || astUtils.isSemicolonToken(nextToken));
|
144
136
|
|
145
137
|
return (lastTokenLine !== nextTokenLine && !isOptOutToken) || isDivider;
|
146
138
|
}
|
@@ -176,7 +168,7 @@ module.exports = {
|
|
176
168
|
report(node, true);
|
177
169
|
}
|
178
170
|
} else {
|
179
|
-
if (!
|
171
|
+
if (!astUtils.isSemicolonToken(lastToken)) {
|
180
172
|
if (!exceptOneLine || !isOneLinerBlock(node)) {
|
181
173
|
report(node);
|
182
174
|
}
|