bahlint 28.58.6934
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/README.md +370 -0
- package/bin/eslint.js +195 -0
- package/conf/ecma-version.js +16 -0
- package/conf/globals.js +169 -0
- package/conf/replacements.json +26 -0
- package/conf/rule-type-list.json +91 -0
- package/lib/api.js +39 -0
- package/lib/cli-engine/formatters/formatters-meta.json +22 -0
- package/lib/cli-engine/formatters/gasoline.js +168 -0
- package/lib/cli-engine/formatters/html.js +359 -0
- package/lib/cli-engine/formatters/json-with-metadata.js +16 -0
- package/lib/cli-engine/formatters/json.js +13 -0
- package/lib/cli-engine/formatters/stylish.js +153 -0
- package/lib/cli-engine/hash.js +35 -0
- package/lib/cli-engine/lint-result-cache.js +220 -0
- package/lib/cli.js +607 -0
- package/lib/config/config-loader.js +683 -0
- package/lib/config/config.js +674 -0
- package/lib/config/default-config.js +78 -0
- package/lib/config/flat-config-array.js +217 -0
- package/lib/config/flat-config-schema.js +598 -0
- package/lib/config-api.js +12 -0
- package/lib/eslint/eslint-helpers.js +1462 -0
- package/lib/eslint/eslint.js +1364 -0
- package/lib/eslint/index.js +7 -0
- package/lib/eslint/worker.js +173 -0
- package/lib/languages/js/index.js +336 -0
- package/lib/languages/js/source-code/index.js +7 -0
- package/lib/languages/js/source-code/source-code.js +1178 -0
- package/lib/languages/js/source-code/token-store/backward-token-comment-cursor.js +61 -0
- package/lib/languages/js/source-code/token-store/backward-token-cursor.js +57 -0
- package/lib/languages/js/source-code/token-store/cursor.js +76 -0
- package/lib/languages/js/source-code/token-store/cursors.js +120 -0
- package/lib/languages/js/source-code/token-store/decorative-cursor.js +38 -0
- package/lib/languages/js/source-code/token-store/filter-cursor.js +42 -0
- package/lib/languages/js/source-code/token-store/forward-token-comment-cursor.js +65 -0
- package/lib/languages/js/source-code/token-store/forward-token-cursor.js +62 -0
- package/lib/languages/js/source-code/token-store/index.js +695 -0
- package/lib/languages/js/source-code/token-store/limit-cursor.js +39 -0
- package/lib/languages/js/source-code/token-store/padded-token-cursor.js +45 -0
- package/lib/languages/js/source-code/token-store/skip-cursor.js +41 -0
- package/lib/languages/js/source-code/token-store/utils.js +131 -0
- package/lib/languages/js/validate-language-options.js +196 -0
- package/lib/linter/apply-disable-directives.js +583 -0
- package/lib/linter/code-path-analysis/code-path-analyzer.js +828 -0
- package/lib/linter/code-path-analysis/code-path-segment.js +262 -0
- package/lib/linter/code-path-analysis/code-path-state.js +2370 -0
- package/lib/linter/code-path-analysis/code-path.js +332 -0
- package/lib/linter/code-path-analysis/debug-helpers.js +223 -0
- package/lib/linter/code-path-analysis/fork-context.js +374 -0
- package/lib/linter/code-path-analysis/id-generator.js +44 -0
- package/lib/linter/esquery.js +332 -0
- package/lib/linter/file-context.js +88 -0
- package/lib/linter/file-report.js +604 -0
- package/lib/linter/index.js +11 -0
- package/lib/linter/interpolate.js +50 -0
- package/lib/linter/linter.js +1614 -0
- package/lib/linter/rule-fixer.js +199 -0
- package/lib/linter/source-code-fixer.js +154 -0
- package/lib/linter/source-code-traverser.js +333 -0
- package/lib/linter/source-code-visitor.js +81 -0
- package/lib/linter/timing.js +209 -0
- package/lib/linter/vfile.js +115 -0
- package/lib/options.js +416 -0
- package/lib/rule-tester/index.js +7 -0
- package/lib/rule-tester/rule-tester.js +1817 -0
- package/lib/rules/accessor-pairs.js +420 -0
- package/lib/rules/array-bracket-newline.js +291 -0
- package/lib/rules/array-bracket-spacing.js +301 -0
- package/lib/rules/array-callback-return.js +493 -0
- package/lib/rules/array-element-newline.js +374 -0
- package/lib/rules/arrow-body-style.js +418 -0
- package/lib/rules/arrow-parens.js +237 -0
- package/lib/rules/arrow-spacing.js +188 -0
- package/lib/rules/block-scoped-var.js +137 -0
- package/lib/rules/block-spacing.js +202 -0
- package/lib/rules/brace-style.js +278 -0
- package/lib/rules/callback-return.js +216 -0
- package/lib/rules/camelcase.js +422 -0
- package/lib/rules/capitalized-comments.js +325 -0
- package/lib/rules/class-methods-use-this.js +250 -0
- package/lib/rules/comma-dangle.js +424 -0
- package/lib/rules/comma-spacing.js +205 -0
- package/lib/rules/comma-style.js +391 -0
- package/lib/rules/complexity.js +201 -0
- package/lib/rules/computed-property-spacing.js +251 -0
- package/lib/rules/consistent-return.js +221 -0
- package/lib/rules/consistent-this.js +179 -0
- package/lib/rules/constructor-super.js +453 -0
- package/lib/rules/curly.js +425 -0
- package/lib/rules/default-case-last.js +51 -0
- package/lib/rules/default-case.js +103 -0
- package/lib/rules/default-param-last.js +78 -0
- package/lib/rules/dot-location.js +138 -0
- package/lib/rules/dot-notation.js +216 -0
- package/lib/rules/eol-last.js +135 -0
- package/lib/rules/eqeqeq.js +210 -0
- package/lib/rules/for-direction.js +168 -0
- package/lib/rules/func-call-spacing.js +281 -0
- package/lib/rules/func-name-matching.js +338 -0
- package/lib/rules/func-names.js +194 -0
- package/lib/rules/func-style.js +221 -0
- package/lib/rules/function-call-argument-newline.js +166 -0
- package/lib/rules/function-paren-newline.js +368 -0
- package/lib/rules/generator-star-spacing.js +246 -0
- package/lib/rules/getter-return.js +242 -0
- package/lib/rules/global-require.js +117 -0
- package/lib/rules/grouped-accessor-pairs.js +268 -0
- package/lib/rules/guard-for-in.js +85 -0
- package/lib/rules/handle-callback-err.js +122 -0
- package/lib/rules/id-blacklist.js +241 -0
- package/lib/rules/id-denylist.js +223 -0
- package/lib/rules/id-length.js +217 -0
- package/lib/rules/id-match.js +363 -0
- package/lib/rules/implicit-arrow-linebreak.js +125 -0
- package/lib/rules/indent-legacy.js +1369 -0
- package/lib/rules/indent.js +2334 -0
- package/lib/rules/index.js +332 -0
- package/lib/rules/init-declarations.js +172 -0
- package/lib/rules/jsx-quotes.js +128 -0
- package/lib/rules/key-spacing.js +822 -0
- package/lib/rules/keyword-spacing.js +701 -0
- package/lib/rules/line-comment-position.js +157 -0
- package/lib/rules/linebreak-style.js +135 -0
- package/lib/rules/lines-around-comment.js +581 -0
- package/lib/rules/lines-around-directive.js +249 -0
- package/lib/rules/lines-between-class-members.js +358 -0
- package/lib/rules/logical-assignment-operators.js +688 -0
- package/lib/rules/max-classes-per-file.js +90 -0
- package/lib/rules/max-depth.js +159 -0
- package/lib/rules/max-len.js +497 -0
- package/lib/rules/max-lines-per-function.js +238 -0
- package/lib/rules/max-lines.js +189 -0
- package/lib/rules/max-nested-callbacks.js +115 -0
- package/lib/rules/max-params.js +148 -0
- package/lib/rules/max-statements-per-line.js +224 -0
- package/lib/rules/max-statements.js +188 -0
- package/lib/rules/multiline-comment-style.js +652 -0
- package/lib/rules/multiline-ternary.js +257 -0
- package/lib/rules/new-cap.js +277 -0
- package/lib/rules/new-parens.js +120 -0
- package/lib/rules/newline-after-var.js +307 -0
- package/lib/rules/newline-before-return.js +242 -0
- package/lib/rules/newline-per-chained-call.js +159 -0
- package/lib/rules/no-alert.js +149 -0
- package/lib/rules/no-array-constructor.js +195 -0
- package/lib/rules/no-async-promise-executor.js +45 -0
- package/lib/rules/no-await-in-loop.js +115 -0
- package/lib/rules/no-bitwise.js +145 -0
- package/lib/rules/no-buffer-constructor.js +74 -0
- package/lib/rules/no-caller.js +52 -0
- package/lib/rules/no-case-declarations.js +80 -0
- package/lib/rules/no-catch-shadow.js +96 -0
- package/lib/rules/no-class-assign.js +66 -0
- package/lib/rules/no-compare-neg-zero.js +74 -0
- package/lib/rules/no-cond-assign.js +175 -0
- package/lib/rules/no-confusing-arrow.js +127 -0
- package/lib/rules/no-console.js +221 -0
- package/lib/rules/no-const-assign.js +73 -0
- package/lib/rules/no-constant-binary-expression.js +603 -0
- package/lib/rules/no-constant-condition.js +177 -0
- package/lib/rules/no-constructor-return.js +62 -0
- package/lib/rules/no-continue.js +38 -0
- package/lib/rules/no-control-regex.js +142 -0
- package/lib/rules/no-debugger.js +41 -0
- package/lib/rules/no-delete-var.js +42 -0
- package/lib/rules/no-div-regex.js +60 -0
- package/lib/rules/no-dupe-args.js +92 -0
- package/lib/rules/no-dupe-class-members.js +117 -0
- package/lib/rules/no-dupe-else-if.js +145 -0
- package/lib/rules/no-dupe-keys.js +165 -0
- package/lib/rules/no-duplicate-case.js +78 -0
- package/lib/rules/no-duplicate-imports.js +368 -0
- package/lib/rules/no-else-return.js +450 -0
- package/lib/rules/no-empty-character-class.js +83 -0
- package/lib/rules/no-empty-function.js +236 -0
- package/lib/rules/no-empty-pattern.js +85 -0
- package/lib/rules/no-empty-static-block.js +73 -0
- package/lib/rules/no-empty.js +153 -0
- package/lib/rules/no-eq-null.js +51 -0
- package/lib/rules/no-eval.js +295 -0
- package/lib/rules/no-ex-assign.js +57 -0
- package/lib/rules/no-extend-native.js +180 -0
- package/lib/rules/no-extra-bind.js +224 -0
- package/lib/rules/no-extra-boolean-cast.js +420 -0
- package/lib/rules/no-extra-label.js +169 -0
- package/lib/rules/no-extra-parens.js +1669 -0
- package/lib/rules/no-extra-semi.js +167 -0
- package/lib/rules/no-fallthrough.js +260 -0
- package/lib/rules/no-floating-decimal.js +99 -0
- package/lib/rules/no-func-assign.js +77 -0
- package/lib/rules/no-global-assign.js +101 -0
- package/lib/rules/no-implicit-coercion.js +468 -0
- package/lib/rules/no-implicit-globals.js +187 -0
- package/lib/rules/no-implied-eval.js +170 -0
- package/lib/rules/no-import-assign.js +227 -0
- package/lib/rules/no-inline-comments.js +115 -0
- package/lib/rules/no-inner-declarations.js +147 -0
- package/lib/rules/no-invalid-regexp.js +244 -0
- package/lib/rules/no-invalid-this.js +178 -0
- package/lib/rules/no-irregular-whitespace.js +292 -0
- package/lib/rules/no-iterator.js +48 -0
- package/lib/rules/no-label-var.js +78 -0
- package/lib/rules/no-labels.js +156 -0
- package/lib/rules/no-lone-blocks.js +140 -0
- package/lib/rules/no-lonely-if.js +126 -0
- package/lib/rules/no-loop-func.js +267 -0
- package/lib/rules/no-loss-of-precision.js +249 -0
- package/lib/rules/no-magic-numbers.js +365 -0
- package/lib/rules/no-misleading-character-class.js +595 -0
- package/lib/rules/no-mixed-operators.js +253 -0
- package/lib/rules/no-mixed-requires.js +267 -0
- package/lib/rules/no-mixed-spaces-and-tabs.js +148 -0
- package/lib/rules/no-multi-assign.js +66 -0
- package/lib/rules/no-multi-spaces.js +179 -0
- package/lib/rules/no-multi-str.js +67 -0
- package/lib/rules/no-multiple-empty-lines.js +210 -0
- package/lib/rules/no-native-reassign.js +114 -0
- package/lib/rules/no-negated-condition.js +100 -0
- package/lib/rules/no-negated-in-lhs.js +59 -0
- package/lib/rules/no-nested-ternary.js +46 -0
- package/lib/rules/no-new-func.js +96 -0
- package/lib/rules/no-new-native-nonconstructor.js +70 -0
- package/lib/rules/no-new-object.js +76 -0
- package/lib/rules/no-new-require.js +67 -0
- package/lib/rules/no-new-symbol.js +74 -0
- package/lib/rules/no-new-wrappers.js +62 -0
- package/lib/rules/no-new.js +42 -0
- package/lib/rules/no-nonoctal-decimal-escape.js +176 -0
- package/lib/rules/no-obj-calls.js +99 -0
- package/lib/rules/no-object-constructor.js +124 -0
- package/lib/rules/no-octal-escape.js +53 -0
- package/lib/rules/no-octal.js +42 -0
- package/lib/rules/no-param-reassign.js +248 -0
- package/lib/rules/no-path-concat.js +79 -0
- package/lib/rules/no-plusplus.js +102 -0
- package/lib/rules/no-process-env.js +68 -0
- package/lib/rules/no-process-exit.js +67 -0
- package/lib/rules/no-promise-executor-return.js +264 -0
- package/lib/rules/no-proto.js +45 -0
- package/lib/rules/no-prototype-builtins.js +181 -0
- package/lib/rules/no-redeclare.js +173 -0
- package/lib/rules/no-regex-spaces.js +219 -0
- package/lib/rules/no-restricted-exports.js +227 -0
- package/lib/rules/no-restricted-globals.js +266 -0
- package/lib/rules/no-restricted-imports.js +892 -0
- package/lib/rules/no-restricted-modules.js +249 -0
- package/lib/rules/no-restricted-properties.js +233 -0
- package/lib/rules/no-restricted-syntax.js +74 -0
- package/lib/rules/no-return-assign.js +87 -0
- package/lib/rules/no-return-await.js +162 -0
- package/lib/rules/no-script-url.js +68 -0
- package/lib/rules/no-self-assign.js +186 -0
- package/lib/rules/no-self-compare.js +77 -0
- package/lib/rules/no-sequences.js +158 -0
- package/lib/rules/no-setter-return.js +224 -0
- package/lib/rules/no-shadow-restricted-names.js +113 -0
- package/lib/rules/no-shadow.js +624 -0
- package/lib/rules/no-spaced-func.js +105 -0
- package/lib/rules/no-sparse-arrays.js +68 -0
- package/lib/rules/no-sync.js +81 -0
- package/lib/rules/no-tabs.js +110 -0
- package/lib/rules/no-template-curly-in-string.js +45 -0
- package/lib/rules/no-ternary.js +38 -0
- package/lib/rules/no-this-before-super.js +365 -0
- package/lib/rules/no-throw-literal.js +46 -0
- package/lib/rules/no-trailing-spaces.js +227 -0
- package/lib/rules/no-unassigned-vars.js +80 -0
- package/lib/rules/no-undef-init.js +101 -0
- package/lib/rules/no-undef.js +84 -0
- package/lib/rules/no-undefined.js +85 -0
- package/lib/rules/no-underscore-dangle.js +383 -0
- package/lib/rules/no-unexpected-multiline.js +130 -0
- package/lib/rules/no-unmodified-loop-condition.js +360 -0
- package/lib/rules/no-unneeded-ternary.js +232 -0
- package/lib/rules/no-unreachable-loop.js +190 -0
- package/lib/rules/no-unreachable.js +300 -0
- package/lib/rules/no-unsafe-finally.js +119 -0
- package/lib/rules/no-unsafe-negation.js +152 -0
- package/lib/rules/no-unsafe-optional-chaining.js +221 -0
- package/lib/rules/no-unused-expressions.js +227 -0
- package/lib/rules/no-unused-labels.js +158 -0
- package/lib/rules/no-unused-private-class-members.js +219 -0
- package/lib/rules/no-unused-vars.js +1739 -0
- package/lib/rules/no-use-before-define.js +446 -0
- package/lib/rules/no-useless-assignment.js +657 -0
- package/lib/rules/no-useless-backreference.js +263 -0
- package/lib/rules/no-useless-call.js +95 -0
- package/lib/rules/no-useless-catch.js +57 -0
- package/lib/rules/no-useless-computed-key.js +204 -0
- package/lib/rules/no-useless-concat.js +121 -0
- package/lib/rules/no-useless-constructor.js +262 -0
- package/lib/rules/no-useless-escape.js +406 -0
- package/lib/rules/no-useless-rename.js +202 -0
- package/lib/rules/no-useless-return.js +401 -0
- package/lib/rules/no-var.js +367 -0
- package/lib/rules/no-void.js +69 -0
- package/lib/rules/no-warning-comments.js +209 -0
- package/lib/rules/no-whitespace-before-property.js +150 -0
- package/lib/rules/no-with.js +37 -0
- package/lib/rules/nonblock-statement-body-position.js +164 -0
- package/lib/rules/object-curly-newline.js +383 -0
- package/lib/rules/object-curly-spacing.js +369 -0
- package/lib/rules/object-property-newline.js +151 -0
- package/lib/rules/object-shorthand.js +652 -0
- package/lib/rules/one-var-declaration-per-line.js +117 -0
- package/lib/rules/one-var.js +717 -0
- package/lib/rules/operator-assignment.js +270 -0
- package/lib/rules/operator-linebreak.js +315 -0
- package/lib/rules/padded-blocks.js +366 -0
- package/lib/rules/padding-line-between-statements.js +612 -0
- package/lib/rules/prefer-arrow-callback.js +437 -0
- package/lib/rules/prefer-const.js +546 -0
- package/lib/rules/prefer-destructuring.js +332 -0
- package/lib/rules/prefer-exponentiation-operator.js +235 -0
- package/lib/rules/prefer-named-capture-group.js +197 -0
- package/lib/rules/prefer-numeric-literals.js +157 -0
- package/lib/rules/prefer-object-has-own.js +148 -0
- package/lib/rules/prefer-object-spread.js +319 -0
- package/lib/rules/prefer-promise-reject-errors.js +154 -0
- package/lib/rules/prefer-reflect.js +150 -0
- package/lib/rules/prefer-regex-literals.js +605 -0
- package/lib/rules/prefer-rest-params.js +117 -0
- package/lib/rules/prefer-spread.js +91 -0
- package/lib/rules/prefer-template.js +347 -0
- package/lib/rules/preserve-caught-error.js +535 -0
- package/lib/rules/quote-props.js +394 -0
- package/lib/rules/quotes.js +416 -0
- package/lib/rules/radix.js +193 -0
- package/lib/rules/require-atomic-updates.js +365 -0
- package/lib/rules/require-await.js +184 -0
- package/lib/rules/require-unicode-regexp.js +317 -0
- package/lib/rules/require-yield.js +86 -0
- package/lib/rules/rest-spread-spacing.js +150 -0
- package/lib/rules/semi-spacing.js +297 -0
- package/lib/rules/semi-style.js +218 -0
- package/lib/rules/semi.js +476 -0
- package/lib/rules/sort-imports.js +319 -0
- package/lib/rules/sort-keys.js +268 -0
- package/lib/rules/sort-vars.js +140 -0
- package/lib/rules/space-before-blocks.js +232 -0
- package/lib/rules/space-before-function-paren.js +202 -0
- package/lib/rules/space-in-parens.js +374 -0
- package/lib/rules/space-infix-ops.js +249 -0
- package/lib/rules/space-unary-ops.js +400 -0
- package/lib/rules/spaced-comment.js +447 -0
- package/lib/rules/strict.js +314 -0
- package/lib/rules/switch-colon-spacing.js +158 -0
- package/lib/rules/symbol-description.js +70 -0
- package/lib/rules/template-curly-spacing.js +168 -0
- package/lib/rules/template-tag-spacing.js +121 -0
- package/lib/rules/unicode-bom.js +73 -0
- package/lib/rules/use-isnan.js +268 -0
- package/lib/rules/utils/ast-utils.js +2828 -0
- package/lib/rules/utils/char-source.js +247 -0
- package/lib/rules/utils/fix-tracker.js +125 -0
- package/lib/rules/utils/keywords.js +67 -0
- package/lib/rules/utils/lazy-loading-rule-map.js +118 -0
- package/lib/rules/utils/regular-expressions.js +58 -0
- package/lib/rules/utils/unicode/index.js +16 -0
- package/lib/rules/utils/unicode/is-combining-character.js +13 -0
- package/lib/rules/utils/unicode/is-emoji-modifier.js +13 -0
- package/lib/rules/utils/unicode/is-regional-indicator-symbol.js +13 -0
- package/lib/rules/utils/unicode/is-surrogate-pair.js +14 -0
- package/lib/rules/valid-typeof.js +171 -0
- package/lib/rules/vars-on-top.js +165 -0
- package/lib/rules/wrap-iife.js +238 -0
- package/lib/rules/wrap-regex.js +91 -0
- package/lib/rules/yield-star-spacing.js +158 -0
- package/lib/rules/yoda.js +362 -0
- package/lib/services/parser-service.js +64 -0
- package/lib/services/processor-service.js +100 -0
- package/lib/services/suppressions-service.js +302 -0
- package/lib/services/warning-service.js +87 -0
- package/lib/shared/ajv.js +34 -0
- package/lib/shared/assert.js +21 -0
- package/lib/shared/ast-utils.js +30 -0
- package/lib/shared/deep-merge-arrays.js +62 -0
- package/lib/shared/directives.js +16 -0
- package/lib/shared/flags.js +89 -0
- package/lib/shared/logging.js +38 -0
- package/lib/shared/naming.js +109 -0
- package/lib/shared/option-utils.js +63 -0
- package/lib/shared/relative-module-resolver.js +28 -0
- package/lib/shared/runtime-info.js +177 -0
- package/lib/shared/serialization.js +78 -0
- package/lib/shared/severity.js +49 -0
- package/lib/shared/stats.js +30 -0
- package/lib/shared/string-utils.js +58 -0
- package/lib/shared/text-table.js +68 -0
- package/lib/shared/translate-cli-options.js +223 -0
- package/lib/shared/traverser.js +202 -0
- package/lib/types/config-api.d.ts +12 -0
- package/lib/types/index.d.ts +1482 -0
- package/lib/types/rules.d.ts +5603 -0
- package/lib/types/universal.d.ts +6 -0
- package/lib/types/use-at-your-own-risk.d.ts +34 -0
- package/lib/universal.js +10 -0
- package/lib/unsupported-api.js +26 -0
- package/messages/all-files-ignored.js +16 -0
- package/messages/all-matched-files-ignored.js +21 -0
- package/messages/config-file-missing.js +16 -0
- package/messages/config-plugin-missing.js +14 -0
- package/messages/config-serialize-function.js +30 -0
- package/messages/eslintrc-incompat.js +117 -0
- package/messages/eslintrc-plugins.js +27 -0
- package/messages/extend-config-missing.js +13 -0
- package/messages/failed-to-read-json.js +11 -0
- package/messages/file-not-found.js +10 -0
- package/messages/invalid-rule-options.js +17 -0
- package/messages/invalid-rule-severity.js +13 -0
- package/messages/no-config-found.js +15 -0
- package/messages/plugin-conflict.js +22 -0
- package/messages/plugin-invalid.js +16 -0
- package/messages/plugin-missing.js +19 -0
- package/messages/print-config-with-directory-path.js +8 -0
- package/messages/shared.js +23 -0
- package/messages/whitespace-found.js +11 -0
- package/package.json +220 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to flag use of alert, confirm, prompt
|
|
3
|
+
* @author Nicholas C. Zakas
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
//------------------------------------------------------------------------------
|
|
8
|
+
// Requirements
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
getStaticPropertyName: getPropertyName,
|
|
13
|
+
getVariableByName,
|
|
14
|
+
skipChainExpression,
|
|
15
|
+
} = require("./utils/ast-utils");
|
|
16
|
+
|
|
17
|
+
//------------------------------------------------------------------------------
|
|
18
|
+
// Helpers
|
|
19
|
+
//------------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Checks if the given name is a prohibited identifier.
|
|
23
|
+
* @param {string} name The name to check
|
|
24
|
+
* @returns {boolean} Whether or not the name is prohibited.
|
|
25
|
+
*/
|
|
26
|
+
function isProhibitedIdentifier(name) {
|
|
27
|
+
return /^(?:alert|confirm|prompt)$/u.test(name);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Finds the eslint-scope reference in the given scope.
|
|
32
|
+
* @param {Object} scope The scope to search.
|
|
33
|
+
* @param {ASTNode} node The identifier node.
|
|
34
|
+
* @returns {Reference|null} Returns the found reference or null if none were found.
|
|
35
|
+
*/
|
|
36
|
+
function findReference(scope, node) {
|
|
37
|
+
const references = scope.references.filter(
|
|
38
|
+
reference =>
|
|
39
|
+
reference.identifier.range[0] === node.range[0] &&
|
|
40
|
+
reference.identifier.range[1] === node.range[1],
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
if (references.length === 1) {
|
|
44
|
+
return references[0];
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Checks if the given identifier node is shadowed in the given scope.
|
|
51
|
+
* @param {Object} scope The current scope.
|
|
52
|
+
* @param {string} node The identifier node to check
|
|
53
|
+
* @returns {boolean} Whether or not the name is shadowed.
|
|
54
|
+
*/
|
|
55
|
+
function isShadowed(scope, node) {
|
|
56
|
+
const reference = findReference(scope, node);
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
reference && reference.resolved && reference.resolved.defs.length > 0
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Checks if the given identifier node is a ThisExpression in the global scope or the global window property.
|
|
65
|
+
* @param {Object} scope The current scope.
|
|
66
|
+
* @param {string} node The identifier node to check
|
|
67
|
+
* @returns {boolean} Whether or not the node is a reference to the global object.
|
|
68
|
+
*/
|
|
69
|
+
function isGlobalThisReferenceOrGlobalWindow(scope, node) {
|
|
70
|
+
if (scope.type === "global" && node.type === "ThisExpression") {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
if (
|
|
74
|
+
node.type === "Identifier" &&
|
|
75
|
+
(node.name === "window" ||
|
|
76
|
+
(node.name === "globalThis" &&
|
|
77
|
+
getVariableByName(scope, "globalThis")))
|
|
78
|
+
) {
|
|
79
|
+
return !isShadowed(scope, node);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//------------------------------------------------------------------------------
|
|
86
|
+
// Rule Definition
|
|
87
|
+
//------------------------------------------------------------------------------
|
|
88
|
+
|
|
89
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
90
|
+
module.exports = {
|
|
91
|
+
meta: {
|
|
92
|
+
type: "suggestion",
|
|
93
|
+
|
|
94
|
+
docs: {
|
|
95
|
+
description: "Disallow the use of `alert`, `confirm`, and `prompt`",
|
|
96
|
+
recommended: false,
|
|
97
|
+
url: "https://eslint.org/docs/latest/rules/no-alert",
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
schema: [],
|
|
101
|
+
|
|
102
|
+
messages: {
|
|
103
|
+
unexpected: "Unexpected {{name}}.",
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
create(context) {
|
|
108
|
+
const sourceCode = context.sourceCode;
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
CallExpression(node) {
|
|
112
|
+
const callee = skipChainExpression(node.callee),
|
|
113
|
+
currentScope = sourceCode.getScope(node);
|
|
114
|
+
|
|
115
|
+
// without window.
|
|
116
|
+
if (callee.type === "Identifier") {
|
|
117
|
+
const name = callee.name;
|
|
118
|
+
|
|
119
|
+
if (
|
|
120
|
+
!isShadowed(currentScope, callee) &&
|
|
121
|
+
isProhibitedIdentifier(callee.name)
|
|
122
|
+
) {
|
|
123
|
+
context.report({
|
|
124
|
+
node,
|
|
125
|
+
messageId: "unexpected",
|
|
126
|
+
data: { name },
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
} else if (
|
|
130
|
+
callee.type === "MemberExpression" &&
|
|
131
|
+
isGlobalThisReferenceOrGlobalWindow(
|
|
132
|
+
currentScope,
|
|
133
|
+
callee.object,
|
|
134
|
+
)
|
|
135
|
+
) {
|
|
136
|
+
const name = getPropertyName(callee);
|
|
137
|
+
|
|
138
|
+
if (isProhibitedIdentifier(name)) {
|
|
139
|
+
context.report({
|
|
140
|
+
node,
|
|
141
|
+
messageId: "unexpected",
|
|
142
|
+
data: { name },
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
},
|
|
149
|
+
};
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Disallow construction of dense arrays using the Array constructor
|
|
3
|
+
* @author Matt DuVall <http://www.mattduvall.com/>
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
//------------------------------------------------------------------------------
|
|
9
|
+
// Requirements
|
|
10
|
+
//------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
getVariableByName,
|
|
14
|
+
isClosingParenToken,
|
|
15
|
+
isOpeningParenToken,
|
|
16
|
+
isStartOfExpressionStatement,
|
|
17
|
+
needsPrecedingSemicolon,
|
|
18
|
+
} = require("./utils/ast-utils");
|
|
19
|
+
|
|
20
|
+
//------------------------------------------------------------------------------
|
|
21
|
+
// Rule Definition
|
|
22
|
+
//------------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
25
|
+
module.exports = {
|
|
26
|
+
meta: {
|
|
27
|
+
dialects: ["javascript", "typescript"],
|
|
28
|
+
language: "javascript",
|
|
29
|
+
type: "suggestion",
|
|
30
|
+
|
|
31
|
+
docs: {
|
|
32
|
+
description: "Disallow `Array` constructors",
|
|
33
|
+
recommended: false,
|
|
34
|
+
url: "https://eslint.org/docs/latest/rules/no-array-constructor",
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
fixable: "code",
|
|
38
|
+
|
|
39
|
+
hasSuggestions: true,
|
|
40
|
+
|
|
41
|
+
schema: [],
|
|
42
|
+
|
|
43
|
+
messages: {
|
|
44
|
+
preferLiteral: "The array literal notation [] is preferable.",
|
|
45
|
+
useLiteral: "Replace with an array literal.",
|
|
46
|
+
useLiteralAfterSemicolon:
|
|
47
|
+
"Replace with an array literal, add preceding semicolon.",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
create(context) {
|
|
52
|
+
const sourceCode = context.sourceCode;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Checks if there are comments in Array constructor expressions.
|
|
56
|
+
* @param {ASTNode} node A CallExpression or NewExpression node.
|
|
57
|
+
* @returns {boolean} True if there are comments, false otherwise.
|
|
58
|
+
*/
|
|
59
|
+
function hasCommentsInArrayConstructor(node) {
|
|
60
|
+
const firstToken = sourceCode.getFirstToken(node);
|
|
61
|
+
const lastToken = sourceCode.getLastToken(node);
|
|
62
|
+
|
|
63
|
+
let lastRelevantToken = sourceCode.getLastToken(node.callee);
|
|
64
|
+
|
|
65
|
+
while (
|
|
66
|
+
lastRelevantToken !== lastToken &&
|
|
67
|
+
!isOpeningParenToken(lastRelevantToken)
|
|
68
|
+
) {
|
|
69
|
+
lastRelevantToken = sourceCode.getTokenAfter(lastRelevantToken);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return sourceCode.commentsExistBetween(
|
|
73
|
+
firstToken,
|
|
74
|
+
lastRelevantToken,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Gets the text between the calling parentheses of a CallExpression or NewExpression.
|
|
80
|
+
* @param {ASTNode} node A CallExpression or NewExpression node.
|
|
81
|
+
* @returns {string} The text between the calling parentheses, or an empty string if there are none.
|
|
82
|
+
*/
|
|
83
|
+
function getArgumentsText(node) {
|
|
84
|
+
const lastToken = sourceCode.getLastToken(node);
|
|
85
|
+
|
|
86
|
+
if (!isClosingParenToken(lastToken)) {
|
|
87
|
+
return "";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let firstToken = node.callee;
|
|
91
|
+
|
|
92
|
+
do {
|
|
93
|
+
firstToken = sourceCode.getTokenAfter(firstToken);
|
|
94
|
+
if (!firstToken || firstToken === lastToken) {
|
|
95
|
+
return "";
|
|
96
|
+
}
|
|
97
|
+
} while (!isOpeningParenToken(firstToken));
|
|
98
|
+
|
|
99
|
+
return sourceCode.text.slice(
|
|
100
|
+
firstToken.range[1],
|
|
101
|
+
lastToken.range[0],
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Disallow construction of dense arrays using the Array constructor
|
|
107
|
+
* @param {ASTNode} node node to evaluate
|
|
108
|
+
* @returns {void}
|
|
109
|
+
* @private
|
|
110
|
+
*/
|
|
111
|
+
function check(node) {
|
|
112
|
+
if (
|
|
113
|
+
node.callee.type !== "Identifier" ||
|
|
114
|
+
node.callee.name !== "Array" ||
|
|
115
|
+
node.typeArguments ||
|
|
116
|
+
(node.arguments.length === 1 &&
|
|
117
|
+
node.arguments[0].type !== "SpreadElement")
|
|
118
|
+
) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const variable = getVariableByName(
|
|
123
|
+
sourceCode.getScope(node),
|
|
124
|
+
"Array",
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
/*
|
|
128
|
+
* Check if `Array` is a predefined global variable: predefined globals have no declarations,
|
|
129
|
+
* meaning that the `identifiers` list of the variable object is empty.
|
|
130
|
+
*/
|
|
131
|
+
if (variable && variable.identifiers.length === 0) {
|
|
132
|
+
const argsText = getArgumentsText(node);
|
|
133
|
+
let fixText;
|
|
134
|
+
let messageId;
|
|
135
|
+
|
|
136
|
+
const nonSpreadCount = node.arguments.reduce(
|
|
137
|
+
(count, arg) =>
|
|
138
|
+
arg.type !== "SpreadElement" ? count + 1 : count,
|
|
139
|
+
0,
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
const shouldSuggest =
|
|
143
|
+
node.optional ||
|
|
144
|
+
(node.arguments.length > 0 && nonSpreadCount < 2) ||
|
|
145
|
+
hasCommentsInArrayConstructor(node);
|
|
146
|
+
|
|
147
|
+
/*
|
|
148
|
+
* Check if the suggested change should include a preceding semicolon or not.
|
|
149
|
+
* Due to JavaScript's ASI rules, a missing semicolon may be inserted automatically
|
|
150
|
+
* before an expression like `Array()` or `new Array()`, but not when the expression
|
|
151
|
+
* is changed into an array literal like `[]`.
|
|
152
|
+
*/
|
|
153
|
+
if (
|
|
154
|
+
isStartOfExpressionStatement(node) &&
|
|
155
|
+
needsPrecedingSemicolon(sourceCode, node)
|
|
156
|
+
) {
|
|
157
|
+
fixText = `;[${argsText}]`;
|
|
158
|
+
messageId = "useLiteralAfterSemicolon";
|
|
159
|
+
} else {
|
|
160
|
+
fixText = `[${argsText}]`;
|
|
161
|
+
messageId = "useLiteral";
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
context.report({
|
|
165
|
+
node,
|
|
166
|
+
messageId: "preferLiteral",
|
|
167
|
+
fix(fixer) {
|
|
168
|
+
if (shouldSuggest) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return fixer.replaceText(node, fixText);
|
|
173
|
+
},
|
|
174
|
+
suggest: [
|
|
175
|
+
{
|
|
176
|
+
messageId,
|
|
177
|
+
fix(fixer) {
|
|
178
|
+
if (shouldSuggest) {
|
|
179
|
+
return fixer.replaceText(node, fixText);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return null;
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
CallExpression: check,
|
|
192
|
+
NewExpression: check,
|
|
193
|
+
};
|
|
194
|
+
},
|
|
195
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview disallow using an async function as a Promise executor
|
|
3
|
+
* @author Teddy Katz
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
//------------------------------------------------------------------------------
|
|
8
|
+
// Rule Definition
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
12
|
+
module.exports = {
|
|
13
|
+
meta: {
|
|
14
|
+
type: "problem",
|
|
15
|
+
|
|
16
|
+
docs: {
|
|
17
|
+
description:
|
|
18
|
+
"Disallow using an async function as a Promise executor",
|
|
19
|
+
recommended: true,
|
|
20
|
+
url: "https://eslint.org/docs/latest/rules/no-async-promise-executor",
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
fixable: null,
|
|
24
|
+
schema: [],
|
|
25
|
+
messages: {
|
|
26
|
+
async: "Promise executor functions should not be async.",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
create(context) {
|
|
31
|
+
return {
|
|
32
|
+
"NewExpression[callee.name='Promise'][arguments.0.async=true]"(
|
|
33
|
+
node,
|
|
34
|
+
) {
|
|
35
|
+
context.report({
|
|
36
|
+
node: context.sourceCode.getFirstToken(
|
|
37
|
+
node.arguments[0],
|
|
38
|
+
token => token.value === "async",
|
|
39
|
+
),
|
|
40
|
+
messageId: "async",
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to disallow uses of await inside of loops.
|
|
3
|
+
* @author Nat Mote (nmote)
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Check whether it should stop traversing ancestors at the given node.
|
|
9
|
+
* @param {ASTNode} node A node to check.
|
|
10
|
+
* @returns {boolean} `true` if it should stop traversing.
|
|
11
|
+
*/
|
|
12
|
+
function isBoundary(node) {
|
|
13
|
+
const t = node.type;
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
t === "FunctionDeclaration" ||
|
|
17
|
+
t === "FunctionExpression" ||
|
|
18
|
+
t === "ArrowFunctionExpression" ||
|
|
19
|
+
/*
|
|
20
|
+
* Don't report the await expressions on for-await-of loop since it's
|
|
21
|
+
* asynchronous iteration intentionally.
|
|
22
|
+
*/
|
|
23
|
+
(t === "ForOfStatement" && node.await === true)
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Check whether the given node is in loop.
|
|
29
|
+
* @param {ASTNode} node A node to check.
|
|
30
|
+
* @param {ASTNode} parent A parent node to check.
|
|
31
|
+
* @returns {boolean} `true` if the node is in loop.
|
|
32
|
+
*/
|
|
33
|
+
function isLooped(node, parent) {
|
|
34
|
+
switch (parent.type) {
|
|
35
|
+
case "ForStatement":
|
|
36
|
+
return (
|
|
37
|
+
node === parent.test ||
|
|
38
|
+
node === parent.update ||
|
|
39
|
+
node === parent.body
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
case "ForOfStatement":
|
|
43
|
+
case "ForInStatement":
|
|
44
|
+
return (
|
|
45
|
+
node === parent.body ||
|
|
46
|
+
(node === parent.left && node.kind === "await using")
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
case "WhileStatement":
|
|
50
|
+
case "DoWhileStatement":
|
|
51
|
+
return node === parent.test || node === parent.body;
|
|
52
|
+
|
|
53
|
+
default:
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
59
|
+
module.exports = {
|
|
60
|
+
meta: {
|
|
61
|
+
type: "problem",
|
|
62
|
+
|
|
63
|
+
docs: {
|
|
64
|
+
description: "Disallow `await` inside of loops",
|
|
65
|
+
recommended: false,
|
|
66
|
+
url: "https://eslint.org/docs/latest/rules/no-await-in-loop",
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
schema: [],
|
|
70
|
+
|
|
71
|
+
messages: {
|
|
72
|
+
unexpectedAwait: "Unexpected `await` inside a loop.",
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
create(context) {
|
|
76
|
+
/**
|
|
77
|
+
* Validate an await expression.
|
|
78
|
+
* @param {ASTNode} awaitNode An AwaitExpression or ForOfStatement node to validate.
|
|
79
|
+
* @returns {void}
|
|
80
|
+
*/
|
|
81
|
+
function validate(awaitNode) {
|
|
82
|
+
if (
|
|
83
|
+
awaitNode.type === "VariableDeclaration" &&
|
|
84
|
+
awaitNode.kind !== "await using"
|
|
85
|
+
) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (awaitNode.type === "ForOfStatement" && !awaitNode.await) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let node = awaitNode;
|
|
94
|
+
let parent = node.parent;
|
|
95
|
+
|
|
96
|
+
while (parent && !isBoundary(parent)) {
|
|
97
|
+
if (isLooped(node, parent)) {
|
|
98
|
+
context.report({
|
|
99
|
+
node: awaitNode,
|
|
100
|
+
messageId: "unexpectedAwait",
|
|
101
|
+
});
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
node = parent;
|
|
105
|
+
parent = parent.parent;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
AwaitExpression: validate,
|
|
111
|
+
ForOfStatement: validate,
|
|
112
|
+
VariableDeclaration: validate,
|
|
113
|
+
};
|
|
114
|
+
},
|
|
115
|
+
};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to flag bitwise identifiers
|
|
3
|
+
* @author Nicholas C. Zakas
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
*
|
|
10
|
+
* Set of bitwise operators.
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
const BITWISE_OPERATORS = [
|
|
14
|
+
"^",
|
|
15
|
+
"|",
|
|
16
|
+
"&",
|
|
17
|
+
"<<",
|
|
18
|
+
">>",
|
|
19
|
+
">>>",
|
|
20
|
+
"^=",
|
|
21
|
+
"|=",
|
|
22
|
+
"&=",
|
|
23
|
+
"<<=",
|
|
24
|
+
">>=",
|
|
25
|
+
">>>=",
|
|
26
|
+
"~",
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
//------------------------------------------------------------------------------
|
|
30
|
+
// Rule Definition
|
|
31
|
+
//------------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
34
|
+
module.exports = {
|
|
35
|
+
meta: {
|
|
36
|
+
type: "suggestion",
|
|
37
|
+
|
|
38
|
+
defaultOptions: [
|
|
39
|
+
{
|
|
40
|
+
allow: [],
|
|
41
|
+
int32Hint: false,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
|
|
45
|
+
docs: {
|
|
46
|
+
description: "Disallow bitwise operators",
|
|
47
|
+
recommended: false,
|
|
48
|
+
url: "https://eslint.org/docs/latest/rules/no-bitwise",
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
schema: [
|
|
52
|
+
{
|
|
53
|
+
type: "object",
|
|
54
|
+
properties: {
|
|
55
|
+
allow: {
|
|
56
|
+
type: "array",
|
|
57
|
+
items: {
|
|
58
|
+
enum: BITWISE_OPERATORS,
|
|
59
|
+
},
|
|
60
|
+
uniqueItems: true,
|
|
61
|
+
},
|
|
62
|
+
int32Hint: {
|
|
63
|
+
type: "boolean",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
additionalProperties: false,
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
|
|
70
|
+
messages: {
|
|
71
|
+
unexpected: "Unexpected use of '{{operator}}'.",
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
create(context) {
|
|
76
|
+
const [{ allow: allowed, int32Hint }] = context.options;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Reports an unexpected use of a bitwise operator.
|
|
80
|
+
* @param {ASTNode} node Node which contains the bitwise operator.
|
|
81
|
+
* @returns {void}
|
|
82
|
+
*/
|
|
83
|
+
function report(node) {
|
|
84
|
+
context.report({
|
|
85
|
+
node,
|
|
86
|
+
messageId: "unexpected",
|
|
87
|
+
data: { operator: node.operator },
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Checks if the given node has a bitwise operator.
|
|
93
|
+
* @param {ASTNode} node The node to check.
|
|
94
|
+
* @returns {boolean} Whether or not the node has a bitwise operator.
|
|
95
|
+
*/
|
|
96
|
+
function hasBitwiseOperator(node) {
|
|
97
|
+
return BITWISE_OPERATORS.includes(node.operator);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Checks if exceptions were provided, e.g. `{ allow: ['~', '|'] }`.
|
|
102
|
+
* @param {ASTNode} node The node to check.
|
|
103
|
+
* @returns {boolean} Whether or not the node has a bitwise operator.
|
|
104
|
+
*/
|
|
105
|
+
function allowedOperator(node) {
|
|
106
|
+
return allowed.includes(node.operator);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Checks if the given bitwise operator is used for integer typecasting, i.e. "|0"
|
|
111
|
+
* @param {ASTNode} node The node to check.
|
|
112
|
+
* @returns {boolean} whether the node is used in integer typecasting.
|
|
113
|
+
*/
|
|
114
|
+
function isInt32Hint(node) {
|
|
115
|
+
return (
|
|
116
|
+
int32Hint &&
|
|
117
|
+
node.operator === "|" &&
|
|
118
|
+
node.right &&
|
|
119
|
+
node.right.type === "Literal" &&
|
|
120
|
+
node.right.value === 0
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Report if the given node contains a bitwise operator.
|
|
126
|
+
* @param {ASTNode} node The node to check.
|
|
127
|
+
* @returns {void}
|
|
128
|
+
*/
|
|
129
|
+
function checkNodeForBitwiseOperator(node) {
|
|
130
|
+
if (
|
|
131
|
+
hasBitwiseOperator(node) &&
|
|
132
|
+
!allowedOperator(node) &&
|
|
133
|
+
!isInt32Hint(node)
|
|
134
|
+
) {
|
|
135
|
+
report(node);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
AssignmentExpression: checkNodeForBitwiseOperator,
|
|
141
|
+
BinaryExpression: checkNodeForBitwiseOperator,
|
|
142
|
+
UnaryExpression: checkNodeForBitwiseOperator,
|
|
143
|
+
};
|
|
144
|
+
},
|
|
145
|
+
};
|