eslint 9.23.0 → 9.25.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 +3 -2
- package/lib/cli-engine/cli-engine.js +2 -2
- package/lib/cli-engine/formatters/html.js +3 -3
- package/lib/cli-engine/formatters/stylish.js +1 -1
- package/lib/cli.js +98 -1
- package/lib/config/config-loader.js +108 -34
- package/lib/config/flat-config-helpers.js +7 -4
- package/lib/eslint/eslint-helpers.js +50 -5
- package/lib/eslint/eslint.js +17 -53
- package/lib/eslint/legacy-eslint.js +1 -1
- package/lib/languages/js/source-code/source-code.js +3 -3
- package/lib/languages/js/source-code/token-store/index.js +3 -3
- package/lib/linter/code-path-analysis/code-path-state.js +1 -1
- package/lib/linter/linter.js +1 -1
- package/lib/linter/node-event-generator.js +3 -1
- package/lib/linter/report-translator.js +1 -1
- package/lib/linter/rule-fixer.js +13 -5
- package/lib/linter/rules.js +1 -1
- package/lib/linter/source-code-fixer.js +2 -2
- package/lib/linter/timing.js +2 -2
- package/lib/options.js +29 -0
- package/lib/rule-tester/rule-tester.js +1 -1
- package/lib/rules/accessor-pairs.js +1 -1
- package/lib/rules/array-bracket-newline.js +1 -1
- package/lib/rules/array-bracket-spacing.js +1 -1
- package/lib/rules/array-callback-return.js +1 -1
- package/lib/rules/array-element-newline.js +1 -1
- package/lib/rules/arrow-body-style.js +1 -1
- package/lib/rules/arrow-parens.js +1 -1
- package/lib/rules/arrow-spacing.js +1 -1
- package/lib/rules/block-scoped-var.js +1 -1
- package/lib/rules/block-spacing.js +1 -1
- package/lib/rules/brace-style.js +1 -1
- package/lib/rules/callback-return.js +1 -1
- package/lib/rules/camelcase.js +1 -1
- package/lib/rules/capitalized-comments.js +1 -1
- package/lib/rules/class-methods-use-this.js +46 -2
- package/lib/rules/comma-dangle.js +1 -1
- package/lib/rules/comma-spacing.js +1 -1
- package/lib/rules/comma-style.js +1 -1
- package/lib/rules/complexity.js +1 -1
- package/lib/rules/computed-property-spacing.js +1 -1
- package/lib/rules/consistent-return.js +1 -1
- package/lib/rules/consistent-this.js +1 -1
- package/lib/rules/constructor-super.js +1 -1
- package/lib/rules/curly.js +1 -1
- package/lib/rules/default-case-last.js +1 -1
- package/lib/rules/default-case.js +1 -1
- package/lib/rules/default-param-last.js +1 -1
- package/lib/rules/dot-location.js +1 -1
- package/lib/rules/dot-notation.js +1 -1
- package/lib/rules/eol-last.js +1 -1
- package/lib/rules/eqeqeq.js +1 -1
- package/lib/rules/for-direction.js +5 -5
- package/lib/rules/func-call-spacing.js +1 -1
- package/lib/rules/func-name-matching.js +2 -2
- package/lib/rules/func-names.js +1 -1
- package/lib/rules/func-style.js +1 -1
- package/lib/rules/function-call-argument-newline.js +1 -1
- package/lib/rules/function-paren-newline.js +1 -1
- package/lib/rules/generator-star-spacing.js +1 -1
- package/lib/rules/getter-return.js +1 -1
- package/lib/rules/global-require.js +1 -1
- package/lib/rules/grouped-accessor-pairs.js +1 -1
- package/lib/rules/guard-for-in.js +1 -1
- package/lib/rules/handle-callback-err.js +1 -1
- package/lib/rules/id-blacklist.js +1 -1
- package/lib/rules/id-denylist.js +1 -1
- package/lib/rules/id-length.js +1 -1
- package/lib/rules/id-match.js +1 -1
- package/lib/rules/implicit-arrow-linebreak.js +1 -1
- package/lib/rules/indent-legacy.js +14 -14
- package/lib/rules/indent.js +4 -4
- package/lib/rules/init-declarations.js +22 -1
- package/lib/rules/jsx-quotes.js +1 -1
- package/lib/rules/key-spacing.js +3 -3
- package/lib/rules/keyword-spacing.js +1 -1
- package/lib/rules/line-comment-position.js +1 -1
- package/lib/rules/linebreak-style.js +10 -2
- package/lib/rules/lines-around-comment.js +1 -1
- package/lib/rules/lines-around-directive.js +1 -1
- package/lib/rules/lines-between-class-members.js +1 -1
- package/lib/rules/logical-assignment-operators.js +1 -1
- package/lib/rules/max-classes-per-file.js +1 -1
- package/lib/rules/max-depth.js +1 -1
- package/lib/rules/max-len.js +3 -3
- package/lib/rules/max-lines-per-function.js +1 -1
- package/lib/rules/max-lines.js +1 -1
- package/lib/rules/max-nested-callbacks.js +1 -1
- package/lib/rules/max-params.js +1 -1
- package/lib/rules/max-statements-per-line.js +1 -1
- package/lib/rules/max-statements.js +3 -3
- package/lib/rules/multiline-comment-style.js +1 -1
- package/lib/rules/multiline-ternary.js +1 -1
- package/lib/rules/new-cap.js +1 -1
- package/lib/rules/new-parens.js +1 -1
- package/lib/rules/newline-after-var.js +1 -1
- package/lib/rules/newline-before-return.js +1 -1
- package/lib/rules/newline-per-chained-call.js +1 -1
- package/lib/rules/no-alert.js +1 -1
- package/lib/rules/no-array-constructor.js +4 -1
- package/lib/rules/no-async-promise-executor.js +1 -1
- package/lib/rules/no-await-in-loop.js +1 -1
- package/lib/rules/no-bitwise.js +1 -1
- package/lib/rules/no-buffer-constructor.js +1 -1
- package/lib/rules/no-caller.js +1 -1
- package/lib/rules/no-case-declarations.js +1 -1
- package/lib/rules/no-catch-shadow.js +1 -1
- package/lib/rules/no-class-assign.js +1 -1
- package/lib/rules/no-compare-neg-zero.js +1 -1
- package/lib/rules/no-cond-assign.js +1 -1
- package/lib/rules/no-confusing-arrow.js +1 -1
- package/lib/rules/no-console.js +1 -1
- package/lib/rules/no-const-assign.js +1 -1
- package/lib/rules/no-constant-binary-expression.js +2 -2
- package/lib/rules/no-constant-condition.js +1 -1
- package/lib/rules/no-constructor-return.js +1 -1
- package/lib/rules/no-continue.js +1 -1
- package/lib/rules/no-control-regex.js +1 -1
- package/lib/rules/no-debugger.js +1 -1
- package/lib/rules/no-delete-var.js +1 -1
- package/lib/rules/no-div-regex.js +1 -1
- package/lib/rules/no-dupe-args.js +1 -1
- package/lib/rules/no-dupe-class-members.js +10 -1
- package/lib/rules/no-dupe-else-if.js +1 -1
- package/lib/rules/no-dupe-keys.js +1 -1
- package/lib/rules/no-duplicate-case.js +1 -1
- package/lib/rules/no-duplicate-imports.js +1 -1
- package/lib/rules/no-else-return.js +1 -1
- package/lib/rules/no-empty-character-class.js +1 -1
- package/lib/rules/no-empty-function.js +54 -3
- package/lib/rules/no-empty-pattern.js +1 -1
- package/lib/rules/no-empty-static-block.js +1 -1
- package/lib/rules/no-empty.js +1 -1
- package/lib/rules/no-eq-null.js +1 -1
- package/lib/rules/no-eval.js +1 -1
- package/lib/rules/no-ex-assign.js +1 -1
- package/lib/rules/no-extend-native.js +1 -1
- package/lib/rules/no-extra-bind.js +1 -1
- package/lib/rules/no-extra-boolean-cast.js +1 -1
- package/lib/rules/no-extra-label.js +1 -1
- package/lib/rules/no-extra-parens.js +1 -1
- package/lib/rules/no-extra-semi.js +1 -1
- package/lib/rules/no-fallthrough.js +1 -1
- package/lib/rules/no-floating-decimal.js +1 -1
- package/lib/rules/no-func-assign.js +1 -1
- package/lib/rules/no-global-assign.js +2 -2
- package/lib/rules/no-implicit-coercion.js +1 -1
- package/lib/rules/no-implicit-globals.js +1 -1
- package/lib/rules/no-implied-eval.js +1 -1
- package/lib/rules/no-import-assign.js +1 -1
- package/lib/rules/no-inline-comments.js +1 -1
- package/lib/rules/no-inner-declarations.js +1 -1
- package/lib/rules/no-invalid-regexp.js +1 -1
- package/lib/rules/no-invalid-this.js +23 -1
- package/lib/rules/no-irregular-whitespace.js +1 -1
- package/lib/rules/no-iterator.js +1 -1
- package/lib/rules/no-label-var.js +1 -1
- package/lib/rules/no-labels.js +1 -1
- package/lib/rules/no-lone-blocks.js +1 -1
- package/lib/rules/no-lonely-if.js +1 -1
- package/lib/rules/no-loop-func.js +10 -4
- package/lib/rules/no-loss-of-precision.js +3 -1
- package/lib/rules/no-magic-numbers.js +1 -1
- package/lib/rules/no-misleading-character-class.js +1 -1
- package/lib/rules/no-mixed-operators.js +1 -1
- package/lib/rules/no-mixed-requires.js +1 -1
- package/lib/rules/no-mixed-spaces-and-tabs.js +1 -1
- package/lib/rules/no-multi-assign.js +1 -1
- package/lib/rules/no-multi-spaces.js +1 -1
- package/lib/rules/no-multi-str.js +1 -1
- package/lib/rules/no-multiple-empty-lines.js +1 -1
- package/lib/rules/no-native-reassign.js +2 -2
- package/lib/rules/no-negated-condition.js +1 -1
- package/lib/rules/no-negated-in-lhs.js +1 -1
- package/lib/rules/no-nested-ternary.js +1 -1
- package/lib/rules/no-new-func.js +1 -1
- package/lib/rules/no-new-native-nonconstructor.js +1 -1
- package/lib/rules/no-new-object.js +1 -1
- package/lib/rules/no-new-require.js +1 -1
- package/lib/rules/no-new-symbol.js +1 -1
- package/lib/rules/no-new-wrappers.js +1 -1
- package/lib/rules/no-new.js +1 -1
- package/lib/rules/no-nonoctal-decimal-escape.js +10 -2
- package/lib/rules/no-obj-calls.js +1 -1
- package/lib/rules/no-object-constructor.js +1 -1
- package/lib/rules/no-octal-escape.js +1 -1
- package/lib/rules/no-octal.js +1 -1
- package/lib/rules/no-param-reassign.js +2 -2
- package/lib/rules/no-path-concat.js +1 -1
- package/lib/rules/no-plusplus.js +1 -1
- package/lib/rules/no-process-env.js +1 -1
- package/lib/rules/no-process-exit.js +1 -1
- package/lib/rules/no-promise-executor-return.js +1 -1
- package/lib/rules/no-proto.js +1 -1
- package/lib/rules/no-prototype-builtins.js +1 -1
- package/lib/rules/no-redeclare.js +1 -1
- package/lib/rules/no-regex-spaces.js +1 -1
- package/lib/rules/no-restricted-exports.js +1 -1
- package/lib/rules/no-restricted-globals.js +1 -1
- package/lib/rules/no-restricted-imports.js +1 -1
- package/lib/rules/no-restricted-modules.js +1 -1
- package/lib/rules/no-restricted-properties.js +43 -29
- package/lib/rules/no-restricted-syntax.js +1 -1
- package/lib/rules/no-return-assign.js +1 -1
- package/lib/rules/no-return-await.js +1 -2
- package/lib/rules/no-script-url.js +1 -1
- package/lib/rules/no-self-assign.js +1 -1
- package/lib/rules/no-self-compare.js +1 -1
- package/lib/rules/no-sequences.js +1 -1
- package/lib/rules/no-setter-return.js +1 -1
- package/lib/rules/no-shadow-restricted-names.js +1 -1
- package/lib/rules/no-shadow.js +1 -1
- package/lib/rules/no-spaced-func.js +1 -1
- package/lib/rules/no-sparse-arrays.js +1 -1
- package/lib/rules/no-sync.js +1 -1
- package/lib/rules/no-tabs.js +1 -1
- package/lib/rules/no-template-curly-in-string.js +1 -1
- package/lib/rules/no-ternary.js +1 -1
- package/lib/rules/no-this-before-super.js +1 -1
- package/lib/rules/no-throw-literal.js +1 -1
- package/lib/rules/no-trailing-spaces.js +11 -3
- package/lib/rules/no-undef-init.js +1 -1
- package/lib/rules/no-undef.js +1 -1
- package/lib/rules/no-undefined.js +1 -1
- package/lib/rules/no-underscore-dangle.js +1 -1
- package/lib/rules/no-unexpected-multiline.js +1 -1
- package/lib/rules/no-unmodified-loop-condition.js +1 -1
- package/lib/rules/no-unneeded-ternary.js +1 -1
- package/lib/rules/no-unreachable-loop.js +1 -1
- package/lib/rules/no-unreachable.js +1 -1
- package/lib/rules/no-unsafe-finally.js +1 -1
- package/lib/rules/no-unsafe-negation.js +1 -1
- package/lib/rules/no-unsafe-optional-chaining.js +1 -1
- package/lib/rules/no-unused-expressions.js +15 -57
- package/lib/rules/no-unused-labels.js +1 -1
- package/lib/rules/no-unused-private-class-members.js +1 -1
- package/lib/rules/no-unused-vars.js +3 -3
- package/lib/rules/no-use-before-define.js +1 -1
- package/lib/rules/no-useless-assignment.js +1 -1
- package/lib/rules/no-useless-backreference.js +1 -1
- package/lib/rules/no-useless-call.js +1 -1
- package/lib/rules/no-useless-catch.js +1 -1
- package/lib/rules/no-useless-computed-key.js +1 -1
- package/lib/rules/no-useless-concat.js +1 -1
- package/lib/rules/no-useless-constructor.js +1 -1
- package/lib/rules/no-useless-escape.js +1 -1
- package/lib/rules/no-useless-rename.js +1 -1
- package/lib/rules/no-useless-return.js +1 -1
- package/lib/rules/no-var.js +1 -1
- package/lib/rules/no-void.js +1 -1
- package/lib/rules/no-warning-comments.js +1 -1
- package/lib/rules/no-whitespace-before-property.js +1 -1
- package/lib/rules/no-with.js +1 -1
- package/lib/rules/nonblock-statement-body-position.js +1 -1
- package/lib/rules/object-curly-newline.js +1 -1
- package/lib/rules/object-curly-spacing.js +1 -1
- package/lib/rules/object-property-newline.js +1 -1
- package/lib/rules/object-shorthand.js +1 -1
- package/lib/rules/one-var-declaration-per-line.js +1 -1
- package/lib/rules/one-var.js +1 -1
- package/lib/rules/operator-assignment.js +1 -1
- package/lib/rules/operator-linebreak.js +1 -1
- package/lib/rules/padded-blocks.js +1 -1
- package/lib/rules/padding-line-between-statements.js +1 -1
- package/lib/rules/prefer-arrow-callback.js +1 -1
- package/lib/rules/prefer-const.js +1 -1
- package/lib/rules/prefer-destructuring.js +1 -1
- package/lib/rules/prefer-exponentiation-operator.js +1 -1
- package/lib/rules/prefer-named-capture-group.js +1 -1
- package/lib/rules/prefer-numeric-literals.js +1 -1
- package/lib/rules/prefer-object-has-own.js +1 -1
- package/lib/rules/prefer-object-spread.js +1 -1
- package/lib/rules/prefer-promise-reject-errors.js +1 -1
- package/lib/rules/prefer-reflect.js +1 -2
- package/lib/rules/prefer-regex-literals.js +1 -1
- package/lib/rules/prefer-rest-params.js +1 -1
- package/lib/rules/prefer-spread.js +1 -1
- package/lib/rules/prefer-template.js +1 -1
- package/lib/rules/quote-props.js +1 -1
- package/lib/rules/quotes.js +1 -1
- package/lib/rules/radix.js +1 -1
- package/lib/rules/require-atomic-updates.js +1 -1
- package/lib/rules/require-await.js +1 -1
- package/lib/rules/require-unicode-regexp.js +1 -1
- package/lib/rules/require-yield.js +1 -1
- package/lib/rules/rest-spread-spacing.js +1 -1
- package/lib/rules/semi-spacing.js +1 -1
- package/lib/rules/semi-style.js +1 -1
- package/lib/rules/semi.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-before-blocks.js +1 -1
- package/lib/rules/space-before-function-paren.js +1 -1
- package/lib/rules/space-in-parens.js +1 -1
- package/lib/rules/space-infix-ops.js +1 -1
- package/lib/rules/space-unary-ops.js +1 -1
- package/lib/rules/spaced-comment.js +1 -1
- package/lib/rules/strict.js +1 -1
- package/lib/rules/switch-colon-spacing.js +1 -1
- package/lib/rules/symbol-description.js +1 -1
- package/lib/rules/template-curly-spacing.js +1 -1
- package/lib/rules/template-tag-spacing.js +1 -1
- package/lib/rules/unicode-bom.js +1 -1
- package/lib/rules/use-isnan.js +1 -1
- package/lib/rules/utils/ast-utils.js +13 -2
- package/lib/rules/utils/fix-tracker.js +10 -2
- package/lib/rules/valid-typeof.js +1 -1
- package/lib/rules/vars-on-top.js +1 -1
- package/lib/rules/wrap-iife.js +1 -1
- package/lib/rules/wrap-regex.js +1 -1
- package/lib/rules/yield-star-spacing.js +1 -1
- package/lib/rules/yoda.js +1 -1
- package/lib/services/suppressions-service.js +289 -0
- package/lib/shared/flags.js +4 -0
- package/lib/shared/types.js +4 -27
- package/lib/types/index.d.ts +30 -7
- package/lib/types/rules.d.ts +14 -0
- package/package.json +9 -9
@@ -11,7 +11,7 @@ const { isEqToken } = require("./utils/ast-utils");
|
|
11
11
|
// Rule Definition
|
12
12
|
//------------------------------------------------------------------------------
|
13
13
|
|
14
|
-
/** @type {import('../
|
14
|
+
/** @type {import('../types').Rule.RuleModule} */
|
15
15
|
module.exports = {
|
16
16
|
meta: {
|
17
17
|
deprecated: {
|
@@ -15,7 +15,7 @@ const astUtils = require("./utils/ast-utils");
|
|
15
15
|
// Rule Definition
|
16
16
|
//------------------------------------------------------------------------------
|
17
17
|
|
18
|
-
/** @type {import('../
|
18
|
+
/** @type {import('../types').Rule.RuleModule} */
|
19
19
|
module.exports = {
|
20
20
|
meta: {
|
21
21
|
deprecated: {
|
@@ -140,7 +140,7 @@ function createNeverStylePattern(markers) {
|
|
140
140
|
// Rule Definition
|
141
141
|
//------------------------------------------------------------------------------
|
142
142
|
|
143
|
-
/** @type {import('../
|
143
|
+
/** @type {import('../types').Rule.RuleModule} */
|
144
144
|
module.exports = {
|
145
145
|
meta: {
|
146
146
|
deprecated: {
|
package/lib/rules/strict.js
CHANGED
@@ -63,7 +63,7 @@ function isSimpleParameterList(params) {
|
|
63
63
|
// Rule Definition
|
64
64
|
//------------------------------------------------------------------------------
|
65
65
|
|
66
|
-
/** @type {import('../
|
66
|
+
/** @type {import('../types').Rule.RuleModule} */
|
67
67
|
module.exports = {
|
68
68
|
meta: {
|
69
69
|
type: "suggestion",
|
@@ -16,7 +16,7 @@ const astUtils = require("./utils/ast-utils");
|
|
16
16
|
// Rule Definition
|
17
17
|
//------------------------------------------------------------------------------
|
18
18
|
|
19
|
-
/** @type {import('../
|
19
|
+
/** @type {import('../types').Rule.RuleModule} */
|
20
20
|
module.exports = {
|
21
21
|
meta: {
|
22
22
|
deprecated: {
|
@@ -15,7 +15,7 @@ const astUtils = require("./utils/ast-utils");
|
|
15
15
|
// Rule Definition
|
16
16
|
//------------------------------------------------------------------------------
|
17
17
|
|
18
|
-
/** @type {import('../
|
18
|
+
/** @type {import('../types').Rule.RuleModule} */
|
19
19
|
module.exports = {
|
20
20
|
meta: {
|
21
21
|
type: "suggestion",
|
@@ -16,7 +16,7 @@ const astUtils = require("./utils/ast-utils");
|
|
16
16
|
// Rule Definition
|
17
17
|
//------------------------------------------------------------------------------
|
18
18
|
|
19
|
-
/** @type {import('../
|
19
|
+
/** @type {import('../types').Rule.RuleModule} */
|
20
20
|
module.exports = {
|
21
21
|
meta: {
|
22
22
|
deprecated: {
|
@@ -10,7 +10,7 @@
|
|
10
10
|
// Rule Definition
|
11
11
|
//------------------------------------------------------------------------------
|
12
12
|
|
13
|
-
/** @type {import('../
|
13
|
+
/** @type {import('../types').Rule.RuleModule} */
|
14
14
|
module.exports = {
|
15
15
|
meta: {
|
16
16
|
deprecated: {
|
package/lib/rules/unicode-bom.js
CHANGED
package/lib/rules/use-isnan.js
CHANGED
@@ -38,7 +38,7 @@ function isNaNIdentifier(node) {
|
|
38
38
|
// Rule Definition
|
39
39
|
//------------------------------------------------------------------------------
|
40
40
|
|
41
|
-
/** @type {import('../
|
41
|
+
/** @type {import('../types').Rule.RuleModule} */
|
42
42
|
module.exports = {
|
43
43
|
meta: {
|
44
44
|
hasSuggestions: true,
|
@@ -65,7 +65,7 @@ const ECMASCRIPT_GLOBALS = globals[`es${LATEST_ECMA_VERSION}`];
|
|
65
65
|
/**
|
66
66
|
* Checks reference if is non initializer and writable.
|
67
67
|
* @param {Reference} reference A reference to check.
|
68
|
-
* @param {
|
68
|
+
* @param {number} index The index of the reference in the references.
|
69
69
|
* @param {Reference[]} references The array that the reference belongs to.
|
70
70
|
* @returns {boolean} Success/Failure
|
71
71
|
* @private
|
@@ -1488,6 +1488,17 @@ module.exports = {
|
|
1488
1488
|
return false;
|
1489
1489
|
}
|
1490
1490
|
|
1491
|
+
// Check if the function has a parameter named `this`.
|
1492
|
+
if (
|
1493
|
+
(node.type === "FunctionDeclaration" ||
|
1494
|
+
node.type === "FunctionExpression") &&
|
1495
|
+
node.params.some(
|
1496
|
+
param => param.type === "Identifier" && param.name === "this",
|
1497
|
+
)
|
1498
|
+
) {
|
1499
|
+
return false;
|
1500
|
+
}
|
1501
|
+
|
1491
1502
|
if (
|
1492
1503
|
(capIsConstructor && isES5Constructor(node)) ||
|
1493
1504
|
hasJSDocThisTag(node, sourceCode)
|
@@ -1662,7 +1673,7 @@ module.exports = {
|
|
1662
1673
|
/**
|
1663
1674
|
* Get the precedence level based on the node type
|
1664
1675
|
* @param {ASTNode} node node to evaluate
|
1665
|
-
* @returns {
|
1676
|
+
* @returns {number} precedence level
|
1666
1677
|
* @private
|
1667
1678
|
*/
|
1668
1679
|
getPrecedence(node) {
|
@@ -4,6 +4,14 @@
|
|
4
4
|
*/
|
5
5
|
"use strict";
|
6
6
|
|
7
|
+
//------------------------------------------------------------------------------
|
8
|
+
// Typedefs
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
|
11
|
+
/**
|
12
|
+
* @import { SourceRange } from "@eslint/core";
|
13
|
+
*/
|
14
|
+
|
7
15
|
//------------------------------------------------------------------------------
|
8
16
|
// Requirements
|
9
17
|
//------------------------------------------------------------------------------
|
@@ -34,7 +42,7 @@ class FixTracker {
|
|
34
42
|
/**
|
35
43
|
* Mark the given range as "retained", meaning that other fixes may not
|
36
44
|
* may not modify this region in the same pass.
|
37
|
-
* @param {
|
45
|
+
* @param {SourceRange} range The range to retain.
|
38
46
|
* @returns {FixTracker} The same RuleFixer, for chained calls.
|
39
47
|
*/
|
40
48
|
retainRange(range) {
|
@@ -79,7 +87,7 @@ class FixTracker {
|
|
79
87
|
/**
|
80
88
|
* Create a fix command that replaces the given range with the given text,
|
81
89
|
* accounting for any retained ranges.
|
82
|
-
* @param {
|
90
|
+
* @param {SourceRange} range The range to remove in the fix.
|
83
91
|
* @param {string} text The text to insert in place of the range.
|
84
92
|
* @returns {Object} The fix command.
|
85
93
|
*/
|
@@ -14,7 +14,7 @@ const astUtils = require("./utils/ast-utils");
|
|
14
14
|
// Rule Definition
|
15
15
|
//------------------------------------------------------------------------------
|
16
16
|
|
17
|
-
/** @type {import('../
|
17
|
+
/** @type {import('../types').Rule.RuleModule} */
|
18
18
|
module.exports = {
|
19
19
|
meta: {
|
20
20
|
type: "problem",
|
package/lib/rules/vars-on-top.js
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
// Rule Definition
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
|
-
/** @type {import('../
|
12
|
+
/** @type {import('../types').Rule.RuleModule} */
|
13
13
|
module.exports = {
|
14
14
|
meta: {
|
15
15
|
type: "suggestion",
|
package/lib/rules/wrap-iife.js
CHANGED
@@ -37,7 +37,7 @@ function isCalleeOfNewExpression(node) {
|
|
37
37
|
// Rule Definition
|
38
38
|
//------------------------------------------------------------------------------
|
39
39
|
|
40
|
-
/** @type {import('../
|
40
|
+
/** @type {import('../types').Rule.RuleModule} */
|
41
41
|
module.exports = {
|
42
42
|
meta: {
|
43
43
|
deprecated: {
|
package/lib/rules/wrap-regex.js
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
// Rule Definition
|
11
11
|
//------------------------------------------------------------------------------
|
12
12
|
|
13
|
-
/** @type {import('../
|
13
|
+
/** @type {import('../types').Rule.RuleModule} */
|
14
14
|
module.exports = {
|
15
15
|
meta: {
|
16
16
|
deprecated: {
|
@@ -10,7 +10,7 @@
|
|
10
10
|
// Rule Definition
|
11
11
|
//------------------------------------------------------------------------------
|
12
12
|
|
13
|
-
/** @type {import('../
|
13
|
+
/** @type {import('../types').Rule.RuleModule} */
|
14
14
|
module.exports = {
|
15
15
|
meta: {
|
16
16
|
deprecated: {
|
package/lib/rules/yoda.js
CHANGED
@@ -108,7 +108,7 @@ function getNormalizedLiteral(node) {
|
|
108
108
|
// Rule Definition
|
109
109
|
//------------------------------------------------------------------------------
|
110
110
|
|
111
|
-
/** @type {import('../
|
111
|
+
/** @type {import('../types').Rule.RuleModule} */
|
112
112
|
module.exports = {
|
113
113
|
meta: {
|
114
114
|
type: "suggestion",
|
@@ -0,0 +1,289 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Manages the suppressed violations.
|
3
|
+
* @author Iacovos Constantinou
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//-----------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//-----------------------------------------------------------------------------
|
11
|
+
|
12
|
+
const fs = require("node:fs");
|
13
|
+
const path = require("node:path");
|
14
|
+
const { calculateStatsPerFile } = require("../eslint/eslint-helpers");
|
15
|
+
|
16
|
+
//------------------------------------------------------------------------------
|
17
|
+
// Typedefs
|
18
|
+
//------------------------------------------------------------------------------
|
19
|
+
|
20
|
+
// For VSCode IntelliSense
|
21
|
+
/** @typedef {import("../shared/types").LintResult} LintResult */
|
22
|
+
/** @typedef {import("../shared/types").SuppressedViolations} SuppressedViolations */
|
23
|
+
|
24
|
+
//-----------------------------------------------------------------------------
|
25
|
+
// Exports
|
26
|
+
//-----------------------------------------------------------------------------
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Manages the suppressed violations.
|
30
|
+
*/
|
31
|
+
class SuppressionsService {
|
32
|
+
filePath = "";
|
33
|
+
cwd = "";
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Creates a new instance of SuppressionsService.
|
37
|
+
* @param {Object} options The options.
|
38
|
+
* @param {string} [options.filePath] The location of the suppressions file.
|
39
|
+
* @param {string} [options.cwd] The current working directory.
|
40
|
+
*/
|
41
|
+
constructor({ filePath, cwd }) {
|
42
|
+
this.filePath = filePath;
|
43
|
+
this.cwd = cwd;
|
44
|
+
}
|
45
|
+
|
46
|
+
/**
|
47
|
+
* Updates the suppressions file based on the current violations and the provided rules.
|
48
|
+
* If no rules are provided, all violations are suppressed.
|
49
|
+
* @param {LintResult[]|undefined} results The lint results.
|
50
|
+
* @param {string[]|undefined} rules The rules to suppress.
|
51
|
+
* @returns {Promise<void>}
|
52
|
+
*/
|
53
|
+
async suppress(results, rules) {
|
54
|
+
const suppressions = await this.load();
|
55
|
+
|
56
|
+
for (const result of results) {
|
57
|
+
const relativeFilePath = this.getRelativeFilePath(result.filePath);
|
58
|
+
const violationsByRule = SuppressionsService.countViolationsByRule(
|
59
|
+
result.messages,
|
60
|
+
);
|
61
|
+
|
62
|
+
for (const ruleId in violationsByRule) {
|
63
|
+
if (rules && !rules.includes(ruleId)) {
|
64
|
+
continue;
|
65
|
+
}
|
66
|
+
|
67
|
+
suppressions[relativeFilePath] ??= {};
|
68
|
+
suppressions[relativeFilePath][ruleId] =
|
69
|
+
violationsByRule[ruleId];
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
return this.save(suppressions);
|
74
|
+
}
|
75
|
+
|
76
|
+
/**
|
77
|
+
* Removes old, unused suppressions for violations that do not occur anymore.
|
78
|
+
* @param {LintResult[]} results The lint results.
|
79
|
+
* @returns {Promise<void>} No return value.
|
80
|
+
*/
|
81
|
+
async prune(results) {
|
82
|
+
const suppressions = await this.load();
|
83
|
+
const { unused } = this.applySuppressions(results, suppressions);
|
84
|
+
|
85
|
+
for (const file in unused) {
|
86
|
+
if (!suppressions[file]) {
|
87
|
+
continue;
|
88
|
+
}
|
89
|
+
|
90
|
+
for (const rule in unused[file]) {
|
91
|
+
if (!suppressions[file][rule]) {
|
92
|
+
continue;
|
93
|
+
}
|
94
|
+
|
95
|
+
const suppressionsCount = suppressions[file][rule].count;
|
96
|
+
const violationsCount = unused[file][rule].count;
|
97
|
+
|
98
|
+
if (suppressionsCount === violationsCount) {
|
99
|
+
// Remove unused rules
|
100
|
+
delete suppressions[file][rule];
|
101
|
+
} else {
|
102
|
+
// Update the count to match the new number of violations
|
103
|
+
suppressions[file][rule].count -= violationsCount;
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
// Cleanup files with no rules
|
108
|
+
if (Object.keys(suppressions[file]).length === 0) {
|
109
|
+
delete suppressions[file];
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|
113
|
+
return this.save(suppressions);
|
114
|
+
}
|
115
|
+
|
116
|
+
/**
|
117
|
+
* Checks the provided suppressions against the lint results.
|
118
|
+
*
|
119
|
+
* For each file, counts the number of violations per rule.
|
120
|
+
* For each rule in each file, compares the number of violations against the counter from the suppressions file.
|
121
|
+
* If the number of violations is less or equal to the counter, messages are moved to `LintResult#suppressedMessages` and ignored.
|
122
|
+
* Otherwise, all violations are reported as usual.
|
123
|
+
* @param {LintResult[]} results The lint results.
|
124
|
+
* @param {SuppressedViolations} suppressions The suppressions.
|
125
|
+
* @returns {{
|
126
|
+
* results: LintResult[],
|
127
|
+
* unused: SuppressedViolations
|
128
|
+
* }} The updated results and the unused suppressions.
|
129
|
+
*/
|
130
|
+
applySuppressions(results, suppressions) {
|
131
|
+
/**
|
132
|
+
* We copy the results to avoid modifying the original objects
|
133
|
+
* We remove only result messages that are matched and hence suppressed
|
134
|
+
* We leave the rest untouched to minimize the risk of losing parts of the original data
|
135
|
+
*/
|
136
|
+
const filtered = structuredClone(results);
|
137
|
+
const unused = {};
|
138
|
+
|
139
|
+
for (const result of filtered) {
|
140
|
+
const relativeFilePath = this.getRelativeFilePath(result.filePath);
|
141
|
+
|
142
|
+
if (!suppressions[relativeFilePath]) {
|
143
|
+
continue;
|
144
|
+
}
|
145
|
+
|
146
|
+
const violationsByRule = SuppressionsService.countViolationsByRule(
|
147
|
+
result.messages,
|
148
|
+
);
|
149
|
+
let wasSuppressed = false;
|
150
|
+
|
151
|
+
for (const ruleId in violationsByRule) {
|
152
|
+
if (!suppressions[relativeFilePath][ruleId]) {
|
153
|
+
continue;
|
154
|
+
}
|
155
|
+
|
156
|
+
const suppressionsCount =
|
157
|
+
suppressions[relativeFilePath][ruleId].count;
|
158
|
+
const violationsCount = violationsByRule[ruleId].count;
|
159
|
+
|
160
|
+
// Suppress messages if the number of violations is less or equal to the suppressions count
|
161
|
+
if (violationsCount <= suppressionsCount) {
|
162
|
+
SuppressionsService.suppressMessagesByRule(result, ruleId);
|
163
|
+
wasSuppressed = true;
|
164
|
+
}
|
165
|
+
|
166
|
+
// Update the count to match the new number of violations, otherwise remove the rule entirely
|
167
|
+
if (violationsCount < suppressionsCount) {
|
168
|
+
unused[relativeFilePath] ??= {};
|
169
|
+
unused[relativeFilePath][ruleId] ??= {};
|
170
|
+
unused[relativeFilePath][ruleId].count =
|
171
|
+
suppressionsCount - violationsCount;
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
// Mark as unused all the suppressions that were not matched against a rule
|
176
|
+
for (const ruleId in suppressions[relativeFilePath]) {
|
177
|
+
if (violationsByRule[ruleId]) {
|
178
|
+
continue;
|
179
|
+
}
|
180
|
+
|
181
|
+
unused[relativeFilePath] ??= {};
|
182
|
+
unused[relativeFilePath][ruleId] =
|
183
|
+
suppressions[relativeFilePath][ruleId];
|
184
|
+
}
|
185
|
+
|
186
|
+
// Recalculate stats if messages were suppressed
|
187
|
+
if (wasSuppressed) {
|
188
|
+
Object.assign(result, calculateStatsPerFile(result.messages));
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
return {
|
193
|
+
results: filtered,
|
194
|
+
unused,
|
195
|
+
};
|
196
|
+
}
|
197
|
+
|
198
|
+
/**
|
199
|
+
* Loads the suppressions file.
|
200
|
+
* @throws {Error} If the suppressions file cannot be parsed.
|
201
|
+
* @returns {Promise<SuppressedViolations>} The suppressions.
|
202
|
+
*/
|
203
|
+
async load() {
|
204
|
+
try {
|
205
|
+
const data = await fs.promises.readFile(this.filePath, "utf8");
|
206
|
+
|
207
|
+
return JSON.parse(data);
|
208
|
+
} catch (err) {
|
209
|
+
if (err.code === "ENOENT") {
|
210
|
+
return {};
|
211
|
+
}
|
212
|
+
throw new Error(
|
213
|
+
`Failed to parse suppressions file at ${this.filePath}`,
|
214
|
+
);
|
215
|
+
}
|
216
|
+
}
|
217
|
+
|
218
|
+
/**
|
219
|
+
* Updates the suppressions file.
|
220
|
+
* @param {SuppressedViolations} suppressions The suppressions to save.
|
221
|
+
* @returns {Promise<void>}
|
222
|
+
* @private
|
223
|
+
*/
|
224
|
+
save(suppressions) {
|
225
|
+
return fs.promises.writeFile(
|
226
|
+
this.filePath,
|
227
|
+
JSON.stringify(suppressions, null, 2),
|
228
|
+
);
|
229
|
+
}
|
230
|
+
|
231
|
+
/**
|
232
|
+
* Counts the violations by rule, ignoring warnings.
|
233
|
+
* @param {LintMessage[]} messages The messages to count.
|
234
|
+
* @returns {Record<string, number>} The number of violations by rule.
|
235
|
+
*/
|
236
|
+
static countViolationsByRule(messages) {
|
237
|
+
return messages.reduce((totals, message) => {
|
238
|
+
if (message.severity === 2 && message.ruleId) {
|
239
|
+
totals[message.ruleId] ??= { count: 0 };
|
240
|
+
totals[message.ruleId].count++;
|
241
|
+
}
|
242
|
+
return totals;
|
243
|
+
}, {});
|
244
|
+
}
|
245
|
+
|
246
|
+
/**
|
247
|
+
* Returns the relative path of a file to the current working directory.
|
248
|
+
* Always in POSIX format for consistency and interoperability.
|
249
|
+
* @param {string} filePath The file path.
|
250
|
+
* @returns {string} The relative file path.
|
251
|
+
*/
|
252
|
+
getRelativeFilePath(filePath) {
|
253
|
+
return path
|
254
|
+
.relative(this.cwd, filePath)
|
255
|
+
.split(path.sep)
|
256
|
+
.join(path.posix.sep);
|
257
|
+
}
|
258
|
+
|
259
|
+
/**
|
260
|
+
* Moves the messages matching the rule to `LintResult#suppressedMessages` and updates the stats.
|
261
|
+
* @param {LintResult} result The result to update.
|
262
|
+
* @param {string} ruleId The rule to suppress.
|
263
|
+
* @returns {void}
|
264
|
+
*/
|
265
|
+
static suppressMessagesByRule(result, ruleId) {
|
266
|
+
const suppressedMessages = result.messages.filter(
|
267
|
+
message => message.ruleId === ruleId,
|
268
|
+
);
|
269
|
+
|
270
|
+
result.suppressedMessages = result.suppressedMessages.concat(
|
271
|
+
suppressedMessages.map(message => {
|
272
|
+
message.suppressions = [
|
273
|
+
{
|
274
|
+
kind: "file",
|
275
|
+
justification: "",
|
276
|
+
},
|
277
|
+
];
|
278
|
+
|
279
|
+
return message;
|
280
|
+
}),
|
281
|
+
);
|
282
|
+
|
283
|
+
result.messages = result.messages.filter(
|
284
|
+
message => message.ruleId !== ruleId,
|
285
|
+
);
|
286
|
+
}
|
287
|
+
}
|
288
|
+
|
289
|
+
module.exports = { SuppressionsService };
|
package/lib/shared/flags.js
CHANGED
@@ -31,6 +31,10 @@ const activeFlags = new Map([
|
|
31
31
|
"unstable_config_lookup_from_file",
|
32
32
|
"Look up `eslint.config.js` from the file being linted.",
|
33
33
|
],
|
34
|
+
[
|
35
|
+
"unstable_native_nodejs_ts_config",
|
36
|
+
"Use native Node.js to load TypeScript configuration.",
|
37
|
+
],
|
34
38
|
]);
|
35
39
|
|
36
40
|
/**
|
package/lib/shared/types.js
CHANGED
@@ -124,6 +124,10 @@ module.exports = {};
|
|
124
124
|
* @property {Array<{desc?: string, messageId?: string, fix: {range: [number, number], text: string}}>} [suggestions] Information for suggestions.
|
125
125
|
*/
|
126
126
|
|
127
|
+
/**
|
128
|
+
* @typedef {Record<string, Record<string, { count: number }>>} SuppressedViolations
|
129
|
+
*/
|
130
|
+
|
127
131
|
/**
|
128
132
|
* @typedef {Object} SuggestionResult
|
129
133
|
* @property {string} desc A short description.
|
@@ -162,25 +166,6 @@ module.exports = {};
|
|
162
166
|
* @property {{ name?: string, url?: string }} [rule] Name and information of the replacement rule
|
163
167
|
*/
|
164
168
|
|
165
|
-
/**
|
166
|
-
* @typedef {Object} RuleMeta
|
167
|
-
* @property {boolean|DeprecatedInfo} [deprecated] If `true` then the rule has been deprecated.
|
168
|
-
* @property {Array} [defaultOptions] Default options for the rule.
|
169
|
-
* @property {RuleMetaDocs} docs The document information of the rule.
|
170
|
-
* @property {"code"|"whitespace"} [fixable] The autofix type.
|
171
|
-
* @property {boolean} [hasSuggestions] If `true` then the rule provides suggestions.
|
172
|
-
* @property {Record<string,string>} [messages] The messages the rule reports.
|
173
|
-
* @property {string[]} [replacedBy] The IDs of the alternative rules.
|
174
|
-
* @property {Array|Object} schema The option schema of the rule.
|
175
|
-
* @property {"problem"|"suggestion"|"layout"} type The rule type.
|
176
|
-
*/
|
177
|
-
|
178
|
-
/**
|
179
|
-
* @typedef {Object} Rule
|
180
|
-
* @property {Function} create The factory of the rule.
|
181
|
-
* @property {RuleMeta} meta The meta data of the rule.
|
182
|
-
*/
|
183
|
-
|
184
169
|
/**
|
185
170
|
* @typedef {Object} Plugin
|
186
171
|
* @property {Record<string, ConfigData>} [configs] The definition of plugin configs.
|
@@ -259,11 +244,3 @@ module.exports = {};
|
|
259
244
|
* @typedef {Object} ResultsMeta
|
260
245
|
* @property {MaxWarningsExceeded} [maxWarningsExceeded] Present if the maxWarnings threshold was exceeded.
|
261
246
|
*/
|
262
|
-
|
263
|
-
/**
|
264
|
-
* A formatter function.
|
265
|
-
* @callback FormatterFunction
|
266
|
-
* @param {LintResult[]} results The list of linting results.
|
267
|
-
* @param {{cwd: string, maxWarningsExceeded?: MaxWarningsExceeded, rulesMeta: Record<string, RuleMeta>}} context A context object.
|
268
|
-
* @returns {string | Promise<string>} Formatted text.
|
269
|
-
*/
|
package/lib/types/index.d.ts
CHANGED
@@ -1174,13 +1174,13 @@ export namespace Rule {
|
|
1174
1174
|
}
|
1175
1175
|
|
1176
1176
|
interface RuleContext
|
1177
|
-
extends CoreRuleContext<
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
> {
|
1177
|
+
extends CoreRuleContext<{
|
1178
|
+
LangOptions: Linter.LanguageOptions;
|
1179
|
+
Code: SourceCode;
|
1180
|
+
RuleOptions: any[];
|
1181
|
+
Node: ESTree.Node;
|
1182
|
+
MessageIds: string;
|
1183
|
+
}> {
|
1184
1184
|
/*
|
1185
1185
|
* Need to extend the `RuleContext` interface to include the
|
1186
1186
|
* deprecated methods that have not yet been removed.
|
@@ -1262,6 +1262,29 @@ export namespace Rule {
|
|
1262
1262
|
}
|
1263
1263
|
}
|
1264
1264
|
|
1265
|
+
export type JSRuleDefinitionTypeOptions = {
|
1266
|
+
RuleOptions: unknown[];
|
1267
|
+
MessageIds: string;
|
1268
|
+
ExtRuleDocs: Record<string, unknown>;
|
1269
|
+
};
|
1270
|
+
|
1271
|
+
export type JSRuleDefinition<
|
1272
|
+
Options extends Partial<JSRuleDefinitionTypeOptions> = {},
|
1273
|
+
> = RuleDefinition<
|
1274
|
+
// Language specific type options (non-configurable)
|
1275
|
+
{
|
1276
|
+
LangOptions: Linter.LanguageOptions;
|
1277
|
+
Code: SourceCode;
|
1278
|
+
Visitor: Rule.NodeListener;
|
1279
|
+
Node: ESTree.Node;
|
1280
|
+
} & Required<
|
1281
|
+
// Rule specific type options (custom)
|
1282
|
+
Options &
|
1283
|
+
// Rule specific type options (defaults)
|
1284
|
+
Omit<JSRuleDefinitionTypeOptions, keyof Options>
|
1285
|
+
>
|
1286
|
+
>;
|
1287
|
+
|
1265
1288
|
// #region Linter
|
1266
1289
|
|
1267
1290
|
export class Linter {
|
package/lib/types/rules.d.ts
CHANGED
@@ -422,6 +422,15 @@ export interface ESLintRules extends Linter.RulesRecord {
|
|
422
422
|
[
|
423
423
|
Partial<{
|
424
424
|
exceptMethods: string[];
|
425
|
+
/**
|
426
|
+
* @default true
|
427
|
+
*/
|
428
|
+
enforceForClassFields: boolean;
|
429
|
+
/**
|
430
|
+
* @default false
|
431
|
+
*/
|
432
|
+
ignoreOverrideMethods: boolean;
|
433
|
+
ignoreClassesWithImplements: "all" | "public-fields";
|
425
434
|
}>,
|
426
435
|
]
|
427
436
|
>;
|
@@ -2350,6 +2359,10 @@ export interface ESLintRules extends Linter.RulesRecord {
|
|
2350
2359
|
| "constructors"
|
2351
2360
|
| "asyncFunctions"
|
2352
2361
|
| "asyncMethods"
|
2362
|
+
| "privateConstructors"
|
2363
|
+
| "protectedConstructors"
|
2364
|
+
| "decoratedFunctions"
|
2365
|
+
| "overrideMethods"
|
2353
2366
|
>;
|
2354
2367
|
}>,
|
2355
2368
|
]
|
@@ -3430,6 +3443,7 @@ export interface ESLintRules extends Linter.RulesRecord {
|
|
3430
3443
|
}
|
3431
3444
|
| {
|
3432
3445
|
property: string;
|
3446
|
+
allowObjects?: string[];
|
3433
3447
|
message?: string | undefined;
|
3434
3448
|
}
|
3435
3449
|
>,
|