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,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to check empty newline after "var" statement
|
|
3
|
+
* @author Gopal Venkatesan
|
|
4
|
+
* @deprecated in ESLint v4.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
// Requirements
|
|
11
|
+
//------------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
const astUtils = require("./utils/ast-utils");
|
|
14
|
+
|
|
15
|
+
//------------------------------------------------------------------------------
|
|
16
|
+
// Rule Definition
|
|
17
|
+
//------------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
20
|
+
module.exports = {
|
|
21
|
+
meta: {
|
|
22
|
+
type: "layout",
|
|
23
|
+
|
|
24
|
+
docs: {
|
|
25
|
+
description:
|
|
26
|
+
"Require or disallow an empty line after variable declarations",
|
|
27
|
+
recommended: false,
|
|
28
|
+
url: "https://eslint.org/docs/latest/rules/newline-after-var",
|
|
29
|
+
},
|
|
30
|
+
schema: [
|
|
31
|
+
{
|
|
32
|
+
enum: ["never", "always"],
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
fixable: "whitespace",
|
|
36
|
+
messages: {
|
|
37
|
+
expected: "Expected blank line after variable declarations.",
|
|
38
|
+
unexpected: "Unexpected blank line after variable declarations.",
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
deprecated: {
|
|
42
|
+
message: "The rule was replaced with a more general rule.",
|
|
43
|
+
url: "https://eslint.org/blog/2017/06/eslint-v4.0.0-released/",
|
|
44
|
+
deprecatedSince: "4.0.0",
|
|
45
|
+
availableUntil: "11.0.0",
|
|
46
|
+
replacedBy: [
|
|
47
|
+
{
|
|
48
|
+
message: "The new rule moved to a plugin.",
|
|
49
|
+
url: "https://eslint.org/docs/latest/rules/padding-line-between-statements#examples",
|
|
50
|
+
plugin: {
|
|
51
|
+
name: "@stylistic/eslint-plugin",
|
|
52
|
+
url: "https://eslint.style",
|
|
53
|
+
},
|
|
54
|
+
rule: {
|
|
55
|
+
name: "padding-line-between-statements",
|
|
56
|
+
url: "https://eslint.style/rules/padding-line-between-statements",
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
create(context) {
|
|
64
|
+
const sourceCode = context.sourceCode;
|
|
65
|
+
|
|
66
|
+
// Default `mode` to "always".
|
|
67
|
+
const mode = context.options[0] === "never" ? "never" : "always";
|
|
68
|
+
|
|
69
|
+
// Cache starting and ending line numbers of comments for faster lookup
|
|
70
|
+
const commentEndLine = sourceCode
|
|
71
|
+
.getAllComments()
|
|
72
|
+
.reduce((result, token) => {
|
|
73
|
+
result[token.loc.start.line] = token.loc.end.line;
|
|
74
|
+
return result;
|
|
75
|
+
}, {});
|
|
76
|
+
|
|
77
|
+
//--------------------------------------------------------------------------
|
|
78
|
+
// Helpers
|
|
79
|
+
//--------------------------------------------------------------------------
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Gets a token from the given node to compare line to the next statement.
|
|
83
|
+
*
|
|
84
|
+
* In general, the token is the last token of the node. However, the token is the second last token if the following conditions satisfy.
|
|
85
|
+
*
|
|
86
|
+
* - The last token is semicolon.
|
|
87
|
+
* - The semicolon is on a different line from the previous token of the semicolon.
|
|
88
|
+
*
|
|
89
|
+
* This behavior would address semicolon-less style code. e.g.:
|
|
90
|
+
*
|
|
91
|
+
* var foo = 1
|
|
92
|
+
*
|
|
93
|
+
* ;(a || b).doSomething()
|
|
94
|
+
* @param {ASTNode} node The node to get.
|
|
95
|
+
* @returns {Token} The token to compare line to the next statement.
|
|
96
|
+
*/
|
|
97
|
+
function getLastToken(node) {
|
|
98
|
+
const lastToken = sourceCode.getLastToken(node);
|
|
99
|
+
|
|
100
|
+
if (lastToken.type === "Punctuator" && lastToken.value === ";") {
|
|
101
|
+
const prevToken = sourceCode.getTokenBefore(lastToken);
|
|
102
|
+
|
|
103
|
+
if (prevToken.loc.end.line !== lastToken.loc.start.line) {
|
|
104
|
+
return prevToken;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return lastToken;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Determine if provided keyword is a variable declaration
|
|
113
|
+
* @private
|
|
114
|
+
* @param {string} keyword keyword to test
|
|
115
|
+
* @returns {boolean} True if `keyword` is a type of var
|
|
116
|
+
*/
|
|
117
|
+
function isVar(keyword) {
|
|
118
|
+
return (
|
|
119
|
+
keyword === "var" || keyword === "let" || keyword === "const"
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Determine if provided keyword is a variant of for specifiers
|
|
125
|
+
* @private
|
|
126
|
+
* @param {string} keyword keyword to test
|
|
127
|
+
* @returns {boolean} True if `keyword` is a variant of for specifier
|
|
128
|
+
*/
|
|
129
|
+
function isForTypeSpecifier(keyword) {
|
|
130
|
+
return (
|
|
131
|
+
keyword === "ForStatement" ||
|
|
132
|
+
keyword === "ForInStatement" ||
|
|
133
|
+
keyword === "ForOfStatement"
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Determine if provided keyword is an export specifiers
|
|
139
|
+
* @private
|
|
140
|
+
* @param {string} nodeType nodeType to test
|
|
141
|
+
* @returns {boolean} True if `nodeType` is an export specifier
|
|
142
|
+
*/
|
|
143
|
+
function isExportSpecifier(nodeType) {
|
|
144
|
+
return (
|
|
145
|
+
nodeType === "ExportNamedDeclaration" ||
|
|
146
|
+
nodeType === "ExportSpecifier" ||
|
|
147
|
+
nodeType === "ExportDefaultDeclaration" ||
|
|
148
|
+
nodeType === "ExportAllDeclaration"
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Determine if provided node is the last of their parent block.
|
|
154
|
+
* @private
|
|
155
|
+
* @param {ASTNode} node node to test
|
|
156
|
+
* @returns {boolean} True if `node` is last of their parent block.
|
|
157
|
+
*/
|
|
158
|
+
function isLastNode(node) {
|
|
159
|
+
const token = sourceCode.getTokenAfter(node);
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
!token || (token.type === "Punctuator" && token.value === "}")
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Gets the last line of a group of consecutive comments
|
|
168
|
+
* @param {number} commentStartLine The starting line of the group
|
|
169
|
+
* @returns {number} The number of the last comment line of the group
|
|
170
|
+
*/
|
|
171
|
+
function getLastCommentLineOfBlock(commentStartLine) {
|
|
172
|
+
const currentCommentEnd = commentEndLine[commentStartLine];
|
|
173
|
+
|
|
174
|
+
return commentEndLine[currentCommentEnd + 1]
|
|
175
|
+
? getLastCommentLineOfBlock(currentCommentEnd + 1)
|
|
176
|
+
: currentCommentEnd;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Determine if a token starts more than one line after a comment ends
|
|
181
|
+
* @param {token} token The token being checked
|
|
182
|
+
* @param {integer} commentStartLine The line number on which the comment starts
|
|
183
|
+
* @returns {boolean} True if `token` does not start immediately after a comment
|
|
184
|
+
*/
|
|
185
|
+
function hasBlankLineAfterComment(token, commentStartLine) {
|
|
186
|
+
return (
|
|
187
|
+
token.loc.start.line >
|
|
188
|
+
getLastCommentLineOfBlock(commentStartLine) + 1
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Checks that a blank line exists after a variable declaration when mode is
|
|
194
|
+
* set to "always", or checks that there is no blank line when mode is set
|
|
195
|
+
* to "never"
|
|
196
|
+
* @private
|
|
197
|
+
* @param {ASTNode} node `VariableDeclaration` node to test
|
|
198
|
+
* @returns {void}
|
|
199
|
+
*/
|
|
200
|
+
function checkForBlankLine(node) {
|
|
201
|
+
/*
|
|
202
|
+
* lastToken is the last token on the node's line. It will usually also be the last token of the node, but it will
|
|
203
|
+
* sometimes be second-last if there is a semicolon on a different line.
|
|
204
|
+
*/
|
|
205
|
+
const lastToken = getLastToken(node),
|
|
206
|
+
/*
|
|
207
|
+
* If lastToken is the last token of the node, nextToken should be the token after the node. Otherwise, nextToken
|
|
208
|
+
* is the last token of the node.
|
|
209
|
+
*/
|
|
210
|
+
nextToken =
|
|
211
|
+
lastToken === sourceCode.getLastToken(node)
|
|
212
|
+
? sourceCode.getTokenAfter(node)
|
|
213
|
+
: sourceCode.getLastToken(node),
|
|
214
|
+
nextLineNum = lastToken.loc.end.line + 1;
|
|
215
|
+
|
|
216
|
+
// Ignore if there is no following statement
|
|
217
|
+
if (!nextToken) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Ignore if parent of node is a for variant
|
|
222
|
+
if (isForTypeSpecifier(node.parent.type)) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Ignore if parent of node is an export specifier
|
|
227
|
+
if (isExportSpecifier(node.parent.type)) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/*
|
|
232
|
+
* Some coding styles use multiple `var` statements, so do nothing if
|
|
233
|
+
* the next token is a `var` statement.
|
|
234
|
+
*/
|
|
235
|
+
if (nextToken.type === "Keyword" && isVar(nextToken.value)) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Ignore if it is last statement in a block
|
|
240
|
+
if (isLastNode(node)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Next statement is not a `var`...
|
|
245
|
+
const noNextLineToken = nextToken.loc.start.line > nextLineNum;
|
|
246
|
+
const hasNextLineComment =
|
|
247
|
+
typeof commentEndLine[nextLineNum] !== "undefined";
|
|
248
|
+
|
|
249
|
+
if (mode === "never" && noNextLineToken && !hasNextLineComment) {
|
|
250
|
+
context.report({
|
|
251
|
+
node,
|
|
252
|
+
messageId: "unexpected",
|
|
253
|
+
fix(fixer) {
|
|
254
|
+
const linesBetween = sourceCode
|
|
255
|
+
.getText()
|
|
256
|
+
.slice(lastToken.range[1], nextToken.range[0])
|
|
257
|
+
.split(astUtils.LINEBREAK_MATCHER);
|
|
258
|
+
|
|
259
|
+
return fixer.replaceTextRange(
|
|
260
|
+
[lastToken.range[1], nextToken.range[0]],
|
|
261
|
+
`${linesBetween.slice(0, -1).join("")}\n${linesBetween.at(-1)}`,
|
|
262
|
+
);
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Token on the next line, or comment without blank line
|
|
268
|
+
if (
|
|
269
|
+
mode === "always" &&
|
|
270
|
+
(!noNextLineToken ||
|
|
271
|
+
(hasNextLineComment &&
|
|
272
|
+
!hasBlankLineAfterComment(nextToken, nextLineNum)))
|
|
273
|
+
) {
|
|
274
|
+
context.report({
|
|
275
|
+
node,
|
|
276
|
+
messageId: "expected",
|
|
277
|
+
fix(fixer) {
|
|
278
|
+
if (
|
|
279
|
+
(noNextLineToken
|
|
280
|
+
? getLastCommentLineOfBlock(nextLineNum)
|
|
281
|
+
: lastToken.loc.end.line) ===
|
|
282
|
+
nextToken.loc.start.line
|
|
283
|
+
) {
|
|
284
|
+
return fixer.insertTextBefore(nextToken, "\n\n");
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return fixer.insertTextBeforeRange(
|
|
288
|
+
[
|
|
289
|
+
nextToken.range[0] - nextToken.loc.start.column,
|
|
290
|
+
nextToken.range[1],
|
|
291
|
+
],
|
|
292
|
+
"\n",
|
|
293
|
+
);
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
//--------------------------------------------------------------------------
|
|
300
|
+
// Public
|
|
301
|
+
//--------------------------------------------------------------------------
|
|
302
|
+
|
|
303
|
+
return {
|
|
304
|
+
VariableDeclaration: checkForBlankLine,
|
|
305
|
+
};
|
|
306
|
+
},
|
|
307
|
+
};
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to require newlines before `return` statement
|
|
3
|
+
* @author Kai Cataldo
|
|
4
|
+
* @deprecated in ESLint v4.0.0
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
//------------------------------------------------------------------------------
|
|
9
|
+
// Rule Definition
|
|
10
|
+
//------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
13
|
+
module.exports = {
|
|
14
|
+
meta: {
|
|
15
|
+
type: "layout",
|
|
16
|
+
|
|
17
|
+
docs: {
|
|
18
|
+
description: "Require an empty line before `return` statements",
|
|
19
|
+
recommended: false,
|
|
20
|
+
url: "https://eslint.org/docs/latest/rules/newline-before-return",
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
fixable: "whitespace",
|
|
24
|
+
schema: [],
|
|
25
|
+
messages: {
|
|
26
|
+
expected: "Expected newline before return statement.",
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
deprecated: {
|
|
30
|
+
message: "The rule was replaced with a more general rule.",
|
|
31
|
+
url: "https://eslint.org/blog/2017/06/eslint-v4.0.0-released/",
|
|
32
|
+
deprecatedSince: "4.0.0",
|
|
33
|
+
availableUntil: "11.0.0",
|
|
34
|
+
replacedBy: [
|
|
35
|
+
{
|
|
36
|
+
message: "The new rule moved to a plugin.",
|
|
37
|
+
url: "https://eslint.org/docs/latest/rules/padding-line-between-statements#examples",
|
|
38
|
+
plugin: {
|
|
39
|
+
name: "@stylistic/eslint-plugin",
|
|
40
|
+
url: "https://eslint.style",
|
|
41
|
+
},
|
|
42
|
+
rule: {
|
|
43
|
+
name: "padding-line-between-statements",
|
|
44
|
+
url: "https://eslint.style/rules/padding-line-between-statements",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
create(context) {
|
|
52
|
+
const sourceCode = context.sourceCode;
|
|
53
|
+
|
|
54
|
+
//--------------------------------------------------------------------------
|
|
55
|
+
// Helpers
|
|
56
|
+
//--------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Tests whether node is preceded by supplied tokens
|
|
60
|
+
* @param {ASTNode} node node to check
|
|
61
|
+
* @param {Array} testTokens array of tokens to test against
|
|
62
|
+
* @returns {boolean} Whether or not the node is preceded by one of the supplied tokens
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
function isPrecededByTokens(node, testTokens) {
|
|
66
|
+
const tokenBefore = sourceCode.getTokenBefore(node);
|
|
67
|
+
|
|
68
|
+
return testTokens.includes(tokenBefore.value);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Checks whether node is the first node after statement or in block
|
|
73
|
+
* @param {ASTNode} node node to check
|
|
74
|
+
* @returns {boolean} Whether or not the node is the first node after statement or in block
|
|
75
|
+
* @private
|
|
76
|
+
*/
|
|
77
|
+
function isFirstNode(node) {
|
|
78
|
+
const parentType = node.parent.type;
|
|
79
|
+
|
|
80
|
+
if (node.parent.body) {
|
|
81
|
+
return Array.isArray(node.parent.body)
|
|
82
|
+
? node.parent.body[0] === node
|
|
83
|
+
: node.parent.body === node;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (parentType === "IfStatement") {
|
|
87
|
+
return isPrecededByTokens(node, ["else", ")"]);
|
|
88
|
+
}
|
|
89
|
+
if (parentType === "DoWhileStatement") {
|
|
90
|
+
return isPrecededByTokens(node, ["do"]);
|
|
91
|
+
}
|
|
92
|
+
if (parentType === "SwitchCase") {
|
|
93
|
+
return isPrecededByTokens(node, [":"]);
|
|
94
|
+
}
|
|
95
|
+
return isPrecededByTokens(node, [")"]);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Returns the number of lines of comments that precede the node
|
|
100
|
+
* @param {ASTNode} node node to check for overlapping comments
|
|
101
|
+
* @param {number} lineNumTokenBefore line number of previous token, to check for overlapping comments
|
|
102
|
+
* @returns {number} Number of lines of comments that precede the node
|
|
103
|
+
* @private
|
|
104
|
+
*/
|
|
105
|
+
function calcCommentLines(node, lineNumTokenBefore) {
|
|
106
|
+
const comments = sourceCode.getCommentsBefore(node);
|
|
107
|
+
let numLinesComments = 0;
|
|
108
|
+
|
|
109
|
+
if (!comments.length) {
|
|
110
|
+
return numLinesComments;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
comments.forEach(comment => {
|
|
114
|
+
numLinesComments++;
|
|
115
|
+
|
|
116
|
+
if (comment.type === "Block") {
|
|
117
|
+
numLinesComments +=
|
|
118
|
+
comment.loc.end.line - comment.loc.start.line;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// avoid counting lines with inline comments twice
|
|
122
|
+
if (comment.loc.start.line === lineNumTokenBefore) {
|
|
123
|
+
numLinesComments--;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (comment.loc.end.line === node.loc.start.line) {
|
|
127
|
+
numLinesComments--;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return numLinesComments;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Returns the line number of the token before the node that is passed in as an argument
|
|
136
|
+
* @param {ASTNode} node The node to use as the start of the calculation
|
|
137
|
+
* @returns {number} Line number of the token before `node`
|
|
138
|
+
* @private
|
|
139
|
+
*/
|
|
140
|
+
function getLineNumberOfTokenBefore(node) {
|
|
141
|
+
const tokenBefore = sourceCode.getTokenBefore(node);
|
|
142
|
+
let lineNumTokenBefore;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Global return (at the beginning of a script) is a special case.
|
|
146
|
+
* If there is no token before `return`, then we expect no line
|
|
147
|
+
* break before the return. Comments are allowed to occupy lines
|
|
148
|
+
* before the global return, just no blank lines.
|
|
149
|
+
* Setting lineNumTokenBefore to zero in that case results in the
|
|
150
|
+
* desired behavior.
|
|
151
|
+
*/
|
|
152
|
+
if (tokenBefore) {
|
|
153
|
+
lineNumTokenBefore = tokenBefore.loc.end.line;
|
|
154
|
+
} else {
|
|
155
|
+
lineNumTokenBefore = 0; // global return at beginning of script
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return lineNumTokenBefore;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Checks whether node is preceded by a newline
|
|
163
|
+
* @param {ASTNode} node node to check
|
|
164
|
+
* @returns {boolean} Whether or not the node is preceded by a newline
|
|
165
|
+
* @private
|
|
166
|
+
*/
|
|
167
|
+
function hasNewlineBefore(node) {
|
|
168
|
+
const lineNumNode = node.loc.start.line;
|
|
169
|
+
const lineNumTokenBefore = getLineNumberOfTokenBefore(node);
|
|
170
|
+
const commentLines = calcCommentLines(node, lineNumTokenBefore);
|
|
171
|
+
|
|
172
|
+
return lineNumNode - lineNumTokenBefore - commentLines > 1;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Checks whether it is safe to apply a fix to a given return statement.
|
|
177
|
+
*
|
|
178
|
+
* The fix is not considered safe if the given return statement has leading comments,
|
|
179
|
+
* as we cannot safely determine if the newline should be added before or after the comments.
|
|
180
|
+
* For more information, see: https://github.com/eslint/eslint/issues/5958#issuecomment-222767211
|
|
181
|
+
* @param {ASTNode} node The return statement node to check.
|
|
182
|
+
* @returns {boolean} `true` if it can fix the node.
|
|
183
|
+
* @private
|
|
184
|
+
*/
|
|
185
|
+
function canFix(node) {
|
|
186
|
+
const leadingComments = sourceCode.getCommentsBefore(node);
|
|
187
|
+
const lastLeadingComment = leadingComments.at(-1);
|
|
188
|
+
const tokenBefore = sourceCode.getTokenBefore(node);
|
|
189
|
+
|
|
190
|
+
if (leadingComments.length === 0) {
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/*
|
|
195
|
+
* if the last leading comment ends in the same line as the previous token and
|
|
196
|
+
* does not share a line with the `return` node, we can consider it safe to fix.
|
|
197
|
+
* Example:
|
|
198
|
+
* function a() {
|
|
199
|
+
* var b; //comment
|
|
200
|
+
* return;
|
|
201
|
+
* }
|
|
202
|
+
*/
|
|
203
|
+
if (
|
|
204
|
+
lastLeadingComment.loc.end.line === tokenBefore.loc.end.line &&
|
|
205
|
+
lastLeadingComment.loc.end.line !== node.loc.start.line
|
|
206
|
+
) {
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
//--------------------------------------------------------------------------
|
|
214
|
+
// Public
|
|
215
|
+
//--------------------------------------------------------------------------
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
ReturnStatement(node) {
|
|
219
|
+
if (!isFirstNode(node) && !hasNewlineBefore(node)) {
|
|
220
|
+
context.report({
|
|
221
|
+
node,
|
|
222
|
+
messageId: "expected",
|
|
223
|
+
fix(fixer) {
|
|
224
|
+
if (canFix(node)) {
|
|
225
|
+
const tokenBefore =
|
|
226
|
+
sourceCode.getTokenBefore(node);
|
|
227
|
+
const newlines =
|
|
228
|
+
node.loc.start.line ===
|
|
229
|
+
tokenBefore.loc.end.line
|
|
230
|
+
? "\n\n"
|
|
231
|
+
: "\n";
|
|
232
|
+
|
|
233
|
+
return fixer.insertTextBefore(node, newlines);
|
|
234
|
+
}
|
|
235
|
+
return null;
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
},
|
|
242
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to ensure newline per method call when chaining calls
|
|
3
|
+
* @author Rajendra Patil
|
|
4
|
+
* @author Burak Yigit Kaya
|
|
5
|
+
* @deprecated in ESLint v8.53.0
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
"use strict";
|
|
9
|
+
|
|
10
|
+
const astUtils = require("./utils/ast-utils");
|
|
11
|
+
|
|
12
|
+
//------------------------------------------------------------------------------
|
|
13
|
+
// Rule Definition
|
|
14
|
+
//------------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
/** @type {import('../types').Rule.RuleModule} */
|
|
17
|
+
module.exports = {
|
|
18
|
+
meta: {
|
|
19
|
+
deprecated: {
|
|
20
|
+
message: "Formatting rules are being moved out of ESLint core.",
|
|
21
|
+
url: "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
|
|
22
|
+
deprecatedSince: "8.53.0",
|
|
23
|
+
availableUntil: "11.0.0",
|
|
24
|
+
replacedBy: [
|
|
25
|
+
{
|
|
26
|
+
message:
|
|
27
|
+
"ESLint Stylistic now maintains deprecated stylistic core rules.",
|
|
28
|
+
url: "https://eslint.style/guide/migration",
|
|
29
|
+
plugin: {
|
|
30
|
+
name: "@stylistic/eslint-plugin",
|
|
31
|
+
url: "https://eslint.style",
|
|
32
|
+
},
|
|
33
|
+
rule: {
|
|
34
|
+
name: "newline-per-chained-call",
|
|
35
|
+
url: "https://eslint.style/rules/newline-per-chained-call",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
type: "layout",
|
|
41
|
+
|
|
42
|
+
docs: {
|
|
43
|
+
description: "Require a newline after each call in a method chain",
|
|
44
|
+
recommended: false,
|
|
45
|
+
url: "https://eslint.org/docs/latest/rules/newline-per-chained-call",
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
fixable: "whitespace",
|
|
49
|
+
|
|
50
|
+
schema: [
|
|
51
|
+
{
|
|
52
|
+
type: "object",
|
|
53
|
+
properties: {
|
|
54
|
+
ignoreChainWithDepth: {
|
|
55
|
+
type: "integer",
|
|
56
|
+
minimum: 1,
|
|
57
|
+
maximum: 10,
|
|
58
|
+
default: 2,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
additionalProperties: false,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
messages: {
|
|
65
|
+
expected: "Expected line break before `{{callee}}`.",
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
create(context) {
|
|
70
|
+
const options = context.options[0] || {},
|
|
71
|
+
ignoreChainWithDepth = options.ignoreChainWithDepth || 2;
|
|
72
|
+
|
|
73
|
+
const sourceCode = context.sourceCode;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Get the prefix of a given MemberExpression node.
|
|
77
|
+
* If the MemberExpression node is a computed value it returns a
|
|
78
|
+
* left bracket. If not it returns a period.
|
|
79
|
+
* @param {ASTNode} node A MemberExpression node to get
|
|
80
|
+
* @returns {string} The prefix of the node.
|
|
81
|
+
*/
|
|
82
|
+
function getPrefix(node) {
|
|
83
|
+
if (node.computed) {
|
|
84
|
+
if (node.optional) {
|
|
85
|
+
return "?.[";
|
|
86
|
+
}
|
|
87
|
+
return "[";
|
|
88
|
+
}
|
|
89
|
+
if (node.optional) {
|
|
90
|
+
return "?.";
|
|
91
|
+
}
|
|
92
|
+
return ".";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Gets the property text of a given MemberExpression node.
|
|
97
|
+
* If the text is multiline, this returns only the first line.
|
|
98
|
+
* @param {ASTNode} node A MemberExpression node to get.
|
|
99
|
+
* @returns {string} The property text of the node.
|
|
100
|
+
*/
|
|
101
|
+
function getPropertyText(node) {
|
|
102
|
+
const prefix = getPrefix(node);
|
|
103
|
+
const lines = sourceCode
|
|
104
|
+
.getText(node.property)
|
|
105
|
+
.split(astUtils.LINEBREAK_MATCHER);
|
|
106
|
+
const suffix = node.computed && lines.length === 1 ? "]" : "";
|
|
107
|
+
|
|
108
|
+
return prefix + lines[0] + suffix;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
"CallExpression:exit"(node) {
|
|
113
|
+
const callee = astUtils.skipChainExpression(node.callee);
|
|
114
|
+
|
|
115
|
+
if (callee.type !== "MemberExpression") {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let parent = astUtils.skipChainExpression(callee.object);
|
|
120
|
+
let depth = 1;
|
|
121
|
+
|
|
122
|
+
while (parent && parent.callee) {
|
|
123
|
+
depth += 1;
|
|
124
|
+
parent = astUtils.skipChainExpression(
|
|
125
|
+
astUtils.skipChainExpression(parent.callee).object,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (
|
|
130
|
+
depth > ignoreChainWithDepth &&
|
|
131
|
+
astUtils.isTokenOnSameLine(callee.object, callee.property)
|
|
132
|
+
) {
|
|
133
|
+
const firstTokenAfterObject = sourceCode.getTokenAfter(
|
|
134
|
+
callee.object,
|
|
135
|
+
astUtils.isNotClosingParenToken,
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
context.report({
|
|
139
|
+
node: callee.property,
|
|
140
|
+
loc: {
|
|
141
|
+
start: firstTokenAfterObject.loc.start,
|
|
142
|
+
end: callee.loc.end,
|
|
143
|
+
},
|
|
144
|
+
messageId: "expected",
|
|
145
|
+
data: {
|
|
146
|
+
callee: getPropertyText(callee),
|
|
147
|
+
},
|
|
148
|
+
fix(fixer) {
|
|
149
|
+
return fixer.insertTextBefore(
|
|
150
|
+
firstTokenAfterObject,
|
|
151
|
+
"\n",
|
|
152
|
+
);
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
},
|
|
159
|
+
};
|