eslint 8.39.0 → 8.47.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 +10 -4
- package/conf/globals.js +6 -1
- package/lib/cli-engine/cli-engine.js +30 -19
- package/lib/cli.js +2 -28
- package/lib/config/default-config.js +1 -1
- package/lib/config/flat-config-schema.js +127 -35
- package/lib/eslint/eslint-helpers.js +11 -10
- package/lib/eslint/eslint.js +1 -1
- package/lib/eslint/flat-eslint.js +119 -161
- package/lib/linter/apply-disable-directives.js +11 -1
- package/lib/linter/code-path-analysis/debug-helpers.js +1 -1
- package/lib/linter/config-comment-parser.js +9 -2
- package/lib/linter/linter.js +20 -11
- package/lib/linter/report-translator.js +22 -21
- package/lib/rule-tester/flat-rule-tester.js +1 -2
- package/lib/rule-tester/rule-tester.js +1 -2
- package/lib/rules/accessor-pairs.js +35 -43
- package/lib/rules/array-bracket-newline.js +2 -2
- package/lib/rules/array-bracket-spacing.js +2 -2
- package/lib/rules/array-callback-return.js +2 -2
- package/lib/rules/array-element-newline.js +12 -6
- package/lib/rules/arrow-body-style.js +2 -2
- package/lib/rules/arrow-parens.js +2 -2
- package/lib/rules/arrow-spacing.js +2 -2
- package/lib/rules/block-scoped-var.js +17 -7
- package/lib/rules/block-spacing.js +2 -2
- package/lib/rules/brace-style.js +2 -2
- package/lib/rules/callback-return.js +2 -2
- package/lib/rules/camelcase.js +2 -2
- package/lib/rules/capitalized-comments.js +2 -2
- package/lib/rules/class-methods-use-this.js +2 -2
- package/lib/rules/comma-dangle.js +2 -2
- package/lib/rules/comma-spacing.js +2 -2
- package/lib/rules/comma-style.js +2 -2
- package/lib/rules/complexity.js +1 -1
- package/lib/rules/computed-property-spacing.js +2 -2
- package/lib/rules/consistent-return.js +3 -3
- package/lib/rules/consistent-this.js +2 -2
- package/lib/rules/constructor-super.js +1 -1
- package/lib/rules/curly.js +2 -2
- package/lib/rules/default-case-last.js +1 -1
- package/lib/rules/default-case.js +2 -2
- package/lib/rules/default-param-last.js +1 -1
- package/lib/rules/dot-location.js +2 -2
- package/lib/rules/dot-notation.js +3 -4
- package/lib/rules/eol-last.js +2 -2
- package/lib/rules/eqeqeq.js +2 -2
- package/lib/rules/for-direction.js +1 -1
- package/lib/rules/func-call-spacing.js +2 -2
- package/lib/rules/func-name-matching.js +1 -1
- package/lib/rules/func-names.js +2 -2
- package/lib/rules/func-style.js +1 -1
- package/lib/rules/function-call-argument-newline.js +2 -2
- package/lib/rules/function-paren-newline.js +2 -2
- package/lib/rules/generator-star-spacing.js +2 -2
- package/lib/rules/getter-return.js +2 -2
- package/lib/rules/global-require.js +2 -2
- package/lib/rules/grouped-accessor-pairs.js +35 -44
- package/lib/rules/guard-for-in.js +1 -1
- package/lib/rules/handle-callback-err.js +2 -2
- package/lib/rules/id-blacklist.js +2 -2
- package/lib/rules/id-denylist.js +2 -2
- package/lib/rules/id-length.js +3 -36
- package/lib/rules/id-match.js +2 -2
- package/lib/rules/implicit-arrow-linebreak.js +2 -2
- package/lib/rules/indent-legacy.js +2 -2
- package/lib/rules/indent.js +84 -88
- package/lib/rules/init-declarations.js +1 -1
- package/lib/rules/jsx-quotes.js +1 -1
- package/lib/rules/key-spacing.js +4 -10
- package/lib/rules/keyword-spacing.js +2 -2
- package/lib/rules/line-comment-position.js +2 -2
- package/lib/rules/linebreak-style.js +2 -2
- package/lib/rules/lines-around-comment.js +2 -2
- package/lib/rules/lines-around-directive.js +2 -2
- package/lib/rules/lines-between-class-members.js +2 -2
- package/lib/rules/logical-assignment-operators.js +7 -5
- package/lib/rules/max-classes-per-file.js +1 -1
- package/lib/rules/max-depth.js +1 -1
- package/lib/rules/max-len.js +19 -15
- package/lib/rules/max-lines-per-function.js +2 -2
- package/lib/rules/max-lines.js +2 -2
- package/lib/rules/max-nested-callbacks.js +1 -1
- package/lib/rules/max-params.js +2 -2
- package/lib/rules/max-statements-per-line.js +2 -2
- package/lib/rules/max-statements.js +1 -1
- package/lib/rules/multiline-comment-style.js +2 -2
- package/lib/rules/multiline-ternary.js +2 -2
- package/lib/rules/new-cap.js +2 -2
- package/lib/rules/new-parens.js +2 -2
- package/lib/rules/newline-after-var.js +2 -4
- package/lib/rules/newline-before-return.js +2 -2
- package/lib/rules/newline-per-chained-call.js +2 -2
- package/lib/rules/no-alert.js +2 -2
- package/lib/rules/no-array-constructor.js +1 -1
- package/lib/rules/no-async-promise-executor.js +2 -2
- 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 +2 -2
- package/lib/rules/no-class-assign.js +2 -2
- package/lib/rules/no-compare-neg-zero.js +1 -1
- package/lib/rules/no-cond-assign.js +2 -2
- package/lib/rules/no-confusing-arrow.js +2 -2
- package/lib/rules/no-console.js +2 -2
- package/lib/rules/no-const-assign.js +2 -2
- package/lib/rules/no-constant-binary-expression.js +2 -2
- package/lib/rules/no-constant-condition.js +2 -2
- package/lib/rules/no-constructor-return.js +1 -1
- package/lib/rules/no-continue.js +1 -1
- package/lib/rules/no-control-regex.js +16 -3
- package/lib/rules/no-debugger.js +1 -1
- package/lib/rules/no-delete-var.js +1 -1
- package/lib/rules/no-div-regex.js +2 -2
- package/lib/rules/no-dupe-args.js +2 -2
- package/lib/rules/no-dupe-class-members.js +1 -1
- package/lib/rules/no-dupe-else-if.js +2 -2
- package/lib/rules/no-dupe-keys.js +1 -1
- package/lib/rules/no-duplicate-case.js +2 -2
- package/lib/rules/no-duplicate-imports.js +1 -1
- package/lib/rules/no-else-return.js +2 -2
- package/lib/rules/no-empty-character-class.js +34 -13
- package/lib/rules/no-empty-function.js +2 -2
- package/lib/rules/no-empty-pattern.js +39 -4
- package/lib/rules/no-empty-static-block.js +2 -2
- package/lib/rules/no-empty.js +2 -2
- package/lib/rules/no-eq-null.js +1 -1
- package/lib/rules/no-eval.js +2 -2
- package/lib/rules/no-ex-assign.js +2 -2
- package/lib/rules/no-extend-native.js +2 -2
- package/lib/rules/no-extra-bind.js +2 -2
- package/lib/rules/no-extra-boolean-cast.js +2 -2
- package/lib/rules/no-extra-label.js +2 -2
- package/lib/rules/no-extra-parens.js +48 -12
- package/lib/rules/no-extra-semi.js +31 -13
- package/lib/rules/no-fallthrough.js +3 -3
- package/lib/rules/no-floating-decimal.js +2 -2
- package/lib/rules/no-func-assign.js +2 -2
- package/lib/rules/no-global-assign.js +2 -2
- package/lib/rules/no-implicit-coercion.js +2 -2
- package/lib/rules/no-implicit-globals.js +2 -2
- package/lib/rules/no-implied-eval.js +2 -2
- package/lib/rules/no-import-assign.js +2 -2
- package/lib/rules/no-inline-comments.js +2 -2
- package/lib/rules/no-inner-declarations.js +1 -1
- package/lib/rules/no-invalid-regexp.js +23 -8
- package/lib/rules/no-invalid-this.js +2 -2
- package/lib/rules/no-irregular-whitespace.js +23 -6
- package/lib/rules/no-iterator.js +1 -1
- package/lib/rules/no-label-var.js +2 -2
- package/lib/rules/no-labels.js +1 -1
- package/lib/rules/no-lone-blocks.js +2 -2
- package/lib/rules/no-lonely-if.js +2 -2
- package/lib/rules/no-loop-func.js +3 -3
- package/lib/rules/no-loss-of-precision.js +15 -7
- package/lib/rules/no-magic-numbers.js +1 -1
- package/lib/rules/no-misleading-character-class.js +10 -4
- package/lib/rules/no-mixed-operators.js +2 -2
- package/lib/rules/no-mixed-requires.js +1 -1
- package/lib/rules/no-mixed-spaces-and-tabs.js +2 -2
- package/lib/rules/no-multi-assign.js +1 -1
- package/lib/rules/no-multi-spaces.js +2 -2
- package/lib/rules/no-multi-str.js +1 -1
- package/lib/rules/no-multiple-empty-lines.js +2 -2
- 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 +2 -2
- package/lib/rules/no-new-native-nonconstructor.js +2 -2
- package/lib/rules/no-new-object.js +2 -2
- package/lib/rules/no-new-require.js +1 -1
- package/lib/rules/no-new-symbol.js +2 -2
- package/lib/rules/no-new-wrappers.js +20 -8
- package/lib/rules/no-new.js +1 -1
- package/lib/rules/no-nonoctal-decimal-escape.js +2 -2
- package/lib/rules/no-obj-calls.js +2 -2
- 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 +2 -2
- package/lib/rules/no-proto.js +1 -1
- package/lib/rules/no-prototype-builtins.js +1 -1
- package/lib/rules/no-redeclare.js +2 -2
- package/lib/rules/no-regex-spaces.js +20 -5
- package/lib/rules/no-restricted-exports.js +2 -2
- package/lib/rules/no-restricted-globals.js +2 -2
- package/lib/rules/no-restricted-imports.js +2 -2
- package/lib/rules/no-restricted-modules.js +8 -11
- package/lib/rules/no-restricted-properties.js +1 -1
- package/lib/rules/no-restricted-syntax.js +1 -1
- package/lib/rules/no-return-assign.js +2 -2
- package/lib/rules/no-return-await.js +8 -3
- package/lib/rules/no-script-url.js +1 -1
- package/lib/rules/no-self-assign.js +2 -2
- package/lib/rules/no-self-compare.js +2 -2
- package/lib/rules/no-sequences.js +2 -2
- package/lib/rules/no-setter-return.js +2 -2
- package/lib/rules/no-shadow-restricted-names.js +2 -2
- package/lib/rules/no-shadow.js +2 -2
- package/lib/rules/no-spaced-func.js +2 -2
- package/lib/rules/no-sparse-arrays.js +1 -1
- package/lib/rules/no-sync.js +1 -1
- package/lib/rules/no-tabs.js +2 -2
- 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 +2 -2
- package/lib/rules/no-undef-init.js +2 -2
- package/lib/rules/no-undef.js +2 -2
- package/lib/rules/no-undefined.js +2 -2
- package/lib/rules/no-underscore-dangle.js +2 -2
- package/lib/rules/no-unexpected-multiline.js +2 -2
- package/lib/rules/no-unmodified-loop-condition.js +2 -2
- package/lib/rules/no-unneeded-ternary.js +2 -2
- package/lib/rules/no-unreachable-loop.js +1 -1
- package/lib/rules/no-unreachable.js +2 -2
- package/lib/rules/no-unsafe-finally.js +1 -1
- package/lib/rules/no-unsafe-negation.js +2 -2
- package/lib/rules/no-unsafe-optional-chaining.js +1 -1
- package/lib/rules/no-unused-expressions.js +4 -6
- package/lib/rules/no-unused-labels.js +48 -15
- package/lib/rules/no-unused-private-class-members.js +1 -1
- package/lib/rules/no-unused-vars.js +4 -3
- package/lib/rules/no-use-before-define.js +2 -2
- package/lib/rules/no-useless-backreference.js +3 -3
- package/lib/rules/no-useless-call.js +2 -2
- package/lib/rules/no-useless-catch.js +1 -1
- package/lib/rules/no-useless-computed-key.js +2 -2
- package/lib/rules/no-useless-concat.js +2 -2
- package/lib/rules/no-useless-constructor.js +1 -1
- package/lib/rules/no-useless-escape.js +162 -83
- package/lib/rules/no-useless-rename.js +2 -2
- package/lib/rules/no-useless-return.js +37 -9
- package/lib/rules/no-var.js +2 -2
- package/lib/rules/no-void.js +1 -1
- package/lib/rules/no-warning-comments.js +2 -2
- package/lib/rules/no-whitespace-before-property.js +2 -2
- package/lib/rules/no-with.js +1 -1
- package/lib/rules/nonblock-statement-body-position.js +2 -2
- package/lib/rules/object-curly-newline.js +2 -2
- package/lib/rules/object-curly-spacing.js +4 -4
- package/lib/rules/object-property-newline.js +2 -2
- package/lib/rules/object-shorthand.js +2 -2
- package/lib/rules/one-var-declaration-per-line.js +1 -1
- package/lib/rules/one-var.js +2 -2
- package/lib/rules/operator-assignment.js +2 -2
- package/lib/rules/operator-linebreak.js +2 -2
- package/lib/rules/padded-blocks.js +2 -2
- package/lib/rules/padding-line-between-statements.js +8 -53
- package/lib/rules/prefer-arrow-callback.js +2 -2
- package/lib/rules/prefer-const.js +2 -2
- package/lib/rules/prefer-destructuring.js +2 -2
- package/lib/rules/prefer-exponentiation-operator.js +4 -3
- package/lib/rules/prefer-named-capture-group.js +10 -7
- package/lib/rules/prefer-numeric-literals.js +2 -2
- package/lib/rules/prefer-object-has-own.js +2 -2
- package/lib/rules/prefer-object-spread.js +2 -2
- package/lib/rules/prefer-promise-reject-errors.js +2 -2
- package/lib/rules/prefer-reflect.js +1 -1
- package/lib/rules/prefer-regex-literals.js +14 -17
- package/lib/rules/prefer-rest-params.js +2 -2
- package/lib/rules/prefer-spread.js +2 -2
- package/lib/rules/prefer-template.js +2 -2
- package/lib/rules/quote-props.js +2 -2
- package/lib/rules/quotes.js +16 -16
- package/lib/rules/radix.js +2 -2
- package/lib/rules/require-atomic-updates.js +2 -2
- package/lib/rules/require-await.js +2 -2
- package/lib/rules/require-jsdoc.js +2 -2
- package/lib/rules/require-unicode-regexp.js +5 -5
- package/lib/rules/require-yield.js +1 -1
- package/lib/rules/rest-spread-spacing.js +2 -2
- package/lib/rules/semi-spacing.js +2 -2
- package/lib/rules/semi-style.js +2 -2
- package/lib/rules/semi.js +30 -5
- package/lib/rules/sort-imports.js +2 -2
- package/lib/rules/sort-keys.js +2 -2
- package/lib/rules/sort-vars.js +2 -2
- package/lib/rules/space-before-blocks.js +2 -2
- package/lib/rules/space-before-function-paren.js +2 -2
- package/lib/rules/space-in-parens.js +2 -2
- package/lib/rules/space-infix-ops.js +2 -2
- package/lib/rules/space-unary-ops.js +2 -2
- package/lib/rules/spaced-comment.js +2 -2
- package/lib/rules/strict.js +1 -1
- package/lib/rules/switch-colon-spacing.js +2 -2
- package/lib/rules/symbol-description.js +2 -2
- package/lib/rules/template-curly-spacing.js +2 -2
- package/lib/rules/template-tag-spacing.js +2 -2
- package/lib/rules/unicode-bom.js +2 -2
- package/lib/rules/use-isnan.js +1 -1
- package/lib/rules/utils/ast-utils.js +55 -7
- package/lib/rules/utils/regular-expressions.js +2 -2
- package/lib/rules/valid-jsdoc.js +2 -2
- package/lib/rules/valid-typeof.js +9 -3
- package/lib/rules/vars-on-top.js +1 -1
- package/lib/rules/wrap-iife.js +2 -2
- package/lib/rules/wrap-regex.js +2 -2
- package/lib/rules/yield-star-spacing.js +2 -2
- package/lib/rules/yoda.js +4 -13
- package/lib/shared/string-utils.js +39 -1
- package/lib/shared/types.js +7 -3
- package/lib/unsupported-api.js +5 -2
- package/messages/eslintrc-incompat.js +98 -0
- package/messages/eslintrc-plugins.js +24 -0
- package/messages/invalid-rule-options.js +17 -0
- package/messages/invalid-rule-severity.js +13 -0
- package/messages/shared.js +18 -0
- package/package.json +15 -19
@@ -55,6 +55,7 @@ const LintResultCache = require("../cli-engine/lint-result-cache");
|
|
55
55
|
/** @typedef {import("../shared/types").ConfigData} ConfigData */
|
56
56
|
/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */
|
57
57
|
/** @typedef {import("../shared/types").LintMessage} LintMessage */
|
58
|
+
/** @typedef {import("../shared/types").LintResult} LintResult */
|
58
59
|
/** @typedef {import("../shared/types").ParserOptions} ParserOptions */
|
59
60
|
/** @typedef {import("../shared/types").Plugin} Plugin */
|
60
61
|
/** @typedef {import("../shared/types").ResultsMeta} ResultsMeta */
|
@@ -76,7 +77,7 @@ const LintResultCache = require("../cli-engine/lint-result-cache");
|
|
76
77
|
* @property {string[]} [fixTypes] Array of rule types to apply fixes for.
|
77
78
|
* @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file.
|
78
79
|
* @property {boolean} [ignore] False disables all ignore patterns except for the default ones.
|
79
|
-
* @property {string[]} [ignorePatterns] Ignore file patterns to use in addition to config ignores.
|
80
|
+
* @property {string[]} [ignorePatterns] Ignore file patterns to use in addition to config ignores. These patterns are relative to `cwd`.
|
80
81
|
* @property {ConfigData} [overrideConfig] Override config object, overrides all configs used with this instance
|
81
82
|
* @property {boolean|string} [overrideConfigFile] Searches for default config file when falsy;
|
82
83
|
* doesn't do any config file lookup when `true`; considered to be a config filename
|
@@ -102,7 +103,17 @@ const importedConfigFileModificationTime = new Map();
|
|
102
103
|
* @private
|
103
104
|
*/
|
104
105
|
function calculateStatsPerFile(messages) {
|
105
|
-
|
106
|
+
const stat = {
|
107
|
+
errorCount: 0,
|
108
|
+
fatalErrorCount: 0,
|
109
|
+
warningCount: 0,
|
110
|
+
fixableErrorCount: 0,
|
111
|
+
fixableWarningCount: 0
|
112
|
+
};
|
113
|
+
|
114
|
+
for (let i = 0; i < messages.length; i++) {
|
115
|
+
const message = messages[i];
|
116
|
+
|
106
117
|
if (message.fatal || message.severity === 2) {
|
107
118
|
stat.errorCount++;
|
108
119
|
if (message.fatal) {
|
@@ -117,37 +128,8 @@ function calculateStatsPerFile(messages) {
|
|
117
128
|
stat.fixableWarningCount++;
|
118
129
|
}
|
119
130
|
}
|
120
|
-
|
121
|
-
|
122
|
-
errorCount: 0,
|
123
|
-
fatalErrorCount: 0,
|
124
|
-
warningCount: 0,
|
125
|
-
fixableErrorCount: 0,
|
126
|
-
fixableWarningCount: 0
|
127
|
-
});
|
128
|
-
}
|
129
|
-
|
130
|
-
/**
|
131
|
-
* It will calculate the error and warning count for collection of results from all files
|
132
|
-
* @param {LintResult[]} results Collection of messages from all the files
|
133
|
-
* @returns {Object} Contains the stats
|
134
|
-
* @private
|
135
|
-
*/
|
136
|
-
function calculateStatsPerRun(results) {
|
137
|
-
return results.reduce((stat, result) => {
|
138
|
-
stat.errorCount += result.errorCount;
|
139
|
-
stat.fatalErrorCount += result.fatalErrorCount;
|
140
|
-
stat.warningCount += result.warningCount;
|
141
|
-
stat.fixableErrorCount += result.fixableErrorCount;
|
142
|
-
stat.fixableWarningCount += result.fixableWarningCount;
|
143
|
-
return stat;
|
144
|
-
}, {
|
145
|
-
errorCount: 0,
|
146
|
-
fatalErrorCount: 0,
|
147
|
-
warningCount: 0,
|
148
|
-
fixableErrorCount: 0,
|
149
|
-
fixableWarningCount: 0
|
150
|
-
});
|
131
|
+
}
|
132
|
+
return stat;
|
151
133
|
}
|
152
134
|
|
153
135
|
/**
|
@@ -261,7 +243,7 @@ function compareResultsByFilePath(a, b) {
|
|
261
243
|
* Searches from the current working directory up until finding the
|
262
244
|
* given flat config filename.
|
263
245
|
* @param {string} cwd The current working directory to search from.
|
264
|
-
* @returns {Promise<string|
|
246
|
+
* @returns {Promise<string|undefined>} The filename if found or `undefined` if not.
|
265
247
|
*/
|
266
248
|
function findFlatConfigFile(cwd) {
|
267
249
|
return findUp(
|
@@ -320,6 +302,45 @@ async function loadFlatConfigFile(filePath) {
|
|
320
302
|
return config;
|
321
303
|
}
|
322
304
|
|
305
|
+
/**
|
306
|
+
* Determines which config file to use. This is determined by seeing if an
|
307
|
+
* override config file was passed, and if so, using it; otherwise, as long
|
308
|
+
* as override config file is not explicitly set to `false`, it will search
|
309
|
+
* upwards from the cwd for a file named `eslint.config.js`.
|
310
|
+
* @param {import("./eslint").ESLintOptions} options The ESLint instance options.
|
311
|
+
* @returns {{configFilePath:string|undefined,basePath:string,error:Error|null}} Location information for
|
312
|
+
* the config file.
|
313
|
+
*/
|
314
|
+
async function locateConfigFileToUse({ configFile, cwd }) {
|
315
|
+
|
316
|
+
// determine where to load config file from
|
317
|
+
let configFilePath;
|
318
|
+
let basePath = cwd;
|
319
|
+
let error = null;
|
320
|
+
|
321
|
+
if (typeof configFile === "string") {
|
322
|
+
debug(`Override config file path is ${configFile}`);
|
323
|
+
configFilePath = path.resolve(cwd, configFile);
|
324
|
+
} else if (configFile !== false) {
|
325
|
+
debug("Searching for eslint.config.js");
|
326
|
+
configFilePath = await findFlatConfigFile(cwd);
|
327
|
+
|
328
|
+
if (configFilePath) {
|
329
|
+
basePath = path.resolve(path.dirname(configFilePath));
|
330
|
+
} else {
|
331
|
+
error = new Error("Could not find config file.");
|
332
|
+
}
|
333
|
+
|
334
|
+
}
|
335
|
+
|
336
|
+
return {
|
337
|
+
configFilePath,
|
338
|
+
basePath,
|
339
|
+
error
|
340
|
+
};
|
341
|
+
|
342
|
+
}
|
343
|
+
|
323
344
|
/**
|
324
345
|
* Calculates the config array for this run based on inputs.
|
325
346
|
* @param {FlatESLint} eslint The instance to create the config array for.
|
@@ -342,25 +363,13 @@ async function calculateConfigArray(eslint, {
|
|
342
363
|
return slots.configs;
|
343
364
|
}
|
344
365
|
|
345
|
-
|
346
|
-
let configFilePath;
|
347
|
-
let basePath = cwd;
|
348
|
-
|
349
|
-
if (typeof configFile === "string") {
|
350
|
-
debug(`Override config file path is ${configFile}`);
|
351
|
-
configFilePath = path.resolve(cwd, configFile);
|
352
|
-
} else if (configFile !== false) {
|
353
|
-
debug("Searching for eslint.config.js");
|
354
|
-
configFilePath = await findFlatConfigFile(cwd);
|
355
|
-
|
356
|
-
if (!configFilePath) {
|
357
|
-
throw new Error("Could not find config file.");
|
358
|
-
}
|
366
|
+
const { configFilePath, basePath, error } = await locateConfigFileToUse({ configFile, cwd });
|
359
367
|
|
360
|
-
|
368
|
+
// config file is required to calculate config
|
369
|
+
if (error) {
|
370
|
+
throw error;
|
361
371
|
}
|
362
372
|
|
363
|
-
|
364
373
|
const configs = new FlatConfigArray(baseConfig || [], { basePath, shouldIgnore });
|
365
374
|
|
366
375
|
// load config file
|
@@ -377,45 +386,39 @@ async function calculateConfigArray(eslint, {
|
|
377
386
|
// add in any configured defaults
|
378
387
|
configs.push(...slots.defaultConfigs);
|
379
388
|
|
380
|
-
let allIgnorePatterns = [];
|
381
|
-
|
382
389
|
// append command line ignore patterns
|
383
|
-
if (ignorePatterns) {
|
384
|
-
if (typeof ignorePatterns === "string") {
|
385
|
-
allIgnorePatterns.push(ignorePatterns);
|
386
|
-
} else {
|
387
|
-
allIgnorePatterns.push(...ignorePatterns);
|
388
|
-
}
|
389
|
-
}
|
390
|
+
if (ignorePatterns && ignorePatterns.length > 0) {
|
390
391
|
|
391
|
-
|
392
|
-
* If the config file basePath is different than the cwd, then
|
393
|
-
* the ignore patterns won't work correctly. Here, we adjust the
|
394
|
-
* ignore pattern to include the correct relative path. Patterns
|
395
|
-
* loaded from ignore files are always relative to the cwd, whereas
|
396
|
-
* the config file basePath can be an ancestor of the cwd.
|
397
|
-
*/
|
398
|
-
if (basePath !== cwd && allIgnorePatterns.length) {
|
392
|
+
let relativeIgnorePatterns;
|
399
393
|
|
400
|
-
|
394
|
+
/*
|
395
|
+
* If the config file basePath is different than the cwd, then
|
396
|
+
* the ignore patterns won't work correctly. Here, we adjust the
|
397
|
+
* ignore pattern to include the correct relative path. Patterns
|
398
|
+
* passed as `ignorePatterns` are relative to the cwd, whereas
|
399
|
+
* the config file basePath can be an ancestor of the cwd.
|
400
|
+
*/
|
401
|
+
if (basePath === cwd) {
|
402
|
+
relativeIgnorePatterns = ignorePatterns;
|
403
|
+
} else {
|
401
404
|
|
402
|
-
|
403
|
-
const negated = pattern.startsWith("!");
|
404
|
-
const basePattern = negated ? pattern.slice(1) : pattern;
|
405
|
+
const relativeIgnorePath = path.relative(basePath, cwd);
|
405
406
|
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
}
|
407
|
+
relativeIgnorePatterns = ignorePatterns.map(pattern => {
|
408
|
+
const negated = pattern.startsWith("!");
|
409
|
+
const basePattern = negated ? pattern.slice(1) : pattern;
|
410
410
|
|
411
|
-
|
411
|
+
return (negated ? "!" : "") +
|
412
|
+
path.posix.join(relativeIgnorePath, basePattern);
|
413
|
+
});
|
414
|
+
}
|
412
415
|
|
413
416
|
/*
|
414
417
|
* Ignore patterns are added to the end of the config array
|
415
418
|
* so they can override default ignores.
|
416
419
|
*/
|
417
420
|
configs.push({
|
418
|
-
ignores:
|
421
|
+
ignores: relativeIgnorePatterns
|
419
422
|
});
|
420
423
|
}
|
421
424
|
|
@@ -528,43 +531,6 @@ function shouldMessageBeFixed(message, config, fixTypes) {
|
|
528
531
|
return Boolean(rule && rule.meta && fixTypes.has(rule.meta.type));
|
529
532
|
}
|
530
533
|
|
531
|
-
/**
|
532
|
-
* Collect used deprecated rules.
|
533
|
-
* @param {Array<FlatConfig>} configs The configs to evaluate.
|
534
|
-
* @returns {IterableIterator<DeprecatedRuleInfo>} Used deprecated rules.
|
535
|
-
*/
|
536
|
-
function *iterateRuleDeprecationWarnings(configs) {
|
537
|
-
const processedRuleIds = new Set();
|
538
|
-
|
539
|
-
for (const config of configs) {
|
540
|
-
for (const [ruleId, ruleConfig] of Object.entries(config.rules)) {
|
541
|
-
|
542
|
-
// Skip if it was processed.
|
543
|
-
if (processedRuleIds.has(ruleId)) {
|
544
|
-
continue;
|
545
|
-
}
|
546
|
-
processedRuleIds.add(ruleId);
|
547
|
-
|
548
|
-
// Skip if it's not used.
|
549
|
-
if (!getRuleSeverity(ruleConfig)) {
|
550
|
-
continue;
|
551
|
-
}
|
552
|
-
const rule = getRuleFromConfig(ruleId, config);
|
553
|
-
|
554
|
-
// Skip if it's not deprecated.
|
555
|
-
if (!(rule && rule.meta && rule.meta.deprecated)) {
|
556
|
-
continue;
|
557
|
-
}
|
558
|
-
|
559
|
-
// This rule was used and deprecated.
|
560
|
-
yield {
|
561
|
-
ruleId,
|
562
|
-
replacedBy: rule.meta.replacedBy || []
|
563
|
-
};
|
564
|
-
}
|
565
|
-
}
|
566
|
-
}
|
567
|
-
|
568
534
|
/**
|
569
535
|
* Creates an error to be thrown when an array of results passed to `getRulesMetaForResults` was not created by the current engine.
|
570
536
|
* @returns {TypeError} An error object.
|
@@ -610,7 +576,6 @@ class FlatESLint {
|
|
610
576
|
cacheFilePath,
|
611
577
|
lintResultCache,
|
612
578
|
defaultConfigs,
|
613
|
-
defaultIgnores: () => false,
|
614
579
|
configs: null
|
615
580
|
});
|
616
581
|
|
@@ -749,12 +714,10 @@ class FlatESLint {
|
|
749
714
|
}
|
750
715
|
const rule = getRuleFromConfig(ruleId, config);
|
751
716
|
|
752
|
-
//
|
753
|
-
if (
|
754
|
-
|
717
|
+
// ignore unknown rules
|
718
|
+
if (rule) {
|
719
|
+
resultRules.set(ruleId, rule);
|
755
720
|
}
|
756
|
-
|
757
|
-
resultRules.set(ruleId, rule);
|
758
721
|
}
|
759
722
|
}
|
760
723
|
|
@@ -789,7 +752,6 @@ class FlatESLint {
|
|
789
752
|
errorOnUnmatchedPattern
|
790
753
|
} = eslintOptions;
|
791
754
|
const startTime = Date.now();
|
792
|
-
const usedConfigs = [];
|
793
755
|
const fixTypesSet = fixTypes ? new Set(fixTypes) : null;
|
794
756
|
|
795
757
|
// Delete cache file; should this be done here?
|
@@ -847,15 +809,6 @@ class FlatESLint {
|
|
847
809
|
return void 0;
|
848
810
|
}
|
849
811
|
|
850
|
-
/*
|
851
|
-
* Store used configs for:
|
852
|
-
* - this method uses to collect used deprecated rules.
|
853
|
-
* - `--fix-type` option uses to get the loaded rule's meta data.
|
854
|
-
*/
|
855
|
-
if (!usedConfigs.includes(config)) {
|
856
|
-
usedConfigs.push(config);
|
857
|
-
}
|
858
|
-
|
859
812
|
// Skip if there is cached result.
|
860
813
|
if (lintResultCache) {
|
861
814
|
const cachedResult =
|
@@ -924,22 +877,10 @@ class FlatESLint {
|
|
924
877
|
lintResultCache.reconcile();
|
925
878
|
}
|
926
879
|
|
927
|
-
let usedDeprecatedRules;
|
928
880
|
const finalResults = results.filter(result => !!result);
|
929
881
|
|
930
882
|
return processLintReport(this, {
|
931
|
-
results: finalResults
|
932
|
-
...calculateStatsPerRun(finalResults),
|
933
|
-
|
934
|
-
// Initialize it lazily because CLI and `ESLint` API don't use it.
|
935
|
-
get usedDeprecatedRules() {
|
936
|
-
if (!usedDeprecatedRules) {
|
937
|
-
usedDeprecatedRules = Array.from(
|
938
|
-
iterateRuleDeprecationWarnings(usedConfigs)
|
939
|
-
);
|
940
|
-
}
|
941
|
-
return usedDeprecatedRules;
|
942
|
-
}
|
883
|
+
results: finalResults
|
943
884
|
});
|
944
885
|
}
|
945
886
|
|
@@ -1001,7 +942,6 @@ class FlatESLint {
|
|
1001
942
|
const results = [];
|
1002
943
|
const startTime = Date.now();
|
1003
944
|
const resolvedFilename = path.resolve(cwd, filePath || "__placeholder__.js");
|
1004
|
-
let config;
|
1005
945
|
|
1006
946
|
// Clear the last used config arrays.
|
1007
947
|
if (resolvedFilename && await this.isPathIgnored(resolvedFilename)) {
|
@@ -1010,9 +950,6 @@ class FlatESLint {
|
|
1010
950
|
}
|
1011
951
|
} else {
|
1012
952
|
|
1013
|
-
// TODO: Needed?
|
1014
|
-
config = configs.getConfig(resolvedFilename);
|
1015
|
-
|
1016
953
|
// Do lint.
|
1017
954
|
results.push(verifyText({
|
1018
955
|
text: code,
|
@@ -1027,21 +964,9 @@ class FlatESLint {
|
|
1027
964
|
}
|
1028
965
|
|
1029
966
|
debug(`Linting complete in: ${Date.now() - startTime}ms`);
|
1030
|
-
let usedDeprecatedRules;
|
1031
967
|
|
1032
968
|
return processLintReport(this, {
|
1033
|
-
results
|
1034
|
-
...calculateStatsPerRun(results),
|
1035
|
-
|
1036
|
-
// Initialize it lazily because CLI and `ESLint` API don't use it.
|
1037
|
-
get usedDeprecatedRules() {
|
1038
|
-
if (!usedDeprecatedRules) {
|
1039
|
-
usedDeprecatedRules = Array.from(
|
1040
|
-
iterateRuleDeprecationWarnings(config)
|
1041
|
-
);
|
1042
|
-
}
|
1043
|
-
return usedDeprecatedRules;
|
1044
|
-
}
|
969
|
+
results
|
1045
970
|
});
|
1046
971
|
|
1047
972
|
}
|
@@ -1160,6 +1085,19 @@ class FlatESLint {
|
|
1160
1085
|
return configs.getConfig(absolutePath);
|
1161
1086
|
}
|
1162
1087
|
|
1088
|
+
/**
|
1089
|
+
* Finds the config file being used by this instance based on the options
|
1090
|
+
* passed to the constructor.
|
1091
|
+
* @returns {string|undefined} The path to the config file being used or
|
1092
|
+
* `undefined` if no config file is being used.
|
1093
|
+
*/
|
1094
|
+
async findConfigFile() {
|
1095
|
+
const options = privateMembers.get(this).options;
|
1096
|
+
const { configFilePath } = await locateConfigFileToUse(options);
|
1097
|
+
|
1098
|
+
return configFilePath;
|
1099
|
+
}
|
1100
|
+
|
1163
1101
|
/**
|
1164
1102
|
* Checks if a given path is ignored by ESLint.
|
1165
1103
|
* @param {string} filePath The path of the file to check.
|
@@ -1172,11 +1110,31 @@ class FlatESLint {
|
|
1172
1110
|
}
|
1173
1111
|
}
|
1174
1112
|
|
1113
|
+
/**
|
1114
|
+
* Returns whether flat config should be used.
|
1115
|
+
* @returns {Promise<boolean>} Whether flat config should be used.
|
1116
|
+
*/
|
1117
|
+
async function shouldUseFlatConfig() {
|
1118
|
+
switch (process.env.ESLINT_USE_FLAT_CONFIG) {
|
1119
|
+
case "true":
|
1120
|
+
return true;
|
1121
|
+
case "false":
|
1122
|
+
return false;
|
1123
|
+
default:
|
1124
|
+
|
1125
|
+
/*
|
1126
|
+
* If neither explicitly enabled nor disabled, then use the presence
|
1127
|
+
* of a flat config file to determine enablement.
|
1128
|
+
*/
|
1129
|
+
return !!(await findFlatConfigFile(process.cwd()));
|
1130
|
+
}
|
1131
|
+
}
|
1132
|
+
|
1175
1133
|
//------------------------------------------------------------------------------
|
1176
1134
|
// Public Interface
|
1177
1135
|
//------------------------------------------------------------------------------
|
1178
1136
|
|
1179
1137
|
module.exports = {
|
1180
1138
|
FlatESLint,
|
1181
|
-
|
1139
|
+
shouldUseFlatConfig
|
1182
1140
|
};
|
@@ -5,6 +5,16 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Typedefs
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
/** @typedef {import("../shared/types").LintMessage} LintMessage */
|
13
|
+
|
14
|
+
//------------------------------------------------------------------------------
|
15
|
+
// Module Definition
|
16
|
+
//------------------------------------------------------------------------------
|
17
|
+
|
8
18
|
const escapeRegExp = require("escape-string-regexp");
|
9
19
|
|
10
20
|
/**
|
@@ -196,7 +206,7 @@ function processUnusedDisableDirectives(allDirectives) {
|
|
196
206
|
* @param {Object} options options for applying directives. This is the same as the options
|
197
207
|
* for the exported function, except that `reportUnusedDisableDirectives` is not supported
|
198
208
|
* (this function always reports unused disable directives).
|
199
|
-
* @returns {{problems:
|
209
|
+
* @returns {{problems: LintMessage[], unusedDisableDirectives: LintMessage[]}} An object with a list
|
200
210
|
* of problems (including suppressed ones) and unused eslint-disable directives
|
201
211
|
*/
|
202
212
|
function applyDirectives(options) {
|
@@ -109,7 +109,7 @@ module.exports = {
|
|
109
109
|
text += "final[label=\"\",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];\n";
|
110
110
|
}
|
111
111
|
if (codePath.thrownSegments.length > 0) {
|
112
|
-
text += "thrown[label=\"✘\",shape=circle,width=0.3,height=0.3,fixedsize];\n";
|
112
|
+
text += "thrown[label=\"✘\",shape=circle,width=0.3,height=0.3,fixedsize=true];\n";
|
113
113
|
}
|
114
114
|
|
115
115
|
const traceMap = Object.create(null);
|
@@ -19,6 +19,12 @@ const levn = require("levn"),
|
|
19
19
|
|
20
20
|
const debug = require("debug")("eslint:config-comment-parser");
|
21
21
|
|
22
|
+
//------------------------------------------------------------------------------
|
23
|
+
// Typedefs
|
24
|
+
//------------------------------------------------------------------------------
|
25
|
+
|
26
|
+
/** @typedef {import("../shared/types").LintMessage} LintMessage */
|
27
|
+
|
22
28
|
//------------------------------------------------------------------------------
|
23
29
|
// Public Interface
|
24
30
|
//------------------------------------------------------------------------------
|
@@ -61,7 +67,7 @@ module.exports = class ConfigCommentParser {
|
|
61
67
|
* Parses a JSON-like config.
|
62
68
|
* @param {string} string The string to parse.
|
63
69
|
* @param {Object} location Start line and column of comments for potential error message.
|
64
|
-
* @returns {({success: true, config: Object}|{success: false, error:
|
70
|
+
* @returns {({success: true, config: Object}|{success: false, error: LintMessage})} Result map object
|
65
71
|
*/
|
66
72
|
parseJsonConfig(string, location) {
|
67
73
|
debug("Parsing JSON config");
|
@@ -109,7 +115,8 @@ module.exports = class ConfigCommentParser {
|
|
109
115
|
severity: 2,
|
110
116
|
message: `Failed to parse JSON from '${normalizedString}': ${ex.message}`,
|
111
117
|
line: location.start.line,
|
112
|
-
column: location.start.column + 1
|
118
|
+
column: location.start.column + 1,
|
119
|
+
nodeType: null
|
113
120
|
}
|
114
121
|
};
|
115
122
|
|
package/lib/linter/linter.js
CHANGED
@@ -364,7 +364,7 @@ function extractDirectiveComment(value) {
|
|
364
364
|
* @param {ASTNode} ast The top node of the AST.
|
365
365
|
* @param {function(string): {create: Function}} ruleMapper A map from rule IDs to defined rules
|
366
366
|
* @param {string|null} warnInlineConfig If a string then it should warn directive comments as disabled. The string value is the config name what the setting came from.
|
367
|
-
* @returns {{configuredRules: Object, enabledGlobals: {value:string,comment:Token}[], exportedVariables: Object, problems:
|
367
|
+
* @returns {{configuredRules: Object, enabledGlobals: {value:string,comment:Token}[], exportedVariables: Object, problems: LintMessage[], disableDirectives: DisableDirective[]}}
|
368
368
|
* A collection of the directive comments that were found, along with any problems that occurred when parsing
|
369
369
|
*/
|
370
370
|
function getDirectiveComments(ast, ruleMapper, warnInlineConfig) {
|
@@ -592,7 +592,7 @@ function findEslintEnv(text) {
|
|
592
592
|
* Convert "/path/to/<text>" to "<text>".
|
593
593
|
* `CLIEngine#executeOnText()` method gives "/path/to/<text>" if the filename
|
594
594
|
* was omitted because `configArray.extractConfig()` requires an absolute path.
|
595
|
-
* But the linter should pass `<text>` to `RuleContext#
|
595
|
+
* But the linter should pass `<text>` to `RuleContext#filename` in that
|
596
596
|
* case.
|
597
597
|
* Also, code blocks can have their virtual filename. If the parent filename was
|
598
598
|
* `<text>`, the virtual filename is `<text>/0_foo.js` or something like (i.e.,
|
@@ -775,7 +775,7 @@ function analyzeScope(ast, languageOptions, visitorKeys) {
|
|
775
775
|
* @param {string} text The text to parse.
|
776
776
|
* @param {LanguageOptions} languageOptions Options to pass to the parser
|
777
777
|
* @param {string} filePath The path to the file being parsed.
|
778
|
-
* @returns {{success: false, error:
|
778
|
+
* @returns {{success: false, error: LintMessage}|{success: true, sourceCode: SourceCode}}
|
779
779
|
* An object containing the AST and parser services if parsing was successful, or the error if parsing failed
|
780
780
|
* @private
|
781
781
|
*/
|
@@ -851,7 +851,8 @@ function parse(text, languageOptions, filePath) {
|
|
851
851
|
severity: 2,
|
852
852
|
message,
|
853
853
|
line: ex.lineNumber,
|
854
|
-
column: ex.column
|
854
|
+
column: ex.column,
|
855
|
+
nodeType: null
|
855
856
|
}
|
856
857
|
};
|
857
858
|
}
|
@@ -902,7 +903,7 @@ const BASE_TRAVERSAL_CONTEXT = Object.freeze(
|
|
902
903
|
(contextInfo, methodName) =>
|
903
904
|
Object.assign(contextInfo, {
|
904
905
|
[methodName](...args) {
|
905
|
-
return this.
|
906
|
+
return this.sourceCode[DEPRECATED_SOURCECODE_PASSTHROUGHS[methodName]](...args);
|
906
907
|
}
|
907
908
|
}),
|
908
909
|
{}
|
@@ -921,7 +922,7 @@ const BASE_TRAVERSAL_CONTEXT = Object.freeze(
|
|
921
922
|
* @param {boolean} disableFixes If true, it doesn't make `fix` properties.
|
922
923
|
* @param {string | undefined} cwd cwd of the cli
|
923
924
|
* @param {string} physicalFilename The full path of the file on disk without any code block information
|
924
|
-
* @returns {
|
925
|
+
* @returns {LintMessage[]} An array of reported problems
|
925
926
|
*/
|
926
927
|
function runRules(sourceCode, configuredRules, ruleMapper, parserName, languageOptions, settings, filename, disableFixes, cwd, physicalFilename) {
|
927
928
|
const emitter = createEmitter();
|
@@ -951,10 +952,14 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserName, languageO
|
|
951
952
|
getAncestors: () => sourceCode.getAncestors(currentNode),
|
952
953
|
getDeclaredVariables: node => sourceCode.getDeclaredVariables(node),
|
953
954
|
getCwd: () => cwd,
|
955
|
+
cwd,
|
954
956
|
getFilename: () => filename,
|
957
|
+
filename,
|
955
958
|
getPhysicalFilename: () => physicalFilename || filename,
|
959
|
+
physicalFilename: physicalFilename || filename,
|
956
960
|
getScope: () => sourceCode.getScope(currentNode),
|
957
961
|
getSourceCode: () => sourceCode,
|
962
|
+
sourceCode,
|
958
963
|
markVariableAsUsed: name => sourceCode.markVariableAsUsed(name, currentNode),
|
959
964
|
parserOptions: {
|
960
965
|
...languageOptions.parserOptions
|
@@ -1249,7 +1254,8 @@ class Linter {
|
|
1249
1254
|
severity: 2,
|
1250
1255
|
message: `Configured parser '${config.parser}' was not found.`,
|
1251
1256
|
line: 0,
|
1252
|
-
column: 0
|
1257
|
+
column: 0,
|
1258
|
+
nodeType: null
|
1253
1259
|
}];
|
1254
1260
|
}
|
1255
1261
|
parserName = config.parser;
|
@@ -1460,7 +1466,8 @@ class Linter {
|
|
1460
1466
|
severity: 2,
|
1461
1467
|
message,
|
1462
1468
|
line: ex.lineNumber,
|
1463
|
-
column: ex.column
|
1469
|
+
column: ex.column,
|
1470
|
+
nodeType: null
|
1464
1471
|
}
|
1465
1472
|
];
|
1466
1473
|
}
|
@@ -1725,7 +1732,8 @@ class Linter {
|
|
1725
1732
|
severity: 1,
|
1726
1733
|
message: `No matching configuration found for ${filename}.`,
|
1727
1734
|
line: 0,
|
1728
|
-
column: 0
|
1735
|
+
column: 0,
|
1736
|
+
nodeType: null
|
1729
1737
|
}
|
1730
1738
|
];
|
1731
1739
|
}
|
@@ -1790,7 +1798,8 @@ class Linter {
|
|
1790
1798
|
severity: 2,
|
1791
1799
|
message,
|
1792
1800
|
line: ex.lineNumber,
|
1793
|
-
column: ex.column
|
1801
|
+
column: ex.column,
|
1802
|
+
nodeType: null
|
1794
1803
|
}
|
1795
1804
|
];
|
1796
1805
|
}
|
@@ -1836,7 +1845,7 @@ class Linter {
|
|
1836
1845
|
/**
|
1837
1846
|
* Given a list of reported problems, distinguish problems between normal messages and suppressed messages.
|
1838
1847
|
* The normal messages will be returned and the suppressed messages will be stored as lastSuppressedMessages.
|
1839
|
-
* @param {
|
1848
|
+
* @param {Array<LintMessage|SuppressedLintMessage>} problems A list of reported problems.
|
1840
1849
|
* @returns {LintMessage[]} A list of LintMessage.
|
1841
1850
|
*/
|
1842
1851
|
_distinguishSuppressedMessages(problems) {
|