eslint 6.2.0 → 6.4.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 +66 -0
- package/README.md +8 -2
- package/conf/config-schema.js +1 -0
- package/conf/default-cli-options.js +1 -1
- package/lib/cli-engine/config-array/config-array.js +6 -0
- package/lib/cli-engine/config-array/extracted-config.js +6 -0
- package/lib/cli-engine/config-array/override-tester.js +2 -2
- package/lib/cli-engine/config-array-factory.js +2 -0
- package/lib/cli-engine/formatters/stylish.js +2 -1
- package/lib/init/config-initializer.js +29 -0
- package/lib/init/npm-utils.js +8 -8
- package/lib/linter/apply-disable-directives.js +17 -9
- package/lib/linter/linter.js +23 -3
- package/lib/options.js +1 -1
- package/lib/rules/accessor-pairs.js +51 -11
- package/lib/rules/computed-property-spacing.js +18 -1
- package/lib/rules/default-param-last.js +61 -0
- package/lib/rules/eqeqeq.js +7 -19
- package/lib/rules/func-name-matching.js +1 -0
- package/lib/rules/function-paren-newline.js +2 -2
- package/lib/rules/indent.js +16 -6
- package/lib/rules/index.js +3 -0
- package/lib/rules/no-extra-boolean-cast.js +12 -2
- package/lib/rules/no-extra-parens.js +8 -1
- package/lib/rules/no-import-assign.js +238 -0
- package/lib/rules/no-lone-blocks.js +6 -1
- package/lib/rules/no-obj-calls.js +29 -9
- package/lib/rules/no-octal-escape.js +14 -8
- package/lib/rules/no-self-assign.js +17 -6
- package/lib/rules/no-sequences.js +2 -2
- package/lib/rules/no-unsafe-negation.js +2 -10
- package/lib/rules/object-curly-spacing.js +1 -1
- package/lib/rules/object-shorthand.js +35 -9
- package/lib/rules/prefer-regex-literals.js +125 -0
- package/lib/rules/quotes.js +6 -0
- package/lib/rules/space-before-function-paren.js +12 -1
- package/lib/rules/space-in-parens.js +77 -71
- package/lib/rules/yoda.js +11 -2
- package/lib/shared/types.js +2 -0
- package/package.json +3 -3
@@ -244,6 +244,7 @@ module.exports = {
|
|
244
244
|
const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]);
|
245
245
|
let keyPrefix = "";
|
246
246
|
|
247
|
+
// key: /* */ () => {}
|
247
248
|
if (sourceCode.commentsExistBetween(lastKeyToken, node.value)) {
|
248
249
|
return null;
|
249
250
|
}
|
@@ -255,24 +256,49 @@ module.exports = {
|
|
255
256
|
keyPrefix += "*";
|
256
257
|
}
|
257
258
|
|
259
|
+
const fixRange = [firstKeyToken.range[0], node.range[1]];
|
260
|
+
const methodPrefix = keyPrefix + keyText;
|
261
|
+
|
258
262
|
if (node.value.type === "FunctionExpression") {
|
259
263
|
const functionToken = sourceCode.getTokens(node.value).find(token => token.type === "Keyword" && token.value === "function");
|
260
264
|
const tokenBeforeParams = node.value.generator ? sourceCode.getTokenAfter(functionToken) : functionToken;
|
261
265
|
|
262
266
|
return fixer.replaceTextRange(
|
263
|
-
|
264
|
-
|
267
|
+
fixRange,
|
268
|
+
methodPrefix + sourceCode.text.slice(tokenBeforeParams.range[1], node.value.range[1])
|
265
269
|
);
|
266
270
|
}
|
267
|
-
|
268
|
-
const
|
269
|
-
const
|
270
|
-
|
271
|
-
|
271
|
+
|
272
|
+
const arrowToken = sourceCode.getTokenBefore(node.value.body, astUtils.isArrowToken);
|
273
|
+
const fnBody = sourceCode.text.slice(arrowToken.range[1], node.value.range[1]);
|
274
|
+
|
275
|
+
let shouldAddParensAroundParameters = false;
|
276
|
+
let tokenBeforeParams;
|
277
|
+
|
278
|
+
if (node.value.params.length === 0) {
|
279
|
+
tokenBeforeParams = sourceCode.getFirstToken(node.value, astUtils.isOpeningParenToken);
|
280
|
+
} else {
|
281
|
+
tokenBeforeParams = sourceCode.getTokenBefore(node.value.params[0]);
|
282
|
+
}
|
283
|
+
|
284
|
+
if (node.value.params.length === 1) {
|
285
|
+
const hasParen = astUtils.isOpeningParenToken(tokenBeforeParams);
|
286
|
+
const isTokenOutsideNode = tokenBeforeParams.range[0] < node.range[0];
|
287
|
+
|
288
|
+
shouldAddParensAroundParameters = !hasParen || isTokenOutsideNode;
|
289
|
+
}
|
290
|
+
|
291
|
+
const sliceStart = shouldAddParensAroundParameters
|
292
|
+
? node.value.params[0].range[0]
|
293
|
+
: tokenBeforeParams.range[0];
|
294
|
+
const sliceEnd = sourceCode.getTokenBefore(arrowToken).range[1];
|
295
|
+
|
296
|
+
const oldParamText = sourceCode.text.slice(sliceStart, sliceEnd);
|
297
|
+
const newParamText = shouldAddParensAroundParameters ? `(${oldParamText})` : oldParamText;
|
272
298
|
|
273
299
|
return fixer.replaceTextRange(
|
274
|
-
|
275
|
-
|
300
|
+
fixRange,
|
301
|
+
methodPrefix + newParamText + fnBody
|
276
302
|
);
|
277
303
|
|
278
304
|
}
|
@@ -0,0 +1,125 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Rule to disallow use of the `RegExp` constructor in favor of regular expression literals
|
3
|
+
* @author Milos Djermanovic
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
const astUtils = require("./utils/ast-utils");
|
13
|
+
const { CALL, CONSTRUCT, ReferenceTracker, findVariable } = require("eslint-utils");
|
14
|
+
|
15
|
+
//------------------------------------------------------------------------------
|
16
|
+
// Helpers
|
17
|
+
//------------------------------------------------------------------------------
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Determines whether the given node is a string literal.
|
21
|
+
* @param {ASTNode} node Node to check.
|
22
|
+
* @returns {boolean} True if the node is a string literal.
|
23
|
+
*/
|
24
|
+
function isStringLiteral(node) {
|
25
|
+
return node.type === "Literal" && typeof node.value === "string";
|
26
|
+
}
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Determines whether the given node is a template literal without expressions.
|
30
|
+
* @param {ASTNode} node Node to check.
|
31
|
+
* @returns {boolean} True if the node is a template literal without expressions.
|
32
|
+
*/
|
33
|
+
function isStaticTemplateLiteral(node) {
|
34
|
+
return node.type === "TemplateLiteral" && node.expressions.length === 0;
|
35
|
+
}
|
36
|
+
|
37
|
+
|
38
|
+
//------------------------------------------------------------------------------
|
39
|
+
// Rule Definition
|
40
|
+
//------------------------------------------------------------------------------
|
41
|
+
|
42
|
+
module.exports = {
|
43
|
+
meta: {
|
44
|
+
type: "suggestion",
|
45
|
+
|
46
|
+
docs: {
|
47
|
+
description: "disallow use of the `RegExp` constructor in favor of regular expression literals",
|
48
|
+
category: "Best Practices",
|
49
|
+
recommended: false,
|
50
|
+
url: "https://eslint.org/docs/rules/prefer-regex-literals"
|
51
|
+
},
|
52
|
+
|
53
|
+
schema: [],
|
54
|
+
|
55
|
+
messages: {
|
56
|
+
unexpectedRegExp: "Use a regular expression literal instead of the 'RegExp' constructor."
|
57
|
+
}
|
58
|
+
},
|
59
|
+
|
60
|
+
create(context) {
|
61
|
+
|
62
|
+
/**
|
63
|
+
* Determines whether the given identifier node is a reference to a global variable.
|
64
|
+
* @param {ASTNode} node `Identifier` node to check.
|
65
|
+
* @returns {boolean} True if the identifier is a reference to a global variable.
|
66
|
+
*/
|
67
|
+
function isGlobalReference(node) {
|
68
|
+
const scope = context.getScope();
|
69
|
+
const variable = findVariable(scope, node);
|
70
|
+
|
71
|
+
return variable !== null && variable.scope.type === "global" && variable.defs.length === 0;
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* Determines whether the given node is a String.raw`` tagged template expression
|
76
|
+
* with a static template literal.
|
77
|
+
* @param {ASTNode} node Node to check.
|
78
|
+
* @returns {boolean} True if the node is String.raw`` with a static template.
|
79
|
+
*/
|
80
|
+
function isStringRawTaggedStaticTemplateLiteral(node) {
|
81
|
+
return node.type === "TaggedTemplateExpression" &&
|
82
|
+
node.tag.type === "MemberExpression" &&
|
83
|
+
node.tag.object.type === "Identifier" &&
|
84
|
+
node.tag.object.name === "String" &&
|
85
|
+
isGlobalReference(node.tag.object) &&
|
86
|
+
astUtils.getStaticPropertyName(node.tag) === "raw" &&
|
87
|
+
isStaticTemplateLiteral(node.quasi);
|
88
|
+
}
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Determines whether the given node is considered to be a static string by the logic of this rule.
|
92
|
+
* @param {ASTNode} node Node to check.
|
93
|
+
* @returns {boolean} True if the node is a static string.
|
94
|
+
*/
|
95
|
+
function isStaticString(node) {
|
96
|
+
return isStringLiteral(node) ||
|
97
|
+
isStaticTemplateLiteral(node) ||
|
98
|
+
isStringRawTaggedStaticTemplateLiteral(node);
|
99
|
+
}
|
100
|
+
|
101
|
+
return {
|
102
|
+
Program() {
|
103
|
+
const scope = context.getScope();
|
104
|
+
const tracker = new ReferenceTracker(scope);
|
105
|
+
const traceMap = {
|
106
|
+
RegExp: {
|
107
|
+
[CALL]: true,
|
108
|
+
[CONSTRUCT]: true
|
109
|
+
}
|
110
|
+
};
|
111
|
+
|
112
|
+
for (const { node } of tracker.iterateGlobalReferences(traceMap)) {
|
113
|
+
const args = node.arguments;
|
114
|
+
|
115
|
+
if (
|
116
|
+
(args.length === 1 || args.length === 2) &&
|
117
|
+
args.every(isStaticString)
|
118
|
+
) {
|
119
|
+
context.report({ node, messageId: "unexpectedRegExp" });
|
120
|
+
}
|
121
|
+
}
|
122
|
+
}
|
123
|
+
};
|
124
|
+
}
|
125
|
+
};
|
package/lib/rules/quotes.js
CHANGED
@@ -279,6 +279,12 @@ module.exports = {
|
|
279
279
|
description: settings.description
|
280
280
|
},
|
281
281
|
fix(fixer) {
|
282
|
+
if (quoteOption === "backtick" && astUtils.hasOctalEscapeSequence(rawVal)) {
|
283
|
+
|
284
|
+
// An octal escape sequence in a template literal would produce syntax error, even in non-strict mode.
|
285
|
+
return null;
|
286
|
+
}
|
287
|
+
|
282
288
|
return fixer.replaceText(node, settings.convert(node.raw));
|
283
289
|
}
|
284
290
|
});
|
@@ -124,7 +124,18 @@ module.exports = {
|
|
124
124
|
node,
|
125
125
|
loc: leftToken.loc.end,
|
126
126
|
message: "Unexpected space before function parentheses.",
|
127
|
-
fix
|
127
|
+
fix(fixer) {
|
128
|
+
const comments = sourceCode.getCommentsBefore(rightToken);
|
129
|
+
|
130
|
+
// Don't fix anything if there's a single line comment between the left and the right token
|
131
|
+
if (comments.some(comment => comment.type === "Line")) {
|
132
|
+
return null;
|
133
|
+
}
|
134
|
+
return fixer.replaceTextRange(
|
135
|
+
[leftToken.range[1], rightToken.range[0]],
|
136
|
+
comments.reduce((text, comment) => text + sourceCode.getText(comment), "")
|
137
|
+
);
|
138
|
+
}
|
128
139
|
});
|
129
140
|
} else if (!hasSpacing && functionConfig === "always") {
|
130
141
|
context.report({
|
@@ -40,23 +40,28 @@ module.exports = {
|
|
40
40
|
},
|
41
41
|
additionalProperties: false
|
42
42
|
}
|
43
|
-
]
|
43
|
+
],
|
44
|
+
|
45
|
+
messages: {
|
46
|
+
missingOpeningSpace: "There must be a space after this paren.",
|
47
|
+
missingClosingSpace: "There must be a space before this paren.",
|
48
|
+
rejectedOpeningSpace: "There should be no space after this paren.",
|
49
|
+
rejectedClosingSpace: "There should be no space before this paren."
|
50
|
+
}
|
44
51
|
},
|
45
52
|
|
46
53
|
create(context) {
|
47
|
-
|
48
|
-
const MISSING_SPACE_MESSAGE = "There must be a space inside this paren.",
|
49
|
-
REJECTED_SPACE_MESSAGE = "There should be no spaces inside this paren.",
|
50
|
-
ALWAYS = context.options[0] === "always",
|
54
|
+
const ALWAYS = context.options[0] === "always",
|
51
55
|
exceptionsArrayOptions = (context.options[1] && context.options[1].exceptions) || [],
|
52
56
|
options = {};
|
57
|
+
|
53
58
|
let exceptions;
|
54
59
|
|
55
60
|
if (exceptionsArrayOptions.length) {
|
56
|
-
options.braceException = exceptionsArrayOptions.
|
57
|
-
options.bracketException = exceptionsArrayOptions.
|
58
|
-
options.parenException = exceptionsArrayOptions.
|
59
|
-
options.empty = exceptionsArrayOptions.
|
61
|
+
options.braceException = exceptionsArrayOptions.includes("{}");
|
62
|
+
options.bracketException = exceptionsArrayOptions.includes("[]");
|
63
|
+
options.parenException = exceptionsArrayOptions.includes("()");
|
64
|
+
options.empty = exceptionsArrayOptions.includes("empty");
|
60
65
|
}
|
61
66
|
|
62
67
|
/**
|
@@ -105,7 +110,7 @@ module.exports = {
|
|
105
110
|
* @returns {boolean} True if the token is one of the exceptions for the opener paren
|
106
111
|
*/
|
107
112
|
function isOpenerException(token) {
|
108
|
-
return
|
113
|
+
return exceptions.openers.includes(token.value);
|
109
114
|
}
|
110
115
|
|
111
116
|
/**
|
@@ -114,102 +119,95 @@ module.exports = {
|
|
114
119
|
* @returns {boolean} True if the token is one of the exceptions for the closer paren
|
115
120
|
*/
|
116
121
|
function isCloserException(token) {
|
117
|
-
return
|
122
|
+
return exceptions.closers.includes(token.value);
|
118
123
|
}
|
119
124
|
|
120
125
|
/**
|
121
|
-
* Determines if an
|
122
|
-
* @param {Object}
|
123
|
-
* @param {Object}
|
124
|
-
* @returns {boolean} True if the paren
|
126
|
+
* Determines if an opening paren is immediately followed by a required space
|
127
|
+
* @param {Object} openingParenToken The paren token
|
128
|
+
* @param {Object} tokenAfterOpeningParen The token after it
|
129
|
+
* @returns {boolean} True if the opening paren is missing a required space
|
125
130
|
*/
|
126
|
-
function
|
127
|
-
if (sourceCode.isSpaceBetweenTokens(
|
131
|
+
function openerMissingSpace(openingParenToken, tokenAfterOpeningParen) {
|
132
|
+
if (sourceCode.isSpaceBetweenTokens(openingParenToken, tokenAfterOpeningParen)) {
|
128
133
|
return false;
|
129
134
|
}
|
130
135
|
|
131
|
-
if (
|
132
|
-
|
133
|
-
return false;
|
134
|
-
}
|
135
|
-
return !isOpenerException(right);
|
136
|
+
if (!options.empty && astUtils.isClosingParenToken(tokenAfterOpeningParen)) {
|
137
|
+
return false;
|
136
138
|
}
|
137
|
-
return isOpenerException(right);
|
138
139
|
|
140
|
+
if (ALWAYS) {
|
141
|
+
return !isOpenerException(tokenAfterOpeningParen);
|
142
|
+
}
|
143
|
+
return isOpenerException(tokenAfterOpeningParen);
|
139
144
|
}
|
140
145
|
|
141
146
|
/**
|
142
|
-
* Determines if an
|
143
|
-
* @param {Object}
|
144
|
-
* @param {Object}
|
145
|
-
* @returns {boolean} True if the paren
|
147
|
+
* Determines if an opening paren is immediately followed by a disallowed space
|
148
|
+
* @param {Object} openingParenToken The paren token
|
149
|
+
* @param {Object} tokenAfterOpeningParen The token after it
|
150
|
+
* @returns {boolean} True if the opening paren has a disallowed space
|
146
151
|
*/
|
147
|
-
function
|
148
|
-
if (astUtils.
|
152
|
+
function openerRejectsSpace(openingParenToken, tokenAfterOpeningParen) {
|
153
|
+
if (!astUtils.isTokenOnSameLine(openingParenToken, tokenAfterOpeningParen)) {
|
149
154
|
return false;
|
150
155
|
}
|
151
156
|
|
152
|
-
if (
|
157
|
+
if (tokenAfterOpeningParen.type === "Line") {
|
153
158
|
return false;
|
154
159
|
}
|
155
160
|
|
156
|
-
if (
|
157
|
-
return
|
161
|
+
if (!sourceCode.isSpaceBetweenTokens(openingParenToken, tokenAfterOpeningParen)) {
|
162
|
+
return false;
|
158
163
|
}
|
159
|
-
return isCloserException(left);
|
160
164
|
|
165
|
+
if (ALWAYS) {
|
166
|
+
return isOpenerException(tokenAfterOpeningParen);
|
167
|
+
}
|
168
|
+
return !isOpenerException(tokenAfterOpeningParen);
|
161
169
|
}
|
162
170
|
|
163
171
|
/**
|
164
|
-
* Determines if
|
165
|
-
* @param {Object}
|
166
|
-
* @param {Object}
|
167
|
-
* @returns {boolean} True if the paren
|
172
|
+
* Determines if a closing paren is immediately preceeded by a required space
|
173
|
+
* @param {Object} tokenBeforeClosingParen The token before the paren
|
174
|
+
* @param {Object} closingParenToken The paren token
|
175
|
+
* @returns {boolean} True if the closing paren is missing a required space
|
168
176
|
*/
|
169
|
-
function
|
170
|
-
if (
|
171
|
-
return false;
|
172
|
-
}
|
173
|
-
|
174
|
-
if (!astUtils.isTokenOnSameLine(left, right)) {
|
177
|
+
function closerMissingSpace(tokenBeforeClosingParen, closingParenToken) {
|
178
|
+
if (sourceCode.isSpaceBetweenTokens(tokenBeforeClosingParen, closingParenToken)) {
|
175
179
|
return false;
|
176
180
|
}
|
177
181
|
|
178
|
-
if (!
|
182
|
+
if (!options.empty && astUtils.isOpeningParenToken(tokenBeforeClosingParen)) {
|
179
183
|
return false;
|
180
184
|
}
|
181
185
|
|
182
186
|
if (ALWAYS) {
|
183
|
-
return
|
187
|
+
return !isCloserException(tokenBeforeClosingParen);
|
184
188
|
}
|
185
|
-
return
|
186
|
-
|
189
|
+
return isCloserException(tokenBeforeClosingParen);
|
187
190
|
}
|
188
191
|
|
189
192
|
/**
|
190
|
-
* Determines if
|
191
|
-
* @param {Object}
|
192
|
-
* @param {Object}
|
193
|
-
* @returns {boolean} True if the paren
|
193
|
+
* Determines if a closer paren is immediately preceeded by a disallowed space
|
194
|
+
* @param {Object} tokenBeforeClosingParen The token before the paren
|
195
|
+
* @param {Object} closingParenToken The paren token
|
196
|
+
* @returns {boolean} True if the closing paren has a disallowed space
|
194
197
|
*/
|
195
|
-
function
|
196
|
-
if (astUtils.
|
198
|
+
function closerRejectsSpace(tokenBeforeClosingParen, closingParenToken) {
|
199
|
+
if (!astUtils.isTokenOnSameLine(tokenBeforeClosingParen, closingParenToken)) {
|
197
200
|
return false;
|
198
201
|
}
|
199
202
|
|
200
|
-
if (!
|
201
|
-
return false;
|
202
|
-
}
|
203
|
-
|
204
|
-
if (!sourceCode.isSpaceBetweenTokens(left, right)) {
|
203
|
+
if (!sourceCode.isSpaceBetweenTokens(tokenBeforeClosingParen, closingParenToken)) {
|
205
204
|
return false;
|
206
205
|
}
|
207
206
|
|
208
207
|
if (ALWAYS) {
|
209
|
-
return isCloserException(
|
208
|
+
return isCloserException(tokenBeforeClosingParen);
|
210
209
|
}
|
211
|
-
return !isCloserException(
|
212
|
-
|
210
|
+
return !isCloserException(tokenBeforeClosingParen);
|
213
211
|
}
|
214
212
|
|
215
213
|
//--------------------------------------------------------------------------
|
@@ -225,44 +223,53 @@ module.exports = {
|
|
225
223
|
const prevToken = tokens[i - 1];
|
226
224
|
const nextToken = tokens[i + 1];
|
227
225
|
|
226
|
+
// if token is not an opening or closing paren token, do nothing
|
228
227
|
if (!astUtils.isOpeningParenToken(token) && !astUtils.isClosingParenToken(token)) {
|
229
228
|
return;
|
230
229
|
}
|
231
230
|
|
232
|
-
if
|
231
|
+
// if token is an opening paren and is not followed by a required space
|
232
|
+
if (token.value === "(" && openerMissingSpace(token, nextToken)) {
|
233
233
|
context.report({
|
234
234
|
node,
|
235
235
|
loc: token.loc.start,
|
236
|
-
|
236
|
+
messageId: "missingOpeningSpace",
|
237
237
|
fix(fixer) {
|
238
238
|
return fixer.insertTextAfter(token, " ");
|
239
239
|
}
|
240
240
|
});
|
241
|
-
}
|
241
|
+
}
|
242
|
+
|
243
|
+
// if token is an opening paren and is followed by a disallowed space
|
244
|
+
if (token.value === "(" && openerRejectsSpace(token, nextToken)) {
|
242
245
|
context.report({
|
243
246
|
node,
|
244
247
|
loc: token.loc.start,
|
245
|
-
|
248
|
+
messageId: "rejectedOpeningSpace",
|
246
249
|
fix(fixer) {
|
247
250
|
return fixer.removeRange([token.range[1], nextToken.range[0]]);
|
248
251
|
}
|
249
252
|
});
|
250
|
-
}
|
253
|
+
}
|
251
254
|
|
252
|
-
|
255
|
+
// if token is a closing paren and is not preceded by a required space
|
256
|
+
if (token.value === ")" && closerMissingSpace(prevToken, token)) {
|
253
257
|
context.report({
|
254
258
|
node,
|
255
259
|
loc: token.loc.start,
|
256
|
-
|
260
|
+
messageId: "missingClosingSpace",
|
257
261
|
fix(fixer) {
|
258
262
|
return fixer.insertTextBefore(token, " ");
|
259
263
|
}
|
260
264
|
});
|
261
|
-
}
|
265
|
+
}
|
266
|
+
|
267
|
+
// if token is a closing paren and is preceded by a disallowed space
|
268
|
+
if (token.value === ")" && closerRejectsSpace(prevToken, token)) {
|
262
269
|
context.report({
|
263
270
|
node,
|
264
271
|
loc: token.loc.start,
|
265
|
-
|
272
|
+
messageId: "rejectedClosingSpace",
|
266
273
|
fix(fixer) {
|
267
274
|
return fixer.removeRange([prevToken.range[1], token.range[0]]);
|
268
275
|
}
|
@@ -271,6 +278,5 @@ module.exports = {
|
|
271
278
|
});
|
272
279
|
}
|
273
280
|
};
|
274
|
-
|
275
281
|
}
|
276
282
|
};
|
package/lib/rules/yoda.js
CHANGED
@@ -274,13 +274,22 @@ module.exports = {
|
|
274
274
|
* @returns {string} A string representation of the node with the sides and operator flipped
|
275
275
|
*/
|
276
276
|
function getFlippedString(node) {
|
277
|
+
const tokenBefore = sourceCode.getTokenBefore(node);
|
277
278
|
const operatorToken = sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator);
|
278
279
|
const textBeforeOperator = sourceCode.getText().slice(sourceCode.getTokenBefore(operatorToken).range[1], operatorToken.range[0]);
|
279
280
|
const textAfterOperator = sourceCode.getText().slice(operatorToken.range[1], sourceCode.getTokenAfter(operatorToken).range[0]);
|
280
281
|
const leftText = sourceCode.getText().slice(node.range[0], sourceCode.getTokenBefore(operatorToken).range[1]);
|
281
|
-
const
|
282
|
+
const firstRightToken = sourceCode.getTokenAfter(operatorToken);
|
283
|
+
const rightText = sourceCode.getText().slice(firstRightToken.range[0], node.range[1]);
|
282
284
|
|
283
|
-
|
285
|
+
let prefix = "";
|
286
|
+
|
287
|
+
if (tokenBefore && tokenBefore.range[1] === node.range[0] &&
|
288
|
+
!astUtils.canTokensBeAdjacent(tokenBefore, firstRightToken)) {
|
289
|
+
prefix = " ";
|
290
|
+
}
|
291
|
+
|
292
|
+
return prefix + rightText + textBeforeOperator + OPERATOR_FLIP_MAP[operatorToken.value] + textAfterOperator + leftText;
|
284
293
|
}
|
285
294
|
|
286
295
|
//--------------------------------------------------------------------------
|
package/lib/shared/types.js
CHANGED
@@ -36,6 +36,7 @@ module.exports = {};
|
|
36
36
|
* @property {ParserOptions} [parserOptions] The parser options.
|
37
37
|
* @property {string[]} [plugins] The plugin specifiers.
|
38
38
|
* @property {string} [processor] The processor specifier.
|
39
|
+
* @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments.
|
39
40
|
* @property {boolean} [root] The root flag.
|
40
41
|
* @property {Record<string, RuleConf>} [rules] The rule settings.
|
41
42
|
* @property {Object} [settings] The shared settings.
|
@@ -54,6 +55,7 @@ module.exports = {};
|
|
54
55
|
* @property {ParserOptions} [parserOptions] The parser options.
|
55
56
|
* @property {string[]} [plugins] The plugin specifiers.
|
56
57
|
* @property {string} [processor] The processor specifier.
|
58
|
+
* @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments.
|
57
59
|
* @property {Record<string, RuleConf>} [rules] The rule settings.
|
58
60
|
* @property {Object} [settings] The shared settings.
|
59
61
|
*/
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "6.
|
3
|
+
"version": "6.4.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -50,9 +50,9 @@
|
|
50
50
|
"debug": "^4.0.1",
|
51
51
|
"doctrine": "^3.0.0",
|
52
52
|
"eslint-scope": "^5.0.0",
|
53
|
-
"eslint-utils": "^1.4.
|
53
|
+
"eslint-utils": "^1.4.2",
|
54
54
|
"eslint-visitor-keys": "^1.1.0",
|
55
|
-
"espree": "^6.1.
|
55
|
+
"espree": "^6.1.1",
|
56
56
|
"esquery": "^1.0.1",
|
57
57
|
"esutils": "^2.0.2",
|
58
58
|
"file-entry-cache": "^5.0.1",
|