eslint 8.0.0-beta.0 → 8.0.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 +4 -4
- package/bin/eslint.js +1 -1
- package/conf/eslint-recommended.js +1 -1
- package/conf/{category-list.json → rule-type-list.json} +4 -7
- package/lib/cli-engine/cli-engine.js +11 -3
- package/lib/cli-engine/file-enumerator.js +4 -3
- package/lib/cli-engine/formatters/html.js +1 -1
- package/lib/cli-engine/hash.js +2 -2
- package/lib/cli-engine/xml-escape.js +1 -1
- package/lib/config/flat-config-array.js +2 -2
- package/lib/config/flat-config-schema.js +1 -1
- package/lib/config/rule-validator.js +25 -8
- package/lib/eslint/eslint.js +4 -0
- package/lib/init/autoconfig.js +17 -18
- package/lib/init/config-file.js +3 -3
- package/lib/init/config-initializer.js +11 -10
- package/lib/init/config-rule.js +15 -16
- package/lib/init/npm-utils.js +16 -15
- package/lib/init/source-code-utils.js +6 -5
- package/lib/linter/apply-disable-directives.js +80 -11
- package/lib/linter/code-path-analysis/code-path-analyzer.js +115 -36
- package/lib/linter/code-path-analysis/code-path-segment.js +0 -1
- package/lib/linter/code-path-analysis/code-path-state.js +4 -1
- package/lib/linter/code-path-analysis/code-path.js +14 -5
- package/lib/linter/code-path-analysis/debug-helpers.js +2 -2
- package/lib/linter/code-path-analysis/fork-context.js +0 -1
- package/lib/linter/code-path-analysis/id-generator.js +0 -1
- package/lib/linter/config-comment-parser.js +1 -1
- package/lib/linter/linter.js +51 -22
- package/lib/linter/node-event-generator.js +0 -1
- package/lib/linter/report-translator.js +12 -12
- package/lib/linter/rules.js +3 -0
- package/lib/linter/safe-emitter.js +2 -2
- package/lib/linter/source-code-fixer.js +2 -2
- package/lib/linter/timing.js +2 -2
- package/lib/rule-tester/rule-tester.js +12 -2
- package/lib/rules/accessor-pairs.js +0 -1
- package/lib/rules/array-bracket-newline.js +0 -1
- package/lib/rules/array-bracket-spacing.js +0 -1
- package/lib/rules/array-callback-return.js +0 -1
- package/lib/rules/array-element-newline.js +0 -1
- package/lib/rules/arrow-body-style.js +0 -1
- package/lib/rules/arrow-parens.js +0 -1
- package/lib/rules/arrow-spacing.js +0 -1
- package/lib/rules/block-scoped-var.js +0 -1
- package/lib/rules/block-spacing.js +0 -1
- package/lib/rules/brace-style.js +0 -1
- package/lib/rules/callback-return.js +1 -1
- package/lib/rules/camelcase.js +17 -19
- package/lib/rules/capitalized-comments.js +0 -1
- package/lib/rules/class-methods-use-this.js +51 -9
- package/lib/rules/comma-dangle.js +0 -1
- package/lib/rules/comma-spacing.js +0 -1
- package/lib/rules/comma-style.js +0 -1
- package/lib/rules/complexity.js +47 -56
- package/lib/rules/computed-property-spacing.js +0 -1
- package/lib/rules/consistent-return.js +0 -1
- package/lib/rules/consistent-this.js +1 -2
- package/lib/rules/constructor-super.js +0 -1
- package/lib/rules/curly.js +0 -1
- package/lib/rules/default-case-last.js +0 -1
- package/lib/rules/default-case.js +2 -3
- package/lib/rules/default-param-last.js +1 -2
- package/lib/rules/dot-location.js +0 -1
- package/lib/rules/dot-notation.js +0 -1
- package/lib/rules/eol-last.js +6 -2
- package/lib/rules/eqeqeq.js +1 -2
- package/lib/rules/for-direction.js +0 -1
- package/lib/rules/func-call-spacing.js +0 -1
- package/lib/rules/func-name-matching.js +9 -6
- package/lib/rules/func-names.js +0 -1
- package/lib/rules/func-style.js +0 -1
- package/lib/rules/function-call-argument-newline.js +0 -1
- package/lib/rules/function-paren-newline.js +1 -1
- package/lib/rules/generator-star-spacing.js +0 -1
- package/lib/rules/getter-return.js +0 -1
- package/lib/rules/global-require.js +1 -1
- package/lib/rules/grouped-accessor-pairs.js +0 -1
- package/lib/rules/guard-for-in.js +0 -1
- package/lib/rules/handle-callback-err.js +1 -1
- package/lib/rules/id-blacklist.js +1 -1
- package/lib/rules/id-denylist.js +0 -1
- package/lib/rules/id-length.js +0 -1
- package/lib/rules/id-match.js +0 -1
- package/lib/rules/implicit-arrow-linebreak.js +0 -1
- package/lib/rules/indent-legacy.js +1 -1
- package/lib/rules/indent.js +7 -10
- package/lib/rules/index.js +1 -1
- package/lib/rules/init-declarations.js +0 -1
- package/lib/rules/jsx-quotes.js +0 -1
- package/lib/rules/key-spacing.js +4 -5
- package/lib/rules/keyword-spacing.js +19 -3
- package/lib/rules/line-comment-position.js +0 -1
- package/lib/rules/linebreak-style.js +0 -1
- package/lib/rules/lines-around-comment.js +0 -1
- package/lib/rules/lines-around-directive.js +1 -2
- package/lib/rules/lines-between-class-members.js +50 -3
- package/lib/rules/max-classes-per-file.js +31 -8
- package/lib/rules/max-depth.js +0 -1
- package/lib/rules/max-len.js +1 -2
- package/lib/rules/max-lines-per-function.js +1 -2
- package/lib/rules/max-lines.js +0 -1
- package/lib/rules/max-nested-callbacks.js +0 -1
- package/lib/rules/max-params.js +0 -1
- package/lib/rules/max-statements-per-line.js +0 -1
- package/lib/rules/max-statements.js +0 -1
- package/lib/rules/multiline-comment-style.js +0 -1
- package/lib/rules/multiline-ternary.js +0 -1
- package/lib/rules/new-cap.js +2 -2
- package/lib/rules/new-parens.js +0 -1
- package/lib/rules/newline-after-var.js +4 -5
- package/lib/rules/newline-before-return.js +2 -3
- package/lib/rules/newline-per-chained-call.js +1 -2
- package/lib/rules/no-alert.js +0 -1
- package/lib/rules/no-array-constructor.js +0 -1
- package/lib/rules/no-async-promise-executor.js +0 -1
- package/lib/rules/no-await-in-loop.js +0 -1
- package/lib/rules/no-bitwise.js +5 -6
- package/lib/rules/no-buffer-constructor.js +1 -1
- package/lib/rules/no-caller.js +0 -1
- package/lib/rules/no-case-declarations.js +0 -1
- package/lib/rules/no-catch-shadow.js +0 -1
- package/lib/rules/no-class-assign.js +0 -1
- package/lib/rules/no-compare-neg-zero.js +0 -1
- package/lib/rules/no-cond-assign.js +0 -1
- package/lib/rules/no-confusing-arrow.js +0 -1
- package/lib/rules/no-console.js +0 -1
- package/lib/rules/no-const-assign.js +0 -1
- package/lib/rules/no-constant-condition.js +0 -1
- package/lib/rules/no-constructor-return.js +0 -1
- package/lib/rules/no-continue.js +0 -1
- package/lib/rules/no-control-regex.js +0 -1
- package/lib/rules/no-debugger.js +0 -1
- package/lib/rules/no-delete-var.js +0 -1
- package/lib/rules/no-div-regex.js +0 -1
- package/lib/rules/no-dupe-args.js +0 -1
- package/lib/rules/no-dupe-class-members.js +0 -1
- package/lib/rules/no-dupe-else-if.js +0 -1
- package/lib/rules/no-dupe-keys.js +0 -2
- package/lib/rules/no-duplicate-case.js +0 -1
- package/lib/rules/no-duplicate-imports.js +0 -1
- package/lib/rules/no-else-return.js +0 -1
- package/lib/rules/no-empty-character-class.js +0 -1
- package/lib/rules/no-empty-function.js +0 -1
- package/lib/rules/no-empty-pattern.js +0 -1
- package/lib/rules/no-empty.js +0 -1
- package/lib/rules/no-eq-null.js +0 -1
- package/lib/rules/no-eval.js +0 -1
- package/lib/rules/no-ex-assign.js +0 -1
- package/lib/rules/no-extend-native.js +0 -1
- package/lib/rules/no-extra-bind.js +0 -1
- package/lib/rules/no-extra-boolean-cast.js +1 -1
- package/lib/rules/no-extra-label.js +0 -1
- package/lib/rules/no-extra-parens.js +0 -1
- package/lib/rules/no-extra-semi.js +0 -1
- package/lib/rules/no-fallthrough.js +0 -1
- package/lib/rules/no-floating-decimal.js +0 -1
- package/lib/rules/no-func-assign.js +0 -1
- package/lib/rules/no-global-assign.js +0 -1
- package/lib/rules/no-implicit-coercion.js +0 -1
- package/lib/rules/no-implicit-globals.js +0 -1
- package/lib/rules/no-implied-eval.js +0 -1
- package/lib/rules/no-import-assign.js +0 -1
- package/lib/rules/no-inline-comments.js +0 -1
- package/lib/rules/no-inner-declarations.js +0 -1
- package/lib/rules/no-invalid-regexp.js +0 -1
- package/lib/rules/no-invalid-this.js +0 -1
- package/lib/rules/no-irregular-whitespace.js +0 -1
- package/lib/rules/no-iterator.js +0 -1
- package/lib/rules/no-label-var.js +0 -1
- package/lib/rules/no-labels.js +0 -1
- package/lib/rules/no-lone-blocks.js +0 -1
- package/lib/rules/no-lonely-if.js +0 -1
- package/lib/rules/no-loop-func.js +1 -2
- package/lib/rules/no-loss-of-precision.js +0 -1
- package/lib/rules/no-magic-numbers.js +0 -1
- package/lib/rules/no-misleading-character-class.js +0 -1
- package/lib/rules/no-mixed-operators.js +1 -2
- package/lib/rules/no-mixed-requires.js +1 -1
- package/lib/rules/no-mixed-spaces-and-tabs.js +0 -1
- package/lib/rules/no-multi-assign.js +0 -1
- package/lib/rules/no-multi-spaces.js +0 -1
- package/lib/rules/no-multi-str.js +0 -1
- package/lib/rules/no-multiple-empty-lines.js +0 -1
- package/lib/rules/no-native-reassign.js +0 -1
- package/lib/rules/no-negated-condition.js +0 -1
- package/lib/rules/no-negated-in-lhs.js +0 -1
- package/lib/rules/no-nested-ternary.js +0 -1
- package/lib/rules/no-new-func.js +34 -7
- package/lib/rules/no-new-object.js +0 -1
- package/lib/rules/no-new-require.js +1 -1
- package/lib/rules/no-new-symbol.js +0 -1
- package/lib/rules/no-new-wrappers.js +0 -1
- package/lib/rules/no-new.js +0 -1
- package/lib/rules/no-nonoctal-decimal-escape.js +0 -1
- package/lib/rules/no-obj-calls.js +0 -1
- package/lib/rules/no-octal-escape.js +0 -1
- package/lib/rules/no-octal.js +0 -1
- package/lib/rules/no-param-reassign.js +0 -1
- package/lib/rules/no-path-concat.js +1 -1
- package/lib/rules/no-plusplus.js +0 -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 +0 -1
- package/lib/rules/no-proto.js +0 -1
- package/lib/rules/no-prototype-builtins.js +0 -1
- package/lib/rules/no-redeclare.js +0 -1
- package/lib/rules/no-regex-spaces.js +0 -1
- package/lib/rules/no-restricted-exports.js +0 -1
- package/lib/rules/no-restricted-globals.js +1 -2
- package/lib/rules/no-restricted-imports.js +5 -6
- package/lib/rules/no-restricted-modules.js +3 -3
- package/lib/rules/no-restricted-properties.js +2 -3
- package/lib/rules/no-restricted-syntax.js +1 -2
- package/lib/rules/no-return-assign.js +0 -1
- package/lib/rules/no-return-await.js +0 -1
- package/lib/rules/no-script-url.js +1 -3
- package/lib/rules/no-self-assign.js +0 -1
- package/lib/rules/no-self-compare.js +0 -1
- package/lib/rules/no-sequences.js +0 -1
- package/lib/rules/no-setter-return.js +0 -1
- package/lib/rules/no-shadow-restricted-names.js +0 -1
- package/lib/rules/no-shadow.js +1 -2
- package/lib/rules/no-spaced-func.js +0 -1
- package/lib/rules/no-sparse-arrays.js +0 -1
- package/lib/rules/no-sync.js +1 -3
- package/lib/rules/no-tabs.js +0 -1
- package/lib/rules/no-template-curly-in-string.js +0 -1
- package/lib/rules/no-ternary.js +0 -1
- package/lib/rules/no-this-before-super.js +0 -1
- package/lib/rules/no-throw-literal.js +0 -1
- package/lib/rules/no-trailing-spaces.js +0 -1
- package/lib/rules/no-undef-init.js +9 -61
- package/lib/rules/no-undef.js +0 -1
- package/lib/rules/no-undefined.js +0 -1
- package/lib/rules/no-underscore-dangle.js +0 -1
- package/lib/rules/no-unexpected-multiline.js +0 -1
- package/lib/rules/no-unmodified-loop-condition.js +0 -1
- package/lib/rules/no-unneeded-ternary.js +0 -1
- package/lib/rules/no-unreachable-loop.js +0 -1
- package/lib/rules/no-unreachable.js +26 -25
- package/lib/rules/no-unsafe-finally.js +0 -1
- package/lib/rules/no-unsafe-negation.js +0 -1
- package/lib/rules/no-unsafe-optional-chaining.js +0 -1
- package/lib/rules/no-unused-expressions.js +4 -5
- package/lib/rules/no-unused-labels.js +0 -1
- package/lib/rules/no-unused-vars.js +26 -28
- package/lib/rules/no-use-before-define.js +0 -1
- package/lib/rules/no-useless-backreference.js +0 -1
- package/lib/rules/no-useless-call.js +0 -1
- package/lib/rules/no-useless-catch.js +0 -1
- package/lib/rules/no-useless-computed-key.js +1 -1
- package/lib/rules/no-useless-concat.js +0 -1
- package/lib/rules/no-useless-constructor.js +0 -1
- package/lib/rules/no-useless-escape.js +9 -9
- package/lib/rules/no-useless-rename.js +0 -1
- package/lib/rules/no-useless-return.js +0 -1
- package/lib/rules/no-var.js +0 -1
- package/lib/rules/no-void.js +0 -1
- package/lib/rules/no-warning-comments.js +0 -1
- package/lib/rules/no-whitespace-before-property.js +0 -1
- package/lib/rules/no-with.js +0 -1
- package/lib/rules/nonblock-statement-body-position.js +0 -1
- package/lib/rules/object-curly-newline.js +0 -1
- package/lib/rules/object-curly-spacing.js +0 -1
- package/lib/rules/object-property-newline.js +0 -1
- package/lib/rules/object-shorthand.js +3 -8
- package/lib/rules/one-var-declaration-per-line.js +0 -1
- package/lib/rules/one-var.js +1 -2
- package/lib/rules/operator-assignment.js +6 -7
- package/lib/rules/operator-linebreak.js +0 -1
- package/lib/rules/padded-blocks.js +1 -1
- package/lib/rules/padding-line-between-statements.js +0 -1
- package/lib/rules/prefer-arrow-callback.js +1 -1
- package/lib/rules/prefer-const.js +0 -1
- package/lib/rules/prefer-destructuring.js +1 -2
- package/lib/rules/prefer-exponentiation-operator.js +0 -1
- package/lib/rules/prefer-named-capture-group.js +0 -1
- package/lib/rules/prefer-numeric-literals.js +0 -1
- package/lib/rules/prefer-object-spread.js +0 -1
- package/lib/rules/prefer-promise-reject-errors.js +0 -1
- package/lib/rules/prefer-reflect.js +0 -1
- package/lib/rules/prefer-regex-literals.js +0 -1
- package/lib/rules/prefer-rest-params.js +0 -1
- package/lib/rules/prefer-spread.js +0 -1
- package/lib/rules/prefer-template.js +0 -1
- package/lib/rules/quote-props.js +8 -9
- package/lib/rules/quotes.js +0 -1
- package/lib/rules/radix.js +0 -1
- package/lib/rules/require-atomic-updates.js +24 -9
- package/lib/rules/require-await.js +0 -1
- package/lib/rules/require-jsdoc.js +1 -1
- package/lib/rules/require-unicode-regexp.js +0 -1
- package/lib/rules/require-yield.js +0 -1
- package/lib/rules/rest-spread-spacing.js +0 -1
- package/lib/rules/semi-spacing.js +0 -1
- package/lib/rules/semi-style.js +0 -1
- package/lib/rules/semi.js +66 -6
- package/lib/rules/sort-imports.js +0 -1
- package/lib/rules/sort-keys.js +0 -1
- package/lib/rules/sort-vars.js +0 -1
- package/lib/rules/space-before-blocks.js +14 -3
- package/lib/rules/space-before-function-paren.js +0 -1
- package/lib/rules/space-in-parens.js +0 -1
- package/lib/rules/space-infix-ops.js +0 -1
- package/lib/rules/space-unary-ops.js +0 -1
- package/lib/rules/spaced-comment.js +0 -1
- package/lib/rules/strict.js +0 -1
- package/lib/rules/switch-colon-spacing.js +1 -14
- package/lib/rules/symbol-description.js +0 -1
- package/lib/rules/template-curly-spacing.js +0 -1
- package/lib/rules/template-tag-spacing.js +0 -1
- package/lib/rules/unicode-bom.js +0 -1
- package/lib/rules/use-isnan.js +0 -1
- package/lib/rules/utils/ast-utils.js +29 -7
- package/lib/rules/utils/lazy-loading-rule-map.js +3 -3
- package/lib/rules/valid-jsdoc.js +1 -1
- package/lib/rules/valid-typeof.js +0 -1
- package/lib/rules/vars-on-top.js +1 -2
- package/lib/rules/wrap-iife.js +0 -1
- package/lib/rules/wrap-regex.js +0 -1
- package/lib/rules/yield-star-spacing.js +0 -1
- package/lib/rules/yoda.js +0 -1
- package/lib/shared/ajv.js +1 -1
- package/lib/shared/config-validator.js +10 -5
- package/lib/shared/logging.js +1 -1
- package/lib/shared/relative-module-resolver.js +1 -0
- package/lib/shared/runtime-info.js +3 -0
- package/lib/shared/traverser.js +2 -2
- package/lib/shared/types.js +2 -2
- package/lib/source-code/source-code.js +11 -5
- package/lib/source-code/token-store/cursor.js +1 -1
- package/package.json +5 -5
package/lib/init/npm-utils.js
CHANGED
@@ -21,8 +21,8 @@ const fs = require("fs"),
|
|
21
21
|
/**
|
22
22
|
* Find the closest package.json file, starting at process.cwd (by default),
|
23
23
|
* and working up to root.
|
24
|
-
* @param
|
25
|
-
* @returns {string}
|
24
|
+
* @param {string} [startDir=process.cwd()] Starting directory
|
25
|
+
* @returns {string} Absolute path to closest package.json file
|
26
26
|
*/
|
27
27
|
function findPackageJson(startDir) {
|
28
28
|
let dir = path.resolve(startDir || process.cwd());
|
@@ -45,7 +45,7 @@ function findPackageJson(startDir) {
|
|
45
45
|
|
46
46
|
/**
|
47
47
|
* Install node modules synchronously and save to devDependencies in package.json
|
48
|
-
* @param
|
48
|
+
* @param {string|string[]} packages Node module or modules to install
|
49
49
|
* @returns {void}
|
50
50
|
*/
|
51
51
|
function installSyncSaveDev(packages) {
|
@@ -86,12 +86,13 @@ function fetchPeerDependencies(packageName) {
|
|
86
86
|
|
87
87
|
/**
|
88
88
|
* Check whether node modules are include in a project's package.json.
|
89
|
-
* @param
|
90
|
-
* @param
|
91
|
-
* @param
|
92
|
-
* @param
|
93
|
-
* @param
|
94
|
-
* @
|
89
|
+
* @param {string[]} packages Array of node module names
|
90
|
+
* @param {Object} opt Options Object
|
91
|
+
* @param {boolean} opt.dependencies Set to true to check for direct dependencies
|
92
|
+
* @param {boolean} opt.devDependencies Set to true to check for development dependencies
|
93
|
+
* @param {boolean} opt.startdir Directory to begin searching from
|
94
|
+
* @throws {Error} If cannot find valid `package.json` file.
|
95
|
+
* @returns {Object} An object whose keys are the module names
|
95
96
|
* and values are booleans indicating installation.
|
96
97
|
*/
|
97
98
|
function check(packages, opt) {
|
@@ -133,9 +134,9 @@ function check(packages, opt) {
|
|
133
134
|
* package.json.
|
134
135
|
*
|
135
136
|
* Convenience wrapper around check().
|
136
|
-
* @param
|
137
|
-
* @param
|
138
|
-
* @returns {Object}
|
137
|
+
* @param {string[]} packages Array of node modules to check.
|
138
|
+
* @param {string} rootDir The directory containing a package.json
|
139
|
+
* @returns {Object} An object whose keys are the module names
|
139
140
|
* and values are booleans indicating installation.
|
140
141
|
*/
|
141
142
|
function checkDeps(packages, rootDir) {
|
@@ -147,8 +148,8 @@ function checkDeps(packages, rootDir) {
|
|
147
148
|
* package.json.
|
148
149
|
*
|
149
150
|
* Convenience wrapper around check().
|
150
|
-
* @param
|
151
|
-
* @returns {Object}
|
151
|
+
* @param {string[]} packages Array of node modules to check.
|
152
|
+
* @returns {Object} An object whose keys are the module names
|
152
153
|
* and values are booleans indicating installation.
|
153
154
|
*/
|
154
155
|
function checkDevDeps(packages) {
|
@@ -157,7 +158,7 @@ function checkDevDeps(packages) {
|
|
157
158
|
|
158
159
|
/**
|
159
160
|
* Check whether package.json is found in current path.
|
160
|
-
* @param
|
161
|
+
* @param {string} [startDir] Starting directory
|
161
162
|
* @returns {boolean} Whether a package.json is found in current path.
|
162
163
|
*/
|
163
164
|
function checkPackageJson(startDir) {
|
@@ -23,7 +23,7 @@ const { CLIEngine } = require("../cli-engine");
|
|
23
23
|
* TODO1: Expose the API that enumerates target files.
|
24
24
|
* TODO2: Extract the creation logic of `SourceCode` from `Linter` class.
|
25
25
|
*/
|
26
|
-
const { getCLIEngineInternalSlots } = require("../cli-engine/cli-engine"); // eslint-disable-line node/no-restricted-require
|
26
|
+
const { getCLIEngineInternalSlots } = require("../cli-engine/cli-engine"); // eslint-disable-line node/no-restricted-require -- Todo
|
27
27
|
|
28
28
|
const debug = require("debug")("eslint:source-code-utils");
|
29
29
|
|
@@ -33,9 +33,10 @@ const debug = require("debug")("eslint:source-code-utils");
|
|
33
33
|
|
34
34
|
/**
|
35
35
|
* Get the SourceCode object for a single file
|
36
|
-
* @param
|
37
|
-
* @param
|
38
|
-
* @
|
36
|
+
* @param {string} filename The fully resolved filename to get SourceCode from.
|
37
|
+
* @param {Object} engine A CLIEngine.
|
38
|
+
* @throws {Error} Upon fatal errors from execution.
|
39
|
+
* @returns {Array} Array of the SourceCode object representing the file
|
39
40
|
* and fatal error message.
|
40
41
|
*/
|
41
42
|
function getSourceCodeOfFile(filename, engine) {
|
@@ -97,7 +98,7 @@ function getSourceCodeOfFiles(patterns, options, callback) {
|
|
97
98
|
sourceCodes[filename] = sourceCode;
|
98
99
|
}
|
99
100
|
if (callback) {
|
100
|
-
callback(filenames.length); // eslint-disable-line node/callback-return
|
101
|
+
callback(filenames.length); // eslint-disable-line node/callback-return -- End of function
|
101
102
|
}
|
102
103
|
});
|
103
104
|
|
@@ -46,26 +46,95 @@ function groupByParentComment(directives) {
|
|
46
46
|
* @returns {{ description, fix, position }[]} Details for later creation of output Problems.
|
47
47
|
*/
|
48
48
|
function createIndividualDirectivesRemoval(directives, commentToken) {
|
49
|
-
|
49
|
+
|
50
|
+
/*
|
51
|
+
* `commentToken.value` starts right after `//` or `/*`.
|
52
|
+
* All calculated offsets will be relative to this index.
|
53
|
+
*/
|
54
|
+
const commentValueStart = commentToken.range[0] + "//".length;
|
55
|
+
|
56
|
+
// Find where the list of rules starts. `\S+` matches with the directive name (e.g. `eslint-disable-line`)
|
57
|
+
const listStartOffset = /^\s*\S+\s+/u.exec(commentToken.value)[0].length;
|
58
|
+
|
59
|
+
/*
|
60
|
+
* Get the list text without any surrounding whitespace. In order to preserve the original
|
61
|
+
* formatting, we don't want to change that whitespace.
|
62
|
+
*
|
63
|
+
* // eslint-disable-line rule-one , rule-two , rule-three -- comment
|
64
|
+
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
65
|
+
*/
|
50
66
|
const listText = commentToken.value
|
51
|
-
.slice(
|
52
|
-
.split(/\s-{2,}\s/u)[0] // remove
|
53
|
-
.trimRight();
|
54
|
-
|
67
|
+
.slice(listStartOffset) // remove directive name and all whitespace before the list
|
68
|
+
.split(/\s-{2,}\s/u)[0] // remove `-- comment`, if it exists
|
69
|
+
.trimRight(); // remove all whitespace after the list
|
70
|
+
|
71
|
+
/*
|
72
|
+
* We can assume that `listText` contains multiple elements.
|
73
|
+
* Otherwise, this function wouldn't be called - if there is
|
74
|
+
* only one rule in the list, then the whole comment must be removed.
|
75
|
+
*/
|
55
76
|
|
56
77
|
return directives.map(directive => {
|
57
78
|
const { ruleId } = directive;
|
58
|
-
|
59
|
-
const
|
60
|
-
const
|
61
|
-
const
|
79
|
+
|
80
|
+
const regex = new RegExp(String.raw`(?:^|\s*,\s*)${escapeRegExp(ruleId)}(?:\s*,\s*|$)`, "u");
|
81
|
+
const match = regex.exec(listText);
|
82
|
+
const matchedText = match[0];
|
83
|
+
const matchStartOffset = listStartOffset + match.index;
|
84
|
+
const matchEndOffset = matchStartOffset + matchedText.length;
|
85
|
+
|
86
|
+
const firstIndexOfComma = matchedText.indexOf(",");
|
87
|
+
const lastIndexOfComma = matchedText.lastIndexOf(",");
|
88
|
+
|
89
|
+
let removalStartOffset, removalEndOffset;
|
90
|
+
|
91
|
+
if (firstIndexOfComma !== lastIndexOfComma) {
|
92
|
+
|
93
|
+
/*
|
94
|
+
* Since there are two commas, this must one of the elements in the middle of the list.
|
95
|
+
* Matched range starts where the previous rule name ends, and ends where the next rule name starts.
|
96
|
+
*
|
97
|
+
* // eslint-disable-line rule-one , rule-two , rule-three -- comment
|
98
|
+
* ^^^^^^^^^^^^^^
|
99
|
+
*
|
100
|
+
* We want to remove only the content between the two commas, and also one of the commas.
|
101
|
+
*
|
102
|
+
* // eslint-disable-line rule-one , rule-two , rule-three -- comment
|
103
|
+
* ^^^^^^^^^^^
|
104
|
+
*/
|
105
|
+
removalStartOffset = matchStartOffset + firstIndexOfComma;
|
106
|
+
removalEndOffset = matchStartOffset + lastIndexOfComma;
|
107
|
+
|
108
|
+
} else {
|
109
|
+
|
110
|
+
/*
|
111
|
+
* This is either the first element or the last element.
|
112
|
+
*
|
113
|
+
* If this is the first element, matched range starts where the first rule name starts
|
114
|
+
* and ends where the second rule name starts. This is exactly the range we want
|
115
|
+
* to remove so that the second rule name will start where the first one was starting
|
116
|
+
* and thus preserve the original formatting.
|
117
|
+
*
|
118
|
+
* // eslint-disable-line rule-one , rule-two , rule-three -- comment
|
119
|
+
* ^^^^^^^^^^^
|
120
|
+
*
|
121
|
+
* Similarly, if this is the last element, we've already matched the range we want to
|
122
|
+
* remove. The previous rule name will end where the last one was ending, relative
|
123
|
+
* to the content on the right side.
|
124
|
+
*
|
125
|
+
* // eslint-disable-line rule-one , rule-two , rule-three -- comment
|
126
|
+
* ^^^^^^^^^^^^^
|
127
|
+
*/
|
128
|
+
removalStartOffset = matchStartOffset;
|
129
|
+
removalEndOffset = matchEndOffset;
|
130
|
+
}
|
62
131
|
|
63
132
|
return {
|
64
133
|
description: `'${ruleId}'`,
|
65
134
|
fix: {
|
66
135
|
range: [
|
67
|
-
|
68
|
-
|
136
|
+
commentValueStart + removalStartOffset,
|
137
|
+
commentValueStart + removalEndOffset
|
69
138
|
],
|
70
139
|
text: ""
|
71
140
|
},
|
@@ -29,6 +29,18 @@ function isCaseNode(node) {
|
|
29
29
|
return Boolean(node.test);
|
30
30
|
}
|
31
31
|
|
32
|
+
/**
|
33
|
+
* Checks if a given node appears as the value of a PropertyDefinition node.
|
34
|
+
* @param {ASTNode} node THe node to check.
|
35
|
+
* @returns {boolean} `true` if the node is a PropertyDefinition value,
|
36
|
+
* false if not.
|
37
|
+
*/
|
38
|
+
function isPropertyDefinitionValue(node) {
|
39
|
+
const parent = node.parent;
|
40
|
+
|
41
|
+
return parent && parent.type === "PropertyDefinition" && parent.value === node;
|
42
|
+
}
|
43
|
+
|
32
44
|
/**
|
33
45
|
* Checks whether the given logical operator is taken into account for the code
|
34
46
|
* path analysis.
|
@@ -138,6 +150,7 @@ function isIdentifierReference(node) {
|
|
138
150
|
return parent.id !== node;
|
139
151
|
|
140
152
|
case "Property":
|
153
|
+
case "PropertyDefinition":
|
141
154
|
case "MethodDefinition":
|
142
155
|
return (
|
143
156
|
parent.key !== node ||
|
@@ -388,29 +401,64 @@ function processCodePathToEnter(analyzer, node) {
|
|
388
401
|
let state = codePath && CodePath.getState(codePath);
|
389
402
|
const parent = node.parent;
|
390
403
|
|
404
|
+
/**
|
405
|
+
* Creates a new code path and trigger the onCodePathStart event
|
406
|
+
* based on the currently selected node.
|
407
|
+
* @param {string} origin The reason the code path was started.
|
408
|
+
* @returns {void}
|
409
|
+
*/
|
410
|
+
function startCodePath(origin) {
|
411
|
+
if (codePath) {
|
412
|
+
|
413
|
+
// Emits onCodePathSegmentStart events if updated.
|
414
|
+
forwardCurrentToHead(analyzer, node);
|
415
|
+
debug.dumpState(node, state, false);
|
416
|
+
}
|
417
|
+
|
418
|
+
// Create the code path of this scope.
|
419
|
+
codePath = analyzer.codePath = new CodePath({
|
420
|
+
id: analyzer.idGenerator.next(),
|
421
|
+
origin,
|
422
|
+
upper: codePath,
|
423
|
+
onLooped: analyzer.onLooped
|
424
|
+
});
|
425
|
+
state = CodePath.getState(codePath);
|
426
|
+
|
427
|
+
// Emits onCodePathStart events.
|
428
|
+
debug.dump(`onCodePathStart ${codePath.id}`);
|
429
|
+
analyzer.emitter.emit("onCodePathStart", codePath, node);
|
430
|
+
}
|
431
|
+
|
432
|
+
/*
|
433
|
+
* Special case: The right side of class field initializer is considered
|
434
|
+
* to be its own function, so we need to start a new code path in this
|
435
|
+
* case.
|
436
|
+
*/
|
437
|
+
if (isPropertyDefinitionValue(node)) {
|
438
|
+
startCodePath("class-field-initializer");
|
439
|
+
|
440
|
+
/*
|
441
|
+
* Intentional fall through because `node` needs to also be
|
442
|
+
* processed by the code below. For example, if we have:
|
443
|
+
*
|
444
|
+
* class Foo {
|
445
|
+
* a = () => {}
|
446
|
+
* }
|
447
|
+
*
|
448
|
+
* In this case, we also need start a second code path.
|
449
|
+
*/
|
450
|
+
|
451
|
+
}
|
452
|
+
|
391
453
|
switch (node.type) {
|
392
454
|
case "Program":
|
455
|
+
startCodePath("program");
|
456
|
+
break;
|
457
|
+
|
393
458
|
case "FunctionDeclaration":
|
394
459
|
case "FunctionExpression":
|
395
460
|
case "ArrowFunctionExpression":
|
396
|
-
|
397
|
-
|
398
|
-
// Emits onCodePathSegmentStart events if updated.
|
399
|
-
forwardCurrentToHead(analyzer, node);
|
400
|
-
debug.dumpState(node, state, false);
|
401
|
-
}
|
402
|
-
|
403
|
-
// Create the code path of this scope.
|
404
|
-
codePath = analyzer.codePath = new CodePath(
|
405
|
-
analyzer.idGenerator.next(),
|
406
|
-
codePath,
|
407
|
-
analyzer.onLooped
|
408
|
-
);
|
409
|
-
state = CodePath.getState(codePath);
|
410
|
-
|
411
|
-
// Emits onCodePathStart events.
|
412
|
-
debug.dump(`onCodePathStart ${codePath.id}`);
|
413
|
-
analyzer.emitter.emit("onCodePathStart", codePath, node);
|
461
|
+
startCodePath("function");
|
414
462
|
break;
|
415
463
|
|
416
464
|
case "ChainExpression":
|
@@ -503,6 +551,7 @@ function processCodePathToEnter(analyzer, node) {
|
|
503
551
|
* @returns {void}
|
504
552
|
*/
|
505
553
|
function processCodePathToExit(analyzer, node) {
|
554
|
+
|
506
555
|
const codePath = analyzer.codePath;
|
507
556
|
const state = CodePath.getState(codePath);
|
508
557
|
let dontForward = false;
|
@@ -627,28 +676,38 @@ function processCodePathToExit(analyzer, node) {
|
|
627
676
|
* @returns {void}
|
628
677
|
*/
|
629
678
|
function postprocess(analyzer, node) {
|
679
|
+
|
680
|
+
/**
|
681
|
+
* Ends the code path for the current node.
|
682
|
+
* @returns {void}
|
683
|
+
*/
|
684
|
+
function endCodePath() {
|
685
|
+
let codePath = analyzer.codePath;
|
686
|
+
|
687
|
+
// Mark the current path as the final node.
|
688
|
+
CodePath.getState(codePath).makeFinal();
|
689
|
+
|
690
|
+
// Emits onCodePathSegmentEnd event of the current segments.
|
691
|
+
leaveFromCurrentSegment(analyzer, node);
|
692
|
+
|
693
|
+
// Emits onCodePathEnd event of this code path.
|
694
|
+
debug.dump(`onCodePathEnd ${codePath.id}`);
|
695
|
+
analyzer.emitter.emit("onCodePathEnd", codePath, node);
|
696
|
+
debug.dumpDot(codePath);
|
697
|
+
|
698
|
+
codePath = analyzer.codePath = analyzer.codePath.upper;
|
699
|
+
if (codePath) {
|
700
|
+
debug.dumpState(node, CodePath.getState(codePath), true);
|
701
|
+
}
|
702
|
+
|
703
|
+
}
|
704
|
+
|
630
705
|
switch (node.type) {
|
631
706
|
case "Program":
|
632
707
|
case "FunctionDeclaration":
|
633
708
|
case "FunctionExpression":
|
634
709
|
case "ArrowFunctionExpression": {
|
635
|
-
|
636
|
-
|
637
|
-
// Mark the current path as the final node.
|
638
|
-
CodePath.getState(codePath).makeFinal();
|
639
|
-
|
640
|
-
// Emits onCodePathSegmentEnd event of the current segments.
|
641
|
-
leaveFromCurrentSegment(analyzer, node);
|
642
|
-
|
643
|
-
// Emits onCodePathEnd event of this code path.
|
644
|
-
debug.dump(`onCodePathEnd ${codePath.id}`);
|
645
|
-
analyzer.emitter.emit("onCodePathEnd", codePath, node);
|
646
|
-
debug.dumpDot(codePath);
|
647
|
-
|
648
|
-
codePath = analyzer.codePath = analyzer.codePath.upper;
|
649
|
-
if (codePath) {
|
650
|
-
debug.dumpState(node, CodePath.getState(codePath), true);
|
651
|
-
}
|
710
|
+
endCodePath();
|
652
711
|
break;
|
653
712
|
}
|
654
713
|
|
@@ -662,6 +721,27 @@ function postprocess(analyzer, node) {
|
|
662
721
|
default:
|
663
722
|
break;
|
664
723
|
}
|
724
|
+
|
725
|
+
/*
|
726
|
+
* Special case: The right side of class field initializer is considered
|
727
|
+
* to be its own function, so we need to end a code path in this
|
728
|
+
* case.
|
729
|
+
*
|
730
|
+
* We need to check after the other checks in order to close the
|
731
|
+
* code paths in the correct order for code like this:
|
732
|
+
*
|
733
|
+
*
|
734
|
+
* class Foo {
|
735
|
+
* a = () => {}
|
736
|
+
* }
|
737
|
+
*
|
738
|
+
* In this case, The ArrowFunctionExpression code path is closed first
|
739
|
+
* and then we need to close the code path for the PropertyDefinition
|
740
|
+
* value.
|
741
|
+
*/
|
742
|
+
if (isPropertyDefinitionValue(node)) {
|
743
|
+
endCodePath();
|
744
|
+
}
|
665
745
|
}
|
666
746
|
|
667
747
|
//------------------------------------------------------------------------------
|
@@ -674,7 +754,6 @@ function postprocess(analyzer, node) {
|
|
674
754
|
*/
|
675
755
|
class CodePathAnalyzer {
|
676
756
|
|
677
|
-
// eslint-disable-next-line jsdoc/require-description
|
678
757
|
/**
|
679
758
|
* @param {EventGenerator} eventGenerator An event generator to wrap.
|
680
759
|
*/
|
@@ -219,7 +219,6 @@ function finalizeTestSegmentsOfFor(context, choiceContext, head) {
|
|
219
219
|
*/
|
220
220
|
class CodePathState {
|
221
221
|
|
222
|
-
// eslint-disable-next-line jsdoc/require-description
|
223
222
|
/**
|
224
223
|
* @param {IdGenerator} idGenerator An id generator to generate id for code
|
225
224
|
* path segments.
|
@@ -360,6 +359,7 @@ class CodePathState {
|
|
360
359
|
|
361
360
|
/**
|
362
361
|
* Pops the last choice context and finalizes it.
|
362
|
+
* @throws {Error} (Unreachable.)
|
363
363
|
* @returns {ChoiceContext} The popped context.
|
364
364
|
*/
|
365
365
|
popChoiceContext() {
|
@@ -450,6 +450,7 @@ class CodePathState {
|
|
450
450
|
/**
|
451
451
|
* Makes a code path segment of the right-hand operand of a logical
|
452
452
|
* expression.
|
453
|
+
* @throws {Error} (Unreachable.)
|
453
454
|
* @returns {void}
|
454
455
|
*/
|
455
456
|
makeLogicalRight() {
|
@@ -965,6 +966,7 @@ class CodePathState {
|
|
965
966
|
* `WhileStatement`, `DoWhileStatement`, `ForStatement`, `ForInStatement`,
|
966
967
|
* and `ForStatement`.
|
967
968
|
* @param {string|null} label A label of the node which was triggered.
|
969
|
+
* @throws {Error} (Unreachable - unknown type.)
|
968
970
|
* @returns {void}
|
969
971
|
*/
|
970
972
|
pushLoopContext(type, label) {
|
@@ -1036,6 +1038,7 @@ class CodePathState {
|
|
1036
1038
|
|
1037
1039
|
/**
|
1038
1040
|
* Pops the last context of a loop statement and finalizes it.
|
1041
|
+
* @throws {Error} (Unreachable - unknown type.)
|
1039
1042
|
* @returns {void}
|
1040
1043
|
*/
|
1041
1044
|
popLoopContext() {
|
@@ -21,13 +21,15 @@ const IdGenerator = require("./id-generator");
|
|
21
21
|
*/
|
22
22
|
class CodePath {
|
23
23
|
|
24
|
-
// eslint-disable-next-line jsdoc/require-description
|
25
24
|
/**
|
26
|
-
*
|
27
|
-
* @param {
|
28
|
-
* @param {
|
25
|
+
* Creates a new instance.
|
26
|
+
* @param {Object} options Options for the function (see below).
|
27
|
+
* @param {string} options.id An identifier.
|
28
|
+
* @param {string} options.origin The type of code path origin.
|
29
|
+
* @param {CodePath|null} options.upper The code path of the upper function scope.
|
30
|
+
* @param {Function} options.onLooped A callback function to notify looping.
|
29
31
|
*/
|
30
|
-
constructor(id, upper, onLooped) {
|
32
|
+
constructor({ id, origin, upper, onLooped }) {
|
31
33
|
|
32
34
|
/**
|
33
35
|
* The identifier of this code path.
|
@@ -36,6 +38,13 @@ class CodePath {
|
|
36
38
|
*/
|
37
39
|
this.id = id;
|
38
40
|
|
41
|
+
/**
|
42
|
+
* The reason that this code path was started. May be "program",
|
43
|
+
* "function", or "class-field-initializer".
|
44
|
+
* @type {string}
|
45
|
+
*/
|
46
|
+
this.origin = origin;
|
47
|
+
|
39
48
|
/**
|
40
49
|
* The code path of the upper function scope.
|
41
50
|
* @type {CodePath|null}
|
@@ -21,7 +21,7 @@ const debug = require("debug")("eslint:code-path");
|
|
21
21
|
* @returns {string} Id of the segment.
|
22
22
|
*/
|
23
23
|
/* istanbul ignore next */
|
24
|
-
function getId(segment) { // eslint-disable-line jsdoc/require-jsdoc
|
24
|
+
function getId(segment) { // eslint-disable-line jsdoc/require-jsdoc -- Ignoring
|
25
25
|
return segment.id + (segment.reachable ? "" : "!");
|
26
26
|
}
|
27
27
|
|
@@ -115,7 +115,7 @@ module.exports = {
|
|
115
115
|
const traceMap = Object.create(null);
|
116
116
|
const arrows = this.makeDotArrows(codePath, traceMap);
|
117
117
|
|
118
|
-
for (const id in traceMap) { // eslint-disable-line guard-for-in
|
118
|
+
for (const id in traceMap) { // eslint-disable-line guard-for-in -- Want ability to traverse prototype
|
119
119
|
const segment = traceMap[id];
|
120
120
|
|
121
121
|
text += `${id}[`;
|
@@ -97,7 +97,6 @@ function mergeExtraSegments(context, segments) {
|
|
97
97
|
*/
|
98
98
|
class ForkContext {
|
99
99
|
|
100
|
-
// eslint-disable-next-line jsdoc/require-description
|
101
100
|
/**
|
102
101
|
* @param {IdGenerator} idGenerator An identifier generator for segments.
|
103
102
|
* @param {ForkContext|null} upper An upper fork context.
|