@depup/typescript-eslint__eslint-plugin 8.57.1-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +25 -0
- package/changes.json +5 -0
- package/dist/configs/eslint-recommended-raw.d.ts +10 -0
- package/dist/configs/eslint-recommended-raw.js +46 -0
- package/dist/configs/eslintrc/all.d.ts +159 -0
- package/dist/configs/eslintrc/all.js +165 -0
- package/dist/configs/eslintrc/base.d.ts +8 -0
- package/dist/configs/eslintrc/base.js +6 -0
- package/dist/configs/eslintrc/disable-type-checked.d.ts +71 -0
- package/dist/configs/eslintrc/disable-type-checked.js +73 -0
- package/dist/configs/eslintrc/eslint-recommended.d.ts +12 -0
- package/dist/configs/eslintrc/eslint-recommended.js +13 -0
- package/dist/configs/eslintrc/recommended-type-checked-only.d.ts +33 -0
- package/dist/configs/eslintrc/recommended-type-checked-only.js +39 -0
- package/dist/configs/eslintrc/recommended-type-checked.d.ts +56 -0
- package/dist/configs/eslintrc/recommended-type-checked.js +62 -0
- package/dist/configs/eslintrc/recommended.d.ts +29 -0
- package/dist/configs/eslintrc/recommended.js +35 -0
- package/dist/configs/eslintrc/strict-type-checked-only.d.ts +64 -0
- package/dist/configs/eslintrc/strict-type-checked-only.js +79 -0
- package/dist/configs/eslintrc/strict-type-checked.d.ts +98 -0
- package/dist/configs/eslintrc/strict-type-checked.js +114 -0
- package/dist/configs/eslintrc/strict.d.ts +40 -0
- package/dist/configs/eslintrc/strict.js +47 -0
- package/dist/configs/eslintrc/stylistic-type-checked-only.d.ts +15 -0
- package/dist/configs/eslintrc/stylistic-type-checked-only.js +21 -0
- package/dist/configs/eslintrc/stylistic-type-checked.d.ts +29 -0
- package/dist/configs/eslintrc/stylistic-type-checked.js +35 -0
- package/dist/configs/eslintrc/stylistic.d.ts +20 -0
- package/dist/configs/eslintrc/stylistic.js +26 -0
- package/dist/configs/flat/all.d.ts +7 -0
- package/dist/configs/flat/all.js +179 -0
- package/dist/configs/flat/base.d.ts +8 -0
- package/dist/configs/flat/base.js +17 -0
- package/dist/configs/flat/disable-type-checked.d.ts +7 -0
- package/dist/configs/flat/disable-type-checked.js +81 -0
- package/dist/configs/flat/eslint-recommended.d.ts +9 -0
- package/dist/configs/flat/eslint-recommended.js +16 -0
- package/dist/configs/flat/recommended-type-checked-only.d.ts +7 -0
- package/dist/configs/flat/recommended-type-checked-only.js +53 -0
- package/dist/configs/flat/recommended-type-checked.d.ts +7 -0
- package/dist/configs/flat/recommended-type-checked.js +76 -0
- package/dist/configs/flat/recommended.d.ts +7 -0
- package/dist/configs/flat/recommended.js +49 -0
- package/dist/configs/flat/strict-type-checked-only.d.ts +7 -0
- package/dist/configs/flat/strict-type-checked-only.js +93 -0
- package/dist/configs/flat/strict-type-checked.d.ts +7 -0
- package/dist/configs/flat/strict-type-checked.js +128 -0
- package/dist/configs/flat/strict.d.ts +7 -0
- package/dist/configs/flat/strict.js +61 -0
- package/dist/configs/flat/stylistic-type-checked-only.d.ts +7 -0
- package/dist/configs/flat/stylistic-type-checked-only.js +35 -0
- package/dist/configs/flat/stylistic-type-checked.d.ts +7 -0
- package/dist/configs/flat/stylistic-type-checked.js +49 -0
- package/dist/configs/flat/stylistic.d.ts +7 -0
- package/dist/configs/flat/stylistic.js +40 -0
- package/dist/index.d.ts +1128 -0
- package/dist/index.js +6 -0
- package/dist/raw-plugin.d.ts +1152 -0
- package/dist/raw-plugin.js +122 -0
- package/dist/rules/adjacent-overload-signatures.d.ts +4 -0
- package/dist/rules/adjacent-overload-signatures.js +124 -0
- package/dist/rules/array-type.d.ts +12 -0
- package/dist/rules/array-type.js +232 -0
- package/dist/rules/await-thenable.d.ts +6 -0
- package/dist/rules/await-thenable.js +228 -0
- package/dist/rules/ban-ts-comment.d.ts +17 -0
- package/dist/rules/ban-ts-comment.js +195 -0
- package/dist/rules/ban-tslint-comment.d.ts +4 -0
- package/dist/rules/ban-tslint-comment.js +53 -0
- package/dist/rules/class-literal-property-style.d.ts +7 -0
- package/dist/rules/class-literal-property-style.js +160 -0
- package/dist/rules/class-methods-use-this.d.ts +13 -0
- package/dist/rules/class-methods-use-this.js +219 -0
- package/dist/rules/consistent-generic-constructors.d.ts +6 -0
- package/dist/rules/consistent-generic-constructors.js +126 -0
- package/dist/rules/consistent-indexed-object-style.d.ts +7 -0
- package/dist/rules/consistent-indexed-object-style.js +256 -0
- package/dist/rules/consistent-return.d.ts +18 -0
- package/dist/rules/consistent-return.js +135 -0
- package/dist/rules/consistent-type-assertions.d.ts +14 -0
- package/dist/rules/consistent-type-assertions.js +256 -0
- package/dist/rules/consistent-type-definitions.d.ts +5 -0
- package/dist/rules/consistent-type-definitions.js +100 -0
- package/dist/rules/consistent-type-exports.d.ts +11 -0
- package/dist/rules/consistent-type-exports.js +335 -0
- package/dist/rules/consistent-type-imports.d.ts +15 -0
- package/dist/rules/consistent-type-imports.js +608 -0
- package/dist/rules/default-param-last.d.ts +4 -0
- package/dist/rules/default-param-last.js +68 -0
- package/dist/rules/dot-notation.d.ts +23 -0
- package/dist/rules/dot-notation.js +139 -0
- package/dist/rules/enum-utils/shared.d.ts +36 -0
- package/dist/rules/enum-utils/shared.js +121 -0
- package/dist/rules/explicit-function-return-type.d.ts +17 -0
- package/dist/rules/explicit-function-return-type.js +179 -0
- package/dist/rules/explicit-member-accessibility.d.ts +19 -0
- package/dist/rules/explicit-member-accessibility.js +299 -0
- package/dist/rules/explicit-module-boundary-types.d.ts +15 -0
- package/dist/rules/explicit-module-boundary-types.js +386 -0
- package/dist/rules/index.d.ts +448 -0
- package/dist/rules/index.js +275 -0
- package/dist/rules/init-declarations.d.ts +15 -0
- package/dist/rules/init-declarations.js +105 -0
- package/dist/rules/max-params.d.ts +25 -0
- package/dist/rules/max-params.js +72 -0
- package/dist/rules/member-ordering.d.ts +33 -0
- package/dist/rules/member-ordering.js +833 -0
- package/dist/rules/method-signature-style.d.ts +6 -0
- package/dist/rules/method-signature-style.js +186 -0
- package/dist/rules/naming-convention-utils/enums.d.ts +79 -0
- package/dist/rules/naming-convention-utils/enums.js +102 -0
- package/dist/rules/naming-convention-utils/format.d.ts +2 -0
- package/dist/rules/naming-convention-utils/format.js +89 -0
- package/dist/rules/naming-convention-utils/index.d.ts +6 -0
- package/dist/rules/naming-convention-utils/index.js +11 -0
- package/dist/rules/naming-convention-utils/parse-options.d.ts +2 -0
- package/dist/rules/naming-convention-utils/parse-options.js +69 -0
- package/dist/rules/naming-convention-utils/schema.d.ts +2 -0
- package/dist/rules/naming-convention-utils/schema.js +305 -0
- package/dist/rules/naming-convention-utils/shared.d.ts +5 -0
- package/dist/rules/naming-convention-utils/shared.js +16 -0
- package/dist/rules/naming-convention-utils/types.d.ts +39 -0
- package/dist/rules/naming-convention-utils/types.js +2 -0
- package/dist/rules/naming-convention-utils/validator.d.ts +3 -0
- package/dist/rules/naming-convention-utils/validator.js +349 -0
- package/dist/rules/naming-convention.d.ts +8 -0
- package/dist/rules/naming-convention.js +505 -0
- package/dist/rules/no-array-constructor.d.ts +4 -0
- package/dist/rules/no-array-constructor.js +62 -0
- package/dist/rules/no-array-delete.d.ts +6 -0
- package/dist/rules/no-array-delete.js +80 -0
- package/dist/rules/no-base-to-string.d.ts +11 -0
- package/dist/rules/no-base-to-string.js +324 -0
- package/dist/rules/no-confusing-non-null-assertion.d.ts +6 -0
- package/dist/rules/no-confusing-non-null-assertion.js +142 -0
- package/dist/rules/no-confusing-void-expression.d.ts +13 -0
- package/dist/rules/no-confusing-void-expression.js +357 -0
- package/dist/rules/no-deprecated.d.ts +11 -0
- package/dist/rules/no-deprecated.js +402 -0
- package/dist/rules/no-dupe-class-members.d.ts +14 -0
- package/dist/rules/no-dupe-class-members.js +39 -0
- package/dist/rules/no-duplicate-enum-values.d.ts +4 -0
- package/dist/rules/no-duplicate-enum-values.js +83 -0
- package/dist/rules/no-duplicate-type-constituents.d.ts +11 -0
- package/dist/rules/no-duplicate-type-constituents.js +219 -0
- package/dist/rules/no-dynamic-delete.d.ts +4 -0
- package/dist/rules/no-dynamic-delete.js +42 -0
- package/dist/rules/no-empty-function.d.ts +16 -0
- package/dist/rules/no-empty-function.js +134 -0
- package/dist/rules/no-empty-interface.d.ts +11 -0
- package/dist/rules/no-empty-interface.js +102 -0
- package/dist/rules/no-empty-object-type.d.ts +15 -0
- package/dist/rules/no-empty-object-type.js +143 -0
- package/dist/rules/no-explicit-any.d.ts +12 -0
- package/dist/rules/no-explicit-any.js +197 -0
- package/dist/rules/no-extra-non-null-assertion.d.ts +4 -0
- package/dist/rules/no-extra-non-null-assertion.js +35 -0
- package/dist/rules/no-extraneous-class.d.ts +13 -0
- package/dist/rules/no-extraneous-class.js +120 -0
- package/dist/rules/no-floating-promises.d.ts +16 -0
- package/dist/rules/no-floating-promises.js +365 -0
- package/dist/rules/no-for-in-array.d.ts +4 -0
- package/dist/rules/no-for-in-array.js +86 -0
- package/dist/rules/no-implied-eval.d.ts +4 -0
- package/dist/rules/no-implied-eval.js +152 -0
- package/dist/rules/no-import-type-side-effects.d.ts +7 -0
- package/dist/rules/no-import-type-side-effects.js +53 -0
- package/dist/rules/no-inferrable-types.d.ts +11 -0
- package/dist/rules/no-inferrable-types.js +182 -0
- package/dist/rules/no-invalid-this.d.ts +15 -0
- package/dist/rules/no-invalid-this.js +75 -0
- package/dist/rules/no-invalid-void-type.d.ts +9 -0
- package/dist/rules/no-invalid-void-type.js +210 -0
- package/dist/rules/no-loop-func.d.ts +13 -0
- package/dist/rules/no-loop-func.js +187 -0
- package/dist/rules/no-loss-of-precision.d.ts +9 -0
- package/dist/rules/no-loss-of-precision.js +35 -0
- package/dist/rules/no-magic-numbers.d.ts +29 -0
- package/dist/rules/no-magic-numbers.js +248 -0
- package/dist/rules/no-meaningless-void-operator.d.ts +10 -0
- package/dist/rules/no-meaningless-void-operator.js +102 -0
- package/dist/rules/no-misused-new.d.ts +4 -0
- package/dist/rules/no-misused-new.js +81 -0
- package/dist/rules/no-misused-promises.d.ts +21 -0
- package/dist/rules/no-misused-promises.js +765 -0
- package/dist/rules/no-misused-spread.d.ts +12 -0
- package/dist/rules/no-misused-spread.js +260 -0
- package/dist/rules/no-mixed-enums.d.ts +4 -0
- package/dist/rules/no-mixed-enums.js +200 -0
- package/dist/rules/no-namespace.d.ts +11 -0
- package/dist/rules/no-namespace.js +60 -0
- package/dist/rules/no-non-null-asserted-nullish-coalescing.d.ts +5 -0
- package/dist/rules/no-non-null-asserted-nullish-coalescing.js +73 -0
- package/dist/rules/no-non-null-asserted-optional-chain.d.ts +5 -0
- package/dist/rules/no-non-null-asserted-optional-chain.js +65 -0
- package/dist/rules/no-non-null-assertion.d.ts +6 -0
- package/dist/rules/no-non-null-assertion.js +93 -0
- package/dist/rules/no-redeclare.d.ts +12 -0
- package/dist/rules/no-redeclare.js +199 -0
- package/dist/rules/no-redundant-type-constituents.d.ts +4 -0
- package/dist/rules/no-redundant-type-constituents.js +431 -0
- package/dist/rules/no-require-imports.d.ts +11 -0
- package/dist/rules/no-require-imports.js +115 -0
- package/dist/rules/no-restricted-imports.d.ts +9 -0
- package/dist/rules/no-restricted-imports.js +243 -0
- package/dist/rules/no-restricted-types.d.ts +16 -0
- package/dist/rules/no-restricted-types.js +165 -0
- package/dist/rules/no-shadow.d.ts +16 -0
- package/dist/rules/no-shadow.js +521 -0
- package/dist/rules/no-this-alias.d.ts +11 -0
- package/dist/rules/no-this-alias.js +66 -0
- package/dist/rules/no-type-alias.d.ts +18 -0
- package/dist/rules/no-type-alias.js +268 -0
- package/dist/rules/no-unnecessary-boolean-literal-compare.d.ts +12 -0
- package/dist/rules/no-unnecessary-boolean-literal-compare.js +263 -0
- package/dist/rules/no-unnecessary-condition.d.ts +14 -0
- package/dist/rules/no-unnecessary-condition.js +675 -0
- package/dist/rules/no-unnecessary-parameter-property-assignment.d.ts +4 -0
- package/dist/rules/no-unnecessary-parameter-property-assignment.js +148 -0
- package/dist/rules/no-unnecessary-qualifier.d.ts +4 -0
- package/dist/rules/no-unnecessary-qualifier.js +156 -0
- package/dist/rules/no-unnecessary-template-expression.d.ts +6 -0
- package/dist/rules/no-unnecessary-template-expression.js +361 -0
- package/dist/rules/no-unnecessary-type-arguments.d.ts +5 -0
- package/dist/rules/no-unnecessary-type-arguments.js +197 -0
- package/dist/rules/no-unnecessary-type-assertion.d.ts +11 -0
- package/dist/rules/no-unnecessary-type-assertion.js +353 -0
- package/dist/rules/no-unnecessary-type-constraint.d.ts +5 -0
- package/dist/rules/no-unnecessary-type-constraint.js +119 -0
- package/dist/rules/no-unnecessary-type-conversion.d.ts +5 -0
- package/dist/rules/no-unnecessary-type-conversion.js +356 -0
- package/dist/rules/no-unnecessary-type-parameters.d.ts +5 -0
- package/dist/rules/no-unnecessary-type-parameters.js +422 -0
- package/dist/rules/no-unsafe-argument.d.ts +5 -0
- package/dist/rules/no-unsafe-argument.js +272 -0
- package/dist/rules/no-unsafe-assignment.d.ts +4 -0
- package/dist/rules/no-unsafe-assignment.js +322 -0
- package/dist/rules/no-unsafe-call.d.ts +5 -0
- package/dist/rules/no-unsafe-call.js +136 -0
- package/dist/rules/no-unsafe-declaration-merging.d.ts +4 -0
- package/dist/rules/no-unsafe-declaration-merging.js +54 -0
- package/dist/rules/no-unsafe-enum-comparison.d.ts +5 -0
- package/dist/rules/no-unsafe-enum-comparison.js +192 -0
- package/dist/rules/no-unsafe-function-type.d.ts +4 -0
- package/dist/rules/no-unsafe-function-type.js +45 -0
- package/dist/rules/no-unsafe-member-access.d.ts +10 -0
- package/dist/rules/no-unsafe-member-access.js +183 -0
- package/dist/rules/no-unsafe-return.d.ts +4 -0
- package/dist/rules/no-unsafe-return.js +183 -0
- package/dist/rules/no-unsafe-type-assertion.d.ts +4 -0
- package/dist/rules/no-unsafe-type-assertion.js +158 -0
- package/dist/rules/no-unsafe-unary-minus.d.ts +6 -0
- package/dist/rules/no-unsafe-unary-minus.js +78 -0
- package/dist/rules/no-unused-expressions.d.ts +19 -0
- package/dist/rules/no-unused-expressions.js +64 -0
- package/dist/rules/no-unused-private-class-members.d.ts +6 -0
- package/dist/rules/no-unused-private-class-members.js +44 -0
- package/dist/rules/no-unused-vars.d.ts +24 -0
- package/dist/rules/no-unused-vars.js +1033 -0
- package/dist/rules/no-use-before-define.d.ts +16 -0
- package/dist/rules/no-use-before-define.js +303 -0
- package/dist/rules/no-useless-constructor.d.ts +11 -0
- package/dist/rules/no-useless-constructor.js +57 -0
- package/dist/rules/no-useless-default-assignment.d.ts +11 -0
- package/dist/rules/no-useless-default-assignment.js +318 -0
- package/dist/rules/no-useless-empty-export.d.ts +4 -0
- package/dist/rules/no-useless-empty-export.js +70 -0
- package/dist/rules/no-var-requires.d.ts +10 -0
- package/dist/rules/no-var-requires.js +83 -0
- package/dist/rules/no-wrapper-object-types.d.ts +5 -0
- package/dist/rules/no-wrapper-object-types.js +60 -0
- package/dist/rules/non-nullable-type-assertion-style.d.ts +4 -0
- package/dist/rules/non-nullable-type-assertion-style.js +132 -0
- package/dist/rules/only-throw-error.d.ts +14 -0
- package/dist/rules/only-throw-error.js +158 -0
- package/dist/rules/parameter-properties.d.ts +13 -0
- package/dist/rules/parameter-properties.js +164 -0
- package/dist/rules/prefer-as-const.d.ts +5 -0
- package/dist/rules/prefer-as-const.js +72 -0
- package/dist/rules/prefer-destructuring.d.ts +19 -0
- package/dist/rules/prefer-destructuring.js +216 -0
- package/dist/rules/prefer-enum-initializers.d.ts +6 -0
- package/dist/rules/prefer-enum-initializers.js +62 -0
- package/dist/rules/prefer-find.d.ts +5 -0
- package/dist/rules/prefer-find.js +247 -0
- package/dist/rules/prefer-for-of.d.ts +5 -0
- package/dist/rules/prefer-for-of.js +115 -0
- package/dist/rules/prefer-function-type.d.ts +9 -0
- package/dist/rules/prefer-function-type.js +186 -0
- package/dist/rules/prefer-includes.d.ts +5 -0
- package/dist/rules/prefer-includes.js +242 -0
- package/dist/rules/prefer-literal-enum-member.d.ts +6 -0
- package/dist/rules/prefer-literal-enum-member.js +116 -0
- package/dist/rules/prefer-namespace-keyword.d.ts +4 -0
- package/dist/rules/prefer-namespace-keyword.js +42 -0
- package/dist/rules/prefer-nullish-coalescing.d.ts +22 -0
- package/dist/rules/prefer-nullish-coalescing.js +647 -0
- package/dist/rules/prefer-optional-chain-utils/PreferOptionalChainOptions.d.ts +11 -0
- package/dist/rules/prefer-optional-chain-utils/PreferOptionalChainOptions.js +2 -0
- package/dist/rules/prefer-optional-chain-utils/analyzeChain.d.ts +7 -0
- package/dist/rules/prefer-optional-chain-utils/analyzeChain.js +569 -0
- package/dist/rules/prefer-optional-chain-utils/checkNullishAndReport.d.ts +6 -0
- package/dist/rules/prefer-optional-chain-utils/checkNullishAndReport.js +45 -0
- package/dist/rules/prefer-optional-chain-utils/compareNodes.d.ts +15 -0
- package/dist/rules/prefer-optional-chain-utils/compareNodes.js +326 -0
- package/dist/rules/prefer-optional-chain-utils/gatherLogicalOperands.d.ts +61 -0
- package/dist/rules/prefer-optional-chain-utils/gatherLogicalOperands.js +411 -0
- package/dist/rules/prefer-optional-chain.d.ts +5 -0
- package/dist/rules/prefer-optional-chain.js +150 -0
- package/dist/rules/prefer-promise-reject-errors.d.ts +14 -0
- package/dist/rules/prefer-promise-reject-errors.js +124 -0
- package/dist/rules/prefer-readonly-parameter-types.d.ts +14 -0
- package/dist/rules/prefer-readonly-parameter-types.js +89 -0
- package/dist/rules/prefer-readonly.d.ts +10 -0
- package/dist/rules/prefer-readonly.js +439 -0
- package/dist/rules/prefer-reduce-type-parameter.d.ts +4 -0
- package/dist/rules/prefer-reduce-type-parameter.js +114 -0
- package/dist/rules/prefer-regexp-exec.d.ts +4 -0
- package/dist/rules/prefer-regexp-exec.js +178 -0
- package/dist/rules/prefer-return-this-type.d.ts +4 -0
- package/dist/rules/prefer-return-this-type.js +154 -0
- package/dist/rules/prefer-string-starts-ends-with.d.ts +12 -0
- package/dist/rules/prefer-string-starts-ends-with.js +512 -0
- package/dist/rules/prefer-ts-expect-error.d.ts +5 -0
- package/dist/rules/prefer-ts-expect-error.js +71 -0
- package/dist/rules/promise-function-async.d.ts +15 -0
- package/dist/rules/promise-function-async.js +204 -0
- package/dist/rules/related-getter-setter-pairs.d.ts +4 -0
- package/dist/rules/related-getter-setter-pairs.js +71 -0
- package/dist/rules/require-array-sort-compare.d.ts +10 -0
- package/dist/rules/require-array-sort-compare.js +63 -0
- package/dist/rules/require-await.d.ts +4 -0
- package/dist/rules/require-await.js +263 -0
- package/dist/rules/restrict-plus-operands.d.ts +15 -0
- package/dist/rules/restrict-plus-operands.js +231 -0
- package/dist/rules/restrict-template-expressions.d.ts +19 -0
- package/dist/rules/restrict-template-expressions.js +119 -0
- package/dist/rules/return-await.d.ts +5 -0
- package/dist/rules/return-await.js +363 -0
- package/dist/rules/sort-type-constituents.d.ts +14 -0
- package/dist/rules/sort-type-constituents.js +272 -0
- package/dist/rules/strict-boolean-expressions.d.ts +19 -0
- package/dist/rules/strict-boolean-expressions.js +882 -0
- package/dist/rules/strict-void-return.d.ts +10 -0
- package/dist/rules/strict-void-return.js +374 -0
- package/dist/rules/switch-exhaustiveness-check.d.ts +33 -0
- package/dist/rules/switch-exhaustiveness-check.js +291 -0
- package/dist/rules/triple-slash-reference.d.ts +12 -0
- package/dist/rules/triple-slash-reference.js +110 -0
- package/dist/rules/typedef.d.ts +16 -0
- package/dist/rules/typedef.js +239 -0
- package/dist/rules/unbound-method.d.ts +9 -0
- package/dist/rules/unbound-method.js +334 -0
- package/dist/rules/unified-signatures.d.ts +11 -0
- package/dist/rules/unified-signatures.js +465 -0
- package/dist/rules/use-unknown-in-catch-callback-variable.d.ts +6 -0
- package/dist/rules/use-unknown-in-catch-callback-variable.js +261 -0
- package/dist/util/assertionFunctionUtils.d.ts +16 -0
- package/dist/util/assertionFunctionUtils.js +116 -0
- package/dist/util/astUtils.d.ts +17 -0
- package/dist/util/astUtils.js +143 -0
- package/dist/util/baseTypeUtils.d.ts +13 -0
- package/dist/util/baseTypeUtils.js +75 -0
- package/dist/util/class-scope-analyzer/classScopeAnalyzer.d.ts +52 -0
- package/dist/util/class-scope-analyzer/classScopeAnalyzer.js +566 -0
- package/dist/util/class-scope-analyzer/extractComputedName.d.ts +17 -0
- package/dist/util/class-scope-analyzer/extractComputedName.js +70 -0
- package/dist/util/class-scope-analyzer/types.d.ts +12 -0
- package/dist/util/class-scope-analyzer/types.js +10 -0
- package/dist/util/collectUnusedVariables.d.ts +15 -0
- package/dist/util/collectUnusedVariables.js +598 -0
- package/dist/util/createRule.d.ts +5 -0
- package/dist/util/createRule.js +5 -0
- package/dist/util/escapeRegExp.d.ts +1 -0
- package/dist/util/escapeRegExp.js +14 -0
- package/dist/util/explicitReturnTypeUtils.d.ts +47 -0
- package/dist/util/explicitReturnTypeUtils.js +238 -0
- package/dist/util/getBaseTypesOfClassMember.d.ts +11 -0
- package/dist/util/getBaseTypesOfClassMember.js +31 -0
- package/dist/util/getConstraintInfo.d.ts +35 -0
- package/dist/util/getConstraintInfo.js +70 -0
- package/dist/util/getESLintCoreRule.d.ts +27 -0
- package/dist/util/getESLintCoreRule.js +16 -0
- package/dist/util/getFixOrSuggest.d.ts +9 -0
- package/dist/util/getFixOrSuggest.js +13 -0
- package/dist/util/getForStatementHeadLoc.d.ts +17 -0
- package/dist/util/getForStatementHeadLoc.js +26 -0
- package/dist/util/getFunctionHeadLoc.d.ts +101 -0
- package/dist/util/getFunctionHeadLoc.js +161 -0
- package/dist/util/getMemberHeadLoc.d.ts +36 -0
- package/dist/util/getMemberHeadLoc.js +79 -0
- package/dist/util/getOperatorPrecedence.d.ts +39 -0
- package/dist/util/getOperatorPrecedence.js +421 -0
- package/dist/util/getParentFunctionNode.d.ts +2 -0
- package/dist/util/getParentFunctionNode.js +18 -0
- package/dist/util/getStaticStringValue.d.ts +11 -0
- package/dist/util/getStaticStringValue.js +44 -0
- package/dist/util/getStringLength.d.ts +1 -0
- package/dist/util/getStringLength.js +14 -0
- package/dist/util/getTextWithParentheses.d.ts +3 -0
- package/dist/util/getTextWithParentheses.js +16 -0
- package/dist/util/getThisExpression.d.ts +2 -0
- package/dist/util/getThisExpression.js +24 -0
- package/dist/util/getValueOfLiteralType.d.ts +2 -0
- package/dist/util/getValueOfLiteralType.js +16 -0
- package/dist/util/getWrappedCode.d.ts +2 -0
- package/dist/util/getWrappedCode.js +6 -0
- package/dist/util/getWrappingFixer.d.ts +42 -0
- package/dist/util/getWrappingFixer.js +184 -0
- package/dist/util/hasOverloadSignatures.d.ts +6 -0
- package/dist/util/hasOverloadSignatures.js +47 -0
- package/dist/util/index.d.ts +40 -0
- package/dist/util/index.js +53 -0
- package/dist/util/isArrayMethodCallWithPredicate.d.ts +3 -0
- package/dist/util/isArrayMethodCallWithPredicate.js +64 -0
- package/dist/util/isAssignee.d.ts +2 -0
- package/dist/util/isAssignee.js +50 -0
- package/dist/util/isHigherPrecedenceThanAwait.d.ts +2 -0
- package/dist/util/isHigherPrecedenceThanAwait.js +46 -0
- package/dist/util/isNodeEqual.d.ts +2 -0
- package/dist/util/isNodeEqual.js +25 -0
- package/dist/util/isNullLiteral.d.ts +2 -0
- package/dist/util/isNullLiteral.js +7 -0
- package/dist/util/isPromiseAggregatorMethod.d.ts +3 -0
- package/dist/util/isPromiseAggregatorMethod.js +22 -0
- package/dist/util/isStartOfExpressionStatement.d.ts +7 -0
- package/dist/util/isStartOfExpressionStatement.js +22 -0
- package/dist/util/isTypeImport.d.ts +12 -0
- package/dist/util/isTypeImport.js +21 -0
- package/dist/util/isUndefinedIdentifier.d.ts +2 -0
- package/dist/util/isUndefinedIdentifier.js +7 -0
- package/dist/util/misc.d.ts +115 -0
- package/dist/util/misc.js +270 -0
- package/dist/util/needsPrecedingSemiColon.d.ts +11 -0
- package/dist/util/needsPrecedingSemiColon.js +97 -0
- package/dist/util/needsToBeAwaited.d.ts +7 -0
- package/dist/util/needsToBeAwaited.js +63 -0
- package/dist/util/objectIterators.d.ts +3 -0
- package/dist/util/objectIterators.js +25 -0
- package/dist/util/promiseUtils.d.ts +27 -0
- package/dist/util/promiseUtils.js +98 -0
- package/dist/util/rangeToLoc.d.ts +2 -0
- package/dist/util/rangeToLoc.js +9 -0
- package/dist/util/referenceContainsTypeQuery.d.ts +5 -0
- package/dist/util/referenceContainsTypeQuery.js +19 -0
- package/dist/util/scopeUtils.d.ts +3 -0
- package/dist/util/scopeUtils.js +10 -0
- package/dist/util/skipChainExpression.d.ts +2 -0
- package/dist/util/skipChainExpression.js +7 -0
- package/dist/util/truthinessUtils.d.ts +3 -0
- package/dist/util/truthinessUtils.js +60 -0
- package/dist/util/types.d.ts +2 -0
- package/dist/util/types.js +2 -0
- package/dist/util/walkStatements.d.ts +7 -0
- package/dist/util/walkStatements.js +56 -0
- package/index.d.ts +13 -0
- package/package.json +137 -0
- package/raw-plugin.d.ts +25 -0
- package/rules.d.ts +87 -0
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.analyzeChain = analyzeChain;
|
|
37
|
+
const utils_1 = require("@typescript-eslint/utils");
|
|
38
|
+
const ts_api_utils_1 = require("ts-api-utils");
|
|
39
|
+
const ts = __importStar(require("typescript"));
|
|
40
|
+
const util_1 = require("../../util");
|
|
41
|
+
const checkNullishAndReport_1 = require("./checkNullishAndReport");
|
|
42
|
+
const compareNodes_1 = require("./compareNodes");
|
|
43
|
+
const gatherLogicalOperands_1 = require("./gatherLogicalOperands");
|
|
44
|
+
function includesType(parserServices, node, typeFlagIn) {
|
|
45
|
+
const typeFlag = typeFlagIn | ts.TypeFlags.Any | ts.TypeFlags.Unknown;
|
|
46
|
+
const types = (0, ts_api_utils_1.unionConstituents)(parserServices.getTypeAtLocation(node));
|
|
47
|
+
for (const type of types) {
|
|
48
|
+
if ((0, util_1.isTypeFlagSet)(type, typeFlag)) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
function isValidAndLastChainOperand(ComparisonValueType, comparisonType, parserServices) {
|
|
55
|
+
const type = parserServices.getTypeAtLocation(ComparisonValueType);
|
|
56
|
+
const ANY_UNKNOWN_FLAGS = ts.TypeFlags.Any | ts.TypeFlags.Unknown;
|
|
57
|
+
const types = (0, ts_api_utils_1.unionConstituents)(type);
|
|
58
|
+
switch (comparisonType) {
|
|
59
|
+
case gatherLogicalOperands_1.ComparisonType.Equal: {
|
|
60
|
+
const isNullish = types.some(t => (0, util_1.isTypeFlagSet)(t, ANY_UNKNOWN_FLAGS | ts.TypeFlags.Null | ts.TypeFlags.Undefined));
|
|
61
|
+
return !isNullish;
|
|
62
|
+
}
|
|
63
|
+
case gatherLogicalOperands_1.ComparisonType.StrictEqual: {
|
|
64
|
+
const isUndefined = types.some(t => (0, util_1.isTypeFlagSet)(t, ANY_UNKNOWN_FLAGS | ts.TypeFlags.Undefined));
|
|
65
|
+
return !isUndefined;
|
|
66
|
+
}
|
|
67
|
+
case gatherLogicalOperands_1.ComparisonType.NotStrictEqual: {
|
|
68
|
+
return types.every(t => (0, util_1.isTypeFlagSet)(t, ts.TypeFlags.Undefined));
|
|
69
|
+
}
|
|
70
|
+
case gatherLogicalOperands_1.ComparisonType.NotEqual: {
|
|
71
|
+
return types.every(t => (0, util_1.isTypeFlagSet)(t, ts.TypeFlags.Undefined | ts.TypeFlags.Null));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function isValidOrLastChainOperand(ComparisonValueType, comparisonType, parserServices) {
|
|
76
|
+
const type = parserServices.getTypeAtLocation(ComparisonValueType);
|
|
77
|
+
const ANY_UNKNOWN_FLAGS = ts.TypeFlags.Any | ts.TypeFlags.Unknown;
|
|
78
|
+
const types = (0, ts_api_utils_1.unionConstituents)(type);
|
|
79
|
+
switch (comparisonType) {
|
|
80
|
+
case gatherLogicalOperands_1.ComparisonType.NotEqual: {
|
|
81
|
+
const isNullish = types.some(t => (0, util_1.isTypeFlagSet)(t, ANY_UNKNOWN_FLAGS | ts.TypeFlags.Null | ts.TypeFlags.Undefined));
|
|
82
|
+
return !isNullish;
|
|
83
|
+
}
|
|
84
|
+
case gatherLogicalOperands_1.ComparisonType.NotStrictEqual: {
|
|
85
|
+
const isUndefined = types.some(t => (0, util_1.isTypeFlagSet)(t, ANY_UNKNOWN_FLAGS | ts.TypeFlags.Undefined));
|
|
86
|
+
return !isUndefined;
|
|
87
|
+
}
|
|
88
|
+
case gatherLogicalOperands_1.ComparisonType.Equal:
|
|
89
|
+
return types.every(t => (0, util_1.isTypeFlagSet)(t, ts.TypeFlags.Undefined | ts.TypeFlags.Null));
|
|
90
|
+
case gatherLogicalOperands_1.ComparisonType.StrictEqual:
|
|
91
|
+
return types.every(t => (0, util_1.isTypeFlagSet)(t, ts.TypeFlags.Undefined));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const analyzeAndChainOperand = (parserServices, operand, index, chain) => {
|
|
95
|
+
switch (operand.comparisonType) {
|
|
96
|
+
case gatherLogicalOperands_1.NullishComparisonType.Boolean:
|
|
97
|
+
case gatherLogicalOperands_1.NullishComparisonType.NotEqualNullOrUndefined:
|
|
98
|
+
return [operand];
|
|
99
|
+
case gatherLogicalOperands_1.NullishComparisonType.NotStrictEqualNull: {
|
|
100
|
+
// handle `x !== null && x !== undefined`
|
|
101
|
+
const nextOperand = chain.at(index + 1);
|
|
102
|
+
if (nextOperand?.comparisonType ===
|
|
103
|
+
gatherLogicalOperands_1.NullishComparisonType.NotStrictEqualUndefined &&
|
|
104
|
+
(0, compareNodes_1.compareNodes)(operand.comparedName, nextOperand.comparedName) ===
|
|
105
|
+
compareNodes_1.NodeComparisonResult.Equal) {
|
|
106
|
+
return [operand, nextOperand];
|
|
107
|
+
}
|
|
108
|
+
if (nextOperand &&
|
|
109
|
+
!includesType(parserServices, operand.comparedName, ts.TypeFlags.Undefined)) {
|
|
110
|
+
// we know the next operand is not an `undefined` check and that this
|
|
111
|
+
// operand includes `undefined` - which means that making this an
|
|
112
|
+
// optional chain would change the runtime behavior of the expression
|
|
113
|
+
return [operand];
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
case gatherLogicalOperands_1.NullishComparisonType.NotStrictEqualUndefined: {
|
|
118
|
+
// handle `x !== undefined && x !== null`
|
|
119
|
+
const nextOperand = chain.at(index + 1);
|
|
120
|
+
if (nextOperand?.comparisonType ===
|
|
121
|
+
gatherLogicalOperands_1.NullishComparisonType.NotStrictEqualNull &&
|
|
122
|
+
(0, compareNodes_1.compareNodes)(operand.comparedName, nextOperand.comparedName) ===
|
|
123
|
+
compareNodes_1.NodeComparisonResult.Equal) {
|
|
124
|
+
return [operand, nextOperand];
|
|
125
|
+
}
|
|
126
|
+
if (includesType(parserServices, operand.comparedName, ts.TypeFlags.Null)) {
|
|
127
|
+
// we know the next operand is not a `null` check and that this
|
|
128
|
+
// operand includes `null` - which means that making this an
|
|
129
|
+
// optional chain would change the runtime behavior of the expression
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
return [operand];
|
|
133
|
+
}
|
|
134
|
+
default:
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
const analyzeOrChainOperand = (parserServices, operand, index, chain) => {
|
|
139
|
+
switch (operand.comparisonType) {
|
|
140
|
+
case gatherLogicalOperands_1.NullishComparisonType.NotBoolean:
|
|
141
|
+
case gatherLogicalOperands_1.NullishComparisonType.EqualNullOrUndefined:
|
|
142
|
+
return [operand];
|
|
143
|
+
case gatherLogicalOperands_1.NullishComparisonType.StrictEqualNull: {
|
|
144
|
+
// handle `x === null || x === undefined`
|
|
145
|
+
const nextOperand = chain.at(index + 1);
|
|
146
|
+
if (nextOperand?.comparisonType ===
|
|
147
|
+
gatherLogicalOperands_1.NullishComparisonType.StrictEqualUndefined &&
|
|
148
|
+
(0, compareNodes_1.compareNodes)(operand.comparedName, nextOperand.comparedName) ===
|
|
149
|
+
compareNodes_1.NodeComparisonResult.Equal) {
|
|
150
|
+
return [operand, nextOperand];
|
|
151
|
+
}
|
|
152
|
+
if (includesType(parserServices, operand.comparedName, ts.TypeFlags.Undefined)) {
|
|
153
|
+
// we know the next operand is not an `undefined` check and that this
|
|
154
|
+
// operand includes `undefined` - which means that making this an
|
|
155
|
+
// optional chain would change the runtime behavior of the expression
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
return [operand];
|
|
159
|
+
}
|
|
160
|
+
case gatherLogicalOperands_1.NullishComparisonType.StrictEqualUndefined: {
|
|
161
|
+
// handle `x === undefined || x === null`
|
|
162
|
+
const nextOperand = chain.at(index + 1);
|
|
163
|
+
if (nextOperand?.comparisonType === gatherLogicalOperands_1.NullishComparisonType.StrictEqualNull &&
|
|
164
|
+
(0, compareNodes_1.compareNodes)(operand.comparedName, nextOperand.comparedName) ===
|
|
165
|
+
compareNodes_1.NodeComparisonResult.Equal) {
|
|
166
|
+
return [operand, nextOperand];
|
|
167
|
+
}
|
|
168
|
+
if (includesType(parserServices, operand.comparedName, ts.TypeFlags.Null)) {
|
|
169
|
+
// we know the next operand is not a `null` check and that this
|
|
170
|
+
// operand includes `null` - which means that making this an
|
|
171
|
+
// optional chain would change the runtime behavior of the expression
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
return [operand];
|
|
175
|
+
}
|
|
176
|
+
default:
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
const resolveOperandSubset = (previousOperand, lastChainOperand) => {
|
|
181
|
+
const isNameSubset = (0, compareNodes_1.compareNodes)(previousOperand.comparedName, lastChainOperand.comparedName) === compareNodes_1.NodeComparisonResult.Subset;
|
|
182
|
+
if (lastChainOperand.yoda !== gatherLogicalOperands_1.Yoda.Unknown) {
|
|
183
|
+
return {
|
|
184
|
+
comparedName: lastChainOperand.comparedName,
|
|
185
|
+
comparisonValue: lastChainOperand.comparisonValue,
|
|
186
|
+
isSubset: isNameSubset,
|
|
187
|
+
isYoda: lastChainOperand.yoda === gatherLogicalOperands_1.Yoda.Yes,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
const isValueSubset = (0, compareNodes_1.compareNodes)(previousOperand.comparedName, lastChainOperand.comparisonValue) === compareNodes_1.NodeComparisonResult.Subset;
|
|
191
|
+
if (isNameSubset && !isValueSubset) {
|
|
192
|
+
return {
|
|
193
|
+
comparedName: lastChainOperand.comparedName,
|
|
194
|
+
comparisonValue: lastChainOperand.comparisonValue,
|
|
195
|
+
isSubset: true,
|
|
196
|
+
isYoda: false,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
if (!isNameSubset && isValueSubset) {
|
|
200
|
+
return {
|
|
201
|
+
comparedName: lastChainOperand.comparisonValue,
|
|
202
|
+
comparisonValue: lastChainOperand.comparedName,
|
|
203
|
+
isSubset: true,
|
|
204
|
+
isYoda: true,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
comparedName: lastChainOperand.comparisonValue,
|
|
209
|
+
comparisonValue: lastChainOperand.comparisonValue,
|
|
210
|
+
isSubset: false,
|
|
211
|
+
isYoda: true,
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* Returns the range that needs to be reported from the chain.
|
|
216
|
+
* @param chain The chain of logical expressions.
|
|
217
|
+
* @param boundary The boundary range that the range to report cannot fall outside.
|
|
218
|
+
* @param sourceCode The source code to get tokens.
|
|
219
|
+
* @returns The range to report.
|
|
220
|
+
*/
|
|
221
|
+
function getReportRange(chain, boundary, sourceCode) {
|
|
222
|
+
const leftNode = chain[0].node;
|
|
223
|
+
const rightNode = chain[chain.length - 1].node;
|
|
224
|
+
let leftMost = (0, util_1.nullThrows)(sourceCode.getFirstToken(leftNode), util_1.NullThrowsReasons.MissingToken('any token', leftNode.type));
|
|
225
|
+
let rightMost = (0, util_1.nullThrows)(sourceCode.getLastToken(rightNode), util_1.NullThrowsReasons.MissingToken('any token', rightNode.type));
|
|
226
|
+
while (leftMost.range[0] > boundary[0]) {
|
|
227
|
+
const token = sourceCode.getTokenBefore(leftMost);
|
|
228
|
+
if (!token || !(0, util_1.isOpeningParenToken)(token) || token.range[0] < boundary[0]) {
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
leftMost = token;
|
|
232
|
+
}
|
|
233
|
+
while (rightMost.range[1] < boundary[1]) {
|
|
234
|
+
const token = sourceCode.getTokenAfter(rightMost);
|
|
235
|
+
if (!token || !(0, util_1.isClosingParenToken)(token) || token.range[1] > boundary[1]) {
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
rightMost = token;
|
|
239
|
+
}
|
|
240
|
+
return [leftMost.range[0], rightMost.range[1]];
|
|
241
|
+
}
|
|
242
|
+
function getReportDescriptor(sourceCode, parserServices, node, operator, options, subChain, lastChain) {
|
|
243
|
+
const chain = lastChain ? [...subChain, lastChain] : subChain;
|
|
244
|
+
const lastOperand = chain[chain.length - 1];
|
|
245
|
+
let useSuggestionFixer;
|
|
246
|
+
if (options.allowPotentiallyUnsafeFixesThatModifyTheReturnTypeIKnowWhatImDoing ===
|
|
247
|
+
true) {
|
|
248
|
+
// user has opted-in to the unsafe behavior
|
|
249
|
+
useSuggestionFixer = false;
|
|
250
|
+
}
|
|
251
|
+
// optional chain specifically will union `undefined` into the final type
|
|
252
|
+
// so we need to make sure that there is at least one operand that includes
|
|
253
|
+
// `undefined`, or else we're going to change the final type - which is
|
|
254
|
+
// unsafe and might cause downstream type errors.
|
|
255
|
+
else if (lastChain ||
|
|
256
|
+
lastOperand.comparisonType === gatherLogicalOperands_1.NullishComparisonType.EqualNullOrUndefined ||
|
|
257
|
+
lastOperand.comparisonType ===
|
|
258
|
+
gatherLogicalOperands_1.NullishComparisonType.NotEqualNullOrUndefined ||
|
|
259
|
+
lastOperand.comparisonType === gatherLogicalOperands_1.NullishComparisonType.StrictEqualUndefined ||
|
|
260
|
+
lastOperand.comparisonType ===
|
|
261
|
+
gatherLogicalOperands_1.NullishComparisonType.NotStrictEqualUndefined ||
|
|
262
|
+
(operator === '||' &&
|
|
263
|
+
lastOperand.comparisonType === gatherLogicalOperands_1.NullishComparisonType.NotBoolean)) {
|
|
264
|
+
// we know the last operand is an equality check - so the change in types
|
|
265
|
+
// DOES NOT matter and will not change the runtime result or cause a type
|
|
266
|
+
// check error
|
|
267
|
+
useSuggestionFixer = false;
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
useSuggestionFixer = true;
|
|
271
|
+
for (const operand of chain) {
|
|
272
|
+
if (includesType(parserServices, operand.node, ts.TypeFlags.Undefined)) {
|
|
273
|
+
useSuggestionFixer = false;
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// TODO - we could further reduce the false-positive rate of this check by
|
|
278
|
+
// checking for cases where the change in types don't matter like
|
|
279
|
+
// the test location of an if/while/etc statement.
|
|
280
|
+
// but it's quite complex to do this without false-negatives, so
|
|
281
|
+
// for now we'll just be over-eager with our matching.
|
|
282
|
+
//
|
|
283
|
+
// it's MUCH better to false-positive here and only provide a
|
|
284
|
+
// suggestion fixer, rather than false-negative and autofix to
|
|
285
|
+
// broken code.
|
|
286
|
+
}
|
|
287
|
+
// In its most naive form we could just slap `?.` for every single part of the
|
|
288
|
+
// chain. However this would be undesirable because it'd create unnecessary
|
|
289
|
+
// conditions in the user's code where there were none before - and it would
|
|
290
|
+
// cause errors with rules like our `no-unnecessary-condition`.
|
|
291
|
+
//
|
|
292
|
+
// Instead we want to include the minimum number of `?.` required to correctly
|
|
293
|
+
// unify the code into a single chain. Naively you might think that we can
|
|
294
|
+
// just take the final operand add `?.` after the locations from the previous
|
|
295
|
+
// operands - however this won't be correct either because earlier operands
|
|
296
|
+
// can include a necessary `?.` that's not needed or included in a later
|
|
297
|
+
// operand.
|
|
298
|
+
//
|
|
299
|
+
// So instead what we need to do is to start at the first operand and
|
|
300
|
+
// iteratively diff it against the next operand, and add the difference to the
|
|
301
|
+
// first operand.
|
|
302
|
+
//
|
|
303
|
+
// eg
|
|
304
|
+
// `foo && foo.bar && foo.bar.baz?.bam && foo.bar.baz.bam()`
|
|
305
|
+
// 1) `foo`
|
|
306
|
+
// 2) diff(`foo`, `foo.bar`) = `.bar`
|
|
307
|
+
// 3) result = `foo?.bar`
|
|
308
|
+
// 4) diff(`foo.bar`, `foo.bar.baz?.bam`) = `.baz?.bam`
|
|
309
|
+
// 5) result = `foo?.bar?.baz?.bam`
|
|
310
|
+
// 6) diff(`foo.bar.baz?.bam`, `foo.bar.baz.bam()`) = `()`
|
|
311
|
+
// 7) result = `foo?.bar?.baz?.bam?.()`
|
|
312
|
+
const parts = [];
|
|
313
|
+
for (const current of chain) {
|
|
314
|
+
const nextOperand = flattenChainExpression(sourceCode, current.comparedName);
|
|
315
|
+
const diff = nextOperand.slice(parts.length);
|
|
316
|
+
if (diff.length > 0) {
|
|
317
|
+
if (parts.length > 0) {
|
|
318
|
+
// we need to make the first operand of the diff optional so it matches the
|
|
319
|
+
// logic before merging
|
|
320
|
+
// foo.bar && foo.bar.baz
|
|
321
|
+
// diff = .baz
|
|
322
|
+
// result = foo.bar?.baz
|
|
323
|
+
diff[0].optional = true;
|
|
324
|
+
}
|
|
325
|
+
parts.push(...diff);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
let newCode = parts
|
|
329
|
+
.map(part => {
|
|
330
|
+
let str = '';
|
|
331
|
+
if (part.optional) {
|
|
332
|
+
str += '?.';
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
if (part.nonNull) {
|
|
336
|
+
str += '!';
|
|
337
|
+
}
|
|
338
|
+
if (part.requiresDot) {
|
|
339
|
+
str += '.';
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
if (part.precedence !== util_1.OperatorPrecedence.Invalid &&
|
|
343
|
+
part.precedence < util_1.OperatorPrecedence.Member) {
|
|
344
|
+
str += `(${part.text})`;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
str += part.text;
|
|
348
|
+
}
|
|
349
|
+
return str;
|
|
350
|
+
})
|
|
351
|
+
.join('');
|
|
352
|
+
if (lastOperand.node.type === utils_1.AST_NODE_TYPES.BinaryExpression) {
|
|
353
|
+
// retain the ending comparison for cases like
|
|
354
|
+
// x && x.a != null
|
|
355
|
+
// x && typeof x.a !== 'undefined'
|
|
356
|
+
const operator = lastOperand.node.operator;
|
|
357
|
+
const { left, right } = (() => {
|
|
358
|
+
if (lastOperand.isYoda) {
|
|
359
|
+
const unaryOperator = lastOperand.node.right.type === utils_1.AST_NODE_TYPES.UnaryExpression
|
|
360
|
+
? `${lastOperand.node.right.operator} `
|
|
361
|
+
: '';
|
|
362
|
+
return {
|
|
363
|
+
left: sourceCode.getText(lastOperand.node.left),
|
|
364
|
+
right: unaryOperator + newCode,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
const unaryOperator = lastOperand.node.left.type === utils_1.AST_NODE_TYPES.UnaryExpression
|
|
368
|
+
? `${lastOperand.node.left.operator} `
|
|
369
|
+
: '';
|
|
370
|
+
return {
|
|
371
|
+
left: unaryOperator + newCode,
|
|
372
|
+
right: sourceCode.getText(lastOperand.node.right),
|
|
373
|
+
};
|
|
374
|
+
})();
|
|
375
|
+
newCode = `${left} ${operator} ${right}`;
|
|
376
|
+
}
|
|
377
|
+
else if (lastOperand.comparisonType === gatherLogicalOperands_1.NullishComparisonType.NotBoolean) {
|
|
378
|
+
newCode = `!${newCode}`;
|
|
379
|
+
}
|
|
380
|
+
const reportRange = getReportRange(chain, node.range, sourceCode);
|
|
381
|
+
const fix = fixer => fixer.replaceTextRange(reportRange, newCode);
|
|
382
|
+
return {
|
|
383
|
+
loc: {
|
|
384
|
+
end: sourceCode.getLocFromIndex(reportRange[1]),
|
|
385
|
+
start: sourceCode.getLocFromIndex(reportRange[0]),
|
|
386
|
+
},
|
|
387
|
+
messageId: 'preferOptionalChain',
|
|
388
|
+
...(0, util_1.getFixOrSuggest)({
|
|
389
|
+
fixOrSuggest: useSuggestionFixer ? 'suggest' : 'fix',
|
|
390
|
+
suggestion: {
|
|
391
|
+
fix,
|
|
392
|
+
messageId: 'optionalChainSuggest',
|
|
393
|
+
},
|
|
394
|
+
}),
|
|
395
|
+
};
|
|
396
|
+
function flattenChainExpression(sourceCode, node) {
|
|
397
|
+
switch (node.type) {
|
|
398
|
+
case utils_1.AST_NODE_TYPES.ChainExpression:
|
|
399
|
+
return flattenChainExpression(sourceCode, node.expression);
|
|
400
|
+
case utils_1.AST_NODE_TYPES.CallExpression: {
|
|
401
|
+
const argumentsText = (() => {
|
|
402
|
+
const closingParenToken = (0, util_1.nullThrows)(sourceCode.getLastToken(node), util_1.NullThrowsReasons.MissingToken('closing parenthesis', node.type));
|
|
403
|
+
const openingParenToken = (0, util_1.nullThrows)(sourceCode.getFirstTokenBetween(node.typeArguments ?? node.callee, closingParenToken, util_1.isOpeningParenToken), util_1.NullThrowsReasons.MissingToken('opening parenthesis', node.type));
|
|
404
|
+
return sourceCode.text.substring(openingParenToken.range[0], closingParenToken.range[1]);
|
|
405
|
+
})();
|
|
406
|
+
const typeArgumentsText = (() => {
|
|
407
|
+
if (node.typeArguments == null) {
|
|
408
|
+
return '';
|
|
409
|
+
}
|
|
410
|
+
return sourceCode.getText(node.typeArguments);
|
|
411
|
+
})();
|
|
412
|
+
return [
|
|
413
|
+
...flattenChainExpression(sourceCode, node.callee),
|
|
414
|
+
{
|
|
415
|
+
nonNull: false,
|
|
416
|
+
optional: node.optional,
|
|
417
|
+
// no precedence for this
|
|
418
|
+
precedence: util_1.OperatorPrecedence.Invalid,
|
|
419
|
+
requiresDot: false,
|
|
420
|
+
text: typeArgumentsText + argumentsText,
|
|
421
|
+
},
|
|
422
|
+
];
|
|
423
|
+
}
|
|
424
|
+
case utils_1.AST_NODE_TYPES.MemberExpression: {
|
|
425
|
+
const propertyText = sourceCode.getText(node.property);
|
|
426
|
+
return [
|
|
427
|
+
...flattenChainExpression(sourceCode, node.object),
|
|
428
|
+
{
|
|
429
|
+
nonNull: node.object.type === utils_1.AST_NODE_TYPES.TSNonNullExpression,
|
|
430
|
+
optional: node.optional,
|
|
431
|
+
precedence: node.computed
|
|
432
|
+
? // computed is already wrapped in [] so no need to wrap in () as well
|
|
433
|
+
util_1.OperatorPrecedence.Invalid
|
|
434
|
+
: (0, util_1.getOperatorPrecedenceForNode)(node.property),
|
|
435
|
+
requiresDot: !node.computed,
|
|
436
|
+
text: node.computed ? `[${propertyText}]` : propertyText,
|
|
437
|
+
},
|
|
438
|
+
];
|
|
439
|
+
}
|
|
440
|
+
case utils_1.AST_NODE_TYPES.TSNonNullExpression:
|
|
441
|
+
return flattenChainExpression(sourceCode, node.expression);
|
|
442
|
+
default:
|
|
443
|
+
return [
|
|
444
|
+
{
|
|
445
|
+
nonNull: false,
|
|
446
|
+
optional: false,
|
|
447
|
+
precedence: (0, util_1.getOperatorPrecedenceForNode)(node),
|
|
448
|
+
requiresDot: false,
|
|
449
|
+
text: sourceCode.getText(node),
|
|
450
|
+
},
|
|
451
|
+
];
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
function analyzeChain(context, parserServices, options, node, operator, chain, lastChainOperand) {
|
|
456
|
+
// need at least 2 operands in a chain for it to be a chain
|
|
457
|
+
if (chain.length + (lastChainOperand ? 1 : 0) <= 1 ||
|
|
458
|
+
/* istanbul ignore next -- previous checks make this unreachable, but keep it for exhaustiveness check */
|
|
459
|
+
operator === '??') {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
const analyzeOperand = (() => {
|
|
463
|
+
switch (operator) {
|
|
464
|
+
case '&&':
|
|
465
|
+
return analyzeAndChainOperand;
|
|
466
|
+
case '||':
|
|
467
|
+
return analyzeOrChainOperand;
|
|
468
|
+
}
|
|
469
|
+
})();
|
|
470
|
+
// Things like x !== null && x !== undefined have two nodes, but they are
|
|
471
|
+
// one logical unit here, so we'll allow them to be grouped.
|
|
472
|
+
let subChain = [];
|
|
473
|
+
let lastChain = undefined;
|
|
474
|
+
const maybeReportThenReset = (newChainSeed) => {
|
|
475
|
+
if (subChain.length + (lastChain ? 1 : 0) > 1) {
|
|
476
|
+
const subChainFlat = subChain.flat();
|
|
477
|
+
const maybeNullishNodes = lastChain
|
|
478
|
+
? subChainFlat.map(({ node }) => node)
|
|
479
|
+
: subChainFlat.slice(0, -1).map(({ node }) => node);
|
|
480
|
+
(0, checkNullishAndReport_1.checkNullishAndReport)(context, parserServices, options, maybeNullishNodes, getReportDescriptor(context.sourceCode, parserServices, node, operator, options, subChainFlat, lastChain));
|
|
481
|
+
}
|
|
482
|
+
// we've reached the end of a chain of logical expressions
|
|
483
|
+
// i.e. the current operand doesn't belong to the previous chain.
|
|
484
|
+
//
|
|
485
|
+
// we don't want to throw away the current operand otherwise we will skip it
|
|
486
|
+
// and that can cause us to miss chains. So instead we seed the new chain
|
|
487
|
+
// with the current operand
|
|
488
|
+
//
|
|
489
|
+
// eg this means we can catch cases like:
|
|
490
|
+
// unrelated != null && foo != null && foo.bar != null;
|
|
491
|
+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ first "chain"
|
|
492
|
+
// ^^^^^^^^^^^ newChainSeed
|
|
493
|
+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ second chain
|
|
494
|
+
subChain = newChainSeed ? [newChainSeed] : [];
|
|
495
|
+
lastChain = undefined;
|
|
496
|
+
};
|
|
497
|
+
for (let i = 0; i < chain.length; i += 1) {
|
|
498
|
+
const lastOperand = subChain.flat().at(-1);
|
|
499
|
+
const operand = chain[i];
|
|
500
|
+
const validatedOperands = analyzeOperand(parserServices, operand, i, chain);
|
|
501
|
+
if (!validatedOperands) {
|
|
502
|
+
// TODO - #7170
|
|
503
|
+
// check if the name is a superset/equal - if it is, then it likely
|
|
504
|
+
// intended to be part of the chain and something we should include in the
|
|
505
|
+
// report, eg
|
|
506
|
+
// foo == null || foo.bar;
|
|
507
|
+
// ^^^^^^^^^^^ valid OR chain
|
|
508
|
+
// ^^^^^^^ invalid OR chain logical, but still part of
|
|
509
|
+
// the chain for combination purposes
|
|
510
|
+
if (lastOperand) {
|
|
511
|
+
const comparisonResult = (0, compareNodes_1.compareNodes)(lastOperand.comparedName, operand.comparedName);
|
|
512
|
+
switch (operand.comparisonType) {
|
|
513
|
+
case gatherLogicalOperands_1.NullishComparisonType.StrictEqualUndefined:
|
|
514
|
+
case gatherLogicalOperands_1.NullishComparisonType.NotStrictEqualUndefined: {
|
|
515
|
+
if (comparisonResult === compareNodes_1.NodeComparisonResult.Subset) {
|
|
516
|
+
lastChain = operand;
|
|
517
|
+
}
|
|
518
|
+
break;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
maybeReportThenReset();
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
// in case multiple operands were consumed - make sure to correctly increment the index
|
|
526
|
+
i += validatedOperands.length - 1;
|
|
527
|
+
const currentOperand = validatedOperands[0];
|
|
528
|
+
if (lastOperand) {
|
|
529
|
+
const comparisonResult = (0, compareNodes_1.compareNodes)(lastOperand.comparedName,
|
|
530
|
+
// purposely inspect and push the last operand because the prior operands don't matter
|
|
531
|
+
// this also means we won't false-positive in cases like
|
|
532
|
+
// foo !== null && foo !== undefined
|
|
533
|
+
validatedOperands[validatedOperands.length - 1].comparedName);
|
|
534
|
+
if (comparisonResult === compareNodes_1.NodeComparisonResult.Subset) {
|
|
535
|
+
// the operands are comparable, so we can continue searching
|
|
536
|
+
subChain.push(currentOperand);
|
|
537
|
+
}
|
|
538
|
+
else if (comparisonResult === compareNodes_1.NodeComparisonResult.Invalid) {
|
|
539
|
+
maybeReportThenReset(validatedOperands);
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
// purposely don't push this case because the node is a no-op and if
|
|
543
|
+
// we consider it then we might report on things like
|
|
544
|
+
// foo && foo
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
subChain.push(currentOperand);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
const lastOperand = subChain.flat().at(-1);
|
|
552
|
+
if (lastOperand && lastChainOperand) {
|
|
553
|
+
const isValidLastChainOperand = operator === '&&'
|
|
554
|
+
? isValidAndLastChainOperand
|
|
555
|
+
: isValidOrLastChainOperand;
|
|
556
|
+
const { comparedName, comparisonValue, isSubset, isYoda } = resolveOperandSubset(lastOperand, lastChainOperand);
|
|
557
|
+
if (isSubset &&
|
|
558
|
+
isValidLastChainOperand(comparisonValue, lastChainOperand.comparisonType, parserServices)) {
|
|
559
|
+
lastChain = {
|
|
560
|
+
...lastChainOperand,
|
|
561
|
+
comparedName,
|
|
562
|
+
comparisonValue,
|
|
563
|
+
isYoda,
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
// check the leftovers
|
|
568
|
+
maybeReportThenReset();
|
|
569
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ParserServicesWithTypeInformation, TSESTree } from '@typescript-eslint/utils';
|
|
2
|
+
import type { ReportDescriptor, RuleContext } from '@typescript-eslint/utils/ts-eslint';
|
|
3
|
+
import type { PreferOptionalChainMessageIds, PreferOptionalChainOptions } from './PreferOptionalChainOptions';
|
|
4
|
+
export declare function checkNullishAndReport(context: RuleContext<PreferOptionalChainMessageIds, [
|
|
5
|
+
PreferOptionalChainOptions
|
|
6
|
+
]>, parserServices: ParserServicesWithTypeInformation, { requireNullish }: PreferOptionalChainOptions, maybeNullishNodes: TSESTree.Expression[], descriptor: ReportDescriptor<PreferOptionalChainMessageIds>): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.checkNullishAndReport = checkNullishAndReport;
|
|
37
|
+
const type_utils_1 = require("@typescript-eslint/type-utils");
|
|
38
|
+
const ts_api_utils_1 = require("ts-api-utils");
|
|
39
|
+
const ts = __importStar(require("typescript"));
|
|
40
|
+
function checkNullishAndReport(context, parserServices, { requireNullish }, maybeNullishNodes, descriptor) {
|
|
41
|
+
if (!requireNullish ||
|
|
42
|
+
maybeNullishNodes.some(node => (0, ts_api_utils_1.unionConstituents)(parserServices.getTypeAtLocation(node)).some(t => (0, type_utils_1.isTypeFlagSet)(t, ts.TypeFlags.Null | ts.TypeFlags.Undefined)))) {
|
|
43
|
+
context.report(descriptor);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { TSESTree } from '@typescript-eslint/utils';
|
|
2
|
+
export declare const enum NodeComparisonResult {
|
|
3
|
+
/** the two nodes are comparably the same */
|
|
4
|
+
Equal = "Equal",
|
|
5
|
+
/** the left node is a subset of the right node */
|
|
6
|
+
Subset = "Subset",
|
|
7
|
+
/** the left node is not the same or is a superset of the right node */
|
|
8
|
+
Invalid = "Invalid"
|
|
9
|
+
}
|
|
10
|
+
type CompareNodesArgument = TSESTree.Node | null | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Compares two nodes' ASTs to determine if the A is equal to or a subset of B
|
|
13
|
+
*/
|
|
14
|
+
export declare function compareNodes(nodeA: CompareNodesArgument, nodeB: CompareNodesArgument): NodeComparisonResult;
|
|
15
|
+
export {};
|