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,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Disallows unnecessary `return await`
|
|
3
|
+
* @author Jordan Harband
|
|
4
|
+
* @deprecated in ESLint v8.46.0
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
const astUtils = require("./utils/ast-utils");
|
|
9
|
+
|
|
10
|
+
//------------------------------------------------------------------------------
|
|
11
|
+
// Rule Definition
|
|
12
|
+
//------------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
15
|
+
module.exports = {
|
|
16
|
+
meta: {
|
|
17
|
+
hasSuggestions: true,
|
|
18
|
+
type: "suggestion",
|
|
19
|
+
|
|
20
|
+
docs: {
|
|
21
|
+
description: "Disallow unnecessary `return await`",
|
|
22
|
+
|
|
23
|
+
recommended: false,
|
|
24
|
+
|
|
25
|
+
url: "https://eslint.org/docs/latest/rules/no-return-await",
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
fixable: null,
|
|
29
|
+
|
|
30
|
+
deprecated: {
|
|
31
|
+
message:
|
|
32
|
+
"The original assumption of the rule no longer holds true because of engine optimization.",
|
|
33
|
+
deprecatedSince: "8.46.0",
|
|
34
|
+
availableUntil: null,
|
|
35
|
+
replacedBy: [],
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
schema: [],
|
|
39
|
+
|
|
40
|
+
messages: {
|
|
41
|
+
removeAwait: "Remove redundant `await`.",
|
|
42
|
+
redundantUseOfAwait: "Redundant use of `await` on a return value.",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
create(context) {
|
|
47
|
+
/**
|
|
48
|
+
* Reports a found unnecessary `await` expression.
|
|
49
|
+
* @param {ASTNode} node The node representing the `await` expression to report
|
|
50
|
+
* @returns {void}
|
|
51
|
+
*/
|
|
52
|
+
function reportUnnecessaryAwait(node) {
|
|
53
|
+
context.report({
|
|
54
|
+
node: context.sourceCode.getFirstToken(node),
|
|
55
|
+
loc: node.loc,
|
|
56
|
+
messageId: "redundantUseOfAwait",
|
|
57
|
+
suggest: [
|
|
58
|
+
{
|
|
59
|
+
messageId: "removeAwait",
|
|
60
|
+
fix(fixer) {
|
|
61
|
+
const sourceCode = context.sourceCode;
|
|
62
|
+
const [awaitToken, tokenAfterAwait] =
|
|
63
|
+
sourceCode.getFirstTokens(node, 2);
|
|
64
|
+
|
|
65
|
+
const areAwaitAndAwaitedExpressionOnTheSameLine =
|
|
66
|
+
awaitToken.loc.start.line ===
|
|
67
|
+
tokenAfterAwait.loc.start.line;
|
|
68
|
+
|
|
69
|
+
if (!areAwaitAndAwaitedExpressionOnTheSameLine) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const [startOfAwait, endOfAwait] = awaitToken.range;
|
|
74
|
+
|
|
75
|
+
const characterAfterAwait =
|
|
76
|
+
sourceCode.text[endOfAwait];
|
|
77
|
+
const trimLength =
|
|
78
|
+
characterAfterAwait === " " ? 1 : 0;
|
|
79
|
+
|
|
80
|
+
const range = [
|
|
81
|
+
startOfAwait,
|
|
82
|
+
endOfAwait + trimLength,
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
return fixer.removeRange(range);
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Determines whether a thrown error from this node will be caught/handled within this function rather than immediately halting
|
|
94
|
+
* this function. For example, a statement in a `try` block will always have an error handler. A statement in
|
|
95
|
+
* a `catch` block will only have an error handler if there is also a `finally` block.
|
|
96
|
+
* @param {ASTNode} node A node representing a location where an could be thrown
|
|
97
|
+
* @returns {boolean} `true` if a thrown error will be caught/handled in this function
|
|
98
|
+
*/
|
|
99
|
+
function hasErrorHandler(node) {
|
|
100
|
+
let ancestor = node;
|
|
101
|
+
|
|
102
|
+
while (
|
|
103
|
+
!astUtils.isFunction(ancestor) &&
|
|
104
|
+
ancestor.type !== "Program"
|
|
105
|
+
) {
|
|
106
|
+
if (
|
|
107
|
+
ancestor.parent.type === "TryStatement" &&
|
|
108
|
+
(ancestor === ancestor.parent.block ||
|
|
109
|
+
(ancestor === ancestor.parent.handler &&
|
|
110
|
+
ancestor.parent.finalizer))
|
|
111
|
+
) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
ancestor = ancestor.parent;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Checks if a node is placed in tail call position. Once `return` arguments (or arrow function expressions) can be a complex expression,
|
|
121
|
+
* an `await` expression could or could not be unnecessary by the definition of this rule. So we're looking for `await` expressions that are in tail position.
|
|
122
|
+
* @param {ASTNode} node A node representing the `await` expression to check
|
|
123
|
+
* @returns {boolean} The checking result
|
|
124
|
+
*/
|
|
125
|
+
function isInTailCallPosition(node) {
|
|
126
|
+
if (node.parent.type === "ArrowFunctionExpression") {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
if (node.parent.type === "ReturnStatement") {
|
|
130
|
+
return !hasErrorHandler(node.parent);
|
|
131
|
+
}
|
|
132
|
+
if (
|
|
133
|
+
node.parent.type === "ConditionalExpression" &&
|
|
134
|
+
(node === node.parent.consequent ||
|
|
135
|
+
node === node.parent.alternate)
|
|
136
|
+
) {
|
|
137
|
+
return isInTailCallPosition(node.parent);
|
|
138
|
+
}
|
|
139
|
+
if (
|
|
140
|
+
node.parent.type === "LogicalExpression" &&
|
|
141
|
+
node === node.parent.right
|
|
142
|
+
) {
|
|
143
|
+
return isInTailCallPosition(node.parent);
|
|
144
|
+
}
|
|
145
|
+
if (
|
|
146
|
+
node.parent.type === "SequenceExpression" &&
|
|
147
|
+
node === node.parent.expressions.at(-1)
|
|
148
|
+
) {
|
|
149
|
+
return isInTailCallPosition(node.parent);
|
|
150
|
+
}
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return {
|
|
155
|
+
AwaitExpression(node) {
|
|
156
|
+
if (isInTailCallPosition(node) && !hasErrorHandler(node)) {
|
|
157
|
+
reportUnnecessaryAwait(node);
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to disallow `javascript:` URLs
|
|
3
|
+
* @author Ilya Volodin
|
|
4
|
+
*/
|
|
5
|
+
/* eslint no-script-url: 0 -- Code is checking to report such URLs */
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
const astUtils = require("./utils/ast-utils");
|
|
10
|
+
|
|
11
|
+
//------------------------------------------------------------------------------
|
|
12
|
+
// Rule Definition
|
|
13
|
+
//------------------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
16
|
+
module.exports = {
|
|
17
|
+
meta: {
|
|
18
|
+
type: "suggestion",
|
|
19
|
+
|
|
20
|
+
docs: {
|
|
21
|
+
description: "Disallow `javascript:` URLs",
|
|
22
|
+
recommended: false,
|
|
23
|
+
url: "https://eslint.org/docs/latest/rules/no-script-url",
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
schema: [],
|
|
27
|
+
|
|
28
|
+
messages: {
|
|
29
|
+
unexpectedScriptURL: "Script URL is a form of eval.",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
create(context) {
|
|
34
|
+
/**
|
|
35
|
+
* Check whether a node's static value starts with `javascript:` or not.
|
|
36
|
+
* And report an error for unexpected script URL.
|
|
37
|
+
* @param {ASTNode} node node to check
|
|
38
|
+
* @returns {void}
|
|
39
|
+
*/
|
|
40
|
+
function check(node) {
|
|
41
|
+
const value = astUtils.getStaticStringValue(node);
|
|
42
|
+
|
|
43
|
+
if (
|
|
44
|
+
typeof value === "string" &&
|
|
45
|
+
value.toLowerCase().indexOf("javascript:") === 0
|
|
46
|
+
) {
|
|
47
|
+
context.report({ node, messageId: "unexpectedScriptURL" });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
Literal(node) {
|
|
52
|
+
if (node.value && typeof node.value === "string") {
|
|
53
|
+
check(node);
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
TemplateLiteral(node) {
|
|
57
|
+
if (
|
|
58
|
+
!(
|
|
59
|
+
node.parent &&
|
|
60
|
+
node.parent.type === "TaggedTemplateExpression"
|
|
61
|
+
)
|
|
62
|
+
) {
|
|
63
|
+
check(node);
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to disallow assignments where both sides are exactly the same
|
|
3
|
+
* @author Toru Nagashima
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
//------------------------------------------------------------------------------
|
|
9
|
+
// Requirements
|
|
10
|
+
//------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
const astUtils = require("./utils/ast-utils");
|
|
13
|
+
|
|
14
|
+
//------------------------------------------------------------------------------
|
|
15
|
+
// Helpers
|
|
16
|
+
//------------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
const SPACES = /\s+/gu;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Traverses 2 Pattern nodes in parallel, then reports self-assignments.
|
|
22
|
+
* @param {ASTNode|null} left A left node to traverse. This is a Pattern or
|
|
23
|
+
* a Property.
|
|
24
|
+
* @param {ASTNode|null} right A right node to traverse. This is a Pattern or
|
|
25
|
+
* a Property.
|
|
26
|
+
* @param {boolean} props The flag to check member expressions as well.
|
|
27
|
+
* @param {Function} report A callback function to report.
|
|
28
|
+
* @returns {void}
|
|
29
|
+
*/
|
|
30
|
+
function eachSelfAssignment(left, right, props, report) {
|
|
31
|
+
if (!left || !right) {
|
|
32
|
+
// do nothing
|
|
33
|
+
} else if (
|
|
34
|
+
left.type === "Identifier" &&
|
|
35
|
+
right.type === "Identifier" &&
|
|
36
|
+
left.name === right.name
|
|
37
|
+
) {
|
|
38
|
+
report(right);
|
|
39
|
+
} else if (
|
|
40
|
+
left.type === "ArrayPattern" &&
|
|
41
|
+
right.type === "ArrayExpression"
|
|
42
|
+
) {
|
|
43
|
+
const end = Math.min(left.elements.length, right.elements.length);
|
|
44
|
+
|
|
45
|
+
for (let i = 0; i < end; ++i) {
|
|
46
|
+
const leftElement = left.elements[i];
|
|
47
|
+
const rightElement = right.elements[i];
|
|
48
|
+
|
|
49
|
+
// Avoid cases such as [...a] = [...a, 1]
|
|
50
|
+
if (
|
|
51
|
+
leftElement &&
|
|
52
|
+
leftElement.type === "RestElement" &&
|
|
53
|
+
i < right.elements.length - 1
|
|
54
|
+
) {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
eachSelfAssignment(leftElement, rightElement, props, report);
|
|
59
|
+
|
|
60
|
+
// After a spread element, those indices are unknown.
|
|
61
|
+
if (rightElement && rightElement.type === "SpreadElement") {
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
} else if (left.type === "RestElement" && right.type === "SpreadElement") {
|
|
66
|
+
eachSelfAssignment(left.argument, right.argument, props, report);
|
|
67
|
+
} else if (
|
|
68
|
+
left.type === "ObjectPattern" &&
|
|
69
|
+
right.type === "ObjectExpression" &&
|
|
70
|
+
right.properties.length >= 1
|
|
71
|
+
) {
|
|
72
|
+
/*
|
|
73
|
+
* Gets the index of the last spread property.
|
|
74
|
+
* It's possible to overwrite properties followed by it.
|
|
75
|
+
*/
|
|
76
|
+
let startJ = 0;
|
|
77
|
+
|
|
78
|
+
for (let i = right.properties.length - 1; i >= 0; --i) {
|
|
79
|
+
const propType = right.properties[i].type;
|
|
80
|
+
|
|
81
|
+
if (
|
|
82
|
+
propType === "SpreadElement" ||
|
|
83
|
+
propType === "ExperimentalSpreadProperty"
|
|
84
|
+
) {
|
|
85
|
+
startJ = i + 1;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
for (let i = 0; i < left.properties.length; ++i) {
|
|
91
|
+
for (let j = startJ; j < right.properties.length; ++j) {
|
|
92
|
+
eachSelfAssignment(
|
|
93
|
+
left.properties[i],
|
|
94
|
+
right.properties[j],
|
|
95
|
+
props,
|
|
96
|
+
report,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
} else if (
|
|
101
|
+
left.type === "Property" &&
|
|
102
|
+
right.type === "Property" &&
|
|
103
|
+
right.kind === "init" &&
|
|
104
|
+
!right.method
|
|
105
|
+
) {
|
|
106
|
+
const leftName = astUtils.getStaticPropertyName(left);
|
|
107
|
+
|
|
108
|
+
if (
|
|
109
|
+
leftName !== null &&
|
|
110
|
+
leftName === astUtils.getStaticPropertyName(right)
|
|
111
|
+
) {
|
|
112
|
+
eachSelfAssignment(left.value, right.value, props, report);
|
|
113
|
+
}
|
|
114
|
+
} else if (
|
|
115
|
+
props &&
|
|
116
|
+
astUtils.skipChainExpression(left).type === "MemberExpression" &&
|
|
117
|
+
astUtils.skipChainExpression(right).type === "MemberExpression" &&
|
|
118
|
+
astUtils.isSameReference(left, right)
|
|
119
|
+
) {
|
|
120
|
+
report(right);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
//------------------------------------------------------------------------------
|
|
125
|
+
// Rule Definition
|
|
126
|
+
//------------------------------------------------------------------------------
|
|
127
|
+
|
|
128
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
129
|
+
module.exports = {
|
|
130
|
+
meta: {
|
|
131
|
+
type: "problem",
|
|
132
|
+
|
|
133
|
+
defaultOptions: [{ props: true }],
|
|
134
|
+
|
|
135
|
+
docs: {
|
|
136
|
+
description:
|
|
137
|
+
"Disallow assignments where both sides are exactly the same",
|
|
138
|
+
recommended: true,
|
|
139
|
+
url: "https://eslint.org/docs/latest/rules/no-self-assign",
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
schema: [
|
|
143
|
+
{
|
|
144
|
+
type: "object",
|
|
145
|
+
properties: {
|
|
146
|
+
props: {
|
|
147
|
+
type: "boolean",
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
additionalProperties: false,
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
|
|
154
|
+
messages: {
|
|
155
|
+
selfAssignment: "'{{name}}' is assigned to itself.",
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
create(context) {
|
|
160
|
+
const sourceCode = context.sourceCode;
|
|
161
|
+
const [{ props }] = context.options;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Reports a given node as self assignments.
|
|
165
|
+
* @param {ASTNode} node A node to report. This is an Identifier node.
|
|
166
|
+
* @returns {void}
|
|
167
|
+
*/
|
|
168
|
+
function report(node) {
|
|
169
|
+
context.report({
|
|
170
|
+
node,
|
|
171
|
+
messageId: "selfAssignment",
|
|
172
|
+
data: {
|
|
173
|
+
name: sourceCode.getText(node).replace(SPACES, ""),
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
AssignmentExpression(node) {
|
|
180
|
+
if (["=", "&&=", "||=", "??="].includes(node.operator)) {
|
|
181
|
+
eachSelfAssignment(node.left, node.right, props, report);
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
},
|
|
186
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to flag comparison where left part is the same as the right
|
|
3
|
+
* part.
|
|
4
|
+
* @author Ilya Volodin
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
// Rule Definition
|
|
11
|
+
//------------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
14
|
+
module.exports = {
|
|
15
|
+
meta: {
|
|
16
|
+
type: "problem",
|
|
17
|
+
|
|
18
|
+
docs: {
|
|
19
|
+
description:
|
|
20
|
+
"Disallow comparisons where both sides are exactly the same",
|
|
21
|
+
recommended: false,
|
|
22
|
+
url: "https://eslint.org/docs/latest/rules/no-self-compare",
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
schema: [],
|
|
26
|
+
|
|
27
|
+
messages: {
|
|
28
|
+
comparingToSelf: "Comparing to itself is potentially pointless.",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
create(context) {
|
|
33
|
+
const sourceCode = context.sourceCode;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Determines whether two nodes are composed of the same tokens.
|
|
37
|
+
* @param {ASTNode} nodeA The first node
|
|
38
|
+
* @param {ASTNode} nodeB The second node
|
|
39
|
+
* @returns {boolean} true if the nodes have identical token representations
|
|
40
|
+
*/
|
|
41
|
+
function hasSameTokens(nodeA, nodeB) {
|
|
42
|
+
const tokensA = sourceCode.getTokens(nodeA);
|
|
43
|
+
const tokensB = sourceCode.getTokens(nodeB);
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
tokensA.length === tokensB.length &&
|
|
47
|
+
tokensA.every(
|
|
48
|
+
(token, index) =>
|
|
49
|
+
token.type === tokensB[index].type &&
|
|
50
|
+
token.value === tokensB[index].value,
|
|
51
|
+
)
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
BinaryExpression(node) {
|
|
57
|
+
const operators = new Set([
|
|
58
|
+
"===",
|
|
59
|
+
"==",
|
|
60
|
+
"!==",
|
|
61
|
+
"!=",
|
|
62
|
+
">",
|
|
63
|
+
"<",
|
|
64
|
+
">=",
|
|
65
|
+
"<=",
|
|
66
|
+
]);
|
|
67
|
+
|
|
68
|
+
if (
|
|
69
|
+
operators.has(node.operator) &&
|
|
70
|
+
hasSameTokens(node.left, node.right)
|
|
71
|
+
) {
|
|
72
|
+
context.report({ node, messageId: "comparingToSelf" });
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
};
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to flag use of comma operator
|
|
3
|
+
* @author Brandon Mills
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
//------------------------------------------------------------------------------
|
|
9
|
+
// Requirements
|
|
10
|
+
//------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
const astUtils = require("./utils/ast-utils");
|
|
13
|
+
|
|
14
|
+
//------------------------------------------------------------------------------
|
|
15
|
+
// Helpers
|
|
16
|
+
//------------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
//------------------------------------------------------------------------------
|
|
19
|
+
// Rule Definition
|
|
20
|
+
//------------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
23
|
+
module.exports = {
|
|
24
|
+
meta: {
|
|
25
|
+
type: "suggestion",
|
|
26
|
+
|
|
27
|
+
docs: {
|
|
28
|
+
description: "Disallow comma operators",
|
|
29
|
+
recommended: false,
|
|
30
|
+
url: "https://eslint.org/docs/latest/rules/no-sequences",
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
schema: [
|
|
34
|
+
{
|
|
35
|
+
type: "object",
|
|
36
|
+
properties: {
|
|
37
|
+
allowInParentheses: {
|
|
38
|
+
type: "boolean",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
additionalProperties: false,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
|
|
45
|
+
defaultOptions: [
|
|
46
|
+
{
|
|
47
|
+
allowInParentheses: true,
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
|
|
51
|
+
messages: {
|
|
52
|
+
unexpectedCommaExpression: "Unexpected use of comma operator.",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
create(context) {
|
|
57
|
+
const [{ allowInParentheses }] = context.options;
|
|
58
|
+
const sourceCode = context.sourceCode;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Parts of the grammar that are required to have parens.
|
|
62
|
+
*/
|
|
63
|
+
const parenthesized = {
|
|
64
|
+
DoWhileStatement: "test",
|
|
65
|
+
IfStatement: "test",
|
|
66
|
+
SwitchStatement: "discriminant",
|
|
67
|
+
WhileStatement: "test",
|
|
68
|
+
WithStatement: "object",
|
|
69
|
+
ArrowFunctionExpression: "body",
|
|
70
|
+
|
|
71
|
+
/*
|
|
72
|
+
* Omitting CallExpression - commas are parsed as argument separators
|
|
73
|
+
* Omitting NewExpression - commas are parsed as argument separators
|
|
74
|
+
* Omitting ForInStatement - parts aren't individually parenthesised
|
|
75
|
+
* Omitting ForStatement - parts aren't individually parenthesised
|
|
76
|
+
*/
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Determines whether a node is required by the grammar to be wrapped in
|
|
81
|
+
* parens, e.g. the test of an if statement.
|
|
82
|
+
* @param {ASTNode} node The AST node
|
|
83
|
+
* @returns {boolean} True if parens around node belong to parent node.
|
|
84
|
+
*/
|
|
85
|
+
function requiresExtraParens(node) {
|
|
86
|
+
return (
|
|
87
|
+
node.parent &&
|
|
88
|
+
parenthesized[node.parent.type] &&
|
|
89
|
+
node === node.parent[parenthesized[node.parent.type]]
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Check if a node is wrapped in parens.
|
|
95
|
+
* @param {ASTNode} node The AST node
|
|
96
|
+
* @returns {boolean} True if the node has a paren on each side.
|
|
97
|
+
*/
|
|
98
|
+
function isParenthesised(node) {
|
|
99
|
+
return astUtils.isParenthesised(sourceCode, node);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Check if a node is wrapped in two levels of parens.
|
|
104
|
+
* @param {ASTNode} node The AST node
|
|
105
|
+
* @returns {boolean} True if two parens surround the node on each side.
|
|
106
|
+
*/
|
|
107
|
+
function isParenthesisedTwice(node) {
|
|
108
|
+
const previousToken = sourceCode.getTokenBefore(node, 1),
|
|
109
|
+
nextToken = sourceCode.getTokenAfter(node, 1);
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
isParenthesised(node) &&
|
|
113
|
+
previousToken &&
|
|
114
|
+
nextToken &&
|
|
115
|
+
astUtils.isOpeningParenToken(previousToken) &&
|
|
116
|
+
previousToken.range[1] <= node.range[0] &&
|
|
117
|
+
astUtils.isClosingParenToken(nextToken) &&
|
|
118
|
+
nextToken.range[0] >= node.range[1]
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
SequenceExpression(node) {
|
|
124
|
+
// Always allow sequences in for statement update
|
|
125
|
+
if (
|
|
126
|
+
node.parent.type === "ForStatement" &&
|
|
127
|
+
(node === node.parent.init || node === node.parent.update)
|
|
128
|
+
) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Wrapping a sequence in extra parens indicates intent
|
|
133
|
+
if (allowInParentheses) {
|
|
134
|
+
if (requiresExtraParens(node)) {
|
|
135
|
+
if (isParenthesisedTwice(node)) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
if (isParenthesised(node)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const firstCommaToken = sourceCode.getTokenAfter(
|
|
146
|
+
node.expressions[0],
|
|
147
|
+
astUtils.isCommaToken,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
context.report({
|
|
151
|
+
node,
|
|
152
|
+
loc: firstCommaToken.loc,
|
|
153
|
+
messageId: "unexpectedCommaExpression",
|
|
154
|
+
});
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
};
|