bahlint 28.58.6934
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/LICENSE +19 -0
- package/README.md +370 -0
- package/bin/eslint.js +195 -0
- package/conf/ecma-version.js +16 -0
- package/conf/globals.js +169 -0
- package/conf/replacements.json +26 -0
- package/conf/rule-type-list.json +91 -0
- package/lib/api.js +39 -0
- package/lib/cli-engine/formatters/formatters-meta.json +22 -0
- package/lib/cli-engine/formatters/gasoline.js +168 -0
- package/lib/cli-engine/formatters/html.js +359 -0
- package/lib/cli-engine/formatters/json-with-metadata.js +16 -0
- package/lib/cli-engine/formatters/json.js +13 -0
- package/lib/cli-engine/formatters/stylish.js +153 -0
- package/lib/cli-engine/hash.js +35 -0
- package/lib/cli-engine/lint-result-cache.js +220 -0
- package/lib/cli.js +607 -0
- package/lib/config/config-loader.js +683 -0
- package/lib/config/config.js +674 -0
- package/lib/config/default-config.js +78 -0
- package/lib/config/flat-config-array.js +217 -0
- package/lib/config/flat-config-schema.js +598 -0
- package/lib/config-api.js +12 -0
- package/lib/eslint/eslint-helpers.js +1462 -0
- package/lib/eslint/eslint.js +1364 -0
- package/lib/eslint/index.js +7 -0
- package/lib/eslint/worker.js +173 -0
- package/lib/languages/js/index.js +336 -0
- package/lib/languages/js/source-code/index.js +7 -0
- package/lib/languages/js/source-code/source-code.js +1178 -0
- package/lib/languages/js/source-code/token-store/backward-token-comment-cursor.js +61 -0
- package/lib/languages/js/source-code/token-store/backward-token-cursor.js +57 -0
- package/lib/languages/js/source-code/token-store/cursor.js +76 -0
- package/lib/languages/js/source-code/token-store/cursors.js +120 -0
- package/lib/languages/js/source-code/token-store/decorative-cursor.js +38 -0
- package/lib/languages/js/source-code/token-store/filter-cursor.js +42 -0
- package/lib/languages/js/source-code/token-store/forward-token-comment-cursor.js +65 -0
- package/lib/languages/js/source-code/token-store/forward-token-cursor.js +62 -0
- package/lib/languages/js/source-code/token-store/index.js +695 -0
- package/lib/languages/js/source-code/token-store/limit-cursor.js +39 -0
- package/lib/languages/js/source-code/token-store/padded-token-cursor.js +45 -0
- package/lib/languages/js/source-code/token-store/skip-cursor.js +41 -0
- package/lib/languages/js/source-code/token-store/utils.js +131 -0
- package/lib/languages/js/validate-language-options.js +196 -0
- package/lib/linter/apply-disable-directives.js +583 -0
- package/lib/linter/code-path-analysis/code-path-analyzer.js +828 -0
- package/lib/linter/code-path-analysis/code-path-segment.js +262 -0
- package/lib/linter/code-path-analysis/code-path-state.js +2370 -0
- package/lib/linter/code-path-analysis/code-path.js +332 -0
- package/lib/linter/code-path-analysis/debug-helpers.js +223 -0
- package/lib/linter/code-path-analysis/fork-context.js +374 -0
- package/lib/linter/code-path-analysis/id-generator.js +44 -0
- package/lib/linter/esquery.js +332 -0
- package/lib/linter/file-context.js +88 -0
- package/lib/linter/file-report.js +604 -0
- package/lib/linter/index.js +11 -0
- package/lib/linter/interpolate.js +50 -0
- package/lib/linter/linter.js +1614 -0
- package/lib/linter/rule-fixer.js +199 -0
- package/lib/linter/source-code-fixer.js +154 -0
- package/lib/linter/source-code-traverser.js +333 -0
- package/lib/linter/source-code-visitor.js +81 -0
- package/lib/linter/timing.js +209 -0
- package/lib/linter/vfile.js +115 -0
- package/lib/options.js +416 -0
- package/lib/rule-tester/index.js +7 -0
- package/lib/rule-tester/rule-tester.js +1817 -0
- package/lib/rules/accessor-pairs.js +420 -0
- package/lib/rules/array-bracket-newline.js +291 -0
- package/lib/rules/array-bracket-spacing.js +301 -0
- package/lib/rules/array-callback-return.js +493 -0
- package/lib/rules/array-element-newline.js +374 -0
- package/lib/rules/arrow-body-style.js +418 -0
- package/lib/rules/arrow-parens.js +237 -0
- package/lib/rules/arrow-spacing.js +188 -0
- package/lib/rules/block-scoped-var.js +137 -0
- package/lib/rules/block-spacing.js +202 -0
- package/lib/rules/brace-style.js +278 -0
- package/lib/rules/callback-return.js +216 -0
- package/lib/rules/camelcase.js +422 -0
- package/lib/rules/capitalized-comments.js +325 -0
- package/lib/rules/class-methods-use-this.js +250 -0
- package/lib/rules/comma-dangle.js +424 -0
- package/lib/rules/comma-spacing.js +205 -0
- package/lib/rules/comma-style.js +391 -0
- package/lib/rules/complexity.js +201 -0
- package/lib/rules/computed-property-spacing.js +251 -0
- package/lib/rules/consistent-return.js +221 -0
- package/lib/rules/consistent-this.js +179 -0
- package/lib/rules/constructor-super.js +453 -0
- package/lib/rules/curly.js +425 -0
- package/lib/rules/default-case-last.js +51 -0
- package/lib/rules/default-case.js +103 -0
- package/lib/rules/default-param-last.js +78 -0
- package/lib/rules/dot-location.js +138 -0
- package/lib/rules/dot-notation.js +216 -0
- package/lib/rules/eol-last.js +135 -0
- package/lib/rules/eqeqeq.js +210 -0
- package/lib/rules/for-direction.js +168 -0
- package/lib/rules/func-call-spacing.js +281 -0
- package/lib/rules/func-name-matching.js +338 -0
- package/lib/rules/func-names.js +194 -0
- package/lib/rules/func-style.js +221 -0
- package/lib/rules/function-call-argument-newline.js +166 -0
- package/lib/rules/function-paren-newline.js +368 -0
- package/lib/rules/generator-star-spacing.js +246 -0
- package/lib/rules/getter-return.js +242 -0
- package/lib/rules/global-require.js +117 -0
- package/lib/rules/grouped-accessor-pairs.js +268 -0
- package/lib/rules/guard-for-in.js +85 -0
- package/lib/rules/handle-callback-err.js +122 -0
- package/lib/rules/id-blacklist.js +241 -0
- package/lib/rules/id-denylist.js +223 -0
- package/lib/rules/id-length.js +217 -0
- package/lib/rules/id-match.js +363 -0
- package/lib/rules/implicit-arrow-linebreak.js +125 -0
- package/lib/rules/indent-legacy.js +1369 -0
- package/lib/rules/indent.js +2334 -0
- package/lib/rules/index.js +332 -0
- package/lib/rules/init-declarations.js +172 -0
- package/lib/rules/jsx-quotes.js +128 -0
- package/lib/rules/key-spacing.js +822 -0
- package/lib/rules/keyword-spacing.js +701 -0
- package/lib/rules/line-comment-position.js +157 -0
- package/lib/rules/linebreak-style.js +135 -0
- package/lib/rules/lines-around-comment.js +581 -0
- package/lib/rules/lines-around-directive.js +249 -0
- package/lib/rules/lines-between-class-members.js +358 -0
- package/lib/rules/logical-assignment-operators.js +688 -0
- package/lib/rules/max-classes-per-file.js +90 -0
- package/lib/rules/max-depth.js +159 -0
- package/lib/rules/max-len.js +497 -0
- package/lib/rules/max-lines-per-function.js +238 -0
- package/lib/rules/max-lines.js +189 -0
- package/lib/rules/max-nested-callbacks.js +115 -0
- package/lib/rules/max-params.js +148 -0
- package/lib/rules/max-statements-per-line.js +224 -0
- package/lib/rules/max-statements.js +188 -0
- package/lib/rules/multiline-comment-style.js +652 -0
- package/lib/rules/multiline-ternary.js +257 -0
- package/lib/rules/new-cap.js +277 -0
- package/lib/rules/new-parens.js +120 -0
- package/lib/rules/newline-after-var.js +307 -0
- package/lib/rules/newline-before-return.js +242 -0
- package/lib/rules/newline-per-chained-call.js +159 -0
- package/lib/rules/no-alert.js +149 -0
- package/lib/rules/no-array-constructor.js +195 -0
- package/lib/rules/no-async-promise-executor.js +45 -0
- package/lib/rules/no-await-in-loop.js +115 -0
- package/lib/rules/no-bitwise.js +145 -0
- package/lib/rules/no-buffer-constructor.js +74 -0
- package/lib/rules/no-caller.js +52 -0
- package/lib/rules/no-case-declarations.js +80 -0
- package/lib/rules/no-catch-shadow.js +96 -0
- package/lib/rules/no-class-assign.js +66 -0
- package/lib/rules/no-compare-neg-zero.js +74 -0
- package/lib/rules/no-cond-assign.js +175 -0
- package/lib/rules/no-confusing-arrow.js +127 -0
- package/lib/rules/no-console.js +221 -0
- package/lib/rules/no-const-assign.js +73 -0
- package/lib/rules/no-constant-binary-expression.js +603 -0
- package/lib/rules/no-constant-condition.js +177 -0
- package/lib/rules/no-constructor-return.js +62 -0
- package/lib/rules/no-continue.js +38 -0
- package/lib/rules/no-control-regex.js +142 -0
- package/lib/rules/no-debugger.js +41 -0
- package/lib/rules/no-delete-var.js +42 -0
- package/lib/rules/no-div-regex.js +60 -0
- package/lib/rules/no-dupe-args.js +92 -0
- package/lib/rules/no-dupe-class-members.js +117 -0
- package/lib/rules/no-dupe-else-if.js +145 -0
- package/lib/rules/no-dupe-keys.js +165 -0
- package/lib/rules/no-duplicate-case.js +78 -0
- package/lib/rules/no-duplicate-imports.js +368 -0
- package/lib/rules/no-else-return.js +450 -0
- package/lib/rules/no-empty-character-class.js +83 -0
- package/lib/rules/no-empty-function.js +236 -0
- package/lib/rules/no-empty-pattern.js +85 -0
- package/lib/rules/no-empty-static-block.js +73 -0
- package/lib/rules/no-empty.js +153 -0
- package/lib/rules/no-eq-null.js +51 -0
- package/lib/rules/no-eval.js +295 -0
- package/lib/rules/no-ex-assign.js +57 -0
- package/lib/rules/no-extend-native.js +180 -0
- package/lib/rules/no-extra-bind.js +224 -0
- package/lib/rules/no-extra-boolean-cast.js +420 -0
- package/lib/rules/no-extra-label.js +169 -0
- package/lib/rules/no-extra-parens.js +1669 -0
- package/lib/rules/no-extra-semi.js +167 -0
- package/lib/rules/no-fallthrough.js +260 -0
- package/lib/rules/no-floating-decimal.js +99 -0
- package/lib/rules/no-func-assign.js +77 -0
- package/lib/rules/no-global-assign.js +101 -0
- package/lib/rules/no-implicit-coercion.js +468 -0
- package/lib/rules/no-implicit-globals.js +187 -0
- package/lib/rules/no-implied-eval.js +170 -0
- package/lib/rules/no-import-assign.js +227 -0
- package/lib/rules/no-inline-comments.js +115 -0
- package/lib/rules/no-inner-declarations.js +147 -0
- package/lib/rules/no-invalid-regexp.js +244 -0
- package/lib/rules/no-invalid-this.js +178 -0
- package/lib/rules/no-irregular-whitespace.js +292 -0
- package/lib/rules/no-iterator.js +48 -0
- package/lib/rules/no-label-var.js +78 -0
- package/lib/rules/no-labels.js +156 -0
- package/lib/rules/no-lone-blocks.js +140 -0
- package/lib/rules/no-lonely-if.js +126 -0
- package/lib/rules/no-loop-func.js +267 -0
- package/lib/rules/no-loss-of-precision.js +249 -0
- package/lib/rules/no-magic-numbers.js +365 -0
- package/lib/rules/no-misleading-character-class.js +595 -0
- package/lib/rules/no-mixed-operators.js +253 -0
- package/lib/rules/no-mixed-requires.js +267 -0
- package/lib/rules/no-mixed-spaces-and-tabs.js +148 -0
- package/lib/rules/no-multi-assign.js +66 -0
- package/lib/rules/no-multi-spaces.js +179 -0
- package/lib/rules/no-multi-str.js +67 -0
- package/lib/rules/no-multiple-empty-lines.js +210 -0
- package/lib/rules/no-native-reassign.js +114 -0
- package/lib/rules/no-negated-condition.js +100 -0
- package/lib/rules/no-negated-in-lhs.js +59 -0
- package/lib/rules/no-nested-ternary.js +46 -0
- package/lib/rules/no-new-func.js +96 -0
- package/lib/rules/no-new-native-nonconstructor.js +70 -0
- package/lib/rules/no-new-object.js +76 -0
- package/lib/rules/no-new-require.js +67 -0
- package/lib/rules/no-new-symbol.js +74 -0
- package/lib/rules/no-new-wrappers.js +62 -0
- package/lib/rules/no-new.js +42 -0
- package/lib/rules/no-nonoctal-decimal-escape.js +176 -0
- package/lib/rules/no-obj-calls.js +99 -0
- package/lib/rules/no-object-constructor.js +124 -0
- package/lib/rules/no-octal-escape.js +53 -0
- package/lib/rules/no-octal.js +42 -0
- package/lib/rules/no-param-reassign.js +248 -0
- package/lib/rules/no-path-concat.js +79 -0
- package/lib/rules/no-plusplus.js +102 -0
- package/lib/rules/no-process-env.js +68 -0
- package/lib/rules/no-process-exit.js +67 -0
- package/lib/rules/no-promise-executor-return.js +264 -0
- package/lib/rules/no-proto.js +45 -0
- package/lib/rules/no-prototype-builtins.js +181 -0
- package/lib/rules/no-redeclare.js +173 -0
- package/lib/rules/no-regex-spaces.js +219 -0
- package/lib/rules/no-restricted-exports.js +227 -0
- package/lib/rules/no-restricted-globals.js +266 -0
- package/lib/rules/no-restricted-imports.js +892 -0
- package/lib/rules/no-restricted-modules.js +249 -0
- package/lib/rules/no-restricted-properties.js +233 -0
- package/lib/rules/no-restricted-syntax.js +74 -0
- package/lib/rules/no-return-assign.js +87 -0
- package/lib/rules/no-return-await.js +162 -0
- package/lib/rules/no-script-url.js +68 -0
- package/lib/rules/no-self-assign.js +186 -0
- package/lib/rules/no-self-compare.js +77 -0
- package/lib/rules/no-sequences.js +158 -0
- package/lib/rules/no-setter-return.js +224 -0
- package/lib/rules/no-shadow-restricted-names.js +113 -0
- package/lib/rules/no-shadow.js +624 -0
- package/lib/rules/no-spaced-func.js +105 -0
- package/lib/rules/no-sparse-arrays.js +68 -0
- package/lib/rules/no-sync.js +81 -0
- package/lib/rules/no-tabs.js +110 -0
- package/lib/rules/no-template-curly-in-string.js +45 -0
- package/lib/rules/no-ternary.js +38 -0
- package/lib/rules/no-this-before-super.js +365 -0
- package/lib/rules/no-throw-literal.js +46 -0
- package/lib/rules/no-trailing-spaces.js +227 -0
- package/lib/rules/no-unassigned-vars.js +80 -0
- package/lib/rules/no-undef-init.js +101 -0
- package/lib/rules/no-undef.js +84 -0
- package/lib/rules/no-undefined.js +85 -0
- package/lib/rules/no-underscore-dangle.js +383 -0
- package/lib/rules/no-unexpected-multiline.js +130 -0
- package/lib/rules/no-unmodified-loop-condition.js +360 -0
- package/lib/rules/no-unneeded-ternary.js +232 -0
- package/lib/rules/no-unreachable-loop.js +190 -0
- package/lib/rules/no-unreachable.js +300 -0
- package/lib/rules/no-unsafe-finally.js +119 -0
- package/lib/rules/no-unsafe-negation.js +152 -0
- package/lib/rules/no-unsafe-optional-chaining.js +221 -0
- package/lib/rules/no-unused-expressions.js +227 -0
- package/lib/rules/no-unused-labels.js +158 -0
- package/lib/rules/no-unused-private-class-members.js +219 -0
- package/lib/rules/no-unused-vars.js +1739 -0
- package/lib/rules/no-use-before-define.js +446 -0
- package/lib/rules/no-useless-assignment.js +657 -0
- package/lib/rules/no-useless-backreference.js +263 -0
- package/lib/rules/no-useless-call.js +95 -0
- package/lib/rules/no-useless-catch.js +57 -0
- package/lib/rules/no-useless-computed-key.js +204 -0
- package/lib/rules/no-useless-concat.js +121 -0
- package/lib/rules/no-useless-constructor.js +262 -0
- package/lib/rules/no-useless-escape.js +406 -0
- package/lib/rules/no-useless-rename.js +202 -0
- package/lib/rules/no-useless-return.js +401 -0
- package/lib/rules/no-var.js +367 -0
- package/lib/rules/no-void.js +69 -0
- package/lib/rules/no-warning-comments.js +209 -0
- package/lib/rules/no-whitespace-before-property.js +150 -0
- package/lib/rules/no-with.js +37 -0
- package/lib/rules/nonblock-statement-body-position.js +164 -0
- package/lib/rules/object-curly-newline.js +383 -0
- package/lib/rules/object-curly-spacing.js +369 -0
- package/lib/rules/object-property-newline.js +151 -0
- package/lib/rules/object-shorthand.js +652 -0
- package/lib/rules/one-var-declaration-per-line.js +117 -0
- package/lib/rules/one-var.js +717 -0
- package/lib/rules/operator-assignment.js +270 -0
- package/lib/rules/operator-linebreak.js +315 -0
- package/lib/rules/padded-blocks.js +366 -0
- package/lib/rules/padding-line-between-statements.js +612 -0
- package/lib/rules/prefer-arrow-callback.js +437 -0
- package/lib/rules/prefer-const.js +546 -0
- package/lib/rules/prefer-destructuring.js +332 -0
- package/lib/rules/prefer-exponentiation-operator.js +235 -0
- package/lib/rules/prefer-named-capture-group.js +197 -0
- package/lib/rules/prefer-numeric-literals.js +157 -0
- package/lib/rules/prefer-object-has-own.js +148 -0
- package/lib/rules/prefer-object-spread.js +319 -0
- package/lib/rules/prefer-promise-reject-errors.js +154 -0
- package/lib/rules/prefer-reflect.js +150 -0
- package/lib/rules/prefer-regex-literals.js +605 -0
- package/lib/rules/prefer-rest-params.js +117 -0
- package/lib/rules/prefer-spread.js +91 -0
- package/lib/rules/prefer-template.js +347 -0
- package/lib/rules/preserve-caught-error.js +535 -0
- package/lib/rules/quote-props.js +394 -0
- package/lib/rules/quotes.js +416 -0
- package/lib/rules/radix.js +193 -0
- package/lib/rules/require-atomic-updates.js +365 -0
- package/lib/rules/require-await.js +184 -0
- package/lib/rules/require-unicode-regexp.js +317 -0
- package/lib/rules/require-yield.js +86 -0
- package/lib/rules/rest-spread-spacing.js +150 -0
- package/lib/rules/semi-spacing.js +297 -0
- package/lib/rules/semi-style.js +218 -0
- package/lib/rules/semi.js +476 -0
- package/lib/rules/sort-imports.js +319 -0
- package/lib/rules/sort-keys.js +268 -0
- package/lib/rules/sort-vars.js +140 -0
- package/lib/rules/space-before-blocks.js +232 -0
- package/lib/rules/space-before-function-paren.js +202 -0
- package/lib/rules/space-in-parens.js +374 -0
- package/lib/rules/space-infix-ops.js +249 -0
- package/lib/rules/space-unary-ops.js +400 -0
- package/lib/rules/spaced-comment.js +447 -0
- package/lib/rules/strict.js +314 -0
- package/lib/rules/switch-colon-spacing.js +158 -0
- package/lib/rules/symbol-description.js +70 -0
- package/lib/rules/template-curly-spacing.js +168 -0
- package/lib/rules/template-tag-spacing.js +121 -0
- package/lib/rules/unicode-bom.js +73 -0
- package/lib/rules/use-isnan.js +268 -0
- package/lib/rules/utils/ast-utils.js +2828 -0
- package/lib/rules/utils/char-source.js +247 -0
- package/lib/rules/utils/fix-tracker.js +125 -0
- package/lib/rules/utils/keywords.js +67 -0
- package/lib/rules/utils/lazy-loading-rule-map.js +118 -0
- package/lib/rules/utils/regular-expressions.js +58 -0
- package/lib/rules/utils/unicode/index.js +16 -0
- package/lib/rules/utils/unicode/is-combining-character.js +13 -0
- package/lib/rules/utils/unicode/is-emoji-modifier.js +13 -0
- package/lib/rules/utils/unicode/is-regional-indicator-symbol.js +13 -0
- package/lib/rules/utils/unicode/is-surrogate-pair.js +14 -0
- package/lib/rules/valid-typeof.js +171 -0
- package/lib/rules/vars-on-top.js +165 -0
- package/lib/rules/wrap-iife.js +238 -0
- package/lib/rules/wrap-regex.js +91 -0
- package/lib/rules/yield-star-spacing.js +158 -0
- package/lib/rules/yoda.js +362 -0
- package/lib/services/parser-service.js +64 -0
- package/lib/services/processor-service.js +100 -0
- package/lib/services/suppressions-service.js +302 -0
- package/lib/services/warning-service.js +87 -0
- package/lib/shared/ajv.js +34 -0
- package/lib/shared/assert.js +21 -0
- package/lib/shared/ast-utils.js +30 -0
- package/lib/shared/deep-merge-arrays.js +62 -0
- package/lib/shared/directives.js +16 -0
- package/lib/shared/flags.js +89 -0
- package/lib/shared/logging.js +38 -0
- package/lib/shared/naming.js +109 -0
- package/lib/shared/option-utils.js +63 -0
- package/lib/shared/relative-module-resolver.js +28 -0
- package/lib/shared/runtime-info.js +177 -0
- package/lib/shared/serialization.js +78 -0
- package/lib/shared/severity.js +49 -0
- package/lib/shared/stats.js +30 -0
- package/lib/shared/string-utils.js +58 -0
- package/lib/shared/text-table.js +68 -0
- package/lib/shared/translate-cli-options.js +223 -0
- package/lib/shared/traverser.js +202 -0
- package/lib/types/config-api.d.ts +12 -0
- package/lib/types/index.d.ts +1482 -0
- package/lib/types/rules.d.ts +5603 -0
- package/lib/types/universal.d.ts +6 -0
- package/lib/types/use-at-your-own-risk.d.ts +34 -0
- package/lib/universal.js +10 -0
- package/lib/unsupported-api.js +26 -0
- package/messages/all-files-ignored.js +16 -0
- package/messages/all-matched-files-ignored.js +21 -0
- package/messages/config-file-missing.js +16 -0
- package/messages/config-plugin-missing.js +14 -0
- package/messages/config-serialize-function.js +30 -0
- package/messages/eslintrc-incompat.js +117 -0
- package/messages/eslintrc-plugins.js +27 -0
- package/messages/extend-config-missing.js +13 -0
- package/messages/failed-to-read-json.js +11 -0
- package/messages/file-not-found.js +10 -0
- package/messages/invalid-rule-options.js +17 -0
- package/messages/invalid-rule-severity.js +13 -0
- package/messages/no-config-found.js +15 -0
- package/messages/plugin-conflict.js +22 -0
- package/messages/plugin-invalid.js +16 -0
- package/messages/plugin-missing.js +19 -0
- package/messages/print-config-with-directory-path.js +8 -0
- package/messages/shared.js +23 -0
- package/messages/whitespace-found.js +11 -0
- package/package.json +220 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to disallow useless backreferences in regular expressions
|
|
3
|
+
* @author Milos Djermanovic
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
//------------------------------------------------------------------------------
|
|
9
|
+
// Requirements
|
|
10
|
+
//------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
CALL,
|
|
14
|
+
CONSTRUCT,
|
|
15
|
+
ReferenceTracker,
|
|
16
|
+
getStringIfConstant,
|
|
17
|
+
} = require("@eslint-community/eslint-utils");
|
|
18
|
+
const { RegExpParser, visitRegExpAST } = require("@eslint-community/regexpp");
|
|
19
|
+
|
|
20
|
+
//------------------------------------------------------------------------------
|
|
21
|
+
// Helpers
|
|
22
|
+
//------------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
const parser = new RegExpParser();
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Finds the path from the given `regexpp` AST node to the root node.
|
|
28
|
+
* @param {regexpp.Node} node Node.
|
|
29
|
+
* @returns {regexpp.Node[]} Array that starts with the given node and ends with the root node.
|
|
30
|
+
*/
|
|
31
|
+
function getPathToRoot(node) {
|
|
32
|
+
const path = [];
|
|
33
|
+
let current = node;
|
|
34
|
+
|
|
35
|
+
do {
|
|
36
|
+
path.push(current);
|
|
37
|
+
current = current.parent;
|
|
38
|
+
} while (current);
|
|
39
|
+
|
|
40
|
+
return path;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Determines whether the given `regexpp` AST node is a lookaround node.
|
|
45
|
+
* @param {regexpp.Node} node Node.
|
|
46
|
+
* @returns {boolean} `true` if it is a lookaround node.
|
|
47
|
+
*/
|
|
48
|
+
function isLookaround(node) {
|
|
49
|
+
return (
|
|
50
|
+
node.type === "Assertion" &&
|
|
51
|
+
(node.kind === "lookahead" || node.kind === "lookbehind")
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Determines whether the given `regexpp` AST node is a negative lookaround node.
|
|
57
|
+
* @param {regexpp.Node} node Node.
|
|
58
|
+
* @returns {boolean} `true` if it is a negative lookaround node.
|
|
59
|
+
*/
|
|
60
|
+
function isNegativeLookaround(node) {
|
|
61
|
+
return isLookaround(node) && node.negate;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//------------------------------------------------------------------------------
|
|
65
|
+
// Rule Definition
|
|
66
|
+
//------------------------------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
69
|
+
module.exports = {
|
|
70
|
+
meta: {
|
|
71
|
+
type: "problem",
|
|
72
|
+
|
|
73
|
+
docs: {
|
|
74
|
+
description:
|
|
75
|
+
"Disallow useless backreferences in regular expressions",
|
|
76
|
+
recommended: true,
|
|
77
|
+
url: "https://eslint.org/docs/latest/rules/no-useless-backreference",
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
schema: [],
|
|
81
|
+
|
|
82
|
+
messages: {
|
|
83
|
+
nested: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} from within that group.",
|
|
84
|
+
forward:
|
|
85
|
+
"Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} which appears later in the pattern.",
|
|
86
|
+
backward:
|
|
87
|
+
"Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} which appears before in the same lookbehind.",
|
|
88
|
+
disjunctive:
|
|
89
|
+
"Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} which is in another alternative.",
|
|
90
|
+
intoNegativeLookaround:
|
|
91
|
+
"Backreference '{{ bref }}' will be ignored. It references group '{{ group }}'{{ otherGroups }} which is in a negative lookaround.",
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
create(context) {
|
|
96
|
+
const sourceCode = context.sourceCode;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Checks and reports useless backreferences in the given regular expression.
|
|
100
|
+
* @param {ASTNode} node Node that represents regular expression. A regex literal or RegExp constructor call.
|
|
101
|
+
* @param {string} pattern Regular expression pattern.
|
|
102
|
+
* @param {string} flags Regular expression flags.
|
|
103
|
+
* @returns {void}
|
|
104
|
+
*/
|
|
105
|
+
function checkRegex(node, pattern, flags) {
|
|
106
|
+
let regExpAST;
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
regExpAST = parser.parsePattern(pattern, 0, pattern.length, {
|
|
110
|
+
unicode: flags.includes("u"),
|
|
111
|
+
unicodeSets: flags.includes("v"),
|
|
112
|
+
});
|
|
113
|
+
} catch {
|
|
114
|
+
// Ignore regular expressions with syntax errors
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
visitRegExpAST(regExpAST, {
|
|
119
|
+
onBackreferenceEnter(bref) {
|
|
120
|
+
const groups = [bref.resolved].flat(),
|
|
121
|
+
brefPath = getPathToRoot(bref);
|
|
122
|
+
|
|
123
|
+
const problems = groups.map(group => {
|
|
124
|
+
const groupPath = getPathToRoot(group);
|
|
125
|
+
|
|
126
|
+
if (brefPath.includes(group)) {
|
|
127
|
+
// group is bref's ancestor => bref is nested ('nested reference') => group hasn't matched yet when bref starts to match.
|
|
128
|
+
return {
|
|
129
|
+
messageId: "nested",
|
|
130
|
+
group,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Start from the root to find the lowest common ancestor.
|
|
135
|
+
let i = brefPath.length - 1,
|
|
136
|
+
j = groupPath.length - 1;
|
|
137
|
+
|
|
138
|
+
do {
|
|
139
|
+
i--;
|
|
140
|
+
j--;
|
|
141
|
+
} while (brefPath[i] === groupPath[j]);
|
|
142
|
+
|
|
143
|
+
const indexOfLowestCommonAncestor = j + 1,
|
|
144
|
+
groupCut = groupPath.slice(
|
|
145
|
+
0,
|
|
146
|
+
indexOfLowestCommonAncestor,
|
|
147
|
+
),
|
|
148
|
+
commonPath = groupPath.slice(
|
|
149
|
+
indexOfLowestCommonAncestor,
|
|
150
|
+
),
|
|
151
|
+
lowestCommonLookaround =
|
|
152
|
+
commonPath.find(isLookaround),
|
|
153
|
+
isMatchingBackward =
|
|
154
|
+
lowestCommonLookaround &&
|
|
155
|
+
lowestCommonLookaround.kind === "lookbehind";
|
|
156
|
+
|
|
157
|
+
if (groupCut.at(-1).type === "Alternative") {
|
|
158
|
+
// group's and bref's ancestor nodes below the lowest common ancestor are sibling alternatives => they're disjunctive.
|
|
159
|
+
return {
|
|
160
|
+
messageId: "disjunctive",
|
|
161
|
+
group,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if (!isMatchingBackward && bref.end <= group.start) {
|
|
165
|
+
// bref is left, group is right ('forward reference') => group hasn't matched yet when bref starts to match.
|
|
166
|
+
return {
|
|
167
|
+
messageId: "forward",
|
|
168
|
+
group,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (isMatchingBackward && group.end <= bref.start) {
|
|
172
|
+
// the opposite of the previous when the regex is matching backward in a lookbehind context.
|
|
173
|
+
return {
|
|
174
|
+
messageId: "backward",
|
|
175
|
+
group,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
if (groupCut.some(isNegativeLookaround)) {
|
|
179
|
+
// group is in a negative lookaround which isn't bref's ancestor => group has already failed when bref starts to match.
|
|
180
|
+
return {
|
|
181
|
+
messageId: "intoNegativeLookaround",
|
|
182
|
+
group,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return null;
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
if (
|
|
190
|
+
problems.length === 0 ||
|
|
191
|
+
problems.some(problem => !problem)
|
|
192
|
+
) {
|
|
193
|
+
// If there are no problems or no problems with any group then do not report it.
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
let problemsToReport;
|
|
198
|
+
|
|
199
|
+
// Gets problems that appear in the same disjunction.
|
|
200
|
+
const problemsInSameDisjunction = problems.filter(
|
|
201
|
+
problem => problem.messageId !== "disjunctive",
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
if (problemsInSameDisjunction.length) {
|
|
205
|
+
// Only report problems that appear in the same disjunction.
|
|
206
|
+
problemsToReport = problemsInSameDisjunction;
|
|
207
|
+
} else {
|
|
208
|
+
// If all groups appear in different disjunctions, report it.
|
|
209
|
+
problemsToReport = problems;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const [{ messageId, group }, ...other] = problemsToReport;
|
|
213
|
+
let otherGroups = "";
|
|
214
|
+
|
|
215
|
+
if (other.length === 1) {
|
|
216
|
+
otherGroups = " and another group";
|
|
217
|
+
} else if (other.length > 1) {
|
|
218
|
+
otherGroups = ` and other ${other.length} groups`;
|
|
219
|
+
}
|
|
220
|
+
context.report({
|
|
221
|
+
node,
|
|
222
|
+
messageId,
|
|
223
|
+
data: {
|
|
224
|
+
bref: bref.raw,
|
|
225
|
+
group: group.raw,
|
|
226
|
+
otherGroups,
|
|
227
|
+
},
|
|
228
|
+
});
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
"Literal[regex]"(node) {
|
|
235
|
+
const { pattern, flags } = node.regex;
|
|
236
|
+
|
|
237
|
+
checkRegex(node, pattern, flags);
|
|
238
|
+
},
|
|
239
|
+
Program(node) {
|
|
240
|
+
const scope = sourceCode.getScope(node),
|
|
241
|
+
tracker = new ReferenceTracker(scope),
|
|
242
|
+
traceMap = {
|
|
243
|
+
RegExp: {
|
|
244
|
+
[CALL]: true,
|
|
245
|
+
[CONSTRUCT]: true,
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
for (const { node: refNode } of tracker.iterateGlobalReferences(
|
|
250
|
+
traceMap,
|
|
251
|
+
)) {
|
|
252
|
+
const [patternNode, flagsNode] = refNode.arguments,
|
|
253
|
+
pattern = getStringIfConstant(patternNode, scope),
|
|
254
|
+
flags = getStringIfConstant(flagsNode, scope);
|
|
255
|
+
|
|
256
|
+
if (typeof pattern === "string") {
|
|
257
|
+
checkRegex(refNode, pattern, flags || "");
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
},
|
|
263
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview A rule to disallow unnecessary `.call()` and `.apply()`.
|
|
3
|
+
* @author Toru Nagashima
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
const astUtils = require("./utils/ast-utils");
|
|
9
|
+
|
|
10
|
+
//------------------------------------------------------------------------------
|
|
11
|
+
// Helpers
|
|
12
|
+
//------------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Checks whether or not a node is a `.call()`/`.apply()`.
|
|
16
|
+
* @param {ASTNode} node A CallExpression node to check.
|
|
17
|
+
* @returns {boolean} Whether or not the node is a `.call()`/`.apply()`.
|
|
18
|
+
*/
|
|
19
|
+
function isCallOrNonVariadicApply(node) {
|
|
20
|
+
const callee = astUtils.skipChainExpression(node.callee);
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
callee.type === "MemberExpression" &&
|
|
24
|
+
callee.property.type === "Identifier" &&
|
|
25
|
+
callee.computed === false &&
|
|
26
|
+
((callee.property.name === "call" && node.arguments.length >= 1) ||
|
|
27
|
+
(callee.property.name === "apply" &&
|
|
28
|
+
node.arguments.length === 2 &&
|
|
29
|
+
node.arguments[1].type === "ArrayExpression"))
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Checks whether or not `thisArg` is not changed by `.call()`/`.apply()`.
|
|
35
|
+
* @param {ASTNode|null} expectedThis The node that is the owner of the applied function.
|
|
36
|
+
* @param {ASTNode} thisArg The node that is given to the first argument of the `.call()`/`.apply()`.
|
|
37
|
+
* @param {SourceCode} sourceCode The ESLint source code object.
|
|
38
|
+
* @returns {boolean} Whether or not `thisArg` is not changed by `.call()`/`.apply()`.
|
|
39
|
+
*/
|
|
40
|
+
function isValidThisArg(expectedThis, thisArg, sourceCode) {
|
|
41
|
+
if (!expectedThis) {
|
|
42
|
+
return astUtils.isNullOrUndefined(thisArg);
|
|
43
|
+
}
|
|
44
|
+
return astUtils.equalTokens(expectedThis, thisArg, sourceCode);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//------------------------------------------------------------------------------
|
|
48
|
+
// Rule Definition
|
|
49
|
+
//------------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
52
|
+
module.exports = {
|
|
53
|
+
meta: {
|
|
54
|
+
type: "suggestion",
|
|
55
|
+
|
|
56
|
+
docs: {
|
|
57
|
+
description:
|
|
58
|
+
"Disallow unnecessary calls to `.call()` and `.apply()`",
|
|
59
|
+
recommended: false,
|
|
60
|
+
url: "https://eslint.org/docs/latest/rules/no-useless-call",
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
schema: [],
|
|
64
|
+
|
|
65
|
+
messages: {
|
|
66
|
+
unnecessaryCall: "Unnecessary '.{{name}}()'.",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
create(context) {
|
|
71
|
+
const sourceCode = context.sourceCode;
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
CallExpression(node) {
|
|
75
|
+
if (!isCallOrNonVariadicApply(node)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const callee = astUtils.skipChainExpression(node.callee);
|
|
80
|
+
const applied = astUtils.skipChainExpression(callee.object);
|
|
81
|
+
const expectedThis =
|
|
82
|
+
applied.type === "MemberExpression" ? applied.object : null;
|
|
83
|
+
const thisArg = node.arguments[0];
|
|
84
|
+
|
|
85
|
+
if (isValidThisArg(expectedThis, thisArg, sourceCode)) {
|
|
86
|
+
context.report({
|
|
87
|
+
node,
|
|
88
|
+
messageId: "unnecessaryCall",
|
|
89
|
+
data: { name: callee.property.name },
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
},
|
|
95
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Reports useless `catch` clauses that just rethrow their error.
|
|
3
|
+
* @author Teddy Katz
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
//------------------------------------------------------------------------------
|
|
9
|
+
// Rule Definition
|
|
10
|
+
//------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
13
|
+
module.exports = {
|
|
14
|
+
meta: {
|
|
15
|
+
type: "suggestion",
|
|
16
|
+
|
|
17
|
+
docs: {
|
|
18
|
+
description: "Disallow unnecessary `catch` clauses",
|
|
19
|
+
recommended: true,
|
|
20
|
+
url: "https://eslint.org/docs/latest/rules/no-useless-catch",
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
schema: [],
|
|
24
|
+
|
|
25
|
+
messages: {
|
|
26
|
+
unnecessaryCatchClause: "Unnecessary catch clause.",
|
|
27
|
+
unnecessaryCatch: "Unnecessary try/catch wrapper.",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
create(context) {
|
|
32
|
+
return {
|
|
33
|
+
CatchClause(node) {
|
|
34
|
+
if (
|
|
35
|
+
node.param &&
|
|
36
|
+
node.param.type === "Identifier" &&
|
|
37
|
+
node.body.body.length &&
|
|
38
|
+
node.body.body[0].type === "ThrowStatement" &&
|
|
39
|
+
node.body.body[0].argument.type === "Identifier" &&
|
|
40
|
+
node.body.body[0].argument.name === node.param.name
|
|
41
|
+
) {
|
|
42
|
+
if (node.parent.finalizer) {
|
|
43
|
+
context.report({
|
|
44
|
+
node,
|
|
45
|
+
messageId: "unnecessaryCatchClause",
|
|
46
|
+
});
|
|
47
|
+
} else {
|
|
48
|
+
context.report({
|
|
49
|
+
node: node.parent,
|
|
50
|
+
messageId: "unnecessaryCatch",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
};
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to disallow unnecessary computed property keys in object literals
|
|
3
|
+
* @author Burak Yigit Kaya
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
//------------------------------------------------------------------------------
|
|
8
|
+
// Requirements
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
const astUtils = require("./utils/ast-utils");
|
|
12
|
+
|
|
13
|
+
//------------------------------------------------------------------------------
|
|
14
|
+
// Helpers
|
|
15
|
+
//------------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Determines whether the computed key syntax is unnecessarily used for the given node.
|
|
19
|
+
* In particular, it determines whether removing the square brackets and using the content between them
|
|
20
|
+
* directly as the key (e.g. ['foo'] -> 'foo') would produce valid syntax and preserve the same behavior.
|
|
21
|
+
* Valid non-computed keys are only: identifiers, number literals and string literals.
|
|
22
|
+
* Only literals can preserve the same behavior, with a few exceptions for specific node types:
|
|
23
|
+
* Property
|
|
24
|
+
* - { ["__proto__"]: foo } defines a property named "__proto__"
|
|
25
|
+
* { "__proto__": foo } defines object's prototype
|
|
26
|
+
* PropertyDefinition
|
|
27
|
+
* - class C { ["constructor"]; } defines an instance field named "constructor"
|
|
28
|
+
* class C { "constructor"; } produces a parsing error
|
|
29
|
+
* - class C { static ["constructor"]; } defines a static field named "constructor"
|
|
30
|
+
* class C { static "constructor"; } produces a parsing error
|
|
31
|
+
* - class C { static ["prototype"]; } produces a runtime error (doesn't break the whole script)
|
|
32
|
+
* class C { static "prototype"; } produces a parsing error (breaks the whole script)
|
|
33
|
+
* MethodDefinition
|
|
34
|
+
* - class C { ["constructor"]() {} } defines a prototype method named "constructor"
|
|
35
|
+
* class C { "constructor"() {} } defines the constructor
|
|
36
|
+
* - class C { static ["prototype"]() {} } produces a runtime error (doesn't break the whole script)
|
|
37
|
+
* class C { static "prototype"() {} } produces a parsing error (breaks the whole script)
|
|
38
|
+
* @param {ASTNode} node The node to check. It can be `Property`, `PropertyDefinition` or `MethodDefinition`.
|
|
39
|
+
* @throws {Error} (Unreachable.)
|
|
40
|
+
* @returns {void} `true` if the node has useless computed key.
|
|
41
|
+
*/
|
|
42
|
+
function hasUselessComputedKey(node) {
|
|
43
|
+
if (!node.computed) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const { key } = node;
|
|
48
|
+
|
|
49
|
+
if (key.type !== "Literal") {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const { value } = key;
|
|
54
|
+
|
|
55
|
+
if (typeof value !== "number" && typeof value !== "string") {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
switch (node.type) {
|
|
60
|
+
case "Property":
|
|
61
|
+
if (node.parent.type === "ObjectExpression") {
|
|
62
|
+
return value !== "__proto__";
|
|
63
|
+
}
|
|
64
|
+
return true;
|
|
65
|
+
|
|
66
|
+
case "PropertyDefinition":
|
|
67
|
+
if (node.static) {
|
|
68
|
+
return value !== "constructor" && value !== "prototype";
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return value !== "constructor";
|
|
72
|
+
|
|
73
|
+
case "MethodDefinition":
|
|
74
|
+
if (node.static) {
|
|
75
|
+
return value !== "prototype";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return value !== "constructor";
|
|
79
|
+
|
|
80
|
+
/* c8 ignore next */
|
|
81
|
+
default:
|
|
82
|
+
throw new Error(`Unexpected node type: ${node.type}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
//------------------------------------------------------------------------------
|
|
87
|
+
// Rule Definition
|
|
88
|
+
//------------------------------------------------------------------------------
|
|
89
|
+
|
|
90
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
91
|
+
module.exports = {
|
|
92
|
+
meta: {
|
|
93
|
+
type: "suggestion",
|
|
94
|
+
|
|
95
|
+
defaultOptions: [
|
|
96
|
+
{
|
|
97
|
+
enforceForClassMembers: true,
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
|
|
101
|
+
docs: {
|
|
102
|
+
description:
|
|
103
|
+
"Disallow unnecessary computed property keys in objects and classes",
|
|
104
|
+
recommended: false,
|
|
105
|
+
frozen: true,
|
|
106
|
+
url: "https://eslint.org/docs/latest/rules/no-useless-computed-key",
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
schema: [
|
|
110
|
+
{
|
|
111
|
+
type: "object",
|
|
112
|
+
properties: {
|
|
113
|
+
enforceForClassMembers: {
|
|
114
|
+
type: "boolean",
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
additionalProperties: false,
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
fixable: "code",
|
|
121
|
+
|
|
122
|
+
messages: {
|
|
123
|
+
unnecessarilyComputedProperty:
|
|
124
|
+
"Unnecessarily computed property [{{property}}] found.",
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
create(context) {
|
|
128
|
+
const sourceCode = context.sourceCode;
|
|
129
|
+
const [{ enforceForClassMembers }] = context.options;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Reports a given node if it violated this rule.
|
|
133
|
+
* @param {ASTNode} node The node to check.
|
|
134
|
+
* @returns {void}
|
|
135
|
+
*/
|
|
136
|
+
function check(node) {
|
|
137
|
+
if (hasUselessComputedKey(node)) {
|
|
138
|
+
const { key } = node;
|
|
139
|
+
|
|
140
|
+
context.report({
|
|
141
|
+
node,
|
|
142
|
+
messageId: "unnecessarilyComputedProperty",
|
|
143
|
+
data: { property: sourceCode.getText(key) },
|
|
144
|
+
fix(fixer) {
|
|
145
|
+
const leftSquareBracket = sourceCode.getTokenBefore(
|
|
146
|
+
key,
|
|
147
|
+
astUtils.isOpeningBracketToken,
|
|
148
|
+
);
|
|
149
|
+
const rightSquareBracket = sourceCode.getTokenAfter(
|
|
150
|
+
key,
|
|
151
|
+
astUtils.isClosingBracketToken,
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
// If there are comments between the brackets and the property name, don't do a fix.
|
|
155
|
+
if (
|
|
156
|
+
sourceCode.commentsExistBetween(
|
|
157
|
+
leftSquareBracket,
|
|
158
|
+
rightSquareBracket,
|
|
159
|
+
)
|
|
160
|
+
) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const tokenBeforeLeftBracket =
|
|
165
|
+
sourceCode.getTokenBefore(leftSquareBracket);
|
|
166
|
+
|
|
167
|
+
// Insert a space before the key to avoid changing identifiers, e.g. ({ get[2]() {} }) to ({ get2() {} })
|
|
168
|
+
const needsSpaceBeforeKey =
|
|
169
|
+
tokenBeforeLeftBracket.range[1] ===
|
|
170
|
+
leftSquareBracket.range[0] &&
|
|
171
|
+
!astUtils.canTokensBeAdjacent(
|
|
172
|
+
tokenBeforeLeftBracket,
|
|
173
|
+
sourceCode.getFirstToken(key),
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
const replacementKey =
|
|
177
|
+
(needsSpaceBeforeKey ? " " : "") + key.raw;
|
|
178
|
+
|
|
179
|
+
return fixer.replaceTextRange(
|
|
180
|
+
[
|
|
181
|
+
leftSquareBracket.range[0],
|
|
182
|
+
rightSquareBracket.range[1],
|
|
183
|
+
],
|
|
184
|
+
replacementKey,
|
|
185
|
+
);
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* A no-op function to act as placeholder for checking a node when the `enforceForClassMembers` option is `false`.
|
|
193
|
+
* @returns {void}
|
|
194
|
+
* @private
|
|
195
|
+
*/
|
|
196
|
+
function noop() {}
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
Property: check,
|
|
200
|
+
MethodDefinition: enforceForClassMembers ? check : noop,
|
|
201
|
+
PropertyDefinition: enforceForClassMembers ? check : noop,
|
|
202
|
+
};
|
|
203
|
+
},
|
|
204
|
+
};
|