bahlint 28.58.6934-dev-001
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 +354 -0
- package/bin/bahlint.js +267 -0
- package/bin/eslint.js +194 -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 +18 -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 +521 -0
- package/lib/config/config-loader.js +668 -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 +1989 -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,401 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Disallow redundant return statements
|
|
3
|
+
* @author Teddy Katz
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
//------------------------------------------------------------------------------
|
|
8
|
+
// Requirements
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
const astUtils = require("./utils/ast-utils"),
|
|
12
|
+
FixTracker = require("./utils/fix-tracker");
|
|
13
|
+
|
|
14
|
+
//------------------------------------------------------------------------------
|
|
15
|
+
// Helpers
|
|
16
|
+
//------------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Removes the given element from the array.
|
|
20
|
+
* @param {Array} array The source array to remove.
|
|
21
|
+
* @param {any} element The target item to remove.
|
|
22
|
+
* @returns {void}
|
|
23
|
+
*/
|
|
24
|
+
function remove(array, element) {
|
|
25
|
+
const index = array.indexOf(element);
|
|
26
|
+
|
|
27
|
+
if (index !== -1) {
|
|
28
|
+
array.splice(index, 1);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Checks whether it can remove the given return statement or not.
|
|
34
|
+
* @param {ASTNode} node The return statement node to check.
|
|
35
|
+
* @returns {boolean} `true` if the node is removable.
|
|
36
|
+
*/
|
|
37
|
+
function isRemovable(node) {
|
|
38
|
+
return astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Checks whether the given return statement is in a `finally` block or not.
|
|
43
|
+
* @param {ASTNode} node The return statement node to check.
|
|
44
|
+
* @returns {boolean} `true` if the node is in a `finally` block.
|
|
45
|
+
*/
|
|
46
|
+
function isInFinally(node) {
|
|
47
|
+
for (
|
|
48
|
+
let currentNode = node;
|
|
49
|
+
currentNode && currentNode.parent && !astUtils.isFunction(currentNode);
|
|
50
|
+
currentNode = currentNode.parent
|
|
51
|
+
) {
|
|
52
|
+
if (
|
|
53
|
+
currentNode.parent.type === "TryStatement" &&
|
|
54
|
+
currentNode.parent.finalizer === currentNode
|
|
55
|
+
) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Checks all segments in a set and returns true if any are reachable.
|
|
65
|
+
* @param {Set<CodePathSegment>} segments The segments to check.
|
|
66
|
+
* @returns {boolean} True if any segment is reachable; false otherwise.
|
|
67
|
+
*/
|
|
68
|
+
function isAnySegmentReachable(segments) {
|
|
69
|
+
for (const segment of segments) {
|
|
70
|
+
if (segment.reachable) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//------------------------------------------------------------------------------
|
|
79
|
+
// Rule Definition
|
|
80
|
+
//------------------------------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
83
|
+
module.exports = {
|
|
84
|
+
meta: {
|
|
85
|
+
type: "suggestion",
|
|
86
|
+
|
|
87
|
+
docs: {
|
|
88
|
+
description: "Disallow redundant return statements",
|
|
89
|
+
recommended: false,
|
|
90
|
+
url: "https://eslint.org/docs/latest/rules/no-useless-return",
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
fixable: "code",
|
|
94
|
+
schema: [],
|
|
95
|
+
|
|
96
|
+
messages: {
|
|
97
|
+
unnecessaryReturn: "Unnecessary return statement.",
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
create(context) {
|
|
102
|
+
const segmentInfoMap = new WeakMap();
|
|
103
|
+
const sourceCode = context.sourceCode;
|
|
104
|
+
let scopeInfo = null;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Checks whether the given segment is terminated by a return statement or not.
|
|
108
|
+
* @param {CodePathSegment} segment The segment to check.
|
|
109
|
+
* @returns {boolean} `true` if the segment is terminated by a return statement, or if it's still a part of unreachable.
|
|
110
|
+
*/
|
|
111
|
+
function isReturned(segment) {
|
|
112
|
+
const info = segmentInfoMap.get(segment);
|
|
113
|
+
|
|
114
|
+
return !info || info.returned;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Collects useless return statements from the given previous segments.
|
|
119
|
+
*
|
|
120
|
+
* A previous segment may be an unreachable segment.
|
|
121
|
+
* In that case, the information object of the unreachable segment is not
|
|
122
|
+
* initialized because `onCodePathSegmentStart` event is not notified for
|
|
123
|
+
* unreachable segments.
|
|
124
|
+
* This goes to the previous segments of the unreachable segment recursively
|
|
125
|
+
* if the unreachable segment was generated by a return statement. Otherwise,
|
|
126
|
+
* this ignores the unreachable segment.
|
|
127
|
+
*
|
|
128
|
+
* This behavior would simulate code paths for the case that the return
|
|
129
|
+
* statement does not exist.
|
|
130
|
+
* @param {ASTNode[]} uselessReturns The collected return statements.
|
|
131
|
+
* @param {CodePathSegment[]} prevSegments The previous segments to traverse.
|
|
132
|
+
* @param {WeakSet<CodePathSegment>} [providedTraversedSegments] A set of segments that have already been traversed in this call
|
|
133
|
+
* @returns {ASTNode[]} `uselessReturns`.
|
|
134
|
+
*/
|
|
135
|
+
function getUselessReturns(
|
|
136
|
+
uselessReturns,
|
|
137
|
+
prevSegments,
|
|
138
|
+
providedTraversedSegments,
|
|
139
|
+
) {
|
|
140
|
+
const traversedSegments =
|
|
141
|
+
providedTraversedSegments || new WeakSet();
|
|
142
|
+
|
|
143
|
+
for (const segment of prevSegments) {
|
|
144
|
+
if (!segment.reachable) {
|
|
145
|
+
if (!traversedSegments.has(segment)) {
|
|
146
|
+
traversedSegments.add(segment);
|
|
147
|
+
getUselessReturns(
|
|
148
|
+
uselessReturns,
|
|
149
|
+
segment.allPrevSegments.filter(isReturned),
|
|
150
|
+
traversedSegments,
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (segmentInfoMap.has(segment)) {
|
|
157
|
+
uselessReturns.push(
|
|
158
|
+
...segmentInfoMap.get(segment).uselessReturns,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return uselessReturns;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Removes the return statements on the given segment from the useless return
|
|
168
|
+
* statement list.
|
|
169
|
+
*
|
|
170
|
+
* This segment may be an unreachable segment.
|
|
171
|
+
* In that case, the information object of the unreachable segment is not
|
|
172
|
+
* initialized because `onCodePathSegmentStart` event is not notified for
|
|
173
|
+
* unreachable segments.
|
|
174
|
+
* This goes to the previous segments of the unreachable segment recursively
|
|
175
|
+
* if the unreachable segment was generated by a return statement. Otherwise,
|
|
176
|
+
* this ignores the unreachable segment.
|
|
177
|
+
*
|
|
178
|
+
* This behavior would simulate code paths for the case that the return
|
|
179
|
+
* statement does not exist.
|
|
180
|
+
* @param {CodePathSegment} segment The segment to get return statements.
|
|
181
|
+
* @param {Set<CodePathSegment>} usedUnreachableSegments A set of segments that have already been traversed in this call.
|
|
182
|
+
* @returns {void}
|
|
183
|
+
*/
|
|
184
|
+
function markReturnStatementsOnSegmentAsUsed(
|
|
185
|
+
segment,
|
|
186
|
+
usedUnreachableSegments,
|
|
187
|
+
) {
|
|
188
|
+
if (!segment.reachable) {
|
|
189
|
+
usedUnreachableSegments.add(segment);
|
|
190
|
+
segment.allPrevSegments
|
|
191
|
+
.filter(isReturned)
|
|
192
|
+
.filter(
|
|
193
|
+
prevSegment =>
|
|
194
|
+
!usedUnreachableSegments.has(prevSegment),
|
|
195
|
+
)
|
|
196
|
+
.forEach(prevSegment =>
|
|
197
|
+
markReturnStatementsOnSegmentAsUsed(
|
|
198
|
+
prevSegment,
|
|
199
|
+
usedUnreachableSegments,
|
|
200
|
+
),
|
|
201
|
+
);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const info = segmentInfoMap.get(segment);
|
|
206
|
+
|
|
207
|
+
if (!info) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
info.uselessReturns = info.uselessReturns.filter(node => {
|
|
212
|
+
if (
|
|
213
|
+
scopeInfo.traversedTryBlockStatements &&
|
|
214
|
+
scopeInfo.traversedTryBlockStatements.length > 0
|
|
215
|
+
) {
|
|
216
|
+
const returnInitialRange = node.range[0];
|
|
217
|
+
const returnFinalRange = node.range[1];
|
|
218
|
+
|
|
219
|
+
const areBlocksInRange =
|
|
220
|
+
scopeInfo.traversedTryBlockStatements.some(
|
|
221
|
+
tryBlockStatement => {
|
|
222
|
+
const blockInitialRange =
|
|
223
|
+
tryBlockStatement.range[0];
|
|
224
|
+
const blockFinalRange =
|
|
225
|
+
tryBlockStatement.range[1];
|
|
226
|
+
|
|
227
|
+
return (
|
|
228
|
+
returnInitialRange >= blockInitialRange &&
|
|
229
|
+
returnFinalRange <= blockFinalRange
|
|
230
|
+
);
|
|
231
|
+
},
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
if (areBlocksInRange) {
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
remove(scopeInfo.uselessReturns, node);
|
|
240
|
+
return false;
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Removes the return statements on the current segments from the useless
|
|
246
|
+
* return statement list.
|
|
247
|
+
*
|
|
248
|
+
* This function will be called at every statement except FunctionDeclaration,
|
|
249
|
+
* BlockStatement, and BreakStatement.
|
|
250
|
+
*
|
|
251
|
+
* - FunctionDeclarations are always executed whether it's returned or not.
|
|
252
|
+
* - BlockStatements do nothing.
|
|
253
|
+
* - BreakStatements go the next merely.
|
|
254
|
+
* @returns {void}
|
|
255
|
+
*/
|
|
256
|
+
function markReturnStatementsOnCurrentSegmentsAsUsed() {
|
|
257
|
+
scopeInfo.currentSegments.forEach(segment =>
|
|
258
|
+
markReturnStatementsOnSegmentAsUsed(segment, new Set()),
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
//----------------------------------------------------------------------
|
|
263
|
+
// Public
|
|
264
|
+
//----------------------------------------------------------------------
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
// Makes and pushes a new scope information.
|
|
268
|
+
onCodePathStart(codePath) {
|
|
269
|
+
scopeInfo = {
|
|
270
|
+
upper: scopeInfo,
|
|
271
|
+
uselessReturns: [],
|
|
272
|
+
traversedTryBlockStatements: [],
|
|
273
|
+
codePath,
|
|
274
|
+
currentSegments: new Set(),
|
|
275
|
+
};
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
// Reports useless return statements if exist.
|
|
279
|
+
onCodePathEnd() {
|
|
280
|
+
for (const node of scopeInfo.uselessReturns) {
|
|
281
|
+
context.report({
|
|
282
|
+
node,
|
|
283
|
+
loc: node.loc,
|
|
284
|
+
messageId: "unnecessaryReturn",
|
|
285
|
+
fix(fixer) {
|
|
286
|
+
if (
|
|
287
|
+
isRemovable(node) &&
|
|
288
|
+
!sourceCode.getCommentsInside(node).length
|
|
289
|
+
) {
|
|
290
|
+
/*
|
|
291
|
+
* Extend the replacement range to include the
|
|
292
|
+
* entire function to avoid conflicting with
|
|
293
|
+
* no-else-return.
|
|
294
|
+
* https://github.com/eslint/eslint/issues/8026
|
|
295
|
+
*/
|
|
296
|
+
return new FixTracker(fixer, sourceCode)
|
|
297
|
+
.retainEnclosingFunction(node)
|
|
298
|
+
.remove(node);
|
|
299
|
+
}
|
|
300
|
+
return null;
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
scopeInfo = scopeInfo.upper;
|
|
306
|
+
},
|
|
307
|
+
|
|
308
|
+
/*
|
|
309
|
+
* Initializes segments.
|
|
310
|
+
* NOTE: This event is notified for only reachable segments.
|
|
311
|
+
*/
|
|
312
|
+
onCodePathSegmentStart(segment) {
|
|
313
|
+
scopeInfo.currentSegments.add(segment);
|
|
314
|
+
|
|
315
|
+
const info = {
|
|
316
|
+
uselessReturns: getUselessReturns(
|
|
317
|
+
[],
|
|
318
|
+
segment.allPrevSegments,
|
|
319
|
+
),
|
|
320
|
+
returned: false,
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// Stores the info.
|
|
324
|
+
segmentInfoMap.set(segment, info);
|
|
325
|
+
},
|
|
326
|
+
|
|
327
|
+
onUnreachableCodePathSegmentStart(segment) {
|
|
328
|
+
scopeInfo.currentSegments.add(segment);
|
|
329
|
+
},
|
|
330
|
+
|
|
331
|
+
onUnreachableCodePathSegmentEnd(segment) {
|
|
332
|
+
scopeInfo.currentSegments.delete(segment);
|
|
333
|
+
},
|
|
334
|
+
|
|
335
|
+
onCodePathSegmentEnd(segment) {
|
|
336
|
+
scopeInfo.currentSegments.delete(segment);
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
// Adds ReturnStatement node to check whether it's useless or not.
|
|
340
|
+
ReturnStatement(node) {
|
|
341
|
+
if (node.argument) {
|
|
342
|
+
markReturnStatementsOnCurrentSegmentsAsUsed();
|
|
343
|
+
}
|
|
344
|
+
if (
|
|
345
|
+
node.argument ||
|
|
346
|
+
astUtils.isInLoop(node) ||
|
|
347
|
+
isInFinally(node) ||
|
|
348
|
+
// Ignore `return` statements in unreachable places (https://github.com/eslint/eslint/issues/11647).
|
|
349
|
+
!isAnySegmentReachable(scopeInfo.currentSegments)
|
|
350
|
+
) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
for (const segment of scopeInfo.currentSegments) {
|
|
355
|
+
const info = segmentInfoMap.get(segment);
|
|
356
|
+
|
|
357
|
+
if (info) {
|
|
358
|
+
info.uselessReturns.push(node);
|
|
359
|
+
info.returned = true;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
scopeInfo.uselessReturns.push(node);
|
|
363
|
+
},
|
|
364
|
+
|
|
365
|
+
"TryStatement > BlockStatement.block:exit"(node) {
|
|
366
|
+
scopeInfo.traversedTryBlockStatements.push(node);
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
"TryStatement:exit"() {
|
|
370
|
+
scopeInfo.traversedTryBlockStatements.pop();
|
|
371
|
+
},
|
|
372
|
+
|
|
373
|
+
/*
|
|
374
|
+
* Registers for all statement nodes except FunctionDeclaration, BlockStatement, BreakStatement.
|
|
375
|
+
* Removes return statements of the current segments from the useless return statement list.
|
|
376
|
+
*/
|
|
377
|
+
ClassDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
378
|
+
ContinueStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
379
|
+
DebuggerStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
380
|
+
DoWhileStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
381
|
+
EmptyStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
382
|
+
ExpressionStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
383
|
+
ForInStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
384
|
+
ForOfStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
385
|
+
ForStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
386
|
+
IfStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
387
|
+
ImportDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
388
|
+
LabeledStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
389
|
+
SwitchStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
390
|
+
ThrowStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
391
|
+
TryStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
392
|
+
VariableDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
393
|
+
WhileStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
394
|
+
WithStatement: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
395
|
+
ExportNamedDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
396
|
+
ExportDefaultDeclaration:
|
|
397
|
+
markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
398
|
+
ExportAllDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed,
|
|
399
|
+
};
|
|
400
|
+
},
|
|
401
|
+
};
|