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,425 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to flag statements without curly braces
|
|
3
|
+
* @author Nicholas C. Zakas
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
//------------------------------------------------------------------------------
|
|
8
|
+
// Requirements
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
const astUtils = require("./utils/ast-utils");
|
|
12
|
+
|
|
13
|
+
//------------------------------------------------------------------------------
|
|
14
|
+
// Rule Definition
|
|
15
|
+
//------------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
18
|
+
module.exports = {
|
|
19
|
+
meta: {
|
|
20
|
+
type: "suggestion",
|
|
21
|
+
|
|
22
|
+
docs: {
|
|
23
|
+
description:
|
|
24
|
+
"Enforce consistent brace style for all control statements",
|
|
25
|
+
recommended: false,
|
|
26
|
+
frozen: true,
|
|
27
|
+
url: "https://eslint.org/docs/latest/rules/curly",
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
schema: {
|
|
31
|
+
anyOf: [
|
|
32
|
+
{
|
|
33
|
+
type: "array",
|
|
34
|
+
items: [
|
|
35
|
+
{
|
|
36
|
+
enum: ["all"],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
minItems: 0,
|
|
40
|
+
maxItems: 1,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: "array",
|
|
44
|
+
items: [
|
|
45
|
+
{
|
|
46
|
+
enum: ["multi", "multi-line", "multi-or-nest"],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
enum: ["consistent"],
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
minItems: 0,
|
|
53
|
+
maxItems: 2,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
defaultOptions: ["all"],
|
|
59
|
+
|
|
60
|
+
fixable: "code",
|
|
61
|
+
|
|
62
|
+
messages: {
|
|
63
|
+
missingCurlyAfter: "Expected { after '{{name}}'.",
|
|
64
|
+
missingCurlyAfterCondition:
|
|
65
|
+
"Expected { after '{{name}}' condition.",
|
|
66
|
+
unexpectedCurlyAfter: "Unnecessary { after '{{name}}'.",
|
|
67
|
+
unexpectedCurlyAfterCondition:
|
|
68
|
+
"Unnecessary { after '{{name}}' condition.",
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
create(context) {
|
|
73
|
+
const multiOnly = context.options[0] === "multi";
|
|
74
|
+
const multiLine = context.options[0] === "multi-line";
|
|
75
|
+
const multiOrNest = context.options[0] === "multi-or-nest";
|
|
76
|
+
const consistent = context.options[1] === "consistent";
|
|
77
|
+
|
|
78
|
+
const sourceCode = context.sourceCode;
|
|
79
|
+
|
|
80
|
+
//--------------------------------------------------------------------------
|
|
81
|
+
// Helpers
|
|
82
|
+
//--------------------------------------------------------------------------
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Determines if a given node is a one-liner that's on the same line as it's preceding code.
|
|
86
|
+
* @param {ASTNode} node The node to check.
|
|
87
|
+
* @returns {boolean} True if the node is a one-liner that's on the same line as it's preceding code.
|
|
88
|
+
* @private
|
|
89
|
+
*/
|
|
90
|
+
function isCollapsedOneLiner(node) {
|
|
91
|
+
const before = sourceCode.getTokenBefore(node);
|
|
92
|
+
const last = sourceCode.getLastToken(node);
|
|
93
|
+
const lastExcludingSemicolon = astUtils.isSemicolonToken(last)
|
|
94
|
+
? sourceCode.getTokenBefore(last)
|
|
95
|
+
: last;
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
before.loc.start.line === lastExcludingSemicolon.loc.end.line
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Determines if a given node is a one-liner.
|
|
104
|
+
* @param {ASTNode} node The node to check.
|
|
105
|
+
* @returns {boolean} True if the node is a one-liner.
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
function isOneLiner(node) {
|
|
109
|
+
if (node.type === "EmptyStatement") {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const first = sourceCode.getFirstToken(node);
|
|
114
|
+
const last = sourceCode.getLastToken(node);
|
|
115
|
+
const lastExcludingSemicolon = astUtils.isSemicolonToken(last)
|
|
116
|
+
? sourceCode.getTokenBefore(last)
|
|
117
|
+
: last;
|
|
118
|
+
|
|
119
|
+
return first.loc.start.line === lastExcludingSemicolon.loc.end.line;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Determines if a semicolon needs to be inserted after removing a set of curly brackets, in order to avoid a SyntaxError.
|
|
124
|
+
* @param {Token} closingBracket The } token
|
|
125
|
+
* @returns {boolean} `true` if a semicolon needs to be inserted after the last statement in the block.
|
|
126
|
+
*/
|
|
127
|
+
function needsSemicolon(closingBracket) {
|
|
128
|
+
const tokenBefore = sourceCode.getTokenBefore(closingBracket);
|
|
129
|
+
const tokenAfter = sourceCode.getTokenAfter(closingBracket);
|
|
130
|
+
const lastBlockNode = sourceCode.getNodeByRangeIndex(
|
|
131
|
+
tokenBefore.range[0],
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
if (astUtils.isSemicolonToken(tokenBefore)) {
|
|
135
|
+
// If the last statement already has a semicolon, don't add another one.
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!tokenAfter) {
|
|
140
|
+
// If there are no statements after this block, there is no need to add a semicolon.
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (
|
|
145
|
+
lastBlockNode.type === "BlockStatement" &&
|
|
146
|
+
lastBlockNode.parent.type !== "FunctionExpression" &&
|
|
147
|
+
lastBlockNode.parent.type !== "ArrowFunctionExpression"
|
|
148
|
+
) {
|
|
149
|
+
/*
|
|
150
|
+
* If the last node surrounded by curly brackets is a BlockStatement (other than a FunctionExpression or an ArrowFunctionExpression),
|
|
151
|
+
* don't insert a semicolon. Otherwise, the semicolon would be parsed as a separate statement, which would cause
|
|
152
|
+
* a SyntaxError if it was followed by `else`.
|
|
153
|
+
*/
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (tokenBefore.loc.end.line === tokenAfter.loc.start.line) {
|
|
158
|
+
// If the next token is on the same line, insert a semicolon.
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (/^[([/`+-]/u.test(tokenAfter.value)) {
|
|
163
|
+
// If the next token starts with a character that would disrupt ASI, insert a semicolon.
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (
|
|
168
|
+
tokenBefore.type === "Punctuator" &&
|
|
169
|
+
(tokenBefore.value === "++" || tokenBefore.value === "--")
|
|
170
|
+
) {
|
|
171
|
+
// If the last token is ++ or --, insert a semicolon to avoid disrupting ASI.
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Otherwise, do not insert a semicolon.
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Prepares to check the body of a node to see if it's a block statement.
|
|
181
|
+
* @param {ASTNode} node The node to report if there's a problem.
|
|
182
|
+
* @param {ASTNode} body The body node to check for blocks.
|
|
183
|
+
* @param {string} name The name to report if there's a problem.
|
|
184
|
+
* @param {{ condition: boolean }} opts Options to pass to the report functions
|
|
185
|
+
* @returns {Object} a prepared check object, with "actual", "expected", "check" properties.
|
|
186
|
+
* "actual" will be `true` or `false` whether the body is already a block statement.
|
|
187
|
+
* "expected" will be `true` or `false` if the body should be a block statement or not, or
|
|
188
|
+
* `null` if it doesn't matter, depending on the rule options. It can be modified to change
|
|
189
|
+
* the final behavior of "check".
|
|
190
|
+
* "check" will be a function reporting appropriate problems depending on the other
|
|
191
|
+
* properties.
|
|
192
|
+
*/
|
|
193
|
+
function prepareCheck(node, body, name, opts) {
|
|
194
|
+
const hasBlock = body.type === "BlockStatement";
|
|
195
|
+
let expected = null;
|
|
196
|
+
|
|
197
|
+
if (
|
|
198
|
+
hasBlock &&
|
|
199
|
+
(body.body.length !== 1 ||
|
|
200
|
+
astUtils.areBracesNecessary(body, sourceCode))
|
|
201
|
+
) {
|
|
202
|
+
expected = true;
|
|
203
|
+
} else if (multiOnly) {
|
|
204
|
+
expected = false;
|
|
205
|
+
} else if (multiLine) {
|
|
206
|
+
if (!isCollapsedOneLiner(body)) {
|
|
207
|
+
expected = true;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// otherwise, the body is allowed to have braces or not to have braces
|
|
211
|
+
} else if (multiOrNest) {
|
|
212
|
+
if (hasBlock) {
|
|
213
|
+
const statement = body.body[0];
|
|
214
|
+
const leadingCommentsInBlock =
|
|
215
|
+
sourceCode.getCommentsBefore(statement);
|
|
216
|
+
|
|
217
|
+
expected =
|
|
218
|
+
!isOneLiner(statement) ||
|
|
219
|
+
leadingCommentsInBlock.length > 0;
|
|
220
|
+
} else {
|
|
221
|
+
expected = !isOneLiner(body);
|
|
222
|
+
}
|
|
223
|
+
} else {
|
|
224
|
+
// default "all"
|
|
225
|
+
expected = true;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
actual: hasBlock,
|
|
230
|
+
expected,
|
|
231
|
+
check() {
|
|
232
|
+
if (
|
|
233
|
+
this.expected !== null &&
|
|
234
|
+
this.expected !== this.actual
|
|
235
|
+
) {
|
|
236
|
+
if (this.expected) {
|
|
237
|
+
context.report({
|
|
238
|
+
node,
|
|
239
|
+
loc: body.loc,
|
|
240
|
+
messageId:
|
|
241
|
+
opts && opts.condition
|
|
242
|
+
? "missingCurlyAfterCondition"
|
|
243
|
+
: "missingCurlyAfter",
|
|
244
|
+
data: {
|
|
245
|
+
name,
|
|
246
|
+
},
|
|
247
|
+
fix: fixer =>
|
|
248
|
+
fixer.replaceText(
|
|
249
|
+
body,
|
|
250
|
+
`{${sourceCode.getText(body)}}`,
|
|
251
|
+
),
|
|
252
|
+
});
|
|
253
|
+
} else {
|
|
254
|
+
context.report({
|
|
255
|
+
node,
|
|
256
|
+
loc: body.loc,
|
|
257
|
+
messageId:
|
|
258
|
+
opts && opts.condition
|
|
259
|
+
? "unexpectedCurlyAfterCondition"
|
|
260
|
+
: "unexpectedCurlyAfter",
|
|
261
|
+
data: {
|
|
262
|
+
name,
|
|
263
|
+
},
|
|
264
|
+
fix(fixer) {
|
|
265
|
+
/*
|
|
266
|
+
* `do while` expressions sometimes need a space to be inserted after `do`.
|
|
267
|
+
* e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)`
|
|
268
|
+
*/
|
|
269
|
+
const needsPrecedingSpace =
|
|
270
|
+
node.type === "DoWhileStatement" &&
|
|
271
|
+
sourceCode.getTokenBefore(body)
|
|
272
|
+
.range[1] === body.range[0] &&
|
|
273
|
+
!astUtils.canTokensBeAdjacent(
|
|
274
|
+
"do",
|
|
275
|
+
sourceCode.getFirstToken(body, {
|
|
276
|
+
skip: 1,
|
|
277
|
+
}),
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
const openingBracket =
|
|
281
|
+
sourceCode.getFirstToken(body);
|
|
282
|
+
const closingBracket =
|
|
283
|
+
sourceCode.getLastToken(body);
|
|
284
|
+
const lastTokenInBlock =
|
|
285
|
+
sourceCode.getTokenBefore(
|
|
286
|
+
closingBracket,
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
if (needsSemicolon(closingBracket)) {
|
|
290
|
+
/*
|
|
291
|
+
* If removing braces would cause a SyntaxError due to multiple statements on the same line (or
|
|
292
|
+
* change the semantics of the code due to ASI), don't perform a fix.
|
|
293
|
+
*/
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const resultingBodyText =
|
|
298
|
+
sourceCode
|
|
299
|
+
.getText()
|
|
300
|
+
.slice(
|
|
301
|
+
openingBracket.range[1],
|
|
302
|
+
lastTokenInBlock.range[0],
|
|
303
|
+
) +
|
|
304
|
+
sourceCode.getText(lastTokenInBlock) +
|
|
305
|
+
sourceCode
|
|
306
|
+
.getText()
|
|
307
|
+
.slice(
|
|
308
|
+
lastTokenInBlock.range[1],
|
|
309
|
+
closingBracket.range[0],
|
|
310
|
+
);
|
|
311
|
+
|
|
312
|
+
return fixer.replaceText(
|
|
313
|
+
body,
|
|
314
|
+
(needsPrecedingSpace ? " " : "") +
|
|
315
|
+
resultingBodyText,
|
|
316
|
+
);
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Prepares to check the bodies of a "if", "else if" and "else" chain.
|
|
327
|
+
* @param {ASTNode} node The first IfStatement node of the chain.
|
|
328
|
+
* @returns {Object[]} prepared checks for each body of the chain. See `prepareCheck` for more
|
|
329
|
+
* information.
|
|
330
|
+
*/
|
|
331
|
+
function prepareIfChecks(node) {
|
|
332
|
+
const preparedChecks = [];
|
|
333
|
+
|
|
334
|
+
for (
|
|
335
|
+
let currentNode = node;
|
|
336
|
+
currentNode;
|
|
337
|
+
currentNode = currentNode.alternate
|
|
338
|
+
) {
|
|
339
|
+
preparedChecks.push(
|
|
340
|
+
prepareCheck(currentNode, currentNode.consequent, "if", {
|
|
341
|
+
condition: true,
|
|
342
|
+
}),
|
|
343
|
+
);
|
|
344
|
+
if (
|
|
345
|
+
currentNode.alternate &&
|
|
346
|
+
currentNode.alternate.type !== "IfStatement"
|
|
347
|
+
) {
|
|
348
|
+
preparedChecks.push(
|
|
349
|
+
prepareCheck(
|
|
350
|
+
currentNode,
|
|
351
|
+
currentNode.alternate,
|
|
352
|
+
"else",
|
|
353
|
+
),
|
|
354
|
+
);
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (consistent) {
|
|
360
|
+
/*
|
|
361
|
+
* If any node should have or already have braces, make sure they
|
|
362
|
+
* all have braces.
|
|
363
|
+
* If all nodes shouldn't have braces, make sure they don't.
|
|
364
|
+
*/
|
|
365
|
+
const expected = preparedChecks.some(preparedCheck => {
|
|
366
|
+
if (preparedCheck.expected !== null) {
|
|
367
|
+
return preparedCheck.expected;
|
|
368
|
+
}
|
|
369
|
+
return preparedCheck.actual;
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
preparedChecks.forEach(preparedCheck => {
|
|
373
|
+
preparedCheck.expected = expected;
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return preparedChecks;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
//--------------------------------------------------------------------------
|
|
381
|
+
// Public
|
|
382
|
+
//--------------------------------------------------------------------------
|
|
383
|
+
|
|
384
|
+
return {
|
|
385
|
+
IfStatement(node) {
|
|
386
|
+
const parent = node.parent;
|
|
387
|
+
const isElseIf =
|
|
388
|
+
parent.type === "IfStatement" && parent.alternate === node;
|
|
389
|
+
|
|
390
|
+
if (!isElseIf) {
|
|
391
|
+
// This is a top `if`, check the whole `if-else-if` chain
|
|
392
|
+
prepareIfChecks(node).forEach(preparedCheck => {
|
|
393
|
+
preparedCheck.check();
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Skip `else if`, it's already checked (when the top `if` was visited)
|
|
398
|
+
},
|
|
399
|
+
|
|
400
|
+
WhileStatement(node) {
|
|
401
|
+
prepareCheck(node, node.body, "while", {
|
|
402
|
+
condition: true,
|
|
403
|
+
}).check();
|
|
404
|
+
},
|
|
405
|
+
|
|
406
|
+
DoWhileStatement(node) {
|
|
407
|
+
prepareCheck(node, node.body, "do").check();
|
|
408
|
+
},
|
|
409
|
+
|
|
410
|
+
ForStatement(node) {
|
|
411
|
+
prepareCheck(node, node.body, "for", {
|
|
412
|
+
condition: true,
|
|
413
|
+
}).check();
|
|
414
|
+
},
|
|
415
|
+
|
|
416
|
+
ForInStatement(node) {
|
|
417
|
+
prepareCheck(node, node.body, "for-in").check();
|
|
418
|
+
},
|
|
419
|
+
|
|
420
|
+
ForOfStatement(node) {
|
|
421
|
+
prepareCheck(node, node.body, "for-of").check();
|
|
422
|
+
},
|
|
423
|
+
};
|
|
424
|
+
},
|
|
425
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to enforce `default` clauses in `switch` statements to be last
|
|
3
|
+
* @author Milos Djermanovic
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
//------------------------------------------------------------------------------
|
|
9
|
+
// Rule Definition
|
|
10
|
+
//------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
13
|
+
module.exports = {
|
|
14
|
+
meta: {
|
|
15
|
+
type: "suggestion",
|
|
16
|
+
|
|
17
|
+
docs: {
|
|
18
|
+
description:
|
|
19
|
+
"Enforce `default` clauses in `switch` statements to be last",
|
|
20
|
+
recommended: false,
|
|
21
|
+
url: "https://eslint.org/docs/latest/rules/default-case-last",
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
schema: [],
|
|
25
|
+
|
|
26
|
+
messages: {
|
|
27
|
+
notLast: "Default clause should be the last clause.",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
create(context) {
|
|
32
|
+
return {
|
|
33
|
+
SwitchStatement(node) {
|
|
34
|
+
const cases = node.cases,
|
|
35
|
+
indexOfDefault = cases.findIndex(c => c.test === null);
|
|
36
|
+
|
|
37
|
+
if (
|
|
38
|
+
indexOfDefault !== -1 &&
|
|
39
|
+
indexOfDefault !== cases.length - 1
|
|
40
|
+
) {
|
|
41
|
+
const defaultClause = cases[indexOfDefault];
|
|
42
|
+
|
|
43
|
+
context.report({
|
|
44
|
+
node: defaultClause,
|
|
45
|
+
messageId: "notLast",
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview require default case in switch statements
|
|
3
|
+
* @author Aliaksei Shytkin
|
|
4
|
+
*/
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
const DEFAULT_COMMENT_PATTERN = /^no default$/iu;
|
|
8
|
+
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
// Rule Definition
|
|
11
|
+
//------------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
14
|
+
module.exports = {
|
|
15
|
+
meta: {
|
|
16
|
+
type: "suggestion",
|
|
17
|
+
|
|
18
|
+
defaultOptions: [{}],
|
|
19
|
+
|
|
20
|
+
docs: {
|
|
21
|
+
description: "Require `default` cases in `switch` statements",
|
|
22
|
+
recommended: false,
|
|
23
|
+
url: "https://eslint.org/docs/latest/rules/default-case",
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
schema: [
|
|
27
|
+
{
|
|
28
|
+
type: "object",
|
|
29
|
+
properties: {
|
|
30
|
+
commentPattern: {
|
|
31
|
+
type: "string",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
additionalProperties: false,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
|
|
38
|
+
messages: {
|
|
39
|
+
missingDefaultCase: "Expected a default case.",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
create(context) {
|
|
44
|
+
const [options] = context.options;
|
|
45
|
+
const commentPattern = options.commentPattern
|
|
46
|
+
? new RegExp(options.commentPattern, "u")
|
|
47
|
+
: DEFAULT_COMMENT_PATTERN;
|
|
48
|
+
|
|
49
|
+
const sourceCode = context.sourceCode;
|
|
50
|
+
|
|
51
|
+
//--------------------------------------------------------------------------
|
|
52
|
+
// Helpers
|
|
53
|
+
//--------------------------------------------------------------------------
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Shortcut to get last element of array
|
|
57
|
+
* @param {*[]} collection Array
|
|
58
|
+
* @returns {any} Last element
|
|
59
|
+
*/
|
|
60
|
+
function last(collection) {
|
|
61
|
+
return collection.at(-1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//--------------------------------------------------------------------------
|
|
65
|
+
// Public
|
|
66
|
+
//--------------------------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
SwitchStatement(node) {
|
|
70
|
+
if (!node.cases.length) {
|
|
71
|
+
/*
|
|
72
|
+
* skip check of empty switch because there is no easy way
|
|
73
|
+
* to extract comments inside it now
|
|
74
|
+
*/
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const hasDefault = node.cases.some(v => v.test === null);
|
|
79
|
+
|
|
80
|
+
if (!hasDefault) {
|
|
81
|
+
let comment;
|
|
82
|
+
|
|
83
|
+
const lastCase = last(node.cases);
|
|
84
|
+
const comments = sourceCode.getCommentsAfter(lastCase);
|
|
85
|
+
|
|
86
|
+
if (comments.length) {
|
|
87
|
+
comment = last(comments);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (
|
|
91
|
+
!comment ||
|
|
92
|
+
!commentPattern.test(comment.value.trim())
|
|
93
|
+
) {
|
|
94
|
+
context.report({
|
|
95
|
+
node,
|
|
96
|
+
messageId: "missingDefaultCase",
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview enforce default parameters to be last
|
|
3
|
+
* @author Chiawen Chen
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Checks if node is required: i.e. does not have a default value or ? optional indicator.
|
|
10
|
+
* @param {ASTNode} node the node to be evaluated
|
|
11
|
+
* @returns {boolean} true if the node is required, false if not.
|
|
12
|
+
*/
|
|
13
|
+
function isRequiredParameter(node) {
|
|
14
|
+
return !(
|
|
15
|
+
node.type === "AssignmentPattern" ||
|
|
16
|
+
node.type === "RestElement" ||
|
|
17
|
+
node.optional
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
22
|
+
module.exports = {
|
|
23
|
+
meta: {
|
|
24
|
+
dialects: ["javascript", "typescript"],
|
|
25
|
+
language: "javascript",
|
|
26
|
+
type: "suggestion",
|
|
27
|
+
|
|
28
|
+
docs: {
|
|
29
|
+
description: "Enforce default parameters to be last",
|
|
30
|
+
recommended: false,
|
|
31
|
+
frozen: true,
|
|
32
|
+
url: "https://eslint.org/docs/latest/rules/default-param-last",
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
schema: [],
|
|
36
|
+
|
|
37
|
+
messages: {
|
|
38
|
+
shouldBeLast: "Default parameters should be last.",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
create(context) {
|
|
43
|
+
/**
|
|
44
|
+
* Handler for function contexts.
|
|
45
|
+
* @param {ASTNode} node function node
|
|
46
|
+
* @returns {void}
|
|
47
|
+
*/
|
|
48
|
+
function handleFunction(node) {
|
|
49
|
+
let hasSeenRequiredParameter = false;
|
|
50
|
+
|
|
51
|
+
for (let i = node.params.length - 1; i >= 0; i -= 1) {
|
|
52
|
+
const current = node.params[i];
|
|
53
|
+
const param =
|
|
54
|
+
current.type === "TSParameterProperty"
|
|
55
|
+
? current.parameter
|
|
56
|
+
: current;
|
|
57
|
+
|
|
58
|
+
if (isRequiredParameter(param)) {
|
|
59
|
+
hasSeenRequiredParameter = true;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (hasSeenRequiredParameter) {
|
|
64
|
+
context.report({
|
|
65
|
+
node: current,
|
|
66
|
+
messageId: "shouldBeLast",
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
FunctionDeclaration: handleFunction,
|
|
74
|
+
FunctionExpression: handleFunction,
|
|
75
|
+
ArrowFunctionExpression: handleFunction,
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
};
|