eslint 9.22.0 → 9.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -46
- package/bin/eslint.js +92 -90
- package/conf/default-cli-options.js +22 -22
- package/conf/ecma-version.js +1 -1
- package/conf/globals.js +97 -98
- package/conf/replacements.json +24 -20
- package/conf/rule-type-list.json +88 -92
- package/lib/api.js +12 -12
- package/lib/cli-engine/cli-engine.js +830 -810
- package/lib/cli-engine/file-enumerator.js +381 -387
- package/lib/cli-engine/formatters/formatters-meta.json +16 -16
- package/lib/cli-engine/formatters/html.js +107 -99
- 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 +96 -75
- package/lib/cli-engine/hash.js +1 -1
- package/lib/cli-engine/index.js +1 -1
- package/lib/cli-engine/lint-result-cache.js +144 -145
- package/lib/cli-engine/load-rules.js +16 -16
- package/lib/cli.js +638 -457
- package/lib/config/config-loader.js +726 -622
- package/lib/config/config.js +247 -221
- package/lib/config/default-config.js +54 -45
- package/lib/config/flat-config-array.js +167 -172
- package/lib/config/flat-config-helpers.js +72 -72
- package/lib/config/flat-config-schema.js +375 -368
- package/lib/config/rule-validator.js +139 -144
- package/lib/config-api.js +2 -2
- package/lib/eslint/eslint-helpers.js +756 -681
- package/lib/eslint/eslint.js +934 -912
- package/lib/eslint/index.js +2 -2
- package/lib/eslint/legacy-eslint.js +577 -533
- package/lib/languages/js/index.js +263 -264
- package/lib/languages/js/source-code/index.js +1 -1
- package/lib/languages/js/source-code/source-code.js +1128 -1057
- package/lib/languages/js/source-code/token-store/backward-token-comment-cursor.js +39 -35
- package/lib/languages/js/source-code/token-store/backward-token-cursor.js +35 -36
- package/lib/languages/js/source-code/token-store/cursor.js +36 -36
- package/lib/languages/js/source-code/token-store/cursors.js +80 -52
- package/lib/languages/js/source-code/token-store/decorative-cursor.js +17 -18
- package/lib/languages/js/source-code/token-store/filter-cursor.js +19 -20
- package/lib/languages/js/source-code/token-store/forward-token-comment-cursor.js +40 -32
- package/lib/languages/js/source-code/token-store/forward-token-cursor.js +40 -41
- package/lib/languages/js/source-code/token-store/index.js +592 -498
- package/lib/languages/js/source-code/token-store/limit-cursor.js +17 -18
- package/lib/languages/js/source-code/token-store/padded-token-cursor.js +23 -16
- package/lib/languages/js/source-code/token-store/skip-cursor.js +19 -20
- package/lib/languages/js/source-code/token-store/utils.js +63 -60
- package/lib/languages/js/validate-language-options.js +104 -89
- package/lib/linter/apply-disable-directives.js +467 -383
- package/lib/linter/code-path-analysis/code-path-analyzer.js +650 -672
- 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 -319
- package/lib/linter/code-path-analysis/debug-helpers.js +183 -163
- package/lib/linter/code-path-analysis/fork-context.js +296 -271
- package/lib/linter/code-path-analysis/id-generator.js +22 -23
- package/lib/linter/file-context.js +119 -120
- package/lib/linter/index.js +3 -3
- package/lib/linter/interpolate.js +16 -16
- package/lib/linter/linter.js +2403 -2045
- package/lib/linter/node-event-generator.js +284 -225
- package/lib/linter/report-translator.js +256 -219
- package/lib/linter/rule-fixer.js +122 -124
- package/lib/linter/rules.js +36 -36
- package/lib/linter/safe-emitter.js +18 -18
- package/lib/linter/source-code-fixer.js +94 -92
- package/lib/linter/timing.js +104 -101
- package/lib/linter/vfile.js +70 -73
- package/lib/options.js +404 -361
- package/lib/rule-tester/index.js +1 -1
- package/lib/rule-tester/rule-tester.js +1308 -1046
- package/lib/rules/accessor-pairs.js +298 -263
- package/lib/rules/array-bracket-newline.js +250 -238
- package/lib/rules/array-bracket-spacing.js +263 -224
- package/lib/rules/array-callback-return.js +402 -356
- package/lib/rules/array-element-newline.js +358 -313
- package/lib/rules/arrow-body-style.js +400 -281
- package/lib/rules/arrow-parens.js +206 -173
- package/lib/rules/arrow-spacing.js +169 -163
- package/lib/rules/block-scoped-var.js +125 -123
- package/lib/rules/block-spacing.js +186 -176
- package/lib/rules/brace-style.js +262 -199
- package/lib/rules/callback-return.js +203 -190
- package/lib/rules/camelcase.js +403 -392
- package/lib/rules/capitalized-comments.js +253 -232
- package/lib/rules/class-methods-use-this.js +224 -172
- package/lib/rules/comma-dangle.js +379 -346
- package/lib/rules/comma-spacing.js +193 -195
- package/lib/rules/comma-style.js +375 -316
- package/lib/rules/complexity.js +173 -169
- package/lib/rules/computed-property-spacing.js +236 -211
- package/lib/rules/consistent-return.js +181 -170
- package/lib/rules/consistent-this.js +167 -147
- package/lib/rules/constructor-super.js +412 -404
- package/lib/rules/curly.js +407 -332
- package/lib/rules/default-case-last.js +38 -31
- package/lib/rules/default-case.js +89 -85
- package/lib/rules/default-param-last.js +69 -54
- package/lib/rules/dot-location.js +122 -110
- package/lib/rules/dot-notation.js +192 -156
- package/lib/rules/eol-last.js +122 -120
- package/lib/rules/eqeqeq.js +168 -155
- package/lib/rules/for-direction.js +146 -121
- package/lib/rules/func-call-spacing.js +261 -231
- package/lib/rules/func-name-matching.js +293 -209
- package/lib/rules/func-names.js +165 -164
- package/lib/rules/func-style.js +159 -127
- package/lib/rules/function-call-argument-newline.js +152 -129
- package/lib/rules/function-paren-newline.js +349 -291
- package/lib/rules/generator-star-spacing.js +229 -210
- package/lib/rules/getter-return.js +208 -172
- package/lib/rules/global-require.js +85 -74
- package/lib/rules/grouped-accessor-pairs.js +170 -150
- package/lib/rules/guard-for-in.js +72 -63
- package/lib/rules/handle-callback-err.js +108 -103
- package/lib/rules/id-blacklist.js +182 -199
- package/lib/rules/id-denylist.js +168 -187
- package/lib/rules/id-length.js +197 -171
- package/lib/rules/id-match.js +344 -289
- package/lib/rules/implicit-arrow-linebreak.js +102 -79
- package/lib/rules/indent-legacy.js +1344 -1118
- package/lib/rules/indent.js +2272 -1759
- package/lib/rules/index.js +317 -292
- package/lib/rules/init-declarations.js +137 -107
- package/lib/rules/jsx-quotes.js +94 -82
- package/lib/rules/key-spacing.js +750 -633
- package/lib/rules/keyword-spacing.js +648 -605
- package/lib/rules/line-comment-position.js +142 -128
- package/lib/rules/linebreak-style.js +107 -106
- package/lib/rules/lines-around-comment.js +540 -448
- package/lib/rules/lines-around-directive.js +233 -203
- package/lib/rules/lines-between-class-members.js +305 -234
- package/lib/rules/logical-assignment-operators.js +582 -399
- 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 -434
- 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 +78 -76
- package/lib/rules/max-statements-per-line.js +205 -198
- package/lib/rules/max-statements.js +168 -164
- package/lib/rules/multiline-comment-style.js +637 -479
- package/lib/rules/multiline-ternary.js +241 -176
- package/lib/rules/new-cap.js +233 -213
- package/lib/rules/new-parens.js +88 -79
- package/lib/rules/newline-after-var.js +287 -250
- package/lib/rules/newline-before-return.js +229 -222
- package/lib/rules/newline-per-chained-call.js +142 -127
- package/lib/rules/no-alert.js +90 -79
- package/lib/rules/no-array-constructor.js +125 -113
- package/lib/rules/no-async-promise-executor.js +30 -24
- package/lib/rules/no-await-in-loop.js +69 -71
- package/lib/rules/no-bitwise.js +124 -100
- package/lib/rules/no-buffer-constructor.js +55 -47
- package/lib/rules/no-caller.js +39 -33
- package/lib/rules/no-case-declarations.js +61 -57
- package/lib/rules/no-catch-shadow.js +76 -73
- 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 -81
- package/lib/rules/no-console.js +202 -199
- package/lib/rules/no-const-assign.js +47 -41
- package/lib/rules/no-constant-binary-expression.js +500 -405
- package/lib/rules/no-constant-condition.js +158 -143
- package/lib/rules/no-constructor-return.js +49 -49
- package/lib/rules/no-continue.js +25 -27
- 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 -41
- package/lib/rules/no-dupe-args.js +68 -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 +179 -176
- 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 +127 -128
- package/lib/rules/no-empty-pattern.js +63 -58
- package/lib/rules/no-empty-static-block.js +37 -35
- package/lib/rules/no-empty.js +98 -86
- package/lib/rules/no-eq-null.js +37 -32
- package/lib/rules/no-eval.js +256 -250
- package/lib/rules/no-ex-assign.js +42 -39
- package/lib/rules/no-extend-native.js +161 -159
- package/lib/rules/no-extra-bind.js +201 -190
- package/lib/rules/no-extra-boolean-cast.js +398 -348
- package/lib/rules/no-extra-label.js +150 -131
- package/lib/rules/no-extra-parens.js +1654 -1325
- package/lib/rules/no-extra-semi.js +146 -144
- package/lib/rules/no-fallthrough.js +199 -157
- package/lib/rules/no-floating-decimal.js +74 -66
- package/lib/rules/no-func-assign.js +54 -55
- package/lib/rules/no-global-assign.js +78 -73
- package/lib/rules/no-implicit-coercion.js +349 -293
- package/lib/rules/no-implicit-globals.js +158 -135
- package/lib/rules/no-implied-eval.js +140 -112
- package/lib/rules/no-import-assign.js +145 -159
- package/lib/rules/no-inline-comments.js +101 -95
- package/lib/rules/no-inner-declarations.js +115 -101
- package/lib/rules/no-invalid-regexp.js +222 -190
- package/lib/rules/no-invalid-this.js +123 -117
- package/lib/rules/no-irregular-whitespace.js +266 -252
- package/lib/rules/no-iterator.js +29 -33
- package/lib/rules/no-label-var.js +59 -62
- package/lib/rules/no-labels.js +138 -133
- package/lib/rules/no-lone-blocks.js +127 -123
- package/lib/rules/no-lonely-if.js +108 -77
- package/lib/rules/no-loop-func.js +238 -213
- package/lib/rules/no-loss-of-precision.js +218 -201
- package/lib/rules/no-magic-numbers.js +246 -218
- package/lib/rules/no-misleading-character-class.js +499 -446
- package/lib/rules/no-mixed-operators.js +188 -182
- package/lib/rules/no-mixed-requires.js +253 -240
- package/lib/rules/no-mixed-spaces-and-tabs.js +134 -121
- package/lib/rules/no-multi-assign.js +46 -44
- package/lib/rules/no-multi-spaces.js +163 -143
- package/lib/rules/no-multi-str.js +42 -41
- package/lib/rules/no-multiple-empty-lines.js +196 -158
- package/lib/rules/no-native-reassign.js +90 -85
- package/lib/rules/no-negated-condition.js +79 -75
- package/lib/rules/no-negated-in-lhs.js +45 -43
- package/lib/rules/no-nested-ternary.js +33 -32
- 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 -48
- package/lib/rules/no-new-require.js +48 -47
- package/lib/rules/no-new-symbol.js +52 -50
- 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 +141 -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 +32 -32
- package/lib/rules/no-param-reassign.js +235 -217
- package/lib/rules/no-path-concat.js +66 -67
- package/lib/rules/no-plusplus.js +60 -61
- package/lib/rules/no-process-env.js +49 -48
- package/lib/rules/no-process-exit.js +54 -50
- package/lib/rules/no-promise-executor-return.js +214 -182
- package/lib/rules/no-proto.js +26 -29
- package/lib/rules/no-prototype-builtins.js +146 -124
- package/lib/rules/no-redeclare.js +154 -152
- package/lib/rules/no-regex-spaces.js +183 -161
- package/lib/rules/no-restricted-exports.js +208 -185
- package/lib/rules/no-restricted-globals.js +111 -112
- package/lib/rules/no-restricted-imports.js +657 -537
- package/lib/rules/no-restricted-modules.js +222 -202
- package/lib/rules/no-restricted-properties.js +181 -153
- package/lib/rules/no-restricted-syntax.js +56 -52
- package/lib/rules/no-return-assign.js +55 -50
- package/lib/rules/no-return-await.js +148 -124
- package/lib/rules/no-script-url.js +52 -45
- package/lib/rules/no-self-assign.js +148 -146
- package/lib/rules/no-self-compare.js +63 -46
- package/lib/rules/no-sequences.js +135 -116
- package/lib/rules/no-setter-return.js +185 -152
- package/lib/rules/no-shadow-restricted-names.js +61 -46
- package/lib/rules/no-shadow.js +342 -316
- package/lib/rules/no-spaced-func.js +82 -77
- package/lib/rules/no-sparse-arrays.js +54 -59
- package/lib/rules/no-sync.js +61 -60
- package/lib/rules/no-tabs.js +83 -72
- package/lib/rules/no-template-curly-in-string.js +33 -32
- package/lib/rules/no-ternary.js +25 -29
- package/lib/rules/no-this-before-super.js +321 -319
- package/lib/rules/no-throw-literal.js +31 -36
- package/lib/rules/no-trailing-spaces.js +199 -191
- package/lib/rules/no-undef-init.js +76 -61
- package/lib/rules/no-undef.js +51 -48
- package/lib/rules/no-undefined.js +73 -75
- package/lib/rules/no-underscore-dangle.js +370 -327
- 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 -147
- package/lib/rules/no-unreachable-loop.js +145 -142
- 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 -83
- package/lib/rules/no-unsafe-optional-chaining.js +192 -178
- package/lib/rules/no-unused-expressions.js +178 -162
- 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 +1669 -1449
- package/lib/rules/no-use-before-define.js +229 -231
- package/lib/rules/no-useless-assignment.js +590 -511
- package/lib/rules/no-useless-backreference.js +212 -193
- 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 -115
- package/lib/rules/no-useless-concat.js +65 -60
- package/lib/rules/no-useless-constructor.js +158 -111
- package/lib/rules/no-useless-escape.js +342 -291
- package/lib/rules/no-useless-rename.js +183 -156
- package/lib/rules/no-useless-return.js +344 -312
- package/lib/rules/no-var.js +233 -212
- package/lib/rules/no-void.js +50 -48
- package/lib/rules/no-warning-comments.js +191 -186
- package/lib/rules/no-whitespace-before-property.js +131 -115
- package/lib/rules/no-with.js +24 -26
- package/lib/rules/nonblock-statement-body-position.js +149 -130
- package/lib/rules/object-curly-newline.js +306 -265
- package/lib/rules/object-curly-spacing.js +360 -314
- package/lib/rules/object-property-newline.js +137 -106
- package/lib/rules/object-shorthand.js +607 -502
- package/lib/rules/one-var-declaration-per-line.js +104 -100
- package/lib/rules/one-var.js +653 -537
- package/lib/rules/operator-assignment.js +219 -161
- package/lib/rules/operator-linebreak.js +295 -251
- package/lib/rules/padded-blocks.js +346 -308
- package/lib/rules/padding-line-between-statements.js +443 -439
- package/lib/rules/prefer-arrow-callback.js +362 -313
- package/lib/rules/prefer-const.js +418 -377
- package/lib/rules/prefer-destructuring.js +301 -279
- package/lib/rules/prefer-exponentiation-operator.js +176 -133
- package/lib/rules/prefer-named-capture-group.js +153 -140
- package/lib/rules/prefer-numeric-literals.js +121 -113
- package/lib/rules/prefer-object-has-own.js +116 -82
- package/lib/rules/prefer-object-spread.js +213 -193
- package/lib/rules/prefer-promise-reject-errors.js +140 -122
- package/lib/rules/prefer-reflect.js +127 -107
- package/lib/rules/prefer-regex-literals.js +578 -466
- package/lib/rules/prefer-rest-params.js +79 -80
- package/lib/rules/prefer-spread.js +47 -44
- package/lib/rules/prefer-template.js +266 -195
- package/lib/rules/quote-props.js +373 -307
- package/lib/rules/quotes.js +374 -326
- package/lib/rules/radix.js +152 -136
- package/lib/rules/require-atomic-updates.js +316 -285
- package/lib/rules/require-await.js +144 -116
- package/lib/rules/require-unicode-regexp.js +282 -177
- package/lib/rules/require-yield.js +53 -54
- package/lib/rules/rest-spread-spacing.js +128 -116
- package/lib/rules/semi-spacing.js +281 -250
- package/lib/rules/semi-style.js +176 -134
- package/lib/rules/semi.js +456 -436
- package/lib/rules/sort-imports.js +306 -233
- package/lib/rules/sort-keys.js +219 -188
- package/lib/rules/sort-vars.js +127 -93
- package/lib/rules/space-before-blocks.js +199 -189
- package/lib/rules/space-before-function-paren.js +186 -166
- package/lib/rules/space-in-parens.js +359 -288
- package/lib/rules/space-infix-ops.js +237 -201
- package/lib/rules/space-unary-ops.js +356 -298
- package/lib/rules/spaced-comment.js +363 -319
- package/lib/rules/strict.js +265 -230
- package/lib/rules/switch-colon-spacing.js +130 -122
- package/lib/rules/symbol-description.js +45 -48
- package/lib/rules/template-curly-spacing.js +148 -142
- package/lib/rules/template-tag-spacing.js +98 -88
- package/lib/rules/unicode-bom.js +54 -56
- package/lib/rules/use-isnan.js +237 -206
- package/lib/rules/utils/ast-utils.js +2039 -1860
- package/lib/rules/utils/char-source.js +162 -155
- package/lib/rules/utils/fix-tracker.js +83 -80
- package/lib/rules/utils/keywords.js +59 -59
- package/lib/rules/utils/lazy-loading-rule-map.js +79 -76
- package/lib/rules/utils/regular-expressions.js +32 -24
- package/lib/rules/utils/unicode/index.js +4 -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 -111
- package/lib/rules/vars-on-top.js +152 -145
- package/lib/rules/wrap-iife.js +204 -191
- package/lib/rules/wrap-regex.js +70 -58
- package/lib/rules/yield-star-spacing.js +145 -134
- package/lib/rules/yoda.js +283 -272
- package/lib/services/parser-service.js +35 -35
- package/lib/services/processor-service.js +66 -73
- package/lib/services/suppressions-service.js +289 -0
- package/lib/shared/ajv.js +14 -14
- package/lib/shared/assert.js +3 -4
- package/lib/shared/ast-utils.js +7 -6
- package/lib/shared/deep-merge-arrays.js +24 -22
- package/lib/shared/directives.js +3 -2
- package/lib/shared/flags.js +50 -17
- package/lib/shared/logging.js +24 -25
- package/lib/shared/option-utils.js +43 -36
- package/lib/shared/runtime-info.js +136 -127
- package/lib/shared/serialization.js +27 -27
- package/lib/shared/severity.js +22 -22
- package/lib/shared/stats.js +5 -5
- package/lib/shared/string-utils.js +16 -16
- package/lib/shared/text-table.js +28 -27
- package/lib/shared/traverser.js +153 -146
- package/lib/shared/types.js +4 -27
- package/lib/types/index.d.ts +2010 -1559
- package/lib/types/rules.d.ts +5253 -5140
- package/lib/types/use-at-your-own-risk.d.ts +32 -30
- package/lib/unsupported-api.js +5 -5
- package/messages/all-files-ignored.js +3 -3
- package/messages/all-matched-files-ignored.js +3 -3
- package/messages/config-file-missing.js +2 -2
- package/messages/config-plugin-missing.js +3 -3
- package/messages/config-serialize-function.js +9 -7
- package/messages/eslintrc-incompat.js +13 -15
- package/messages/eslintrc-plugins.js +3 -4
- 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 +3 -3
- package/messages/plugin-conflict.js +8 -8
- package/messages/plugin-invalid.js +3 -3
- package/messages/plugin-missing.js +3 -3
- 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 +14 -20
@@ -20,325 +20,313 @@ const IdGenerator = require("./id-generator");
|
|
20
20
|
* A code path.
|
21
21
|
*/
|
22
22
|
class CodePath {
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
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
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
record[1] = 0;
|
331
|
-
} else {
|
332
|
-
|
333
|
-
/*
|
334
|
-
* If index > end, that means we have no more segments that need
|
335
|
-
* processing. So, we pop that record off of the stack in order to
|
336
|
-
* continue traversing at the next level up.
|
337
|
-
*/
|
338
|
-
stack.pop();
|
339
|
-
}
|
340
|
-
}
|
341
|
-
}
|
23
|
+
/**
|
24
|
+
* Creates a new instance.
|
25
|
+
* @param {Object} options Options for the function (see below).
|
26
|
+
* @param {string} options.id An identifier.
|
27
|
+
* @param {string} options.origin The type of code path origin.
|
28
|
+
* @param {CodePath|null} options.upper The code path of the upper function scope.
|
29
|
+
* @param {Function} options.onLooped A callback function to notify looping.
|
30
|
+
*/
|
31
|
+
constructor({ id, origin, upper, onLooped }) {
|
32
|
+
/**
|
33
|
+
* The identifier of this code path.
|
34
|
+
* Rules use it to store additional information of each rule.
|
35
|
+
* @type {string}
|
36
|
+
*/
|
37
|
+
this.id = id;
|
38
|
+
|
39
|
+
/**
|
40
|
+
* The reason that this code path was started. May be "program",
|
41
|
+
* "function", "class-field-initializer", or "class-static-block".
|
42
|
+
* @type {string}
|
43
|
+
*/
|
44
|
+
this.origin = origin;
|
45
|
+
|
46
|
+
/**
|
47
|
+
* The code path of the upper function scope.
|
48
|
+
* @type {CodePath|null}
|
49
|
+
*/
|
50
|
+
this.upper = upper;
|
51
|
+
|
52
|
+
/**
|
53
|
+
* The code paths of nested function scopes.
|
54
|
+
* @type {CodePath[]}
|
55
|
+
*/
|
56
|
+
this.childCodePaths = [];
|
57
|
+
|
58
|
+
// Initializes internal state.
|
59
|
+
Object.defineProperty(this, "internal", {
|
60
|
+
value: new CodePathState(new IdGenerator(`${id}_`), onLooped),
|
61
|
+
});
|
62
|
+
|
63
|
+
// Adds this into `childCodePaths` of `upper`.
|
64
|
+
if (upper) {
|
65
|
+
upper.childCodePaths.push(this);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Gets the state of a given code path.
|
71
|
+
* @param {CodePath} codePath A code path to get.
|
72
|
+
* @returns {CodePathState} The state of the code path.
|
73
|
+
*/
|
74
|
+
static getState(codePath) {
|
75
|
+
return codePath.internal;
|
76
|
+
}
|
77
|
+
|
78
|
+
/**
|
79
|
+
* The initial code path segment. This is the segment that is at the head
|
80
|
+
* of the code path.
|
81
|
+
* This is a passthrough to the underlying `CodePathState`.
|
82
|
+
* @type {CodePathSegment}
|
83
|
+
*/
|
84
|
+
get initialSegment() {
|
85
|
+
return this.internal.initialSegment;
|
86
|
+
}
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Final code path segments. These are the terminal (tail) segments in the
|
90
|
+
* code path, which is the combination of `returnedSegments` and `thrownSegments`.
|
91
|
+
* All segments in this array are reachable.
|
92
|
+
* This is a passthrough to the underlying `CodePathState`.
|
93
|
+
* @type {CodePathSegment[]}
|
94
|
+
*/
|
95
|
+
get finalSegments() {
|
96
|
+
return this.internal.finalSegments;
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* Final code path segments that represent normal completion of the code path.
|
101
|
+
* For functions, this means both explicit `return` statements and implicit returns,
|
102
|
+
* such as the last reachable segment in a function that does not have an
|
103
|
+
* explicit `return` as this implicitly returns `undefined`. For scripts,
|
104
|
+
* modules, class field initializers, and class static blocks, this means
|
105
|
+
* all lines of code have been executed.
|
106
|
+
* These segments are also present in `finalSegments`.
|
107
|
+
* This is a passthrough to the underlying `CodePathState`.
|
108
|
+
* @type {CodePathSegment[]}
|
109
|
+
*/
|
110
|
+
get returnedSegments() {
|
111
|
+
return this.internal.returnedForkContext;
|
112
|
+
}
|
113
|
+
|
114
|
+
/**
|
115
|
+
* Final code path segments that represent `throw` statements.
|
116
|
+
* This is a passthrough to the underlying `CodePathState`.
|
117
|
+
* These segments are also present in `finalSegments`.
|
118
|
+
* @type {CodePathSegment[]}
|
119
|
+
*/
|
120
|
+
get thrownSegments() {
|
121
|
+
return this.internal.thrownForkContext;
|
122
|
+
}
|
123
|
+
|
124
|
+
/**
|
125
|
+
* Traverses all segments in this code path.
|
126
|
+
*
|
127
|
+
* codePath.traverseSegments((segment, controller) => {
|
128
|
+
* // do something.
|
129
|
+
* });
|
130
|
+
*
|
131
|
+
* This method enumerates segments in order from the head.
|
132
|
+
*
|
133
|
+
* The `controller` argument has two methods:
|
134
|
+
*
|
135
|
+
* - `skip()` - skips the following segments in this branch
|
136
|
+
* - `break()` - skips all following segments in the traversal
|
137
|
+
*
|
138
|
+
* A note on the parameters: the `options` argument is optional. This means
|
139
|
+
* the first argument might be an options object or the callback function.
|
140
|
+
* @param {Object} [optionsOrCallback] Optional first and last segments to traverse.
|
141
|
+
* @param {CodePathSegment} [optionsOrCallback.first] The first segment to traverse.
|
142
|
+
* @param {CodePathSegment} [optionsOrCallback.last] The last segment to traverse.
|
143
|
+
* @param {Function} callback A callback function.
|
144
|
+
* @returns {void}
|
145
|
+
*/
|
146
|
+
traverseSegments(optionsOrCallback, callback) {
|
147
|
+
// normalize the arguments into a callback and options
|
148
|
+
let resolvedOptions;
|
149
|
+
let resolvedCallback;
|
150
|
+
|
151
|
+
if (typeof optionsOrCallback === "function") {
|
152
|
+
resolvedCallback = optionsOrCallback;
|
153
|
+
resolvedOptions = {};
|
154
|
+
} else {
|
155
|
+
resolvedOptions = optionsOrCallback || {};
|
156
|
+
resolvedCallback = callback;
|
157
|
+
}
|
158
|
+
|
159
|
+
// determine where to start traversing from based on the options
|
160
|
+
const startSegment =
|
161
|
+
resolvedOptions.first || this.internal.initialSegment;
|
162
|
+
const lastSegment = resolvedOptions.last;
|
163
|
+
|
164
|
+
// set up initial location information
|
165
|
+
let record;
|
166
|
+
let index;
|
167
|
+
let end;
|
168
|
+
let segment = null;
|
169
|
+
|
170
|
+
// segments that have already been visited during traversal
|
171
|
+
const visited = new Set();
|
172
|
+
|
173
|
+
// tracks the traversal steps
|
174
|
+
const stack = [[startSegment, 0]];
|
175
|
+
|
176
|
+
// segments that have been skipped during traversal
|
177
|
+
const skipped = new Set();
|
178
|
+
|
179
|
+
// indicates if we exited early from the traversal
|
180
|
+
let broken = false;
|
181
|
+
|
182
|
+
/**
|
183
|
+
* Maintains traversal state.
|
184
|
+
*/
|
185
|
+
const controller = {
|
186
|
+
/**
|
187
|
+
* Skip the following segments in this branch.
|
188
|
+
* @returns {void}
|
189
|
+
*/
|
190
|
+
skip() {
|
191
|
+
skipped.add(segment);
|
192
|
+
},
|
193
|
+
|
194
|
+
/**
|
195
|
+
* Stop traversal completely - do not traverse to any
|
196
|
+
* other segments.
|
197
|
+
* @returns {void}
|
198
|
+
*/
|
199
|
+
break() {
|
200
|
+
broken = true;
|
201
|
+
},
|
202
|
+
};
|
203
|
+
|
204
|
+
/**
|
205
|
+
* Checks if a given previous segment has been visited.
|
206
|
+
* @param {CodePathSegment} prevSegment A previous segment to check.
|
207
|
+
* @returns {boolean} `true` if the segment has been visited.
|
208
|
+
*/
|
209
|
+
function isVisited(prevSegment) {
|
210
|
+
return (
|
211
|
+
visited.has(prevSegment) ||
|
212
|
+
segment.isLoopedPrevSegment(prevSegment)
|
213
|
+
);
|
214
|
+
}
|
215
|
+
|
216
|
+
/**
|
217
|
+
* Checks if a given previous segment has been skipped.
|
218
|
+
* @param {CodePathSegment} prevSegment A previous segment to check.
|
219
|
+
* @returns {boolean} `true` if the segment has been skipped.
|
220
|
+
*/
|
221
|
+
function isSkipped(prevSegment) {
|
222
|
+
return (
|
223
|
+
skipped.has(prevSegment) ||
|
224
|
+
segment.isLoopedPrevSegment(prevSegment)
|
225
|
+
);
|
226
|
+
}
|
227
|
+
|
228
|
+
// the traversal
|
229
|
+
while (stack.length > 0) {
|
230
|
+
/*
|
231
|
+
* This isn't a pure stack. We use the top record all the time
|
232
|
+
* but don't always pop it off. The record is popped only if
|
233
|
+
* one of the following is true:
|
234
|
+
*
|
235
|
+
* 1) We have already visited the segment.
|
236
|
+
* 2) We have not visited *all* of the previous segments.
|
237
|
+
* 3) We have traversed past the available next segments.
|
238
|
+
*
|
239
|
+
* Otherwise, we just read the value and sometimes modify the
|
240
|
+
* record as we traverse.
|
241
|
+
*/
|
242
|
+
record = stack.at(-1);
|
243
|
+
segment = record[0];
|
244
|
+
index = record[1];
|
245
|
+
|
246
|
+
if (index === 0) {
|
247
|
+
// Skip if this segment has been visited already.
|
248
|
+
if (visited.has(segment)) {
|
249
|
+
stack.pop();
|
250
|
+
continue;
|
251
|
+
}
|
252
|
+
|
253
|
+
// Skip if all previous segments have not been visited.
|
254
|
+
if (
|
255
|
+
segment !== startSegment &&
|
256
|
+
segment.prevSegments.length > 0 &&
|
257
|
+
!segment.prevSegments.every(isVisited)
|
258
|
+
) {
|
259
|
+
stack.pop();
|
260
|
+
continue;
|
261
|
+
}
|
262
|
+
|
263
|
+
visited.add(segment);
|
264
|
+
|
265
|
+
// Skips the segment if all previous segments have been skipped.
|
266
|
+
const shouldSkip =
|
267
|
+
skipped.size > 0 &&
|
268
|
+
segment.prevSegments.length > 0 &&
|
269
|
+
segment.prevSegments.every(isSkipped);
|
270
|
+
|
271
|
+
/*
|
272
|
+
* If the most recent segment hasn't been skipped, then we call
|
273
|
+
* the callback, passing in the segment and the controller.
|
274
|
+
*/
|
275
|
+
if (!shouldSkip) {
|
276
|
+
resolvedCallback.call(this, segment, controller);
|
277
|
+
|
278
|
+
// exit if we're at the last segment
|
279
|
+
if (segment === lastSegment) {
|
280
|
+
controller.skip();
|
281
|
+
}
|
282
|
+
|
283
|
+
/*
|
284
|
+
* If the previous statement was executed, or if the callback
|
285
|
+
* called a method on the controller, we might need to exit the
|
286
|
+
* loop, so check for that and break accordingly.
|
287
|
+
*/
|
288
|
+
if (broken) {
|
289
|
+
break;
|
290
|
+
}
|
291
|
+
} else {
|
292
|
+
// If the most recent segment has been skipped, then mark it as skipped.
|
293
|
+
skipped.add(segment);
|
294
|
+
}
|
295
|
+
}
|
296
|
+
|
297
|
+
// Update the stack.
|
298
|
+
end = segment.nextSegments.length - 1;
|
299
|
+
if (index < end) {
|
300
|
+
/*
|
301
|
+
* If we haven't yet visited all of the next segments, update
|
302
|
+
* the current top record on the stack to the next index to visit
|
303
|
+
* and then push a record for the current segment on top.
|
304
|
+
*
|
305
|
+
* Setting the current top record's index lets us know how many
|
306
|
+
* times we've been here and ensures that the segment won't be
|
307
|
+
* reprocessed (because we only process segments with an index
|
308
|
+
* of 0).
|
309
|
+
*/
|
310
|
+
record[1] += 1;
|
311
|
+
stack.push([segment.nextSegments[index], 0]);
|
312
|
+
} else if (index === end) {
|
313
|
+
/*
|
314
|
+
* If we are at the last next segment, then reset the top record
|
315
|
+
* in the stack to next segment and set its index to 0 so it will
|
316
|
+
* be processed next.
|
317
|
+
*/
|
318
|
+
record[0] = segment.nextSegments[index];
|
319
|
+
record[1] = 0;
|
320
|
+
} else {
|
321
|
+
/*
|
322
|
+
* If index > end, that means we have no more segments that need
|
323
|
+
* processing. So, we pop that record off of the stack in order to
|
324
|
+
* continue traversing at the next level up.
|
325
|
+
*/
|
326
|
+
stack.pop();
|
327
|
+
}
|
328
|
+
}
|
329
|
+
}
|
342
330
|
}
|
343
331
|
|
344
332
|
module.exports = CodePath;
|