eslint 8.57.1 → 9.39.1
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/README.md +165 -115
- package/bin/eslint.js +112 -89
- package/conf/default-cli-options.js +22 -22
- package/conf/ecma-version.js +16 -0
- package/conf/globals.js +109 -94
- package/conf/replacements.json +24 -20
- package/conf/rule-type-list.json +89 -26
- package/lib/api.js +16 -20
- package/lib/cli-engine/cli-engine.js +841 -810
- package/lib/cli-engine/file-enumerator.js +384 -390
- package/lib/cli-engine/formatters/formatters-meta.json +17 -45
- package/lib/cli-engine/formatters/html.js +110 -102
- package/lib/cli-engine/formatters/json-with-metadata.js +5 -5
- package/lib/cli-engine/formatters/json.js +2 -2
- package/lib/cli-engine/formatters/stylish.js +97 -76
- package/lib/cli-engine/hash.js +1 -1
- package/lib/cli-engine/index.js +1 -1
- package/lib/cli-engine/lint-result-cache.js +165 -148
- package/lib/cli-engine/load-rules.js +17 -17
- package/lib/cli.js +481 -399
- package/lib/config/config-loader.js +816 -0
- package/lib/config/config.js +674 -0
- package/lib/config/default-config.js +57 -46
- package/lib/config/flat-config-array.js +170 -333
- package/lib/config/flat-config-schema.js +389 -389
- package/lib/config-api.js +12 -0
- package/lib/eslint/eslint-helpers.js +1196 -663
- package/lib/eslint/eslint.js +1262 -607
- package/lib/eslint/index.js +3 -3
- package/lib/eslint/legacy-eslint.js +786 -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 +1364 -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/{source-code → languages/js/source-code}/token-store/cursor.js +36 -36
- package/lib/languages/js/source-code/token-store/cursors.js +120 -0
- package/lib/{source-code → languages/js/source-code}/token-store/decorative-cursor.js +17 -18
- package/lib/{source-code → languages/js/source-code}/token-store/filter-cursor.js +19 -20
- 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 +721 -0
- package/lib/{source-code → languages/js/source-code}/token-store/limit-cursor.js +17 -18
- package/lib/languages/js/source-code/token-store/padded-token-cursor.js +45 -0
- package/lib/{source-code → languages/js/source-code}/token-store/skip-cursor.js +19 -20
- package/lib/languages/js/source-code/token-store/utils.js +110 -0
- package/lib/languages/js/validate-language-options.js +196 -0
- package/lib/linter/apply-disable-directives.js +490 -371
- package/lib/linter/code-path-analysis/code-path-analyzer.js +650 -674
- package/lib/linter/code-path-analysis/code-path-segment.js +215 -216
- package/lib/linter/code-path-analysis/code-path-state.js +2118 -2096
- package/lib/linter/code-path-analysis/code-path.js +307 -317
- package/lib/linter/code-path-analysis/debug-helpers.js +183 -163
- package/lib/linter/code-path-analysis/fork-context.js +297 -272
- package/lib/linter/code-path-analysis/id-generator.js +22 -23
- package/lib/linter/esquery.js +332 -0
- package/lib/linter/file-context.js +144 -0
- package/lib/linter/file-report.js +608 -0
- package/lib/linter/index.js +3 -5
- package/lib/linter/interpolate.js +38 -16
- package/lib/linter/linter.js +2328 -1785
- package/lib/linter/rule-fixer.js +136 -107
- package/lib/linter/rules.js +37 -46
- package/lib/linter/source-code-fixer.js +96 -94
- package/lib/linter/source-code-traverser.js +333 -0
- package/lib/linter/source-code-visitor.js +81 -0
- package/lib/linter/timing.js +145 -97
- package/lib/linter/vfile.js +115 -0
- package/lib/options.js +464 -326
- package/lib/rule-tester/index.js +3 -1
- package/lib/rule-tester/rule-tester.js +1371 -998
- package/lib/rules/accessor-pairs.js +333 -259
- package/lib/rules/array-bracket-newline.js +250 -220
- package/lib/rules/array-bracket-spacing.js +286 -229
- package/lib/rules/array-callback-return.js +401 -354
- package/lib/rules/array-element-newline.js +358 -295
- package/lib/rules/arrow-body-style.js +400 -278
- package/lib/rules/arrow-parens.js +206 -155
- package/lib/rules/arrow-spacing.js +169 -145
- package/lib/rules/block-scoped-var.js +125 -123
- package/lib/rules/block-spacing.js +186 -158
- package/lib/rules/brace-style.js +262 -181
- package/lib/rules/callback-return.js +203 -174
- package/lib/rules/camelcase.js +403 -380
- package/lib/rules/capitalized-comments.js +253 -228
- package/lib/rules/class-methods-use-this.js +231 -168
- package/lib/rules/comma-dangle.js +379 -328
- package/lib/rules/comma-spacing.js +193 -177
- package/lib/rules/comma-style.js +375 -298
- package/lib/rules/complexity.js +180 -144
- package/lib/rules/computed-property-spacing.js +236 -193
- package/lib/rules/consistent-return.js +181 -170
- package/lib/rules/consistent-this.js +167 -141
- package/lib/rules/constructor-super.js +418 -411
- package/lib/rules/curly.js +407 -468
- package/lib/rules/default-case-last.js +39 -32
- package/lib/rules/default-case.js +89 -83
- package/lib/rules/default-param-last.js +69 -53
- package/lib/rules/dot-location.js +122 -92
- package/lib/rules/dot-notation.js +193 -153
- package/lib/rules/eol-last.js +122 -102
- package/lib/rules/eqeqeq.js +191 -155
- package/lib/rules/for-direction.js +150 -122
- package/lib/rules/func-call-spacing.js +261 -213
- package/lib/rules/func-name-matching.js +294 -209
- package/lib/rules/func-names.js +165 -164
- package/lib/rules/func-style.js +209 -86
- package/lib/rules/function-call-argument-newline.js +152 -111
- package/lib/rules/function-paren-newline.js +349 -273
- package/lib/rules/generator-star-spacing.js +229 -192
- package/lib/rules/getter-return.js +208 -170
- package/lib/rules/global-require.js +85 -58
- package/lib/rules/grouped-accessor-pairs.js +201 -148
- package/lib/rules/guard-for-in.js +72 -63
- package/lib/rules/handle-callback-err.js +108 -87
- package/lib/rules/id-blacklist.js +182 -187
- package/lib/rules/id-denylist.js +174 -179
- package/lib/rules/id-length.js +197 -157
- package/lib/rules/id-match.js +350 -286
- package/lib/rules/implicit-arrow-linebreak.js +102 -61
- package/lib/rules/indent-legacy.js +1345 -1102
- package/lib/rules/indent.js +2272 -1741
- package/lib/rules/index.js +320 -294
- package/lib/rules/init-declarations.js +139 -106
- package/lib/rules/jsx-quotes.js +94 -64
- package/lib/rules/key-spacing.js +750 -615
- package/lib/rules/keyword-spacing.js +648 -587
- package/lib/rules/line-comment-position.js +143 -108
- package/lib/rules/linebreak-style.js +115 -88
- package/lib/rules/lines-around-comment.js +540 -430
- package/lib/rules/lines-around-directive.js +233 -185
- package/lib/rules/lines-between-class-members.js +305 -216
- package/lib/rules/logical-assignment-operators.js +582 -398
- package/lib/rules/max-classes-per-file.js +69 -68
- package/lib/rules/max-depth.js +146 -143
- package/lib/rules/max-len.js +473 -416
- package/lib/rules/max-lines-per-function.js +201 -176
- package/lib/rules/max-lines.js +158 -162
- package/lib/rules/max-nested-callbacks.js +102 -104
- package/lib/rules/max-params.js +102 -75
- package/lib/rules/max-statements-per-line.js +205 -180
- package/lib/rules/max-statements.js +168 -164
- package/lib/rules/multiline-comment-style.js +638 -460
- package/lib/rules/multiline-ternary.js +241 -158
- package/lib/rules/new-cap.js +233 -232
- package/lib/rules/new-parens.js +88 -61
- package/lib/rules/newline-after-var.js +287 -233
- package/lib/rules/newline-before-return.js +229 -204
- package/lib/rules/newline-per-chained-call.js +142 -109
- package/lib/rules/no-alert.js +90 -79
- package/lib/rules/no-array-constructor.js +175 -113
- package/lib/rules/no-async-promise-executor.js +30 -24
- package/lib/rules/no-await-in-loop.js +79 -70
- package/lib/rules/no-bitwise.js +113 -87
- package/lib/rules/no-buffer-constructor.js +61 -37
- package/lib/rules/no-caller.js +39 -33
- package/lib/rules/no-case-declarations.js +61 -45
- package/lib/rules/no-catch-shadow.js +76 -62
- package/lib/rules/no-class-assign.js +51 -48
- package/lib/rules/no-compare-neg-zero.js +62 -48
- package/lib/rules/no-cond-assign.js +148 -132
- package/lib/rules/no-confusing-arrow.js +98 -63
- package/lib/rules/no-console.js +202 -188
- package/lib/rules/no-const-assign.js +58 -41
- package/lib/rules/no-constant-binary-expression.js +501 -407
- package/lib/rules/no-constant-condition.js +158 -131
- package/lib/rules/no-constructor-return.js +49 -49
- package/lib/rules/no-continue.js +25 -26
- package/lib/rules/no-control-regex.js +125 -121
- package/lib/rules/no-debugger.js +28 -30
- package/lib/rules/no-delete-var.js +29 -29
- package/lib/rules/no-div-regex.js +47 -40
- package/lib/rules/no-dupe-args.js +79 -69
- package/lib/rules/no-dupe-class-members.js +102 -89
- package/lib/rules/no-dupe-else-if.js +100 -77
- package/lib/rules/no-dupe-keys.js +133 -110
- package/lib/rules/no-duplicate-case.js +50 -43
- package/lib/rules/no-duplicate-imports.js +266 -188
- package/lib/rules/no-else-return.js +430 -385
- package/lib/rules/no-empty-character-class.js +57 -50
- package/lib/rules/no-empty-function.js +197 -128
- package/lib/rules/no-empty-pattern.js +63 -56
- package/lib/rules/no-empty-static-block.js +61 -35
- package/lib/rules/no-empty.js +135 -85
- package/lib/rules/no-eq-null.js +37 -32
- package/lib/rules/no-eval.js +258 -249
- package/lib/rules/no-ex-assign.js +42 -39
- package/lib/rules/no-extend-native.js +161 -160
- package/lib/rules/no-extra-bind.js +201 -190
- package/lib/rules/no-extra-boolean-cast.js +398 -295
- package/lib/rules/no-extra-label.js +150 -130
- package/lib/rules/no-extra-parens.js +1654 -1307
- package/lib/rules/no-extra-semi.js +146 -126
- package/lib/rules/no-fallthrough.js +200 -136
- package/lib/rules/no-floating-decimal.js +74 -48
- package/lib/rules/no-func-assign.js +54 -55
- package/lib/rules/no-global-assign.js +78 -72
- package/lib/rules/no-implicit-coercion.js +350 -262
- package/lib/rules/no-implicit-globals.js +174 -133
- package/lib/rules/no-implied-eval.js +150 -112
- package/lib/rules/no-import-assign.js +145 -159
- package/lib/rules/no-inline-comments.js +101 -96
- package/lib/rules/no-inner-declarations.js +115 -78
- package/lib/rules/no-invalid-regexp.js +223 -174
- package/lib/rules/no-invalid-this.js +145 -117
- package/lib/rules/no-irregular-whitespace.js +266 -250
- package/lib/rules/no-iterator.js +29 -33
- package/lib/rules/no-label-var.js +59 -61
- package/lib/rules/no-labels.js +138 -131
- package/lib/rules/no-lone-blocks.js +127 -123
- package/lib/rules/no-lonely-if.js +105 -67
- package/lib/rules/no-loop-func.js +245 -184
- package/lib/rules/no-loss-of-precision.js +236 -201
- package/lib/rules/no-magic-numbers.js +339 -217
- package/lib/rules/no-misleading-character-class.js +548 -253
- package/lib/rules/no-mixed-operators.js +188 -164
- package/lib/rules/no-mixed-requires.js +253 -224
- package/lib/rules/no-mixed-spaces-and-tabs.js +135 -103
- package/lib/rules/no-multi-assign.js +46 -47
- package/lib/rules/no-multi-spaces.js +163 -125
- package/lib/rules/no-multi-str.js +42 -40
- package/lib/rules/no-multiple-empty-lines.js +196 -140
- package/lib/rules/no-native-reassign.js +90 -74
- package/lib/rules/no-negated-condition.js +79 -74
- package/lib/rules/no-negated-in-lhs.js +45 -32
- package/lib/rules/no-nested-ternary.js +33 -31
- package/lib/rules/no-new-func.js +71 -62
- package/lib/rules/no-new-native-nonconstructor.js +43 -39
- package/lib/rules/no-new-object.js +48 -39
- package/lib/rules/no-new-require.js +48 -31
- package/lib/rules/no-new-symbol.js +61 -43
- package/lib/rules/no-new-wrappers.js +43 -41
- package/lib/rules/no-new.js +28 -29
- package/lib/rules/no-nonoctal-decimal-escape.js +149 -121
- package/lib/rules/no-obj-calls.js +66 -53
- package/lib/rules/no-object-constructor.js +104 -97
- package/lib/rules/no-octal-escape.js +40 -43
- package/lib/rules/no-octal.js +29 -32
- package/lib/rules/no-param-reassign.js +236 -218
- package/lib/rules/no-path-concat.js +66 -51
- package/lib/rules/no-plusplus.js +60 -63
- package/lib/rules/no-process-env.js +49 -32
- package/lib/rules/no-process-exit.js +48 -28
- package/lib/rules/no-promise-executor-return.js +205 -204
- package/lib/rules/no-proto.js +26 -29
- package/lib/rules/no-prototype-builtins.js +146 -124
- package/lib/rules/no-redeclare.js +154 -155
- package/lib/rules/no-regex-spaces.js +183 -161
- package/lib/rules/no-restricted-exports.js +208 -174
- package/lib/rules/no-restricted-globals.js +254 -112
- package/lib/rules/no-restricted-imports.js +824 -384
- package/lib/rules/no-restricted-modules.js +222 -186
- package/lib/rules/no-restricted-properties.js +218 -153
- package/lib/rules/no-restricted-syntax.js +56 -52
- package/lib/rules/no-return-assign.js +56 -49
- package/lib/rules/no-return-await.js +147 -120
- package/lib/rules/no-script-url.js +53 -46
- package/lib/rules/no-self-assign.js +148 -145
- package/lib/rules/no-self-compare.js +63 -46
- package/lib/rules/no-sequences.js +135 -115
- package/lib/rules/no-setter-return.js +176 -178
- package/lib/rules/no-shadow-restricted-names.js +84 -36
- package/lib/rules/no-shadow.js +598 -310
- package/lib/rules/no-spaced-func.js +82 -60
- package/lib/rules/no-sparse-arrays.js +46 -28
- package/lib/rules/no-sync.js +61 -44
- package/lib/rules/no-tabs.js +83 -54
- package/lib/rules/no-template-curly-in-string.js +33 -32
- package/lib/rules/no-ternary.js +25 -28
- package/lib/rules/no-this-before-super.js +332 -298
- package/lib/rules/no-throw-literal.js +31 -36
- package/lib/rules/no-trailing-spaces.js +208 -174
- package/lib/rules/no-unassigned-vars.js +80 -0
- package/lib/rules/no-undef-init.js +86 -60
- package/lib/rules/no-undef.js +52 -47
- package/lib/rules/no-undefined.js +73 -74
- package/lib/rules/no-underscore-dangle.js +370 -322
- package/lib/rules/no-unexpected-multiline.js +112 -102
- package/lib/rules/no-unmodified-loop-condition.js +254 -254
- package/lib/rules/no-unneeded-ternary.js +212 -146
- package/lib/rules/no-unreachable-loop.js +145 -140
- package/lib/rules/no-unreachable.js +255 -248
- package/lib/rules/no-unsafe-finally.js +93 -85
- package/lib/rules/no-unsafe-negation.js +105 -81
- package/lib/rules/no-unsafe-optional-chaining.js +193 -177
- package/lib/rules/no-unused-expressions.js +199 -158
- package/lib/rules/no-unused-labels.js +139 -124
- package/lib/rules/no-unused-private-class-members.js +206 -182
- package/lib/rules/no-unused-vars.js +1708 -687
- package/lib/rules/no-use-before-define.js +327 -229
- package/lib/rules/no-useless-assignment.js +654 -0
- package/lib/rules/no-useless-backreference.js +212 -143
- package/lib/rules/no-useless-call.js +58 -53
- package/lib/rules/no-useless-catch.js +40 -40
- package/lib/rules/no-useless-computed-key.js +144 -108
- package/lib/rules/no-useless-concat.js +65 -59
- package/lib/rules/no-useless-constructor.js +160 -97
- package/lib/rules/no-useless-escape.js +364 -291
- package/lib/rules/no-useless-rename.js +183 -153
- package/lib/rules/no-useless-return.js +344 -307
- package/lib/rules/no-var.js +245 -212
- package/lib/rules/no-void.js +51 -46
- package/lib/rules/no-warning-comments.js +191 -183
- package/lib/rules/no-whitespace-before-property.js +131 -97
- package/lib/rules/no-with.js +24 -26
- package/lib/rules/nonblock-statement-body-position.js +149 -112
- package/lib/rules/object-curly-newline.js +306 -247
- package/lib/rules/object-curly-spacing.js +360 -296
- package/lib/rules/object-property-newline.js +137 -88
- package/lib/rules/object-shorthand.js +632 -500
- package/lib/rules/one-var-declaration-per-line.js +104 -82
- package/lib/rules/one-var.js +686 -536
- package/lib/rules/operator-assignment.js +219 -158
- package/lib/rules/operator-linebreak.js +295 -233
- package/lib/rules/padded-blocks.js +346 -290
- package/lib/rules/padding-line-between-statements.js +443 -421
- package/lib/rules/prefer-arrow-callback.js +371 -315
- package/lib/rules/prefer-const.js +418 -373
- package/lib/rules/prefer-destructuring.js +309 -278
- package/lib/rules/prefer-exponentiation-operator.js +176 -132
- package/lib/rules/prefer-named-capture-group.js +160 -141
- package/lib/rules/prefer-numeric-literals.js +121 -112
- package/lib/rules/prefer-object-has-own.js +116 -82
- package/lib/rules/prefer-object-spread.js +214 -193
- package/lib/rules/prefer-promise-reject-errors.js +140 -118
- package/lib/rules/prefer-reflect.js +126 -103
- package/lib/rules/prefer-regex-literals.js +561 -463
- package/lib/rules/prefer-rest-params.js +79 -80
- package/lib/rules/prefer-spread.js +47 -43
- package/lib/rules/prefer-template.js +266 -194
- package/lib/rules/preserve-caught-error.js +535 -0
- package/lib/rules/quote-props.js +373 -289
- package/lib/rules/quotes.js +374 -308
- package/lib/rules/radix.js +152 -134
- package/lib/rules/require-atomic-updates.js +316 -282
- package/lib/rules/require-await.js +153 -82
- package/lib/rules/require-unicode-regexp.js +296 -108
- package/lib/rules/require-yield.js +53 -54
- package/lib/rules/rest-spread-spacing.js +128 -98
- package/lib/rules/semi-spacing.js +281 -232
- package/lib/rules/semi-style.js +176 -116
- package/lib/rules/semi.js +456 -418
- package/lib/rules/sort-imports.js +307 -229
- package/lib/rules/sort-keys.js +219 -181
- package/lib/rules/sort-vars.js +127 -91
- package/lib/rules/space-before-blocks.js +199 -171
- package/lib/rules/space-before-function-paren.js +186 -148
- package/lib/rules/space-in-parens.js +359 -270
- package/lib/rules/space-infix-ops.js +237 -183
- package/lib/rules/space-unary-ops.js +356 -280
- package/lib/rules/spaced-comment.js +363 -301
- package/lib/rules/strict.js +266 -229
- package/lib/rules/switch-colon-spacing.js +130 -104
- package/lib/rules/symbol-description.js +45 -48
- package/lib/rules/template-curly-spacing.js +148 -124
- package/lib/rules/template-tag-spacing.js +98 -70
- package/lib/rules/unicode-bom.js +54 -54
- package/lib/rules/use-isnan.js +237 -110
- package/lib/rules/utils/ast-utils.js +2139 -1688
- package/lib/rules/utils/char-source.js +247 -0
- package/lib/rules/utils/fix-tracker.js +99 -88
- package/lib/rules/utils/keywords.js +59 -59
- package/lib/rules/utils/lazy-loading-rule-map.js +81 -78
- package/lib/rules/utils/regular-expressions.js +35 -19
- package/lib/rules/utils/unicode/index.js +9 -4
- package/lib/rules/utils/unicode/is-combining-character.js +1 -1
- package/lib/rules/utils/unicode/is-emoji-modifier.js +1 -1
- package/lib/rules/utils/unicode/is-regional-indicator-symbol.js +1 -1
- package/lib/rules/utils/unicode/is-surrogate-pair.js +1 -1
- package/lib/rules/valid-typeof.js +153 -109
- package/lib/rules/vars-on-top.js +152 -144
- package/lib/rules/wrap-iife.js +204 -173
- package/lib/rules/wrap-regex.js +77 -47
- package/lib/rules/yield-star-spacing.js +145 -116
- package/lib/rules/yoda.js +283 -274
- package/lib/services/parser-service.js +65 -0
- package/lib/services/processor-service.js +101 -0
- package/lib/services/suppressions-service.js +302 -0
- package/lib/services/warning-service.js +98 -0
- package/lib/shared/ajv.js +14 -14
- package/lib/shared/assert.js +21 -0
- package/lib/shared/ast-utils.js +7 -6
- package/lib/shared/deep-merge-arrays.js +62 -0
- package/lib/shared/directives.js +3 -2
- package/lib/shared/flags.js +108 -0
- package/lib/shared/logging.js +24 -16
- package/lib/shared/naming.js +109 -0
- package/lib/shared/option-utils.js +63 -0
- package/lib/shared/relative-module-resolver.js +18 -40
- package/lib/shared/runtime-info.js +138 -128
- package/lib/shared/serialization.js +78 -0
- package/lib/shared/severity.js +22 -22
- package/lib/shared/stats.js +30 -0
- package/lib/shared/string-utils.js +19 -21
- package/lib/shared/text-table.js +68 -0
- package/lib/shared/translate-cli-options.js +281 -0
- package/lib/shared/traverser.js +153 -146
- package/lib/types/config-api.d.ts +12 -0
- package/lib/types/index.d.ts +1473 -0
- package/lib/types/rules.d.ts +5589 -0
- package/lib/types/universal.d.ts +6 -0
- package/lib/types/use-at-your-own-risk.d.ts +87 -0
- package/lib/universal.js +10 -0
- package/lib/unsupported-api.js +8 -9
- package/messages/all-files-ignored.js +3 -3
- 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 +35 -16
- package/messages/eslintrc-plugins.js +8 -5
- package/messages/extend-config-missing.js +3 -3
- package/messages/failed-to-read-json.js +3 -3
- package/messages/file-not-found.js +3 -3
- package/messages/invalid-rule-options.js +2 -2
- package/messages/invalid-rule-severity.js +2 -2
- package/messages/no-config-found.js +4 -4
- package/messages/plugin-conflict.js +9 -9
- package/messages/plugin-invalid.js +4 -4
- package/messages/plugin-missing.js +4 -4
- package/messages/print-config-with-directory-path.js +2 -2
- package/messages/shared.js +6 -1
- package/messages/whitespace-found.js +3 -3
- package/package.json +105 -60
- package/conf/config-schema.js +0 -93
- package/lib/cli-engine/formatters/checkstyle.js +0 -60
- package/lib/cli-engine/formatters/compact.js +0 -60
- package/lib/cli-engine/formatters/jslint-xml.js +0 -41
- package/lib/cli-engine/formatters/junit.js +0 -82
- package/lib/cli-engine/formatters/tap.js +0 -95
- package/lib/cli-engine/formatters/unix.js +0 -58
- package/lib/cli-engine/formatters/visualstudio.js +0 -63
- package/lib/cli-engine/xml-escape.js +0 -34
- package/lib/config/flat-config-helpers.js +0 -111
- package/lib/config/rule-validator.js +0 -158
- package/lib/eslint/flat-eslint.js +0 -1159
- package/lib/linter/config-comment-parser.js +0 -185
- package/lib/linter/node-event-generator.js +0 -354
- package/lib/linter/report-translator.js +0 -369
- package/lib/linter/safe-emitter.js +0 -52
- package/lib/rule-tester/flat-rule-tester.js +0 -1131
- package/lib/rules/require-jsdoc.js +0 -122
- package/lib/rules/utils/patterns/letters.js +0 -36
- package/lib/rules/valid-jsdoc.js +0 -516
- package/lib/shared/config-validator.js +0 -347
- package/lib/shared/deprecation-warnings.js +0 -58
- package/lib/shared/types.js +0 -216
- package/lib/source-code/index.js +0 -5
- package/lib/source-code/source-code.js +0 -1055
- package/lib/source-code/token-store/backward-token-comment-cursor.js +0 -57
- package/lib/source-code/token-store/backward-token-cursor.js +0 -58
- package/lib/source-code/token-store/cursors.js +0 -90
- package/lib/source-code/token-store/forward-token-comment-cursor.js +0 -57
- package/lib/source-code/token-store/forward-token-cursor.js +0 -63
- package/lib/source-code/token-store/index.js +0 -627
- package/lib/source-code/token-store/padded-token-cursor.js +0 -38
- package/lib/source-code/token-store/utils.js +0 -107
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Traverser for SourceCode objects.
|
|
3
|
+
* @author Nicholas C. Zakas
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
//------------------------------------------------------------------------------
|
|
9
|
+
// Requirements
|
|
10
|
+
//------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
const { parse, matches } = require("./esquery");
|
|
13
|
+
const vk = require("eslint-visitor-keys");
|
|
14
|
+
|
|
15
|
+
//-----------------------------------------------------------------------------
|
|
16
|
+
// Typedefs
|
|
17
|
+
//-----------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @import { Language, SourceCode } from "@eslint/core";
|
|
21
|
+
* @import { ESQueryOptions } from "esquery";
|
|
22
|
+
* @import { ESQueryParsedSelector } from "./esquery.js";
|
|
23
|
+
* @import { SourceCodeVisitor } from "./source-code-visitor.js";
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
//-----------------------------------------------------------------------------
|
|
27
|
+
// Helpers
|
|
28
|
+
//-----------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
const STEP_KIND_VISIT = 1;
|
|
31
|
+
const STEP_KIND_CALL = 2;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Compares two ESQuery selectors by specificity.
|
|
35
|
+
* @param {ESQueryParsedSelector} a The first selector to compare.
|
|
36
|
+
* @param {ESQueryParsedSelector} b The second selector to compare.
|
|
37
|
+
* @returns {number} A negative number if `a` is less specific than `b` or they are equally specific and `a` <= `b` alphabetically, a positive number if `a` is more specific than `b`.
|
|
38
|
+
*/
|
|
39
|
+
function compareSpecificity(a, b) {
|
|
40
|
+
return a.compare(b);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Helper to wrap ESQuery operations.
|
|
45
|
+
*/
|
|
46
|
+
class ESQueryHelper {
|
|
47
|
+
/**
|
|
48
|
+
* Creates a new instance.
|
|
49
|
+
* @param {SourceCodeVisitor} visitor The visitor containing the functions to call.
|
|
50
|
+
* @param {ESQueryOptions} esqueryOptions `esquery` options for traversing custom nodes.
|
|
51
|
+
*/
|
|
52
|
+
constructor(visitor, esqueryOptions) {
|
|
53
|
+
/**
|
|
54
|
+
* The visitor to use during traversal.
|
|
55
|
+
* @type {SourceCodeVisitor}
|
|
56
|
+
*/
|
|
57
|
+
this.visitor = visitor;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The options for `esquery` to use during matching.
|
|
61
|
+
* @type {ESQueryOptions}
|
|
62
|
+
*/
|
|
63
|
+
this.esqueryOptions = esqueryOptions;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* A map of node type to selectors targeting that node type on the
|
|
67
|
+
* enter phase of traversal.
|
|
68
|
+
* @type {Map<string, ESQueryParsedSelector[]>}
|
|
69
|
+
*/
|
|
70
|
+
this.enterSelectorsByNodeType = new Map();
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* A map of node type to selectors targeting that node type on the
|
|
74
|
+
* exit phase of traversal.
|
|
75
|
+
* @type {Map<string, ESQueryParsedSelector[]>}
|
|
76
|
+
*/
|
|
77
|
+
this.exitSelectorsByNodeType = new Map();
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* An array of selectors that match any node type on the
|
|
81
|
+
* enter phase of traversal.
|
|
82
|
+
* @type {ESQueryParsedSelector[]}
|
|
83
|
+
*/
|
|
84
|
+
this.anyTypeEnterSelectors = [];
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* An array of selectors that match any node type on the
|
|
88
|
+
* exit phase of traversal.
|
|
89
|
+
* @type {ESQueryParsedSelector[]}
|
|
90
|
+
*/
|
|
91
|
+
this.anyTypeExitSelectors = [];
|
|
92
|
+
|
|
93
|
+
visitor.forEachName(rawSelector => {
|
|
94
|
+
const selector = parse(rawSelector);
|
|
95
|
+
|
|
96
|
+
/*
|
|
97
|
+
* If this selector has identified specific node types,
|
|
98
|
+
* add it to the map for these node types for faster lookup.
|
|
99
|
+
*/
|
|
100
|
+
if (selector.nodeTypes) {
|
|
101
|
+
const typeMap = selector.isExit
|
|
102
|
+
? this.exitSelectorsByNodeType
|
|
103
|
+
: this.enterSelectorsByNodeType;
|
|
104
|
+
|
|
105
|
+
selector.nodeTypes.forEach(nodeType => {
|
|
106
|
+
if (!typeMap.has(nodeType)) {
|
|
107
|
+
typeMap.set(nodeType, []);
|
|
108
|
+
}
|
|
109
|
+
typeMap.get(nodeType).push(selector);
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/*
|
|
115
|
+
* Remaining selectors are added to the "any type" selectors
|
|
116
|
+
* list for the appropriate phase of traversal. This ensures
|
|
117
|
+
* that all selectors will still be applied even if no
|
|
118
|
+
* specific node type is matched.
|
|
119
|
+
*/
|
|
120
|
+
const selectors = selector.isExit
|
|
121
|
+
? this.anyTypeExitSelectors
|
|
122
|
+
: this.anyTypeEnterSelectors;
|
|
123
|
+
|
|
124
|
+
selectors.push(selector);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// sort all selectors by specificity for prioritizing call order
|
|
128
|
+
this.anyTypeEnterSelectors.sort(compareSpecificity);
|
|
129
|
+
this.anyTypeExitSelectors.sort(compareSpecificity);
|
|
130
|
+
this.enterSelectorsByNodeType.forEach(selectorList =>
|
|
131
|
+
selectorList.sort(compareSpecificity),
|
|
132
|
+
);
|
|
133
|
+
this.exitSelectorsByNodeType.forEach(selectorList =>
|
|
134
|
+
selectorList.sort(compareSpecificity),
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Checks if a node matches a given selector.
|
|
140
|
+
* @param {ASTNode} node The node to check
|
|
141
|
+
* @param {ASTNode[]} ancestry The ancestry of the node being checked.
|
|
142
|
+
* @param {ESQueryParsedSelector} selector An AST selector descriptor
|
|
143
|
+
* @returns {boolean} `true` if the selector matches the node, `false` otherwise
|
|
144
|
+
*/
|
|
145
|
+
matches(node, ancestry, selector) {
|
|
146
|
+
return matches(node, selector.root, ancestry, this.esqueryOptions);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Calculates all appropriate selectors to a node, in specificity order
|
|
151
|
+
* @param {ASTNode} node The node to check
|
|
152
|
+
* @param {ASTNode[]} ancestry The ancestry of the node being checked.
|
|
153
|
+
* @param {boolean} isExit `false` if the node is currently being entered, `true` if it's currently being exited
|
|
154
|
+
* @returns {string[]} An array of selectors that match the node.
|
|
155
|
+
*/
|
|
156
|
+
calculateSelectors(node, ancestry, isExit) {
|
|
157
|
+
const nodeTypeKey = this.esqueryOptions?.nodeTypeKey || "type";
|
|
158
|
+
const selectors = [];
|
|
159
|
+
|
|
160
|
+
/*
|
|
161
|
+
* Get the selectors that may match this node. First, check
|
|
162
|
+
* to see if the node type has specific selectors,
|
|
163
|
+
* then gather the "any type" selectors.
|
|
164
|
+
*/
|
|
165
|
+
const selectorsByNodeType =
|
|
166
|
+
(isExit
|
|
167
|
+
? this.exitSelectorsByNodeType
|
|
168
|
+
: this.enterSelectorsByNodeType
|
|
169
|
+
).get(node[nodeTypeKey]) || [];
|
|
170
|
+
const anyTypeSelectors = isExit
|
|
171
|
+
? this.anyTypeExitSelectors
|
|
172
|
+
: this.anyTypeEnterSelectors;
|
|
173
|
+
|
|
174
|
+
/*
|
|
175
|
+
* selectorsByNodeType and anyTypeSelectors were already sorted by specificity in the constructor.
|
|
176
|
+
* Iterate through each of them, applying selectors in the right order.
|
|
177
|
+
*/
|
|
178
|
+
let selectorsByNodeTypeIndex = 0;
|
|
179
|
+
let anyTypeSelectorsIndex = 0;
|
|
180
|
+
|
|
181
|
+
while (
|
|
182
|
+
selectorsByNodeTypeIndex < selectorsByNodeType.length ||
|
|
183
|
+
anyTypeSelectorsIndex < anyTypeSelectors.length
|
|
184
|
+
) {
|
|
185
|
+
/*
|
|
186
|
+
* If we've already exhausted the selectors for this node type,
|
|
187
|
+
* or if the next any type selector is more specific than the
|
|
188
|
+
* next selector for this node type, apply the any type selector.
|
|
189
|
+
*/
|
|
190
|
+
const hasMoreNodeTypeSelectors =
|
|
191
|
+
selectorsByNodeTypeIndex < selectorsByNodeType.length;
|
|
192
|
+
const hasMoreAnyTypeSelectors =
|
|
193
|
+
anyTypeSelectorsIndex < anyTypeSelectors.length;
|
|
194
|
+
const anyTypeSelector = anyTypeSelectors[anyTypeSelectorsIndex];
|
|
195
|
+
const nodeTypeSelector =
|
|
196
|
+
selectorsByNodeType[selectorsByNodeTypeIndex];
|
|
197
|
+
|
|
198
|
+
// Only compare specificity if both selectors exist
|
|
199
|
+
const isAnyTypeSelectorLessSpecific =
|
|
200
|
+
hasMoreAnyTypeSelectors &&
|
|
201
|
+
hasMoreNodeTypeSelectors &&
|
|
202
|
+
anyTypeSelector.compare(nodeTypeSelector) < 0;
|
|
203
|
+
|
|
204
|
+
if (!hasMoreNodeTypeSelectors || isAnyTypeSelectorLessSpecific) {
|
|
205
|
+
anyTypeSelectorsIndex++;
|
|
206
|
+
|
|
207
|
+
if (this.matches(node, ancestry, anyTypeSelector)) {
|
|
208
|
+
selectors.push(anyTypeSelector.source);
|
|
209
|
+
}
|
|
210
|
+
} else {
|
|
211
|
+
selectorsByNodeTypeIndex++;
|
|
212
|
+
|
|
213
|
+
if (this.matches(node, ancestry, nodeTypeSelector)) {
|
|
214
|
+
selectors.push(nodeTypeSelector.source);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return selectors;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
//------------------------------------------------------------------------------
|
|
224
|
+
// Public Interface
|
|
225
|
+
//------------------------------------------------------------------------------
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Traverses source code and ensures that visitor methods are called when
|
|
229
|
+
* entering and leaving each node.
|
|
230
|
+
*/
|
|
231
|
+
class SourceCodeTraverser {
|
|
232
|
+
/**
|
|
233
|
+
* The language of the source code being traversed.
|
|
234
|
+
* @type {Language}
|
|
235
|
+
*/
|
|
236
|
+
#language;
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Map of languages to instances of this class.
|
|
240
|
+
* @type {WeakMap<Language, SourceCodeTraverser>}
|
|
241
|
+
*/
|
|
242
|
+
static instances = new WeakMap();
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Creates a new instance.
|
|
246
|
+
* @param {Language} language The language of the source code being traversed.
|
|
247
|
+
*/
|
|
248
|
+
constructor(language) {
|
|
249
|
+
this.#language = language;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
static getInstance(language) {
|
|
253
|
+
if (!this.instances.has(language)) {
|
|
254
|
+
this.instances.set(language, new this(language));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return this.instances.get(language);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Traverses the given source code synchronously.
|
|
262
|
+
* @param {SourceCode} sourceCode The source code to traverse.
|
|
263
|
+
* @param {SourceCodeVisitor} visitor The emitter to use for events.
|
|
264
|
+
* @param {Object} options Options for traversal.
|
|
265
|
+
* @param {ReturnType<SourceCode["traverse"]>} options.steps The steps to take during traversal.
|
|
266
|
+
* @returns {void}
|
|
267
|
+
* @throws {Error} If an error occurs during traversal.
|
|
268
|
+
*/
|
|
269
|
+
traverseSync(sourceCode, visitor, { steps } = {}) {
|
|
270
|
+
const esquery = new ESQueryHelper(visitor, {
|
|
271
|
+
visitorKeys: sourceCode.visitorKeys ?? this.#language.visitorKeys,
|
|
272
|
+
fallback: vk.getKeys,
|
|
273
|
+
matchClass: this.#language.matchesSelectorClass ?? (() => false),
|
|
274
|
+
nodeTypeKey: this.#language.nodeTypeKey,
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
const currentAncestry = [];
|
|
278
|
+
|
|
279
|
+
for (const step of steps ?? sourceCode.traverse()) {
|
|
280
|
+
switch (step.kind) {
|
|
281
|
+
case STEP_KIND_VISIT: {
|
|
282
|
+
try {
|
|
283
|
+
if (step.phase === 1) {
|
|
284
|
+
esquery
|
|
285
|
+
.calculateSelectors(
|
|
286
|
+
step.target,
|
|
287
|
+
currentAncestry,
|
|
288
|
+
false,
|
|
289
|
+
)
|
|
290
|
+
.forEach(selector => {
|
|
291
|
+
visitor.callSync(
|
|
292
|
+
selector,
|
|
293
|
+
...(step.args ?? [step.target]),
|
|
294
|
+
);
|
|
295
|
+
});
|
|
296
|
+
currentAncestry.unshift(step.target);
|
|
297
|
+
} else {
|
|
298
|
+
currentAncestry.shift();
|
|
299
|
+
esquery
|
|
300
|
+
.calculateSelectors(
|
|
301
|
+
step.target,
|
|
302
|
+
currentAncestry,
|
|
303
|
+
true,
|
|
304
|
+
)
|
|
305
|
+
.forEach(selector => {
|
|
306
|
+
visitor.callSync(
|
|
307
|
+
selector,
|
|
308
|
+
...(step.args ?? [step.target]),
|
|
309
|
+
);
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
} catch (err) {
|
|
313
|
+
err.currentNode = step.target;
|
|
314
|
+
throw err;
|
|
315
|
+
}
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
case STEP_KIND_CALL: {
|
|
320
|
+
visitor.callSync(step.target, ...step.args);
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
default:
|
|
325
|
+
throw new Error(
|
|
326
|
+
`Invalid traversal step found: "${step.kind}".`,
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
module.exports = { SourceCodeTraverser };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview SourceCodeVisitor class
|
|
3
|
+
* @author Nicholas C. Zakas
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
//-----------------------------------------------------------------------------
|
|
9
|
+
// Helpers
|
|
10
|
+
//-----------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
const emptyArray = Object.freeze([]);
|
|
13
|
+
|
|
14
|
+
//------------------------------------------------------------------------------
|
|
15
|
+
// Exports
|
|
16
|
+
//------------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A structure to hold a list of functions to call for a given name.
|
|
20
|
+
* This is used to allow multiple rules to register functions for a given name
|
|
21
|
+
* without having to know about each other.
|
|
22
|
+
*/
|
|
23
|
+
class SourceCodeVisitor {
|
|
24
|
+
/**
|
|
25
|
+
* The functions to call for a given name.
|
|
26
|
+
* @type {Map<string, Function[]>}
|
|
27
|
+
*/
|
|
28
|
+
#functions = new Map();
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Adds a function to the list of functions to call for a given name.
|
|
32
|
+
* @param {string} name The name of the function to call.
|
|
33
|
+
* @param {Function} func The function to call.
|
|
34
|
+
* @returns {void}
|
|
35
|
+
*/
|
|
36
|
+
add(name, func) {
|
|
37
|
+
if (this.#functions.has(name)) {
|
|
38
|
+
this.#functions.get(name).push(func);
|
|
39
|
+
} else {
|
|
40
|
+
this.#functions.set(name, [func]);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Gets the list of functions to call for a given name.
|
|
46
|
+
* @param {string} name The name of the function to call.
|
|
47
|
+
* @returns {Function[]} The list of functions to call.
|
|
48
|
+
*/
|
|
49
|
+
get(name) {
|
|
50
|
+
if (this.#functions.has(name)) {
|
|
51
|
+
return this.#functions.get(name);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return emptyArray;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Iterates over all names and calls the callback with the name.
|
|
59
|
+
* @param {(name:string) => void} callback The callback to call for each name.
|
|
60
|
+
* @returns {void}
|
|
61
|
+
*/
|
|
62
|
+
forEachName(callback) {
|
|
63
|
+
this.#functions.forEach((funcs, name) => {
|
|
64
|
+
callback(name);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Calls the functions for a given name with the given arguments.
|
|
70
|
+
* @param {string} name The name of the function to call.
|
|
71
|
+
* @param {any[]} args The arguments to pass to the function.
|
|
72
|
+
* @returns {void}
|
|
73
|
+
*/
|
|
74
|
+
callSync(name, ...args) {
|
|
75
|
+
if (this.#functions.has(name)) {
|
|
76
|
+
this.#functions.get(name).forEach(func => func(...args));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = { SourceCodeVisitor };
|
package/lib/linter/timing.js
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
|
+
const { startTime, endTime } = require("../shared/stats");
|
|
9
|
+
|
|
8
10
|
//------------------------------------------------------------------------------
|
|
9
11
|
// Helpers
|
|
10
12
|
//------------------------------------------------------------------------------
|
|
@@ -13,26 +15,26 @@
|
|
|
13
15
|
/**
|
|
14
16
|
* Align the string to left
|
|
15
17
|
* @param {string} str string to evaluate
|
|
16
|
-
* @param {
|
|
18
|
+
* @param {number} len length of the string
|
|
17
19
|
* @param {string} ch delimiter character
|
|
18
20
|
* @returns {string} modified string
|
|
19
21
|
* @private
|
|
20
22
|
*/
|
|
21
23
|
function alignLeft(str, len, ch) {
|
|
22
|
-
|
|
24
|
+
return str + new Array(len - str.length + 1).join(ch || " ");
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
/* c8 ignore next */
|
|
26
28
|
/**
|
|
27
29
|
* Align the string to right
|
|
28
30
|
* @param {string} str string to evaluate
|
|
29
|
-
* @param {
|
|
31
|
+
* @param {number} len length of the string
|
|
30
32
|
* @param {string} ch delimiter character
|
|
31
33
|
* @returns {string} modified string
|
|
32
34
|
* @private
|
|
33
35
|
*/
|
|
34
36
|
function alignRight(str, len, ch) {
|
|
35
|
-
|
|
37
|
+
return new Array(len - str.length + 1).join(ch || " ") + str;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
//------------------------------------------------------------------------------
|
|
@@ -49,19 +51,21 @@ const ALIGN = [alignLeft, alignRight, alignRight];
|
|
|
49
51
|
* @returns {number} the number of rules to show
|
|
50
52
|
*/
|
|
51
53
|
function getListSize() {
|
|
52
|
-
|
|
54
|
+
const MINIMUM_SIZE = 10;
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
if (typeof process.env.TIMING !== "string") {
|
|
57
|
+
return MINIMUM_SIZE;
|
|
58
|
+
}
|
|
57
59
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
if (process.env.TIMING.toLowerCase() === "all") {
|
|
61
|
+
return Number.POSITIVE_INFINITY;
|
|
62
|
+
}
|
|
61
63
|
|
|
62
|
-
|
|
64
|
+
const TIMING_ENV_VAR_AS_INTEGER = Number.parseInt(process.env.TIMING, 10);
|
|
63
65
|
|
|
64
|
-
|
|
66
|
+
return TIMING_ENV_VAR_AS_INTEGER > 10
|
|
67
|
+
? TIMING_ENV_VAR_AS_INTEGER
|
|
68
|
+
: MINIMUM_SIZE;
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
/* c8 ignore next */
|
|
@@ -72,90 +76,134 @@ function getListSize() {
|
|
|
72
76
|
* @private
|
|
73
77
|
*/
|
|
74
78
|
function display(data) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
79
|
+
let total = 0;
|
|
80
|
+
const rows = Object.keys(data)
|
|
81
|
+
.map(key => {
|
|
82
|
+
const time = data[key];
|
|
83
|
+
|
|
84
|
+
total += time;
|
|
85
|
+
return [key, time];
|
|
86
|
+
})
|
|
87
|
+
.sort((a, b) => b[1] - a[1])
|
|
88
|
+
.slice(0, getListSize());
|
|
89
|
+
|
|
90
|
+
rows.forEach(row => {
|
|
91
|
+
row.push(`${((row[1] * 100) / total).toFixed(1)}%`);
|
|
92
|
+
row[1] = row[1].toFixed(3);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
rows.unshift(HEADERS);
|
|
96
|
+
|
|
97
|
+
const widths = [];
|
|
98
|
+
|
|
99
|
+
rows.forEach(row => {
|
|
100
|
+
const len = row.length;
|
|
101
|
+
|
|
102
|
+
for (let i = 0; i < len; i++) {
|
|
103
|
+
const n = row[i].length;
|
|
104
|
+
|
|
105
|
+
if (!widths[i] || n > widths[i]) {
|
|
106
|
+
widths[i] = n;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const table = rows.map(row =>
|
|
112
|
+
row.map((cell, index) => ALIGN[index](cell, widths[index])).join(" | "),
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
table.splice(
|
|
116
|
+
1,
|
|
117
|
+
0,
|
|
118
|
+
widths
|
|
119
|
+
.map((width, index) => {
|
|
120
|
+
const extraAlignment =
|
|
121
|
+
index !== 0 && index !== widths.length - 1 ? 2 : 1;
|
|
122
|
+
|
|
123
|
+
return ALIGN[index](":", width + extraAlignment, "-");
|
|
124
|
+
})
|
|
125
|
+
.join("|"),
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
console.log(table.join("\n")); // eslint-disable-line no-console -- Debugging function
|
|
120
129
|
}
|
|
121
130
|
|
|
122
131
|
/* c8 ignore next */
|
|
123
|
-
module.exports = (function() {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
132
|
+
module.exports = (function () {
|
|
133
|
+
const data = Object.create(null);
|
|
134
|
+
let displayEnabled = true;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Time the run
|
|
138
|
+
* @param {any} key key from the data object
|
|
139
|
+
* @param {Function} fn function to be called
|
|
140
|
+
* @param {boolean} stats if 'stats' is true, return the result and the time difference
|
|
141
|
+
* @returns {Function} function to be executed
|
|
142
|
+
* @private
|
|
143
|
+
*/
|
|
144
|
+
function time(key, fn, stats) {
|
|
145
|
+
return function (...args) {
|
|
146
|
+
const t = startTime();
|
|
147
|
+
const result = fn(...args);
|
|
148
|
+
const tdiff = endTime(t);
|
|
149
|
+
|
|
150
|
+
if (enabled) {
|
|
151
|
+
if (typeof data[key] === "undefined") {
|
|
152
|
+
data[key] = 0;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
data[key] += tdiff;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return stats ? { result, tdiff } : result;
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Returns a shallow copy of the collected timings data.
|
|
164
|
+
* @returns {Record<string, number>} mapping of ruleId to total time in ms
|
|
165
|
+
*/
|
|
166
|
+
function getData() {
|
|
167
|
+
return { ...data };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Merges rule timing totals collected elsewhere into this process' totals.
|
|
172
|
+
* @param {Record<string, number>} dataToMerge mapping of ruleId to total time in ms
|
|
173
|
+
* @returns {void}
|
|
174
|
+
*/
|
|
175
|
+
function mergeData(dataToMerge) {
|
|
176
|
+
for (const [key, value] of Object.entries(dataToMerge)) {
|
|
177
|
+
if (typeof data[key] === "undefined") {
|
|
178
|
+
data[key] = 0;
|
|
179
|
+
}
|
|
180
|
+
data[key] += value;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Disables printing of timing data on process exit.
|
|
186
|
+
* Intended for worker threads or non-main contexts.
|
|
187
|
+
* @returns {void}
|
|
188
|
+
*/
|
|
189
|
+
function disableDisplay() {
|
|
190
|
+
displayEnabled = false;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (enabled) {
|
|
194
|
+
process.on("exit", () => {
|
|
195
|
+
if (displayEnabled && Object.keys(data).length > 0) {
|
|
196
|
+
display(data);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
time,
|
|
203
|
+
enabled,
|
|
204
|
+
getListSize,
|
|
205
|
+
getData,
|
|
206
|
+
mergeData,
|
|
207
|
+
disableDisplay,
|
|
208
|
+
};
|
|
209
|
+
})();
|