eslint 8.57.0 → 9.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/README.md +31 -28
- package/bin/eslint.js +4 -3
- package/conf/ecma-version.js +16 -0
- package/conf/globals.js +1 -0
- package/conf/rule-type-list.json +3 -1
- package/lib/api.js +7 -11
- package/lib/cli-engine/cli-engine.js +14 -3
- package/lib/cli-engine/formatters/formatters-meta.json +1 -29
- package/lib/cli-engine/lint-result-cache.js +2 -2
- package/lib/cli.js +115 -36
- package/lib/config/default-config.js +3 -0
- package/lib/config/flat-config-array.js +110 -24
- package/lib/config/flat-config-helpers.js +41 -20
- package/lib/config/flat-config-schema.js +1 -7
- package/lib/config/rule-validator.js +42 -6
- package/lib/eslint/eslint-helpers.js +116 -58
- package/lib/eslint/eslint.js +892 -377
- package/lib/eslint/index.js +2 -2
- package/lib/eslint/legacy-eslint.js +728 -0
- package/lib/linter/apply-disable-directives.js +59 -31
- package/lib/linter/code-path-analysis/code-path-analyzer.js +0 -1
- package/lib/linter/code-path-analysis/code-path.js +32 -30
- package/lib/linter/code-path-analysis/fork-context.js +1 -1
- package/lib/linter/config-comment-parser.js +8 -11
- package/lib/linter/index.js +1 -3
- package/lib/linter/interpolate.js +24 -2
- package/lib/linter/linter.js +428 -207
- package/lib/linter/report-translator.js +3 -3
- package/lib/linter/rules.js +6 -15
- package/lib/linter/source-code-fixer.js +1 -1
- package/lib/linter/timing.js +16 -8
- package/lib/options.js +35 -3
- package/lib/rule-tester/index.js +3 -1
- package/lib/rule-tester/rule-tester.js +424 -347
- package/lib/rules/array-bracket-newline.js +1 -1
- package/lib/rules/array-bracket-spacing.js +1 -1
- package/lib/rules/block-scoped-var.js +1 -1
- package/lib/rules/callback-return.js +2 -2
- package/lib/rules/camelcase.js +3 -5
- package/lib/rules/capitalized-comments.js +10 -7
- package/lib/rules/comma-dangle.js +1 -1
- package/lib/rules/comma-style.js +2 -2
- package/lib/rules/complexity.js +14 -1
- package/lib/rules/constructor-super.js +99 -100
- package/lib/rules/default-case.js +1 -1
- package/lib/rules/eol-last.js +2 -2
- package/lib/rules/function-paren-newline.js +2 -2
- package/lib/rules/indent-legacy.js +5 -5
- package/lib/rules/indent.js +5 -5
- package/lib/rules/index.js +1 -2
- package/lib/rules/key-spacing.js +2 -2
- package/lib/rules/line-comment-position.js +1 -1
- package/lib/rules/lines-around-directive.js +2 -2
- package/lib/rules/max-depth.js +1 -1
- package/lib/rules/max-len.js +3 -3
- package/lib/rules/max-lines.js +3 -3
- package/lib/rules/max-nested-callbacks.js +1 -1
- package/lib/rules/max-params.js +1 -1
- package/lib/rules/max-statements.js +1 -1
- package/lib/rules/multiline-comment-style.js +7 -7
- package/lib/rules/new-cap.js +1 -1
- package/lib/rules/newline-after-var.js +1 -1
- package/lib/rules/newline-before-return.js +1 -1
- package/lib/rules/no-case-declarations.js +13 -1
- package/lib/rules/no-constant-binary-expression.js +7 -8
- package/lib/rules/no-constant-condition.js +18 -7
- package/lib/rules/no-constructor-return.js +2 -2
- package/lib/rules/no-dupe-class-members.js +2 -2
- package/lib/rules/no-else-return.js +1 -1
- package/lib/rules/no-empty-function.js +2 -2
- package/lib/rules/no-empty-static-block.js +1 -1
- package/lib/rules/no-extend-native.js +1 -2
- package/lib/rules/no-extra-semi.js +1 -1
- package/lib/rules/no-fallthrough.js +41 -16
- package/lib/rules/no-implicit-coercion.js +66 -24
- package/lib/rules/no-inner-declarations.js +23 -2
- package/lib/rules/no-invalid-regexp.js +1 -1
- package/lib/rules/no-invalid-this.js +1 -1
- package/lib/rules/no-lone-blocks.js +3 -3
- package/lib/rules/no-loss-of-precision.js +1 -1
- package/lib/rules/no-misleading-character-class.js +225 -69
- package/lib/rules/no-mixed-spaces-and-tabs.js +1 -1
- package/lib/rules/no-multiple-empty-lines.js +1 -1
- package/lib/rules/no-new-native-nonconstructor.js +1 -1
- package/lib/rules/no-new-symbol.js +8 -1
- package/lib/rules/no-restricted-globals.js +1 -1
- package/lib/rules/no-restricted-imports.js +186 -40
- package/lib/rules/no-restricted-modules.js +2 -2
- package/lib/rules/no-return-await.js +1 -1
- package/lib/rules/no-sequences.js +1 -0
- package/lib/rules/no-this-before-super.js +45 -13
- package/lib/rules/no-trailing-spaces.js +2 -3
- package/lib/rules/no-unneeded-ternary.js +1 -1
- package/lib/rules/no-unsafe-optional-chaining.js +1 -1
- package/lib/rules/no-unused-private-class-members.js +1 -1
- package/lib/rules/no-unused-vars.js +197 -36
- package/lib/rules/no-useless-assignment.js +566 -0
- package/lib/rules/no-useless-backreference.js +1 -1
- package/lib/rules/no-useless-computed-key.js +2 -2
- package/lib/rules/no-useless-return.js +7 -2
- package/lib/rules/object-curly-spacing.js +3 -3
- package/lib/rules/object-property-newline.js +1 -1
- package/lib/rules/one-var.js +5 -5
- package/lib/rules/padded-blocks.js +7 -7
- package/lib/rules/prefer-arrow-callback.js +3 -3
- package/lib/rules/prefer-reflect.js +1 -1
- package/lib/rules/prefer-regex-literals.js +1 -1
- package/lib/rules/prefer-template.js +1 -1
- package/lib/rules/radix.js +2 -2
- package/lib/rules/semi-style.js +1 -1
- package/lib/rules/sort-imports.js +1 -1
- package/lib/rules/sort-keys.js +1 -1
- package/lib/rules/sort-vars.js +1 -1
- package/lib/rules/space-unary-ops.js +1 -1
- package/lib/rules/strict.js +1 -1
- package/lib/rules/use-isnan.js +101 -7
- package/lib/rules/utils/ast-utils.js +16 -7
- package/lib/rules/utils/char-source.js +240 -0
- package/lib/rules/utils/lazy-loading-rule-map.js +1 -1
- package/lib/rules/utils/unicode/index.js +9 -4
- package/lib/rules/yield-star-spacing.js +1 -1
- package/lib/shared/runtime-info.js +1 -0
- package/lib/shared/serialization.js +55 -0
- package/lib/shared/stats.js +30 -0
- package/lib/shared/string-utils.js +9 -11
- package/lib/shared/types.js +35 -1
- package/lib/source-code/index.js +3 -1
- package/lib/source-code/source-code.js +299 -85
- package/lib/source-code/token-store/backward-token-cursor.js +3 -3
- package/lib/source-code/token-store/cursors.js +4 -2
- package/lib/source-code/token-store/forward-token-comment-cursor.js +3 -3
- package/lib/source-code/token-store/forward-token-cursor.js +3 -3
- package/lib/source-code/token-store/index.js +2 -2
- package/lib/unsupported-api.js +3 -5
- package/messages/no-config-found.js +1 -1
- package/messages/plugin-conflict.js +1 -1
- package/messages/plugin-invalid.js +1 -1
- package/messages/plugin-missing.js +1 -1
- package/package.json +32 -29
- package/conf/config-schema.js +0 -93
- package/lib/cli-engine/formatters/checkstyle.js +0 -60
- package/lib/cli-engine/formatters/compact.js +0 -60
- package/lib/cli-engine/formatters/jslint-xml.js +0 -41
- package/lib/cli-engine/formatters/junit.js +0 -82
- package/lib/cli-engine/formatters/tap.js +0 -95
- package/lib/cli-engine/formatters/unix.js +0 -58
- package/lib/cli-engine/formatters/visualstudio.js +0 -63
- package/lib/cli-engine/xml-escape.js +0 -34
- package/lib/eslint/flat-eslint.js +0 -1155
- package/lib/rule-tester/flat-rule-tester.js +0 -1131
- package/lib/rules/require-jsdoc.js +0 -122
- package/lib/rules/utils/patterns/letters.js +0 -36
- package/lib/rules/valid-jsdoc.js +0 -516
- package/lib/shared/config-validator.js +0 -347
- package/lib/shared/deprecation-warnings.js +0 -58
- package/lib/shared/relative-module-resolver.js +0 -50
@@ -18,8 +18,12 @@ const
|
|
18
18
|
directivesPattern
|
19
19
|
} = require("../shared/directives"),
|
20
20
|
|
21
|
-
/* eslint-disable
|
21
|
+
/* eslint-disable n/no-restricted-require -- Should eventually be moved into SourceCode. */
|
22
|
+
CodePathAnalyzer = require("../linter/code-path-analysis/code-path-analyzer"),
|
23
|
+
createEmitter = require("../linter/safe-emitter"),
|
22
24
|
ConfigCommentParser = require("../linter/config-comment-parser"),
|
25
|
+
/* eslint-enable n/no-restricted-require -- Should eventually be moved into SourceCode. */
|
26
|
+
|
23
27
|
eslintScope = require("eslint-scope");
|
24
28
|
|
25
29
|
//------------------------------------------------------------------------------
|
@@ -34,6 +38,16 @@ const
|
|
34
38
|
|
35
39
|
const commentParser = new ConfigCommentParser();
|
36
40
|
|
41
|
+
const CODE_PATH_EVENTS = [
|
42
|
+
"onCodePathStart",
|
43
|
+
"onCodePathEnd",
|
44
|
+
"onCodePathSegmentStart",
|
45
|
+
"onCodePathSegmentEnd",
|
46
|
+
"onCodePathSegmentLoop",
|
47
|
+
"onUnreachableCodePathSegmentStart",
|
48
|
+
"onUnreachableCodePathSegmentEnd"
|
49
|
+
];
|
50
|
+
|
37
51
|
/**
|
38
52
|
* Validates that the given AST has the required information.
|
39
53
|
* @param {ASTNode} ast The Program node of the AST to check.
|
@@ -300,6 +314,115 @@ function markExportedVariables(globalScope, variables) {
|
|
300
314
|
|
301
315
|
}
|
302
316
|
|
317
|
+
const STEP_KIND = {
|
318
|
+
visit: 1,
|
319
|
+
call: 2
|
320
|
+
};
|
321
|
+
|
322
|
+
/**
|
323
|
+
* A class to represent a step in the traversal process.
|
324
|
+
*/
|
325
|
+
class TraversalStep {
|
326
|
+
|
327
|
+
/**
|
328
|
+
* The type of the step.
|
329
|
+
* @type {string}
|
330
|
+
*/
|
331
|
+
type;
|
332
|
+
|
333
|
+
/**
|
334
|
+
* The kind of the step. Represents the same data as the `type` property
|
335
|
+
* but it's a number for performance.
|
336
|
+
* @type {number}
|
337
|
+
*/
|
338
|
+
kind;
|
339
|
+
|
340
|
+
/**
|
341
|
+
* The target of the step.
|
342
|
+
* @type {ASTNode|string}
|
343
|
+
*/
|
344
|
+
target;
|
345
|
+
|
346
|
+
/**
|
347
|
+
* The phase of the step.
|
348
|
+
* @type {number|undefined}
|
349
|
+
*/
|
350
|
+
phase;
|
351
|
+
|
352
|
+
/**
|
353
|
+
* The arguments of the step.
|
354
|
+
* @type {Array<any>}
|
355
|
+
*/
|
356
|
+
args;
|
357
|
+
|
358
|
+
/**
|
359
|
+
* Creates a new instance.
|
360
|
+
* @param {Object} options The options for the step.
|
361
|
+
* @param {string} options.type The type of the step.
|
362
|
+
* @param {ASTNode|string} options.target The target of the step.
|
363
|
+
* @param {number|undefined} [options.phase] The phase of the step.
|
364
|
+
* @param {Array<any>} options.args The arguments of the step.
|
365
|
+
* @returns {void}
|
366
|
+
*/
|
367
|
+
constructor({ type, target, phase, args }) {
|
368
|
+
this.type = type;
|
369
|
+
this.kind = STEP_KIND[type];
|
370
|
+
this.target = target;
|
371
|
+
this.phase = phase;
|
372
|
+
this.args = args;
|
373
|
+
}
|
374
|
+
}
|
375
|
+
|
376
|
+
/**
|
377
|
+
* A class to represent a directive comment.
|
378
|
+
*/
|
379
|
+
class Directive {
|
380
|
+
|
381
|
+
/**
|
382
|
+
* The type of directive.
|
383
|
+
* @type {"disable"|"enable"|"disable-next-line"|"disable-line"}
|
384
|
+
* @readonly
|
385
|
+
*/
|
386
|
+
type;
|
387
|
+
|
388
|
+
/**
|
389
|
+
* The node representing the directive.
|
390
|
+
* @type {ASTNode|Comment}
|
391
|
+
* @readonly
|
392
|
+
*/
|
393
|
+
node;
|
394
|
+
|
395
|
+
/**
|
396
|
+
* Everything after the "eslint-disable" portion of the directive,
|
397
|
+
* but before the "--" that indicates the justification.
|
398
|
+
* @type {string}
|
399
|
+
* @readonly
|
400
|
+
*/
|
401
|
+
value;
|
402
|
+
|
403
|
+
/**
|
404
|
+
* The justification for the directive.
|
405
|
+
* @type {string}
|
406
|
+
* @readonly
|
407
|
+
*/
|
408
|
+
justification;
|
409
|
+
|
410
|
+
/**
|
411
|
+
* Creates a new instance.
|
412
|
+
* @param {Object} options The options for the directive.
|
413
|
+
* @param {"disable"|"enable"|"disable-next-line"|"disable-line"} options.type The type of directive.
|
414
|
+
* @param {ASTNode|Comment} options.node The node representing the directive.
|
415
|
+
* @param {string} options.value The value of the directive.
|
416
|
+
* @param {string} options.justification The justification for the directive.
|
417
|
+
*/
|
418
|
+
constructor({ type, node, value, justification }) {
|
419
|
+
this.type = type;
|
420
|
+
this.node = node;
|
421
|
+
this.value = value;
|
422
|
+
this.justification = justification;
|
423
|
+
}
|
424
|
+
}
|
425
|
+
|
303
426
|
//------------------------------------------------------------------------------
|
304
427
|
// Public Interface
|
305
428
|
//------------------------------------------------------------------------------
|
@@ -311,6 +434,12 @@ const caches = Symbol("caches");
|
|
311
434
|
*/
|
312
435
|
class SourceCode extends TokenStore {
|
313
436
|
|
437
|
+
/**
|
438
|
+
* The cache of steps that were taken while traversing the source code.
|
439
|
+
* @type {Array<TraversalStep>}
|
440
|
+
*/
|
441
|
+
#steps;
|
442
|
+
|
314
443
|
/**
|
315
444
|
* @param {string|Object} textOrConfig The source code text or config object.
|
316
445
|
* @param {string} textOrConfig.text The source code text.
|
@@ -415,13 +544,10 @@ class SourceCode extends TokenStore {
|
|
415
544
|
* and uses match.index to get the correct line start indices.
|
416
545
|
*/
|
417
546
|
while ((match = lineEndingPattern.exec(this.text))) {
|
418
|
-
this.lines.push(this.text.slice(this.lineStartIndices
|
547
|
+
this.lines.push(this.text.slice(this.lineStartIndices.at(-1), match.index));
|
419
548
|
this.lineStartIndices.push(match.index + match[0].length);
|
420
549
|
}
|
421
|
-
this.lines.push(this.text.slice(this.lineStartIndices
|
422
|
-
|
423
|
-
// Cache for comments found using getComments().
|
424
|
-
this._commentCache = new WeakMap();
|
550
|
+
this.lines.push(this.text.slice(this.lineStartIndices.at(-1)));
|
425
551
|
|
426
552
|
// don't allow further modification of this object
|
427
553
|
Object.freeze(this);
|
@@ -472,81 +598,6 @@ class SourceCode extends TokenStore {
|
|
472
598
|
return this.ast.comments;
|
473
599
|
}
|
474
600
|
|
475
|
-
/**
|
476
|
-
* Gets all comments for the given node.
|
477
|
-
* @param {ASTNode} node The AST node to get the comments for.
|
478
|
-
* @returns {Object} An object containing a leading and trailing array
|
479
|
-
* of comments indexed by their position.
|
480
|
-
* @public
|
481
|
-
* @deprecated replaced by getCommentsBefore(), getCommentsAfter(), and getCommentsInside().
|
482
|
-
*/
|
483
|
-
getComments(node) {
|
484
|
-
if (this._commentCache.has(node)) {
|
485
|
-
return this._commentCache.get(node);
|
486
|
-
}
|
487
|
-
|
488
|
-
const comments = {
|
489
|
-
leading: [],
|
490
|
-
trailing: []
|
491
|
-
};
|
492
|
-
|
493
|
-
/*
|
494
|
-
* Return all comments as leading comments of the Program node when
|
495
|
-
* there is no executable code.
|
496
|
-
*/
|
497
|
-
if (node.type === "Program") {
|
498
|
-
if (node.body.length === 0) {
|
499
|
-
comments.leading = node.comments;
|
500
|
-
}
|
501
|
-
} else {
|
502
|
-
|
503
|
-
/*
|
504
|
-
* Return comments as trailing comments of nodes that only contain
|
505
|
-
* comments (to mimic the comment attachment behavior present in Espree).
|
506
|
-
*/
|
507
|
-
if ((node.type === "BlockStatement" || node.type === "ClassBody") && node.body.length === 0 ||
|
508
|
-
node.type === "ObjectExpression" && node.properties.length === 0 ||
|
509
|
-
node.type === "ArrayExpression" && node.elements.length === 0 ||
|
510
|
-
node.type === "SwitchStatement" && node.cases.length === 0
|
511
|
-
) {
|
512
|
-
comments.trailing = this.getTokens(node, {
|
513
|
-
includeComments: true,
|
514
|
-
filter: isCommentToken
|
515
|
-
});
|
516
|
-
}
|
517
|
-
|
518
|
-
/*
|
519
|
-
* Iterate over tokens before and after node and collect comment tokens.
|
520
|
-
* Do not include comments that exist outside of the parent node
|
521
|
-
* to avoid duplication.
|
522
|
-
*/
|
523
|
-
let currentToken = this.getTokenBefore(node, { includeComments: true });
|
524
|
-
|
525
|
-
while (currentToken && isCommentToken(currentToken)) {
|
526
|
-
if (node.parent && node.parent.type !== "Program" && (currentToken.start < node.parent.start)) {
|
527
|
-
break;
|
528
|
-
}
|
529
|
-
comments.leading.push(currentToken);
|
530
|
-
currentToken = this.getTokenBefore(currentToken, { includeComments: true });
|
531
|
-
}
|
532
|
-
|
533
|
-
comments.leading.reverse();
|
534
|
-
|
535
|
-
currentToken = this.getTokenAfter(node, { includeComments: true });
|
536
|
-
|
537
|
-
while (currentToken && isCommentToken(currentToken)) {
|
538
|
-
if (node.parent && node.parent.type !== "Program" && (currentToken.end > node.parent.end)) {
|
539
|
-
break;
|
540
|
-
}
|
541
|
-
comments.trailing.push(currentToken);
|
542
|
-
currentToken = this.getTokenAfter(currentToken, { includeComments: true });
|
543
|
-
}
|
544
|
-
}
|
545
|
-
|
546
|
-
this._commentCache.set(node, comments);
|
547
|
-
return comments;
|
548
|
-
}
|
549
|
-
|
550
601
|
/**
|
551
602
|
* Retrieves the JSDoc comment for a given node.
|
552
603
|
* @param {ASTNode} node The AST node to get the comment for.
|
@@ -701,14 +752,14 @@ class SourceCode extends TokenStore {
|
|
701
752
|
* See getIndexFromLoc for the motivation for this special case.
|
702
753
|
*/
|
703
754
|
if (index === this.text.length) {
|
704
|
-
return { line: this.lines.length, column: this.lines
|
755
|
+
return { line: this.lines.length, column: this.lines.at(-1).length };
|
705
756
|
}
|
706
757
|
|
707
758
|
/*
|
708
759
|
* To figure out which line index is on, determine the last place at which index could
|
709
760
|
* be inserted into lineStartIndices to keep the list sorted.
|
710
761
|
*/
|
711
|
-
const lineNumber = index >= this.lineStartIndices
|
762
|
+
const lineNumber = index >= this.lineStartIndices.at(-1)
|
712
763
|
? this.lineStartIndices.length
|
713
764
|
: this.lineStartIndices.findIndex(el => index < el);
|
714
765
|
|
@@ -920,6 +971,84 @@ class SourceCode extends TokenStore {
|
|
920
971
|
return configNodes;
|
921
972
|
}
|
922
973
|
|
974
|
+
/**
|
975
|
+
* Returns an all directive nodes that enable or disable rules along with any problems
|
976
|
+
* encountered while parsing the directives.
|
977
|
+
* @returns {{problems:Array<Problem>,directives:Array<Directive>}} Information
|
978
|
+
* that ESLint needs to further process the directives.
|
979
|
+
*/
|
980
|
+
getDisableDirectives() {
|
981
|
+
|
982
|
+
// check the cache first
|
983
|
+
const cachedDirectives = this[caches].get("disableDirectives");
|
984
|
+
|
985
|
+
if (cachedDirectives) {
|
986
|
+
return cachedDirectives;
|
987
|
+
}
|
988
|
+
|
989
|
+
const problems = [];
|
990
|
+
const directives = [];
|
991
|
+
|
992
|
+
this.getInlineConfigNodes().forEach(comment => {
|
993
|
+
const { directivePart, justificationPart } = commentParser.extractDirectiveComment(comment.value);
|
994
|
+
|
995
|
+
// Step 1: Extract the directive text
|
996
|
+
const match = directivesPattern.exec(directivePart);
|
997
|
+
|
998
|
+
if (!match) {
|
999
|
+
return;
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
const directiveText = match[1];
|
1003
|
+
|
1004
|
+
// Step 2: Extract the directive value
|
1005
|
+
const lineCommentSupported = /^eslint-disable-(next-)?line$/u.test(directiveText);
|
1006
|
+
|
1007
|
+
if (comment.type === "Line" && !lineCommentSupported) {
|
1008
|
+
return;
|
1009
|
+
}
|
1010
|
+
|
1011
|
+
// Step 3: Validate the directive does not span multiple lines
|
1012
|
+
if (directiveText === "eslint-disable-line" && comment.loc.start.line !== comment.loc.end.line) {
|
1013
|
+
const message = `${directiveText} comment should not span multiple lines.`;
|
1014
|
+
|
1015
|
+
problems.push({
|
1016
|
+
ruleId: null,
|
1017
|
+
message,
|
1018
|
+
loc: comment.loc
|
1019
|
+
});
|
1020
|
+
return;
|
1021
|
+
}
|
1022
|
+
|
1023
|
+
// Step 4: Extract the directive value and create the Directive object
|
1024
|
+
const directiveValue = directivePart.slice(match.index + directiveText.length);
|
1025
|
+
|
1026
|
+
switch (directiveText) {
|
1027
|
+
case "eslint-disable":
|
1028
|
+
case "eslint-enable":
|
1029
|
+
case "eslint-disable-next-line":
|
1030
|
+
case "eslint-disable-line": {
|
1031
|
+
const directiveType = directiveText.slice("eslint-".length);
|
1032
|
+
|
1033
|
+
directives.push(new Directive({
|
1034
|
+
type: directiveType,
|
1035
|
+
node: comment,
|
1036
|
+
value: directiveValue,
|
1037
|
+
justification: justificationPart
|
1038
|
+
}));
|
1039
|
+
}
|
1040
|
+
|
1041
|
+
// no default
|
1042
|
+
}
|
1043
|
+
});
|
1044
|
+
|
1045
|
+
const result = { problems, directives };
|
1046
|
+
|
1047
|
+
this[caches].set("disableDirectives", result);
|
1048
|
+
|
1049
|
+
return result;
|
1050
|
+
}
|
1051
|
+
|
923
1052
|
/**
|
924
1053
|
* Applies language options sent in from the core.
|
925
1054
|
* @param {Object} languageOptions The language options for this run.
|
@@ -934,7 +1063,7 @@ class SourceCode extends TokenStore {
|
|
934
1063
|
* https://github.com/eslint/eslint/issues/16302
|
935
1064
|
*/
|
936
1065
|
const configGlobals = Object.assign(
|
937
|
-
|
1066
|
+
Object.create(null), // https://github.com/eslint/eslint/issues/18363
|
938
1067
|
getGlobalsForEcmaVersion(languageOptions.ecmaVersion),
|
939
1068
|
languageOptions.sourceType === "commonjs" ? globals.commonjs : void 0,
|
940
1069
|
languageOptions.globals
|
@@ -963,7 +1092,7 @@ class SourceCode extends TokenStore {
|
|
963
1092
|
|
964
1093
|
switch (directiveText) {
|
965
1094
|
case "exported":
|
966
|
-
Object.assign(exportedVariables, commentParser.
|
1095
|
+
Object.assign(exportedVariables, commentParser.parseListConfig(directiveValue, comment));
|
967
1096
|
break;
|
968
1097
|
|
969
1098
|
case "globals":
|
@@ -1050,6 +1179,91 @@ class SourceCode extends TokenStore {
|
|
1050
1179
|
|
1051
1180
|
}
|
1052
1181
|
|
1182
|
+
/**
|
1183
|
+
* Traverse the source code and return the steps that were taken.
|
1184
|
+
* @returns {Array<TraversalStep>} The steps that were taken while traversing the source code.
|
1185
|
+
*/
|
1186
|
+
traverse() {
|
1187
|
+
|
1188
|
+
// Because the AST doesn't mutate, we can cache the steps
|
1189
|
+
if (this.#steps) {
|
1190
|
+
return this.#steps;
|
1191
|
+
}
|
1192
|
+
|
1193
|
+
const steps = this.#steps = [];
|
1194
|
+
|
1195
|
+
/*
|
1196
|
+
* This logic works for any AST, not just ESTree. Because ESLint has allowed
|
1197
|
+
* custom parsers to return any AST, we need to ensure that the traversal
|
1198
|
+
* logic works for any AST.
|
1199
|
+
*/
|
1200
|
+
const emitter = createEmitter();
|
1201
|
+
let analyzer = {
|
1202
|
+
enterNode(node) {
|
1203
|
+
steps.push(new TraversalStep({
|
1204
|
+
type: "visit",
|
1205
|
+
target: node,
|
1206
|
+
phase: 1,
|
1207
|
+
args: [node, node.parent]
|
1208
|
+
}));
|
1209
|
+
},
|
1210
|
+
leaveNode(node) {
|
1211
|
+
steps.push(new TraversalStep({
|
1212
|
+
type: "visit",
|
1213
|
+
target: node,
|
1214
|
+
phase: 2,
|
1215
|
+
args: [node, node.parent]
|
1216
|
+
}));
|
1217
|
+
},
|
1218
|
+
emitter
|
1219
|
+
};
|
1220
|
+
|
1221
|
+
/*
|
1222
|
+
* We do code path analysis for ESTree only. Code path analysis is not
|
1223
|
+
* necessary for other ASTs, and it's also not possible to do for other
|
1224
|
+
* ASTs because the necessary information is not available.
|
1225
|
+
*
|
1226
|
+
* Generally speaking, we can tell that the AST is an ESTree if it has a
|
1227
|
+
* Program node at the top level. This is not a perfect heuristic, but it
|
1228
|
+
* is good enough for now.
|
1229
|
+
*/
|
1230
|
+
const isESTree = this.ast.type === "Program";
|
1231
|
+
|
1232
|
+
if (isESTree) {
|
1233
|
+
analyzer = new CodePathAnalyzer(analyzer);
|
1234
|
+
|
1235
|
+
CODE_PATH_EVENTS.forEach(eventName => {
|
1236
|
+
emitter.on(eventName, (...args) => {
|
1237
|
+
steps.push(new TraversalStep({
|
1238
|
+
type: "call",
|
1239
|
+
target: eventName,
|
1240
|
+
args
|
1241
|
+
}));
|
1242
|
+
});
|
1243
|
+
});
|
1244
|
+
}
|
1245
|
+
|
1246
|
+
/*
|
1247
|
+
* The actual AST traversal is done by the `Traverser` class. This class
|
1248
|
+
* is responsible for walking the AST and calling the appropriate methods
|
1249
|
+
* on the `analyzer` object, which is appropriate for the given AST.
|
1250
|
+
*/
|
1251
|
+
Traverser.traverse(this.ast, {
|
1252
|
+
enter(node, parent) {
|
1253
|
+
|
1254
|
+
// save the parent node on a property for backwards compatibility
|
1255
|
+
node.parent = parent;
|
1256
|
+
|
1257
|
+
analyzer.enterNode(node);
|
1258
|
+
},
|
1259
|
+
leave(node) {
|
1260
|
+
analyzer.leaveNode(node);
|
1261
|
+
},
|
1262
|
+
visitorKeys: this.visitorKeys
|
1263
|
+
});
|
1264
|
+
|
1265
|
+
return steps;
|
1266
|
+
}
|
1053
1267
|
}
|
1054
1268
|
|
1055
1269
|
module.exports = SourceCode;
|
@@ -9,7 +9,7 @@
|
|
9
9
|
//------------------------------------------------------------------------------
|
10
10
|
|
11
11
|
const Cursor = require("./cursor");
|
12
|
-
const
|
12
|
+
const { getLastIndex, getFirstIndex } = require("./utils");
|
13
13
|
|
14
14
|
//------------------------------------------------------------------------------
|
15
15
|
// Exports
|
@@ -31,8 +31,8 @@ module.exports = class BackwardTokenCursor extends Cursor {
|
|
31
31
|
constructor(tokens, comments, indexMap, startLoc, endLoc) {
|
32
32
|
super();
|
33
33
|
this.tokens = tokens;
|
34
|
-
this.index =
|
35
|
-
this.indexEnd =
|
34
|
+
this.index = getLastIndex(tokens, indexMap, endLoc);
|
35
|
+
this.indexEnd = getFirstIndex(tokens, indexMap, startLoc);
|
36
36
|
}
|
37
37
|
|
38
38
|
/** @inheritdoc */
|
@@ -86,5 +86,7 @@ class CursorFactory {
|
|
86
86
|
// Exports
|
87
87
|
//------------------------------------------------------------------------------
|
88
88
|
|
89
|
-
exports
|
90
|
-
|
89
|
+
module.exports = {
|
90
|
+
forward: new CursorFactory(ForwardTokenCursor, ForwardTokenCommentCursor),
|
91
|
+
backward: new CursorFactory(BackwardTokenCursor, BackwardTokenCommentCursor)
|
92
|
+
};
|
@@ -9,7 +9,7 @@
|
|
9
9
|
//------------------------------------------------------------------------------
|
10
10
|
|
11
11
|
const Cursor = require("./cursor");
|
12
|
-
const
|
12
|
+
const { getFirstIndex, search } = require("./utils");
|
13
13
|
|
14
14
|
//------------------------------------------------------------------------------
|
15
15
|
// Exports
|
@@ -32,8 +32,8 @@ module.exports = class ForwardTokenCommentCursor extends Cursor {
|
|
32
32
|
super();
|
33
33
|
this.tokens = tokens;
|
34
34
|
this.comments = comments;
|
35
|
-
this.tokenIndex =
|
36
|
-
this.commentIndex =
|
35
|
+
this.tokenIndex = getFirstIndex(tokens, indexMap, startLoc);
|
36
|
+
this.commentIndex = search(comments, startLoc);
|
37
37
|
this.border = endLoc;
|
38
38
|
}
|
39
39
|
|
@@ -9,7 +9,7 @@
|
|
9
9
|
//------------------------------------------------------------------------------
|
10
10
|
|
11
11
|
const Cursor = require("./cursor");
|
12
|
-
const
|
12
|
+
const { getFirstIndex, getLastIndex } = require("./utils");
|
13
13
|
|
14
14
|
//------------------------------------------------------------------------------
|
15
15
|
// Exports
|
@@ -31,8 +31,8 @@ module.exports = class ForwardTokenCursor extends Cursor {
|
|
31
31
|
constructor(tokens, comments, indexMap, startLoc, endLoc) {
|
32
32
|
super();
|
33
33
|
this.tokens = tokens;
|
34
|
-
this.index =
|
35
|
-
this.indexEnd =
|
34
|
+
this.index = getFirstIndex(tokens, indexMap, startLoc);
|
35
|
+
this.indexEnd = getLastIndex(tokens, indexMap, endLoc);
|
36
36
|
}
|
37
37
|
|
38
38
|
/** @inheritdoc */
|
@@ -37,8 +37,8 @@ function createIndexMap(tokens, comments) {
|
|
37
37
|
const map = Object.create(null);
|
38
38
|
let tokenIndex = 0;
|
39
39
|
let commentIndex = 0;
|
40
|
-
let nextStart
|
41
|
-
let range
|
40
|
+
let nextStart;
|
41
|
+
let range;
|
42
42
|
|
43
43
|
while (tokenIndex < tokens.length || commentIndex < comments.length) {
|
44
44
|
nextStart = (commentIndex < comments.length) ? comments[commentIndex].range[0] : Number.MAX_SAFE_INTEGER;
|
package/lib/unsupported-api.js
CHANGED
@@ -12,9 +12,8 @@
|
|
12
12
|
//-----------------------------------------------------------------------------
|
13
13
|
|
14
14
|
const { FileEnumerator } = require("./cli-engine/file-enumerator");
|
15
|
-
const { FlatESLint, shouldUseFlatConfig } = require("./eslint/
|
16
|
-
const
|
17
|
-
const { ESLint } = require("./eslint/eslint");
|
15
|
+
const { ESLint: FlatESLint, shouldUseFlatConfig } = require("./eslint/eslint");
|
16
|
+
const { LegacyESLint } = require("./eslint/legacy-eslint");
|
18
17
|
|
19
18
|
//-----------------------------------------------------------------------------
|
20
19
|
// Exports
|
@@ -24,7 +23,6 @@ module.exports = {
|
|
24
23
|
builtinRules: require("./rules"),
|
25
24
|
FlatESLint,
|
26
25
|
shouldUseFlatConfig,
|
27
|
-
FlatRuleTester,
|
28
26
|
FileEnumerator,
|
29
|
-
LegacyESLint
|
27
|
+
LegacyESLint
|
30
28
|
};
|
@@ -6,7 +6,7 @@ module.exports = function(it) {
|
|
6
6
|
return `
|
7
7
|
ESLint couldn't find a configuration file. To set up a configuration file for this project, please run:
|
8
8
|
|
9
|
-
npm init @eslint/config
|
9
|
+
npm init @eslint/config@latest
|
10
10
|
|
11
11
|
ESLint looked for configuration files in ${directoryPath} and its ancestors. If it found none, it then looked in your home directory.
|
12
12
|
|
@@ -15,7 +15,7 @@ module.exports = function(it) {
|
|
15
15
|
|
16
16
|
Please remove the "plugins" setting from either config or remove either plugin installation.
|
17
17
|
|
18
|
-
If you still can't figure out the problem, please
|
18
|
+
If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting.
|
19
19
|
`;
|
20
20
|
|
21
21
|
return result;
|
@@ -11,6 +11,6 @@ module.exports = function(it) {
|
|
11
11
|
|
12
12
|
"${configName}" was referenced from the config file in "${importerName}".
|
13
13
|
|
14
|
-
If you still can't figure out the problem, please
|
14
|
+
If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting.
|
15
15
|
`.trimStart();
|
16
16
|
};
|
@@ -14,6 +14,6 @@ It's likely that the plugin isn't installed correctly. Try reinstalling by runni
|
|
14
14
|
|
15
15
|
The plugin "${pluginName}" was referenced from the config file in "${importerName}".
|
16
16
|
|
17
|
-
If you still can't figure out the problem, please
|
17
|
+
If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting.
|
18
18
|
`.trimStart();
|
19
19
|
};
|