eslint 7.0.0-alpha.3 → 7.2.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 +303 -0
- package/README.md +10 -11
- package/bin/eslint.js +115 -77
- package/conf/category-list.json +0 -1
- package/lib/api.js +2 -0
- package/lib/cli-engine/cascading-config-array-factory.js +12 -0
- package/lib/cli-engine/cli-engine.js +53 -48
- package/lib/cli-engine/config-array/config-array.js +1 -1
- package/lib/cli-engine/config-array/ignore-pattern.js +7 -1
- package/lib/cli-engine/config-array-factory.js +3 -3
- package/lib/cli.js +181 -95
- package/lib/eslint/eslint.js +656 -0
- package/lib/eslint/index.js +7 -0
- package/lib/init/autoconfig.js +4 -4
- package/lib/init/config-initializer.js +5 -10
- package/lib/init/source-code-utils.js +2 -2
- package/lib/linter/code-path-analysis/code-path-analyzer.js +2 -2
- package/lib/linter/code-path-analysis/code-path-state.js +34 -12
- package/lib/linter/config-comment-parser.js +1 -1
- package/lib/linter/linter.js +2 -1
- package/lib/options.js +0 -1
- package/lib/rule-tester/rule-tester.js +6 -1
- package/lib/rules/accessor-pairs.js +1 -1
- package/lib/rules/array-callback-return.js +3 -18
- package/lib/rules/arrow-parens.js +19 -3
- package/lib/rules/block-spacing.js +19 -2
- package/lib/rules/callback-return.js +4 -0
- package/lib/rules/comma-style.js +3 -8
- package/lib/rules/func-call-spacing.js +22 -6
- package/lib/rules/getter-return.js +2 -12
- package/lib/rules/global-require.js +4 -0
- package/lib/rules/handle-callback-err.js +4 -0
- package/lib/rules/index.js +1 -0
- package/lib/rules/key-spacing.js +1 -1
- package/lib/rules/keyword-spacing.js +9 -2
- package/lib/rules/linebreak-style.js +8 -2
- package/lib/rules/max-lines-per-function.js +1 -1
- package/lib/rules/multiline-ternary.js +44 -25
- package/lib/rules/new-cap.js +1 -1
- package/lib/rules/newline-per-chained-call.js +6 -3
- package/lib/rules/no-buffer-constructor.js +4 -0
- package/lib/rules/no-control-regex.js +1 -1
- package/lib/rules/no-empty-function.js +1 -1
- package/lib/rules/no-extra-boolean-cast.js +3 -0
- package/lib/rules/no-extra-parens.js +35 -3
- package/lib/rules/no-inner-declarations.js +31 -39
- package/lib/rules/no-invalid-regexp.js +1 -1
- package/lib/rules/no-lone-blocks.js +1 -1
- package/lib/rules/no-loss-of-precision.js +198 -0
- package/lib/rules/no-misleading-character-class.js +1 -1
- package/lib/rules/no-mixed-operators.js +3 -2
- package/lib/rules/no-mixed-requires.js +4 -0
- package/lib/rules/no-mixed-spaces-and-tabs.js +14 -6
- package/lib/rules/no-new-func.js +22 -19
- package/lib/rules/no-new-object.js +15 -3
- package/lib/rules/no-new-require.js +4 -0
- package/lib/rules/no-new-symbol.js +2 -1
- package/lib/rules/no-path-concat.js +4 -0
- package/lib/rules/no-process-env.js +4 -0
- package/lib/rules/no-process-exit.js +4 -0
- package/lib/rules/no-regex-spaces.js +1 -1
- package/lib/rules/no-restricted-exports.js +6 -0
- package/lib/rules/no-restricted-modules.js +4 -0
- package/lib/rules/no-sync.js +4 -0
- package/lib/rules/no-unexpected-multiline.js +22 -12
- package/lib/rules/no-unneeded-ternary.js +6 -4
- package/lib/rules/no-unused-expressions.js +1 -1
- package/lib/rules/no-unused-vars.js +3 -1
- package/lib/rules/no-useless-backreference.js +1 -1
- package/lib/rules/no-useless-concat.js +1 -1
- package/lib/rules/one-var-declaration-per-line.js +1 -1
- package/lib/rules/padded-blocks.js +17 -4
- package/lib/rules/prefer-named-capture-group.js +1 -1
- package/lib/rules/quote-props.js +2 -2
- package/lib/rules/rest-spread-spacing.js +3 -6
- package/lib/rules/semi-spacing.js +32 -8
- package/lib/rules/space-before-function-paren.js +5 -2
- package/lib/rules/template-tag-spacing.js +8 -2
- package/lib/rules/utils/ast-utils.js +106 -9
- package/lib/rules/yoda.js +101 -51
- package/lib/shared/relative-module-resolver.js +1 -0
- package/lib/shared/types.js +7 -0
- package/lib/source-code/source-code.js +1 -0
- package/messages/extend-config-missing.txt +1 -1
- package/messages/no-config-found.txt +1 -1
- package/messages/plugin-conflict.txt +1 -1
- package/messages/plugin-missing.txt +1 -1
- package/messages/whitespace-found.txt +1 -1
- package/package.json +27 -26
@@ -15,6 +15,7 @@ const util = require("util"),
|
|
15
15
|
inquirer = require("inquirer"),
|
16
16
|
ProgressBar = require("progress"),
|
17
17
|
semver = require("semver"),
|
18
|
+
espree = require("espree"),
|
18
19
|
recConfig = require("../../conf/eslint-recommended"),
|
19
20
|
ConfigOps = require("../shared/config-ops"),
|
20
21
|
log = require("../shared/logging"),
|
@@ -31,8 +32,6 @@ const debug = require("debug")("eslint:config-initializer");
|
|
31
32
|
// Private
|
32
33
|
//------------------------------------------------------------------------------
|
33
34
|
|
34
|
-
const DEFAULT_ECMA_VERSION = 2018;
|
35
|
-
|
36
35
|
/* istanbul ignore next: hard to test fs function */
|
37
36
|
/**
|
38
37
|
* Create .eslintrc file in the current working directory
|
@@ -265,13 +264,8 @@ function processAnswers(answers) {
|
|
265
264
|
extends: []
|
266
265
|
};
|
267
266
|
|
268
|
-
|
269
|
-
config.
|
270
|
-
config.env.es6 = true;
|
271
|
-
config.globals = {
|
272
|
-
Atomics: "readonly",
|
273
|
-
SharedArrayBuffer: "readonly"
|
274
|
-
};
|
267
|
+
config.parserOptions.ecmaVersion = espree.latestEcmaVersion;
|
268
|
+
config.env.es2020 = true;
|
275
269
|
|
276
270
|
// set the module type
|
277
271
|
if (answers.moduleType === "esm") {
|
@@ -328,6 +322,7 @@ function processAnswers(answers) {
|
|
328
322
|
}
|
329
323
|
if (answers.typescript && config.extends.includes("eslint:recommended")) {
|
330
324
|
config.extends.push("plugin:@typescript-eslint/eslint-recommended");
|
325
|
+
config.extends.push("plugin:@typescript-eslint/recommended");
|
331
326
|
}
|
332
327
|
|
333
328
|
// normalize extends
|
@@ -351,7 +346,7 @@ function getLocalESLintVersion() {
|
|
351
346
|
const eslint = require(eslintPath);
|
352
347
|
|
353
348
|
return eslint.linter.version || null;
|
354
|
-
} catch
|
349
|
+
} catch {
|
355
350
|
return null;
|
356
351
|
}
|
357
352
|
}
|
@@ -23,7 +23,7 @@ const { CLIEngine } = require("../cli-engine");
|
|
23
23
|
* TODO1: Expose the API that enumerates target files.
|
24
24
|
* TODO2: Extract the creation logic of `SourceCode` from `Linter` class.
|
25
25
|
*/
|
26
|
-
const { getCLIEngineInternalSlots } = require("../cli-engine/cli-engine"); // eslint-disable-line no-restricted-
|
26
|
+
const { getCLIEngineInternalSlots } = require("../cli-engine/cli-engine"); // eslint-disable-line node/no-restricted-require
|
27
27
|
|
28
28
|
const debug = require("debug")("eslint:source-code-utils");
|
29
29
|
|
@@ -97,7 +97,7 @@ function getSourceCodeOfFiles(patterns, options, callback) {
|
|
97
97
|
sourceCodes[filename] = sourceCode;
|
98
98
|
}
|
99
99
|
if (callback) {
|
100
|
-
callback(filenames.length); // eslint-disable-line callback-return
|
100
|
+
callback(filenames.length); // eslint-disable-line node/callback-return
|
101
101
|
}
|
102
102
|
});
|
103
103
|
|
@@ -33,10 +33,10 @@ function isCaseNode(node) {
|
|
33
33
|
* Checks whether the given logical operator is taken into account for the code
|
34
34
|
* path analysis.
|
35
35
|
* @param {string} operator The operator found in the LogicalExpression node
|
36
|
-
* @returns {boolean} `true` if the operator is "&&" or "||"
|
36
|
+
* @returns {boolean} `true` if the operator is "&&" or "||" or "??"
|
37
37
|
*/
|
38
38
|
function isHandledLogicalOperator(operator) {
|
39
|
-
return operator === "&&" || operator === "||";
|
39
|
+
return operator === "&&" || operator === "||" || operator === "??";
|
40
40
|
}
|
41
41
|
|
42
42
|
/**
|
@@ -201,6 +201,7 @@ function finalizeTestSegmentsOfFor(context, choiceContext, head) {
|
|
201
201
|
if (!choiceContext.processed) {
|
202
202
|
choiceContext.trueForkContext.add(head);
|
203
203
|
choiceContext.falseForkContext.add(head);
|
204
|
+
choiceContext.qqForkContext.add(head);
|
204
205
|
}
|
205
206
|
|
206
207
|
if (context.test !== true) {
|
@@ -351,6 +352,7 @@ class CodePathState {
|
|
351
352
|
isForkingAsResult,
|
352
353
|
trueForkContext: ForkContext.newEmpty(this.forkContext),
|
353
354
|
falseForkContext: ForkContext.newEmpty(this.forkContext),
|
355
|
+
qqForkContext: ForkContext.newEmpty(this.forkContext),
|
354
356
|
processed: false
|
355
357
|
};
|
356
358
|
}
|
@@ -370,6 +372,7 @@ class CodePathState {
|
|
370
372
|
switch (context.kind) {
|
371
373
|
case "&&":
|
372
374
|
case "||":
|
375
|
+
case "??":
|
373
376
|
|
374
377
|
/*
|
375
378
|
* If any result were not transferred from child contexts,
|
@@ -379,6 +382,7 @@ class CodePathState {
|
|
379
382
|
if (!context.processed) {
|
380
383
|
context.trueForkContext.add(headSegments);
|
381
384
|
context.falseForkContext.add(headSegments);
|
385
|
+
context.qqForkContext.add(headSegments);
|
382
386
|
}
|
383
387
|
|
384
388
|
/*
|
@@ -390,6 +394,7 @@ class CodePathState {
|
|
390
394
|
|
391
395
|
parentContext.trueForkContext.addAll(context.trueForkContext);
|
392
396
|
parentContext.falseForkContext.addAll(context.falseForkContext);
|
397
|
+
parentContext.qqForkContext.addAll(context.qqForkContext);
|
393
398
|
parentContext.processed = true;
|
394
399
|
|
395
400
|
return context;
|
@@ -456,13 +461,24 @@ class CodePathState {
|
|
456
461
|
* This got segments already from the child choice context.
|
457
462
|
* Creates the next path from own true/false fork context.
|
458
463
|
*/
|
459
|
-
|
460
|
-
|
461
|
-
|
464
|
+
let prevForkContext;
|
465
|
+
|
466
|
+
switch (context.kind) {
|
467
|
+
case "&&": // if true then go to the right-hand side.
|
468
|
+
prevForkContext = context.trueForkContext;
|
469
|
+
break;
|
470
|
+
case "||": // if false then go to the right-hand side.
|
471
|
+
prevForkContext = context.falseForkContext;
|
472
|
+
break;
|
473
|
+
case "??": // Both true/false can short-circuit, so needs the third path to go to the right-hand side. That's qqForkContext.
|
474
|
+
prevForkContext = context.qqForkContext;
|
475
|
+
break;
|
476
|
+
default:
|
477
|
+
throw new Error("unreachable");
|
478
|
+
}
|
462
479
|
|
463
480
|
forkContext.replaceHead(prevForkContext.makeNext(0, -1));
|
464
481
|
prevForkContext.clear();
|
465
|
-
|
466
482
|
context.processed = false;
|
467
483
|
} else {
|
468
484
|
|
@@ -471,14 +487,19 @@ class CodePathState {
|
|
471
487
|
* So addresses the head segments.
|
472
488
|
* The head segments are the path of the left-hand operand.
|
473
489
|
*/
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
490
|
+
switch (context.kind) {
|
491
|
+
case "&&": // the false path can short-circuit.
|
492
|
+
context.falseForkContext.add(forkContext.head);
|
493
|
+
break;
|
494
|
+
case "||": // the true path can short-circuit.
|
495
|
+
context.trueForkContext.add(forkContext.head);
|
496
|
+
break;
|
497
|
+
case "??": // both can short-circuit.
|
498
|
+
context.trueForkContext.add(forkContext.head);
|
499
|
+
context.falseForkContext.add(forkContext.head);
|
500
|
+
break;
|
501
|
+
default:
|
502
|
+
throw new Error("unreachable");
|
482
503
|
}
|
483
504
|
|
484
505
|
forkContext.replaceHead(forkContext.makeNext(-1, -1));
|
@@ -501,6 +522,7 @@ class CodePathState {
|
|
501
522
|
if (!context.processed) {
|
502
523
|
context.trueForkContext.add(forkContext.head);
|
503
524
|
context.falseForkContext.add(forkContext.head);
|
525
|
+
context.qqForkContext.add(forkContext.head);
|
504
526
|
}
|
505
527
|
|
506
528
|
context.processed = false;
|
package/lib/linter/linter.js
CHANGED
@@ -938,7 +938,8 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parser
|
|
938
938
|
});
|
939
939
|
});
|
940
940
|
|
941
|
-
|
941
|
+
// only run code path analyzer if the top level node is "Program", skip otherwise
|
942
|
+
const eventGenerator = nodeQueue[0].node.type === "Program" ? new CodePathAnalyzer(new NodeEventGenerator(emitter)) : new NodeEventGenerator(emitter);
|
942
943
|
|
943
944
|
nodeQueue.forEach(traversalInfo => {
|
944
945
|
currentNode = traversalInfo.node;
|
package/lib/options.js
CHANGED
@@ -563,7 +563,12 @@ class RuleTester {
|
|
563
563
|
output = SourceCodeFixer.applyFixes(code, messages).output;
|
564
564
|
const errorMessageInFix = linter.verify(output, config, filename).find(m => m.fatal);
|
565
565
|
|
566
|
-
assert(!errorMessageInFix,
|
566
|
+
assert(!errorMessageInFix, [
|
567
|
+
"A fatal parsing error occurred in autofix.",
|
568
|
+
`Error: ${errorMessageInFix && errorMessageInFix.message}`,
|
569
|
+
"Autofix output:",
|
570
|
+
output
|
571
|
+
].join("\n"));
|
567
572
|
} else {
|
568
573
|
output = code;
|
569
574
|
}
|
@@ -29,22 +29,6 @@ function isReachable(segment) {
|
|
29
29
|
return segment.reachable;
|
30
30
|
}
|
31
31
|
|
32
|
-
/**
|
33
|
-
* Gets a readable location.
|
34
|
-
*
|
35
|
-
* - FunctionExpression -> the function name or `function` keyword.
|
36
|
-
* - ArrowFunctionExpression -> `=>` token.
|
37
|
-
* @param {ASTNode} node A function node to get.
|
38
|
-
* @param {SourceCode} sourceCode A source code to get tokens.
|
39
|
-
* @returns {ASTNode|Token} The node or the token of a location.
|
40
|
-
*/
|
41
|
-
function getLocation(node, sourceCode) {
|
42
|
-
if (node.type === "ArrowFunctionExpression") {
|
43
|
-
return sourceCode.getTokenBefore(node.body);
|
44
|
-
}
|
45
|
-
return node.id || node;
|
46
|
-
}
|
47
|
-
|
48
32
|
/**
|
49
33
|
* Checks a given node is a MemberExpression node which has the specified name's
|
50
34
|
* property.
|
@@ -179,6 +163,7 @@ module.exports = {
|
|
179
163
|
create(context) {
|
180
164
|
|
181
165
|
const options = context.options[0] || { allowImplicit: false, checkForEach: false };
|
166
|
+
const sourceCode = context.getSourceCode();
|
182
167
|
|
183
168
|
let funcInfo = {
|
184
169
|
arrayMethodName: null,
|
@@ -217,12 +202,12 @@ module.exports = {
|
|
217
202
|
}
|
218
203
|
|
219
204
|
if (messageId) {
|
220
|
-
let name = astUtils.getFunctionNameWithKind(
|
205
|
+
let name = astUtils.getFunctionNameWithKind(node);
|
221
206
|
|
222
207
|
name = messageId === "expectedNoReturnValue" ? lodash.upperFirst(name) : name;
|
223
208
|
context.report({
|
224
209
|
node,
|
225
|
-
loc:
|
210
|
+
loc: astUtils.getFunctionHeadLoc(node, sourceCode),
|
226
211
|
messageId,
|
227
212
|
data: { name }
|
228
213
|
});
|
@@ -105,10 +105,27 @@ module.exports = {
|
|
105
105
|
], `${shouldAddSpaceForAsync ? " " : ""}${paramToken.value}`);
|
106
106
|
}
|
107
107
|
|
108
|
+
/**
|
109
|
+
* Checks whether there are comments inside the params or not.
|
110
|
+
* @returns {boolean} `true` if there are comments inside of parens, else `false`
|
111
|
+
*/
|
112
|
+
function hasCommentsInParens() {
|
113
|
+
if (astUtils.isOpeningParenToken(firstTokenOfParam)) {
|
114
|
+
const closingParenToken = sourceCode.getTokenAfter(node.params[0], astUtils.isClosingParenToken);
|
115
|
+
|
116
|
+
return closingParenToken && sourceCode.commentsExistBetween(firstTokenOfParam, closingParenToken);
|
117
|
+
}
|
118
|
+
return false;
|
119
|
+
|
120
|
+
}
|
121
|
+
|
122
|
+
if (hasCommentsInParens()) {
|
123
|
+
return;
|
124
|
+
}
|
125
|
+
|
108
126
|
// "as-needed", { "requireForBlockBody": true }: x => x
|
109
127
|
if (
|
110
128
|
requireForBlockBody &&
|
111
|
-
node.params.length === 1 &&
|
112
129
|
node.params[0].type === "Identifier" &&
|
113
130
|
!node.params[0].typeAnnotation &&
|
114
131
|
node.body.type !== "BlockStatement" &&
|
@@ -144,7 +161,6 @@ module.exports = {
|
|
144
161
|
|
145
162
|
// "as-needed": x => x
|
146
163
|
if (asNeeded &&
|
147
|
-
node.params.length === 1 &&
|
148
164
|
node.params[0].type === "Identifier" &&
|
149
165
|
!node.params[0].typeAnnotation &&
|
150
166
|
!node.returnType
|
@@ -178,7 +194,7 @@ module.exports = {
|
|
178
194
|
}
|
179
195
|
|
180
196
|
return {
|
181
|
-
ArrowFunctionExpression: parens
|
197
|
+
"ArrowFunctionExpression[params.length=1]": parens
|
182
198
|
};
|
183
199
|
}
|
184
200
|
};
|
@@ -102,9 +102,18 @@ module.exports = {
|
|
102
102
|
|
103
103
|
// Check.
|
104
104
|
if (!isValid(openBrace, firstToken)) {
|
105
|
+
let loc = openBrace.loc;
|
106
|
+
|
107
|
+
if (messageId === "extra") {
|
108
|
+
loc = {
|
109
|
+
start: openBrace.loc.end,
|
110
|
+
end: firstToken.loc.start
|
111
|
+
};
|
112
|
+
}
|
113
|
+
|
105
114
|
context.report({
|
106
115
|
node,
|
107
|
-
loc
|
116
|
+
loc,
|
108
117
|
messageId,
|
109
118
|
data: {
|
110
119
|
location: "after",
|
@@ -120,9 +129,17 @@ module.exports = {
|
|
120
129
|
});
|
121
130
|
}
|
122
131
|
if (!isValid(lastToken, closeBrace)) {
|
132
|
+
let loc = closeBrace.loc;
|
133
|
+
|
134
|
+
if (messageId === "extra") {
|
135
|
+
loc = {
|
136
|
+
start: lastToken.loc.end,
|
137
|
+
end: closeBrace.loc.start
|
138
|
+
};
|
139
|
+
}
|
123
140
|
context.report({
|
124
141
|
node,
|
125
|
-
loc
|
142
|
+
loc,
|
126
143
|
messageId,
|
127
144
|
data: {
|
128
145
|
location: "before",
|
package/lib/rules/comma-style.js
CHANGED
@@ -146,10 +146,7 @@ module.exports = {
|
|
146
146
|
// lone comma
|
147
147
|
context.report({
|
148
148
|
node: reportItem,
|
149
|
-
loc:
|
150
|
-
line: commaToken.loc.end.line,
|
151
|
-
column: commaToken.loc.start.column
|
152
|
-
},
|
149
|
+
loc: commaToken.loc,
|
153
150
|
messageId: "unexpectedLineBeforeAndAfterComma",
|
154
151
|
fix: getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken)
|
155
152
|
});
|
@@ -158,6 +155,7 @@ module.exports = {
|
|
158
155
|
|
159
156
|
context.report({
|
160
157
|
node: reportItem,
|
158
|
+
loc: commaToken.loc,
|
161
159
|
messageId: "expectedCommaFirst",
|
162
160
|
fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
|
163
161
|
});
|
@@ -166,10 +164,7 @@ module.exports = {
|
|
166
164
|
|
167
165
|
context.report({
|
168
166
|
node: reportItem,
|
169
|
-
loc:
|
170
|
-
line: commaToken.loc.end.line,
|
171
|
-
column: commaToken.loc.end.column
|
172
|
-
},
|
167
|
+
loc: commaToken.loc,
|
173
168
|
messageId: "expectedCommaLast",
|
174
169
|
fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
|
175
170
|
});
|
@@ -63,7 +63,8 @@ module.exports = {
|
|
63
63
|
},
|
64
64
|
|
65
65
|
messages: {
|
66
|
-
|
66
|
+
unexpectedWhitespace: "Unexpected whitespace between function name and paren.",
|
67
|
+
unexpectedNewline: "Unexpected newline between function name and paren.",
|
67
68
|
missing: "Missing space between function name and paren."
|
68
69
|
}
|
69
70
|
},
|
@@ -115,8 +116,14 @@ module.exports = {
|
|
115
116
|
if (never && hasWhitespace) {
|
116
117
|
context.report({
|
117
118
|
node,
|
118
|
-
loc:
|
119
|
-
|
119
|
+
loc: {
|
120
|
+
start: leftToken.loc.end,
|
121
|
+
end: {
|
122
|
+
line: rightToken.loc.start.line,
|
123
|
+
column: rightToken.loc.start.column - 1
|
124
|
+
}
|
125
|
+
},
|
126
|
+
messageId: "unexpectedWhitespace",
|
120
127
|
fix(fixer) {
|
121
128
|
|
122
129
|
/*
|
@@ -133,7 +140,13 @@ module.exports = {
|
|
133
140
|
} else if (!never && !hasWhitespace) {
|
134
141
|
context.report({
|
135
142
|
node,
|
136
|
-
loc:
|
143
|
+
loc: {
|
144
|
+
start: {
|
145
|
+
line: leftToken.loc.end.line,
|
146
|
+
column: leftToken.loc.end.column - 1
|
147
|
+
},
|
148
|
+
end: rightToken.loc.start
|
149
|
+
},
|
137
150
|
messageId: "missing",
|
138
151
|
fix(fixer) {
|
139
152
|
return fixer.insertTextBefore(rightToken, " ");
|
@@ -142,8 +155,11 @@ module.exports = {
|
|
142
155
|
} else if (!never && !allowNewlines && hasNewline) {
|
143
156
|
context.report({
|
144
157
|
node,
|
145
|
-
loc:
|
146
|
-
|
158
|
+
loc: {
|
159
|
+
start: leftToken.loc.end,
|
160
|
+
end: rightToken.loc.start
|
161
|
+
},
|
162
|
+
messageId: "unexpectedNewline",
|
147
163
|
fix(fixer) {
|
148
164
|
return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " ");
|
149
165
|
}
|
@@ -25,17 +25,6 @@ function isReachable(segment) {
|
|
25
25
|
return segment.reachable;
|
26
26
|
}
|
27
27
|
|
28
|
-
/**
|
29
|
-
* Gets a readable location.
|
30
|
-
*
|
31
|
-
* - FunctionExpression -> the function name or `function` keyword.
|
32
|
-
* @param {ASTNode} node A function node to get.
|
33
|
-
* @returns {ASTNode|Token} The node or the token of a location.
|
34
|
-
*/
|
35
|
-
function getId(node) {
|
36
|
-
return node.id || node;
|
37
|
-
}
|
38
|
-
|
39
28
|
//------------------------------------------------------------------------------
|
40
29
|
// Rule Definition
|
41
30
|
//------------------------------------------------------------------------------
|
@@ -75,6 +64,7 @@ module.exports = {
|
|
75
64
|
create(context) {
|
76
65
|
|
77
66
|
const options = context.options[0] || { allowImplicit: false };
|
67
|
+
const sourceCode = context.getSourceCode();
|
78
68
|
|
79
69
|
let funcInfo = {
|
80
70
|
upper: null,
|
@@ -99,7 +89,7 @@ module.exports = {
|
|
99
89
|
) {
|
100
90
|
context.report({
|
101
91
|
node,
|
102
|
-
loc:
|
92
|
+
loc: astUtils.getFunctionHeadLoc(node, sourceCode),
|
103
93
|
messageId: funcInfo.hasReturn ? "expectedAlways" : "expected",
|
104
94
|
data: {
|
105
95
|
name: astUtils.getFunctionNameWithKind(funcInfo.node)
|
package/lib/rules/index.js
CHANGED
@@ -148,6 +148,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
|
|
148
148
|
"no-lone-blocks": () => require("./no-lone-blocks"),
|
149
149
|
"no-lonely-if": () => require("./no-lonely-if"),
|
150
150
|
"no-loop-func": () => require("./no-loop-func"),
|
151
|
+
"no-loss-of-precision": () => require("./no-loss-of-precision"),
|
151
152
|
"no-magic-numbers": () => require("./no-magic-numbers"),
|
152
153
|
"no-misleading-character-class": () => require("./no-misleading-character-class"),
|
153
154
|
"no-mixed-operators": () => require("./no-mixed-operators"),
|
package/lib/rules/key-spacing.js
CHANGED
@@ -45,7 +45,7 @@ function isSingleLine(node) {
|
|
45
45
|
/**
|
46
46
|
* Checks whether the properties on a single line.
|
47
47
|
* @param {ASTNode[]} properties List of Property AST nodes.
|
48
|
-
* @returns {boolean} True if all
|
48
|
+
* @returns {boolean} True if all properties is on a single line.
|
49
49
|
*/
|
50
50
|
function isSingleLineProperties(properties) {
|
51
51
|
const [firstProp] = properties,
|
@@ -152,7 +152,7 @@ module.exports = {
|
|
152
152
|
sourceCode.isSpaceBetweenTokens(prevToken, token)
|
153
153
|
) {
|
154
154
|
context.report({
|
155
|
-
loc: token.loc.start,
|
155
|
+
loc: { start: prevToken.loc.end, end: token.loc.start },
|
156
156
|
messageId: "unexpectedBefore",
|
157
157
|
data: token,
|
158
158
|
fix(fixer) {
|
@@ -203,8 +203,9 @@ module.exports = {
|
|
203
203
|
astUtils.isTokenOnSameLine(token, nextToken) &&
|
204
204
|
sourceCode.isSpaceBetweenTokens(token, nextToken)
|
205
205
|
) {
|
206
|
+
|
206
207
|
context.report({
|
207
|
-
loc: token.loc.start,
|
208
|
+
loc: { start: token.loc.end, end: nextToken.loc.start },
|
208
209
|
messageId: "unexpectedAfter",
|
209
210
|
data: token,
|
210
211
|
fix(fixer) {
|
@@ -442,6 +443,12 @@ module.exports = {
|
|
442
443
|
checkSpacingAround(sourceCode.getTokenAfter(firstToken));
|
443
444
|
}
|
444
445
|
|
446
|
+
if (node.type === "ExportAllDeclaration" && node.exported) {
|
447
|
+
const asToken = sourceCode.getTokenBefore(node.exported);
|
448
|
+
|
449
|
+
checkSpacingBefore(asToken, PREV_TOKEN_M);
|
450
|
+
}
|
451
|
+
|
445
452
|
if (node.source) {
|
446
453
|
const fromToken = sourceCode.getTokenBefore(node.source);
|
447
454
|
|
@@ -86,8 +86,14 @@ module.exports = {
|
|
86
86
|
context.report({
|
87
87
|
node,
|
88
88
|
loc: {
|
89
|
-
|
90
|
-
|
89
|
+
start: {
|
90
|
+
line: i,
|
91
|
+
column: sourceCode.lines[i - 1].length
|
92
|
+
},
|
93
|
+
end: {
|
94
|
+
line: i + 1,
|
95
|
+
column: 0
|
96
|
+
}
|
91
97
|
},
|
92
98
|
messageId: expectedLF ? "expectedLF" : "expectedCRLF",
|
93
99
|
fix: createFix(range, expectedLFChars)
|
@@ -134,7 +134,7 @@ module.exports = {
|
|
134
134
|
* @returns {boolean} True if it's an IIFE
|
135
135
|
*/
|
136
136
|
function isIIFE(node) {
|
137
|
-
return node.type === "FunctionExpression" && node.parent && node.parent.type === "CallExpression" && node.parent.callee === node;
|
137
|
+
return (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") && node.parent && node.parent.type === "CallExpression" && node.parent.callee === node;
|
138
138
|
}
|
139
139
|
|
140
140
|
/**
|