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.
Files changed (420) hide show
  1. package/LICENSE +19 -0
  2. package/README.md +370 -0
  3. package/bin/eslint.js +195 -0
  4. package/conf/ecma-version.js +16 -0
  5. package/conf/globals.js +169 -0
  6. package/conf/replacements.json +26 -0
  7. package/conf/rule-type-list.json +91 -0
  8. package/lib/api.js +39 -0
  9. package/lib/cli-engine/formatters/formatters-meta.json +22 -0
  10. package/lib/cli-engine/formatters/gasoline.js +168 -0
  11. package/lib/cli-engine/formatters/html.js +359 -0
  12. package/lib/cli-engine/formatters/json-with-metadata.js +16 -0
  13. package/lib/cli-engine/formatters/json.js +13 -0
  14. package/lib/cli-engine/formatters/stylish.js +153 -0
  15. package/lib/cli-engine/hash.js +35 -0
  16. package/lib/cli-engine/lint-result-cache.js +220 -0
  17. package/lib/cli.js +607 -0
  18. package/lib/config/config-loader.js +683 -0
  19. package/lib/config/config.js +674 -0
  20. package/lib/config/default-config.js +78 -0
  21. package/lib/config/flat-config-array.js +217 -0
  22. package/lib/config/flat-config-schema.js +598 -0
  23. package/lib/config-api.js +12 -0
  24. package/lib/eslint/eslint-helpers.js +1462 -0
  25. package/lib/eslint/eslint.js +1364 -0
  26. package/lib/eslint/index.js +7 -0
  27. package/lib/eslint/worker.js +173 -0
  28. package/lib/languages/js/index.js +336 -0
  29. package/lib/languages/js/source-code/index.js +7 -0
  30. package/lib/languages/js/source-code/source-code.js +1178 -0
  31. package/lib/languages/js/source-code/token-store/backward-token-comment-cursor.js +61 -0
  32. package/lib/languages/js/source-code/token-store/backward-token-cursor.js +57 -0
  33. package/lib/languages/js/source-code/token-store/cursor.js +76 -0
  34. package/lib/languages/js/source-code/token-store/cursors.js +120 -0
  35. package/lib/languages/js/source-code/token-store/decorative-cursor.js +38 -0
  36. package/lib/languages/js/source-code/token-store/filter-cursor.js +42 -0
  37. package/lib/languages/js/source-code/token-store/forward-token-comment-cursor.js +65 -0
  38. package/lib/languages/js/source-code/token-store/forward-token-cursor.js +62 -0
  39. package/lib/languages/js/source-code/token-store/index.js +695 -0
  40. package/lib/languages/js/source-code/token-store/limit-cursor.js +39 -0
  41. package/lib/languages/js/source-code/token-store/padded-token-cursor.js +45 -0
  42. package/lib/languages/js/source-code/token-store/skip-cursor.js +41 -0
  43. package/lib/languages/js/source-code/token-store/utils.js +131 -0
  44. package/lib/languages/js/validate-language-options.js +196 -0
  45. package/lib/linter/apply-disable-directives.js +583 -0
  46. package/lib/linter/code-path-analysis/code-path-analyzer.js +828 -0
  47. package/lib/linter/code-path-analysis/code-path-segment.js +262 -0
  48. package/lib/linter/code-path-analysis/code-path-state.js +2370 -0
  49. package/lib/linter/code-path-analysis/code-path.js +332 -0
  50. package/lib/linter/code-path-analysis/debug-helpers.js +223 -0
  51. package/lib/linter/code-path-analysis/fork-context.js +374 -0
  52. package/lib/linter/code-path-analysis/id-generator.js +44 -0
  53. package/lib/linter/esquery.js +332 -0
  54. package/lib/linter/file-context.js +88 -0
  55. package/lib/linter/file-report.js +604 -0
  56. package/lib/linter/index.js +11 -0
  57. package/lib/linter/interpolate.js +50 -0
  58. package/lib/linter/linter.js +1614 -0
  59. package/lib/linter/rule-fixer.js +199 -0
  60. package/lib/linter/source-code-fixer.js +154 -0
  61. package/lib/linter/source-code-traverser.js +333 -0
  62. package/lib/linter/source-code-visitor.js +81 -0
  63. package/lib/linter/timing.js +209 -0
  64. package/lib/linter/vfile.js +115 -0
  65. package/lib/options.js +416 -0
  66. package/lib/rule-tester/index.js +7 -0
  67. package/lib/rule-tester/rule-tester.js +1817 -0
  68. package/lib/rules/accessor-pairs.js +420 -0
  69. package/lib/rules/array-bracket-newline.js +291 -0
  70. package/lib/rules/array-bracket-spacing.js +301 -0
  71. package/lib/rules/array-callback-return.js +493 -0
  72. package/lib/rules/array-element-newline.js +374 -0
  73. package/lib/rules/arrow-body-style.js +418 -0
  74. package/lib/rules/arrow-parens.js +237 -0
  75. package/lib/rules/arrow-spacing.js +188 -0
  76. package/lib/rules/block-scoped-var.js +137 -0
  77. package/lib/rules/block-spacing.js +202 -0
  78. package/lib/rules/brace-style.js +278 -0
  79. package/lib/rules/callback-return.js +216 -0
  80. package/lib/rules/camelcase.js +422 -0
  81. package/lib/rules/capitalized-comments.js +325 -0
  82. package/lib/rules/class-methods-use-this.js +250 -0
  83. package/lib/rules/comma-dangle.js +424 -0
  84. package/lib/rules/comma-spacing.js +205 -0
  85. package/lib/rules/comma-style.js +391 -0
  86. package/lib/rules/complexity.js +201 -0
  87. package/lib/rules/computed-property-spacing.js +251 -0
  88. package/lib/rules/consistent-return.js +221 -0
  89. package/lib/rules/consistent-this.js +179 -0
  90. package/lib/rules/constructor-super.js +453 -0
  91. package/lib/rules/curly.js +425 -0
  92. package/lib/rules/default-case-last.js +51 -0
  93. package/lib/rules/default-case.js +103 -0
  94. package/lib/rules/default-param-last.js +78 -0
  95. package/lib/rules/dot-location.js +138 -0
  96. package/lib/rules/dot-notation.js +216 -0
  97. package/lib/rules/eol-last.js +135 -0
  98. package/lib/rules/eqeqeq.js +210 -0
  99. package/lib/rules/for-direction.js +168 -0
  100. package/lib/rules/func-call-spacing.js +281 -0
  101. package/lib/rules/func-name-matching.js +338 -0
  102. package/lib/rules/func-names.js +194 -0
  103. package/lib/rules/func-style.js +221 -0
  104. package/lib/rules/function-call-argument-newline.js +166 -0
  105. package/lib/rules/function-paren-newline.js +368 -0
  106. package/lib/rules/generator-star-spacing.js +246 -0
  107. package/lib/rules/getter-return.js +242 -0
  108. package/lib/rules/global-require.js +117 -0
  109. package/lib/rules/grouped-accessor-pairs.js +268 -0
  110. package/lib/rules/guard-for-in.js +85 -0
  111. package/lib/rules/handle-callback-err.js +122 -0
  112. package/lib/rules/id-blacklist.js +241 -0
  113. package/lib/rules/id-denylist.js +223 -0
  114. package/lib/rules/id-length.js +217 -0
  115. package/lib/rules/id-match.js +363 -0
  116. package/lib/rules/implicit-arrow-linebreak.js +125 -0
  117. package/lib/rules/indent-legacy.js +1369 -0
  118. package/lib/rules/indent.js +2334 -0
  119. package/lib/rules/index.js +332 -0
  120. package/lib/rules/init-declarations.js +172 -0
  121. package/lib/rules/jsx-quotes.js +128 -0
  122. package/lib/rules/key-spacing.js +822 -0
  123. package/lib/rules/keyword-spacing.js +701 -0
  124. package/lib/rules/line-comment-position.js +157 -0
  125. package/lib/rules/linebreak-style.js +135 -0
  126. package/lib/rules/lines-around-comment.js +581 -0
  127. package/lib/rules/lines-around-directive.js +249 -0
  128. package/lib/rules/lines-between-class-members.js +358 -0
  129. package/lib/rules/logical-assignment-operators.js +688 -0
  130. package/lib/rules/max-classes-per-file.js +90 -0
  131. package/lib/rules/max-depth.js +159 -0
  132. package/lib/rules/max-len.js +497 -0
  133. package/lib/rules/max-lines-per-function.js +238 -0
  134. package/lib/rules/max-lines.js +189 -0
  135. package/lib/rules/max-nested-callbacks.js +115 -0
  136. package/lib/rules/max-params.js +148 -0
  137. package/lib/rules/max-statements-per-line.js +224 -0
  138. package/lib/rules/max-statements.js +188 -0
  139. package/lib/rules/multiline-comment-style.js +652 -0
  140. package/lib/rules/multiline-ternary.js +257 -0
  141. package/lib/rules/new-cap.js +277 -0
  142. package/lib/rules/new-parens.js +120 -0
  143. package/lib/rules/newline-after-var.js +307 -0
  144. package/lib/rules/newline-before-return.js +242 -0
  145. package/lib/rules/newline-per-chained-call.js +159 -0
  146. package/lib/rules/no-alert.js +149 -0
  147. package/lib/rules/no-array-constructor.js +195 -0
  148. package/lib/rules/no-async-promise-executor.js +45 -0
  149. package/lib/rules/no-await-in-loop.js +115 -0
  150. package/lib/rules/no-bitwise.js +145 -0
  151. package/lib/rules/no-buffer-constructor.js +74 -0
  152. package/lib/rules/no-caller.js +52 -0
  153. package/lib/rules/no-case-declarations.js +80 -0
  154. package/lib/rules/no-catch-shadow.js +96 -0
  155. package/lib/rules/no-class-assign.js +66 -0
  156. package/lib/rules/no-compare-neg-zero.js +74 -0
  157. package/lib/rules/no-cond-assign.js +175 -0
  158. package/lib/rules/no-confusing-arrow.js +127 -0
  159. package/lib/rules/no-console.js +221 -0
  160. package/lib/rules/no-const-assign.js +73 -0
  161. package/lib/rules/no-constant-binary-expression.js +603 -0
  162. package/lib/rules/no-constant-condition.js +177 -0
  163. package/lib/rules/no-constructor-return.js +62 -0
  164. package/lib/rules/no-continue.js +38 -0
  165. package/lib/rules/no-control-regex.js +142 -0
  166. package/lib/rules/no-debugger.js +41 -0
  167. package/lib/rules/no-delete-var.js +42 -0
  168. package/lib/rules/no-div-regex.js +60 -0
  169. package/lib/rules/no-dupe-args.js +92 -0
  170. package/lib/rules/no-dupe-class-members.js +117 -0
  171. package/lib/rules/no-dupe-else-if.js +145 -0
  172. package/lib/rules/no-dupe-keys.js +165 -0
  173. package/lib/rules/no-duplicate-case.js +78 -0
  174. package/lib/rules/no-duplicate-imports.js +368 -0
  175. package/lib/rules/no-else-return.js +450 -0
  176. package/lib/rules/no-empty-character-class.js +83 -0
  177. package/lib/rules/no-empty-function.js +236 -0
  178. package/lib/rules/no-empty-pattern.js +85 -0
  179. package/lib/rules/no-empty-static-block.js +73 -0
  180. package/lib/rules/no-empty.js +153 -0
  181. package/lib/rules/no-eq-null.js +51 -0
  182. package/lib/rules/no-eval.js +295 -0
  183. package/lib/rules/no-ex-assign.js +57 -0
  184. package/lib/rules/no-extend-native.js +180 -0
  185. package/lib/rules/no-extra-bind.js +224 -0
  186. package/lib/rules/no-extra-boolean-cast.js +420 -0
  187. package/lib/rules/no-extra-label.js +169 -0
  188. package/lib/rules/no-extra-parens.js +1669 -0
  189. package/lib/rules/no-extra-semi.js +167 -0
  190. package/lib/rules/no-fallthrough.js +260 -0
  191. package/lib/rules/no-floating-decimal.js +99 -0
  192. package/lib/rules/no-func-assign.js +77 -0
  193. package/lib/rules/no-global-assign.js +101 -0
  194. package/lib/rules/no-implicit-coercion.js +468 -0
  195. package/lib/rules/no-implicit-globals.js +187 -0
  196. package/lib/rules/no-implied-eval.js +170 -0
  197. package/lib/rules/no-import-assign.js +227 -0
  198. package/lib/rules/no-inline-comments.js +115 -0
  199. package/lib/rules/no-inner-declarations.js +147 -0
  200. package/lib/rules/no-invalid-regexp.js +244 -0
  201. package/lib/rules/no-invalid-this.js +178 -0
  202. package/lib/rules/no-irregular-whitespace.js +292 -0
  203. package/lib/rules/no-iterator.js +48 -0
  204. package/lib/rules/no-label-var.js +78 -0
  205. package/lib/rules/no-labels.js +156 -0
  206. package/lib/rules/no-lone-blocks.js +140 -0
  207. package/lib/rules/no-lonely-if.js +126 -0
  208. package/lib/rules/no-loop-func.js +267 -0
  209. package/lib/rules/no-loss-of-precision.js +249 -0
  210. package/lib/rules/no-magic-numbers.js +365 -0
  211. package/lib/rules/no-misleading-character-class.js +595 -0
  212. package/lib/rules/no-mixed-operators.js +253 -0
  213. package/lib/rules/no-mixed-requires.js +267 -0
  214. package/lib/rules/no-mixed-spaces-and-tabs.js +148 -0
  215. package/lib/rules/no-multi-assign.js +66 -0
  216. package/lib/rules/no-multi-spaces.js +179 -0
  217. package/lib/rules/no-multi-str.js +67 -0
  218. package/lib/rules/no-multiple-empty-lines.js +210 -0
  219. package/lib/rules/no-native-reassign.js +114 -0
  220. package/lib/rules/no-negated-condition.js +100 -0
  221. package/lib/rules/no-negated-in-lhs.js +59 -0
  222. package/lib/rules/no-nested-ternary.js +46 -0
  223. package/lib/rules/no-new-func.js +96 -0
  224. package/lib/rules/no-new-native-nonconstructor.js +70 -0
  225. package/lib/rules/no-new-object.js +76 -0
  226. package/lib/rules/no-new-require.js +67 -0
  227. package/lib/rules/no-new-symbol.js +74 -0
  228. package/lib/rules/no-new-wrappers.js +62 -0
  229. package/lib/rules/no-new.js +42 -0
  230. package/lib/rules/no-nonoctal-decimal-escape.js +176 -0
  231. package/lib/rules/no-obj-calls.js +99 -0
  232. package/lib/rules/no-object-constructor.js +124 -0
  233. package/lib/rules/no-octal-escape.js +53 -0
  234. package/lib/rules/no-octal.js +42 -0
  235. package/lib/rules/no-param-reassign.js +248 -0
  236. package/lib/rules/no-path-concat.js +79 -0
  237. package/lib/rules/no-plusplus.js +102 -0
  238. package/lib/rules/no-process-env.js +68 -0
  239. package/lib/rules/no-process-exit.js +67 -0
  240. package/lib/rules/no-promise-executor-return.js +264 -0
  241. package/lib/rules/no-proto.js +45 -0
  242. package/lib/rules/no-prototype-builtins.js +181 -0
  243. package/lib/rules/no-redeclare.js +173 -0
  244. package/lib/rules/no-regex-spaces.js +219 -0
  245. package/lib/rules/no-restricted-exports.js +227 -0
  246. package/lib/rules/no-restricted-globals.js +266 -0
  247. package/lib/rules/no-restricted-imports.js +892 -0
  248. package/lib/rules/no-restricted-modules.js +249 -0
  249. package/lib/rules/no-restricted-properties.js +233 -0
  250. package/lib/rules/no-restricted-syntax.js +74 -0
  251. package/lib/rules/no-return-assign.js +87 -0
  252. package/lib/rules/no-return-await.js +162 -0
  253. package/lib/rules/no-script-url.js +68 -0
  254. package/lib/rules/no-self-assign.js +186 -0
  255. package/lib/rules/no-self-compare.js +77 -0
  256. package/lib/rules/no-sequences.js +158 -0
  257. package/lib/rules/no-setter-return.js +224 -0
  258. package/lib/rules/no-shadow-restricted-names.js +113 -0
  259. package/lib/rules/no-shadow.js +624 -0
  260. package/lib/rules/no-spaced-func.js +105 -0
  261. package/lib/rules/no-sparse-arrays.js +68 -0
  262. package/lib/rules/no-sync.js +81 -0
  263. package/lib/rules/no-tabs.js +110 -0
  264. package/lib/rules/no-template-curly-in-string.js +45 -0
  265. package/lib/rules/no-ternary.js +38 -0
  266. package/lib/rules/no-this-before-super.js +365 -0
  267. package/lib/rules/no-throw-literal.js +46 -0
  268. package/lib/rules/no-trailing-spaces.js +227 -0
  269. package/lib/rules/no-unassigned-vars.js +80 -0
  270. package/lib/rules/no-undef-init.js +101 -0
  271. package/lib/rules/no-undef.js +84 -0
  272. package/lib/rules/no-undefined.js +85 -0
  273. package/lib/rules/no-underscore-dangle.js +383 -0
  274. package/lib/rules/no-unexpected-multiline.js +130 -0
  275. package/lib/rules/no-unmodified-loop-condition.js +360 -0
  276. package/lib/rules/no-unneeded-ternary.js +232 -0
  277. package/lib/rules/no-unreachable-loop.js +190 -0
  278. package/lib/rules/no-unreachable.js +300 -0
  279. package/lib/rules/no-unsafe-finally.js +119 -0
  280. package/lib/rules/no-unsafe-negation.js +152 -0
  281. package/lib/rules/no-unsafe-optional-chaining.js +221 -0
  282. package/lib/rules/no-unused-expressions.js +227 -0
  283. package/lib/rules/no-unused-labels.js +158 -0
  284. package/lib/rules/no-unused-private-class-members.js +219 -0
  285. package/lib/rules/no-unused-vars.js +1739 -0
  286. package/lib/rules/no-use-before-define.js +446 -0
  287. package/lib/rules/no-useless-assignment.js +657 -0
  288. package/lib/rules/no-useless-backreference.js +263 -0
  289. package/lib/rules/no-useless-call.js +95 -0
  290. package/lib/rules/no-useless-catch.js +57 -0
  291. package/lib/rules/no-useless-computed-key.js +204 -0
  292. package/lib/rules/no-useless-concat.js +121 -0
  293. package/lib/rules/no-useless-constructor.js +262 -0
  294. package/lib/rules/no-useless-escape.js +406 -0
  295. package/lib/rules/no-useless-rename.js +202 -0
  296. package/lib/rules/no-useless-return.js +401 -0
  297. package/lib/rules/no-var.js +367 -0
  298. package/lib/rules/no-void.js +69 -0
  299. package/lib/rules/no-warning-comments.js +209 -0
  300. package/lib/rules/no-whitespace-before-property.js +150 -0
  301. package/lib/rules/no-with.js +37 -0
  302. package/lib/rules/nonblock-statement-body-position.js +164 -0
  303. package/lib/rules/object-curly-newline.js +383 -0
  304. package/lib/rules/object-curly-spacing.js +369 -0
  305. package/lib/rules/object-property-newline.js +151 -0
  306. package/lib/rules/object-shorthand.js +652 -0
  307. package/lib/rules/one-var-declaration-per-line.js +117 -0
  308. package/lib/rules/one-var.js +717 -0
  309. package/lib/rules/operator-assignment.js +270 -0
  310. package/lib/rules/operator-linebreak.js +315 -0
  311. package/lib/rules/padded-blocks.js +366 -0
  312. package/lib/rules/padding-line-between-statements.js +612 -0
  313. package/lib/rules/prefer-arrow-callback.js +437 -0
  314. package/lib/rules/prefer-const.js +546 -0
  315. package/lib/rules/prefer-destructuring.js +332 -0
  316. package/lib/rules/prefer-exponentiation-operator.js +235 -0
  317. package/lib/rules/prefer-named-capture-group.js +197 -0
  318. package/lib/rules/prefer-numeric-literals.js +157 -0
  319. package/lib/rules/prefer-object-has-own.js +148 -0
  320. package/lib/rules/prefer-object-spread.js +319 -0
  321. package/lib/rules/prefer-promise-reject-errors.js +154 -0
  322. package/lib/rules/prefer-reflect.js +150 -0
  323. package/lib/rules/prefer-regex-literals.js +605 -0
  324. package/lib/rules/prefer-rest-params.js +117 -0
  325. package/lib/rules/prefer-spread.js +91 -0
  326. package/lib/rules/prefer-template.js +347 -0
  327. package/lib/rules/preserve-caught-error.js +535 -0
  328. package/lib/rules/quote-props.js +394 -0
  329. package/lib/rules/quotes.js +416 -0
  330. package/lib/rules/radix.js +193 -0
  331. package/lib/rules/require-atomic-updates.js +365 -0
  332. package/lib/rules/require-await.js +184 -0
  333. package/lib/rules/require-unicode-regexp.js +317 -0
  334. package/lib/rules/require-yield.js +86 -0
  335. package/lib/rules/rest-spread-spacing.js +150 -0
  336. package/lib/rules/semi-spacing.js +297 -0
  337. package/lib/rules/semi-style.js +218 -0
  338. package/lib/rules/semi.js +476 -0
  339. package/lib/rules/sort-imports.js +319 -0
  340. package/lib/rules/sort-keys.js +268 -0
  341. package/lib/rules/sort-vars.js +140 -0
  342. package/lib/rules/space-before-blocks.js +232 -0
  343. package/lib/rules/space-before-function-paren.js +202 -0
  344. package/lib/rules/space-in-parens.js +374 -0
  345. package/lib/rules/space-infix-ops.js +249 -0
  346. package/lib/rules/space-unary-ops.js +400 -0
  347. package/lib/rules/spaced-comment.js +447 -0
  348. package/lib/rules/strict.js +314 -0
  349. package/lib/rules/switch-colon-spacing.js +158 -0
  350. package/lib/rules/symbol-description.js +70 -0
  351. package/lib/rules/template-curly-spacing.js +168 -0
  352. package/lib/rules/template-tag-spacing.js +121 -0
  353. package/lib/rules/unicode-bom.js +73 -0
  354. package/lib/rules/use-isnan.js +268 -0
  355. package/lib/rules/utils/ast-utils.js +2828 -0
  356. package/lib/rules/utils/char-source.js +247 -0
  357. package/lib/rules/utils/fix-tracker.js +125 -0
  358. package/lib/rules/utils/keywords.js +67 -0
  359. package/lib/rules/utils/lazy-loading-rule-map.js +118 -0
  360. package/lib/rules/utils/regular-expressions.js +58 -0
  361. package/lib/rules/utils/unicode/index.js +16 -0
  362. package/lib/rules/utils/unicode/is-combining-character.js +13 -0
  363. package/lib/rules/utils/unicode/is-emoji-modifier.js +13 -0
  364. package/lib/rules/utils/unicode/is-regional-indicator-symbol.js +13 -0
  365. package/lib/rules/utils/unicode/is-surrogate-pair.js +14 -0
  366. package/lib/rules/valid-typeof.js +171 -0
  367. package/lib/rules/vars-on-top.js +165 -0
  368. package/lib/rules/wrap-iife.js +238 -0
  369. package/lib/rules/wrap-regex.js +91 -0
  370. package/lib/rules/yield-star-spacing.js +158 -0
  371. package/lib/rules/yoda.js +362 -0
  372. package/lib/services/parser-service.js +64 -0
  373. package/lib/services/processor-service.js +100 -0
  374. package/lib/services/suppressions-service.js +302 -0
  375. package/lib/services/warning-service.js +87 -0
  376. package/lib/shared/ajv.js +34 -0
  377. package/lib/shared/assert.js +21 -0
  378. package/lib/shared/ast-utils.js +30 -0
  379. package/lib/shared/deep-merge-arrays.js +62 -0
  380. package/lib/shared/directives.js +16 -0
  381. package/lib/shared/flags.js +89 -0
  382. package/lib/shared/logging.js +38 -0
  383. package/lib/shared/naming.js +109 -0
  384. package/lib/shared/option-utils.js +63 -0
  385. package/lib/shared/relative-module-resolver.js +28 -0
  386. package/lib/shared/runtime-info.js +177 -0
  387. package/lib/shared/serialization.js +78 -0
  388. package/lib/shared/severity.js +49 -0
  389. package/lib/shared/stats.js +30 -0
  390. package/lib/shared/string-utils.js +58 -0
  391. package/lib/shared/text-table.js +68 -0
  392. package/lib/shared/translate-cli-options.js +223 -0
  393. package/lib/shared/traverser.js +202 -0
  394. package/lib/types/config-api.d.ts +12 -0
  395. package/lib/types/index.d.ts +1482 -0
  396. package/lib/types/rules.d.ts +5603 -0
  397. package/lib/types/universal.d.ts +6 -0
  398. package/lib/types/use-at-your-own-risk.d.ts +34 -0
  399. package/lib/universal.js +10 -0
  400. package/lib/unsupported-api.js +26 -0
  401. package/messages/all-files-ignored.js +16 -0
  402. package/messages/all-matched-files-ignored.js +21 -0
  403. package/messages/config-file-missing.js +16 -0
  404. package/messages/config-plugin-missing.js +14 -0
  405. package/messages/config-serialize-function.js +30 -0
  406. package/messages/eslintrc-incompat.js +117 -0
  407. package/messages/eslintrc-plugins.js +27 -0
  408. package/messages/extend-config-missing.js +13 -0
  409. package/messages/failed-to-read-json.js +11 -0
  410. package/messages/file-not-found.js +10 -0
  411. package/messages/invalid-rule-options.js +17 -0
  412. package/messages/invalid-rule-severity.js +13 -0
  413. package/messages/no-config-found.js +15 -0
  414. package/messages/plugin-conflict.js +22 -0
  415. package/messages/plugin-invalid.js +16 -0
  416. package/messages/plugin-missing.js +19 -0
  417. package/messages/print-config-with-directory-path.js +8 -0
  418. package/messages/shared.js +23 -0
  419. package/messages/whitespace-found.js +11 -0
  420. package/package.json +220 -0
@@ -0,0 +1,828 @@
1
+ /**
2
+ * @fileoverview A class of the code path analyzer.
3
+ * @author Toru Nagashima
4
+ */
5
+
6
+ "use strict";
7
+
8
+ //------------------------------------------------------------------------------
9
+ // Requirements
10
+ //------------------------------------------------------------------------------
11
+
12
+ const assert = require("../../shared/assert"),
13
+ { breakableTypePattern } = require("../../shared/ast-utils"),
14
+ CodePath = require("./code-path"),
15
+ CodePathSegment = require("./code-path-segment"),
16
+ IdGenerator = require("./id-generator"),
17
+ debug = require("./debug-helpers");
18
+
19
+ //------------------------------------------------------------------------------
20
+ // Helpers
21
+ //------------------------------------------------------------------------------
22
+
23
+ /**
24
+ * Checks whether or not a given node is a `case` node (not `default` node).
25
+ * @param {ASTNode} node A `SwitchCase` node to check.
26
+ * @returns {boolean} `true` if the node is a `case` node (not `default` node).
27
+ */
28
+ function isCaseNode(node) {
29
+ return Boolean(node.test);
30
+ }
31
+
32
+ /**
33
+ * Checks if a given node appears as the value of a PropertyDefinition node.
34
+ * @param {ASTNode} node THe node to check.
35
+ * @returns {boolean} `true` if the node is a PropertyDefinition value,
36
+ * false if not.
37
+ */
38
+ function isPropertyDefinitionValue(node) {
39
+ const parent = node.parent;
40
+
41
+ return (
42
+ parent && parent.type === "PropertyDefinition" && parent.value === node
43
+ );
44
+ }
45
+
46
+ /**
47
+ * Checks whether the given logical operator is taken into account for the code
48
+ * path analysis.
49
+ * @param {string} operator The operator found in the LogicalExpression node
50
+ * @returns {boolean} `true` if the operator is "&&" or "||" or "??"
51
+ */
52
+ function isHandledLogicalOperator(operator) {
53
+ return operator === "&&" || operator === "||" || operator === "??";
54
+ }
55
+
56
+ /**
57
+ * Checks whether the given assignment operator is a logical assignment operator.
58
+ * Logical assignments are taken into account for the code path analysis
59
+ * because of their short-circuiting semantics.
60
+ * @param {string} operator The operator found in the AssignmentExpression node
61
+ * @returns {boolean} `true` if the operator is "&&=" or "||=" or "??="
62
+ */
63
+ function isLogicalAssignmentOperator(operator) {
64
+ return operator === "&&=" || operator === "||=" || operator === "??=";
65
+ }
66
+
67
+ /**
68
+ * Gets the label if the parent node of a given node is a LabeledStatement.
69
+ * @param {ASTNode} node A node to get.
70
+ * @returns {string|null} The label or `null`.
71
+ */
72
+ function getLabel(node) {
73
+ if (node.parent.type === "LabeledStatement") {
74
+ return node.parent.label.name;
75
+ }
76
+ return null;
77
+ }
78
+
79
+ /**
80
+ * Checks whether or not a given logical expression node goes different path
81
+ * between the `true` case and the `false` case.
82
+ * @param {ASTNode} node A node to check.
83
+ * @returns {boolean} `true` if the node is a test of a choice statement.
84
+ */
85
+ function isForkingByTrueOrFalse(node) {
86
+ const parent = node.parent;
87
+
88
+ switch (parent.type) {
89
+ case "ConditionalExpression":
90
+ case "IfStatement":
91
+ case "WhileStatement":
92
+ case "DoWhileStatement":
93
+ case "ForStatement":
94
+ return parent.test === node;
95
+
96
+ case "LogicalExpression":
97
+ return isHandledLogicalOperator(parent.operator);
98
+
99
+ case "AssignmentExpression":
100
+ return isLogicalAssignmentOperator(parent.operator);
101
+
102
+ default:
103
+ return false;
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Gets the boolean value of a given literal node.
109
+ *
110
+ * This is used to detect infinity loops (e.g. `while (true) {}`).
111
+ * Statements preceded by an infinity loop are unreachable if the loop didn't
112
+ * have any `break` statement.
113
+ * @param {ASTNode} node A node to get.
114
+ * @returns {boolean|undefined} a boolean value if the node is a Literal node,
115
+ * otherwise `undefined`.
116
+ */
117
+ function getBooleanValueIfSimpleConstant(node) {
118
+ if (node.type === "Literal") {
119
+ return Boolean(node.value);
120
+ }
121
+ return void 0;
122
+ }
123
+
124
+ /**
125
+ * Checks that a given identifier node is a reference or not.
126
+ *
127
+ * This is used to detect the first throwable node in a `try` block.
128
+ * @param {ASTNode} node An Identifier node to check.
129
+ * @returns {boolean} `true` if the node is a reference.
130
+ */
131
+ function isIdentifierReference(node) {
132
+ const parent = node.parent;
133
+
134
+ switch (parent.type) {
135
+ case "LabeledStatement":
136
+ case "BreakStatement":
137
+ case "ContinueStatement":
138
+ case "ArrayPattern":
139
+ case "RestElement":
140
+ case "ImportSpecifier":
141
+ case "ImportDefaultSpecifier":
142
+ case "ImportNamespaceSpecifier":
143
+ case "CatchClause":
144
+ return false;
145
+
146
+ case "FunctionDeclaration":
147
+ case "FunctionExpression":
148
+ case "ArrowFunctionExpression":
149
+ case "ClassDeclaration":
150
+ case "ClassExpression":
151
+ case "VariableDeclarator":
152
+ return parent.id !== node;
153
+
154
+ case "Property":
155
+ case "PropertyDefinition":
156
+ case "MethodDefinition":
157
+ return parent.key !== node || parent.computed || parent.shorthand;
158
+
159
+ case "AssignmentPattern":
160
+ return parent.key !== node;
161
+
162
+ default:
163
+ return true;
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Updates the current segment with the head segment.
169
+ * This is similar to local branches and tracking branches of git.
170
+ *
171
+ * To separate the current and the head is in order to not make useless segments.
172
+ *
173
+ * In this process, both "onCodePathSegmentStart" and "onCodePathSegmentEnd"
174
+ * events are fired.
175
+ * @param {CodePathAnalyzer} analyzer The instance.
176
+ * @param {ASTNode} node The current AST node.
177
+ * @returns {void}
178
+ */
179
+ function forwardCurrentToHead(analyzer, node) {
180
+ const codePath = analyzer.codePath;
181
+ const state = CodePath.getState(codePath);
182
+ const currentSegments = state.currentSegments;
183
+ const headSegments = state.headSegments;
184
+ const end = Math.max(currentSegments.length, headSegments.length);
185
+ let i, currentSegment, headSegment;
186
+
187
+ // Fires leaving events.
188
+ for (i = 0; i < end; ++i) {
189
+ currentSegment = currentSegments[i];
190
+ headSegment = headSegments[i];
191
+
192
+ if (currentSegment !== headSegment && currentSegment) {
193
+ const eventName = currentSegment.reachable
194
+ ? "onCodePathSegmentEnd"
195
+ : "onUnreachableCodePathSegmentEnd";
196
+
197
+ debug.dump(`${eventName} ${currentSegment.id}`);
198
+
199
+ analyzer.emit(eventName, [currentSegment, node]);
200
+ }
201
+ }
202
+
203
+ // Update state.
204
+ state.currentSegments = headSegments;
205
+
206
+ // Fires entering events.
207
+ for (i = 0; i < end; ++i) {
208
+ currentSegment = currentSegments[i];
209
+ headSegment = headSegments[i];
210
+
211
+ if (currentSegment !== headSegment && headSegment) {
212
+ const eventName = headSegment.reachable
213
+ ? "onCodePathSegmentStart"
214
+ : "onUnreachableCodePathSegmentStart";
215
+
216
+ debug.dump(`${eventName} ${headSegment.id}`);
217
+ CodePathSegment.markUsed(headSegment);
218
+ analyzer.emit(eventName, [headSegment, node]);
219
+ }
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Updates the current segment with empty.
225
+ * This is called at the last of functions or the program.
226
+ * @param {CodePathAnalyzer} analyzer The instance.
227
+ * @param {ASTNode} node The current AST node.
228
+ * @returns {void}
229
+ */
230
+ function leaveFromCurrentSegment(analyzer, node) {
231
+ const state = CodePath.getState(analyzer.codePath);
232
+ const currentSegments = state.currentSegments;
233
+
234
+ for (let i = 0; i < currentSegments.length; ++i) {
235
+ const currentSegment = currentSegments[i];
236
+ const eventName = currentSegment.reachable
237
+ ? "onCodePathSegmentEnd"
238
+ : "onUnreachableCodePathSegmentEnd";
239
+
240
+ debug.dump(`${eventName} ${currentSegment.id}`);
241
+
242
+ analyzer.emit(eventName, [currentSegment, node]);
243
+ }
244
+
245
+ state.currentSegments = [];
246
+ }
247
+
248
+ /**
249
+ * Updates the code path due to the position of a given node in the parent node
250
+ * thereof.
251
+ *
252
+ * For example, if the node is `parent.consequent`, this creates a fork from the
253
+ * current path.
254
+ * @param {CodePathAnalyzer} analyzer The instance.
255
+ * @param {ASTNode} node The current AST node.
256
+ * @returns {void}
257
+ */
258
+ function preprocess(analyzer, node) {
259
+ const codePath = analyzer.codePath;
260
+ const state = CodePath.getState(codePath);
261
+ const parent = node.parent;
262
+
263
+ switch (parent.type) {
264
+ // The `arguments.length == 0` case is in `postprocess` function.
265
+ case "CallExpression":
266
+ if (
267
+ parent.optional === true &&
268
+ parent.arguments.length >= 1 &&
269
+ parent.arguments[0] === node
270
+ ) {
271
+ state.makeOptionalRight();
272
+ }
273
+ break;
274
+ case "MemberExpression":
275
+ if (parent.optional === true && parent.property === node) {
276
+ state.makeOptionalRight();
277
+ }
278
+ break;
279
+
280
+ case "LogicalExpression":
281
+ if (
282
+ parent.right === node &&
283
+ isHandledLogicalOperator(parent.operator)
284
+ ) {
285
+ state.makeLogicalRight();
286
+ }
287
+ break;
288
+
289
+ case "AssignmentExpression":
290
+ if (
291
+ parent.right === node &&
292
+ isLogicalAssignmentOperator(parent.operator)
293
+ ) {
294
+ state.makeLogicalRight();
295
+ }
296
+ break;
297
+
298
+ case "ConditionalExpression":
299
+ case "IfStatement":
300
+ /*
301
+ * Fork if this node is at `consequent`/`alternate`.
302
+ * `popForkContext()` exists at `IfStatement:exit` and
303
+ * `ConditionalExpression:exit`.
304
+ */
305
+ if (parent.consequent === node) {
306
+ state.makeIfConsequent();
307
+ } else if (parent.alternate === node) {
308
+ state.makeIfAlternate();
309
+ }
310
+ break;
311
+
312
+ case "SwitchCase":
313
+ if (parent.consequent[0] === node) {
314
+ state.makeSwitchCaseBody(false, !parent.test);
315
+ }
316
+ break;
317
+
318
+ case "TryStatement":
319
+ if (parent.handler === node) {
320
+ state.makeCatchBlock();
321
+ } else if (parent.finalizer === node) {
322
+ state.makeFinallyBlock();
323
+ }
324
+ break;
325
+
326
+ case "WhileStatement":
327
+ if (parent.test === node) {
328
+ state.makeWhileTest(getBooleanValueIfSimpleConstant(node));
329
+ } else {
330
+ assert(parent.body === node);
331
+ state.makeWhileBody();
332
+ }
333
+ break;
334
+
335
+ case "DoWhileStatement":
336
+ if (parent.body === node) {
337
+ state.makeDoWhileBody();
338
+ } else {
339
+ assert(parent.test === node);
340
+ state.makeDoWhileTest(getBooleanValueIfSimpleConstant(node));
341
+ }
342
+ break;
343
+
344
+ case "ForStatement":
345
+ if (parent.test === node) {
346
+ state.makeForTest(getBooleanValueIfSimpleConstant(node));
347
+ } else if (parent.update === node) {
348
+ state.makeForUpdate();
349
+ } else if (parent.body === node) {
350
+ state.makeForBody();
351
+ }
352
+ break;
353
+
354
+ case "ForInStatement":
355
+ case "ForOfStatement":
356
+ if (parent.left === node) {
357
+ state.makeForInOfLeft();
358
+ } else if (parent.right === node) {
359
+ state.makeForInOfRight();
360
+ } else {
361
+ assert(parent.body === node);
362
+ state.makeForInOfBody();
363
+ }
364
+ break;
365
+
366
+ case "AssignmentPattern":
367
+ /*
368
+ * Fork if this node is at `right`.
369
+ * `left` is executed always, so it uses the current path.
370
+ * `popForkContext()` exists at `AssignmentPattern:exit`.
371
+ */
372
+ if (parent.right === node) {
373
+ state.pushForkContext();
374
+ state.forkBypassPath();
375
+ state.forkPath();
376
+ }
377
+ break;
378
+
379
+ default:
380
+ break;
381
+ }
382
+ }
383
+
384
+ /**
385
+ * Updates the code path due to the type of a given node in entering.
386
+ * @param {CodePathAnalyzer} analyzer The instance.
387
+ * @param {ASTNode} node The current AST node.
388
+ * @returns {void}
389
+ */
390
+ function processCodePathToEnter(analyzer, node) {
391
+ let codePath = analyzer.codePath;
392
+ let state = codePath && CodePath.getState(codePath);
393
+ const parent = node.parent;
394
+
395
+ /**
396
+ * Creates a new code path and trigger the onCodePathStart event
397
+ * based on the currently selected node.
398
+ * @param {string} origin The reason the code path was started.
399
+ * @returns {void}
400
+ */
401
+ function startCodePath(origin) {
402
+ if (codePath) {
403
+ // Emits onCodePathSegmentStart events if updated.
404
+ forwardCurrentToHead(analyzer, node);
405
+ debug.dumpState(node, state, false);
406
+ }
407
+
408
+ // Create the code path of this scope.
409
+ codePath = analyzer.codePath = new CodePath({
410
+ id: analyzer.idGenerator.next(),
411
+ origin,
412
+ upper: codePath,
413
+ onLooped: analyzer.onLooped,
414
+ });
415
+ state = CodePath.getState(codePath);
416
+
417
+ // Emits onCodePathStart events.
418
+ debug.dump(`onCodePathStart ${codePath.id}`);
419
+ analyzer.emit("onCodePathStart", [codePath, node]);
420
+ }
421
+
422
+ /*
423
+ * Special case: The right side of class field initializer is considered
424
+ * to be its own function, so we need to start a new code path in this
425
+ * case.
426
+ */
427
+ if (isPropertyDefinitionValue(node)) {
428
+ startCodePath("class-field-initializer");
429
+
430
+ /*
431
+ * Intentional fall through because `node` needs to also be
432
+ * processed by the code below. For example, if we have:
433
+ *
434
+ * class Foo {
435
+ * a = () => {}
436
+ * }
437
+ *
438
+ * In this case, we also need start a second code path.
439
+ */
440
+ }
441
+
442
+ switch (node.type) {
443
+ case "Program":
444
+ startCodePath("program");
445
+ break;
446
+
447
+ case "FunctionDeclaration":
448
+ case "FunctionExpression":
449
+ case "ArrowFunctionExpression":
450
+ startCodePath("function");
451
+ break;
452
+
453
+ case "StaticBlock":
454
+ startCodePath("class-static-block");
455
+ break;
456
+
457
+ case "ChainExpression":
458
+ state.pushChainContext();
459
+ break;
460
+ case "CallExpression":
461
+ if (node.optional === true) {
462
+ state.makeOptionalNode();
463
+ }
464
+ break;
465
+ case "MemberExpression":
466
+ if (node.optional === true) {
467
+ state.makeOptionalNode();
468
+ }
469
+ break;
470
+
471
+ case "LogicalExpression":
472
+ if (isHandledLogicalOperator(node.operator)) {
473
+ state.pushChoiceContext(
474
+ node.operator,
475
+ isForkingByTrueOrFalse(node),
476
+ );
477
+ }
478
+ break;
479
+
480
+ case "AssignmentExpression":
481
+ if (isLogicalAssignmentOperator(node.operator)) {
482
+ state.pushChoiceContext(
483
+ node.operator.slice(0, -1), // removes `=` from the end
484
+ isForkingByTrueOrFalse(node),
485
+ );
486
+ }
487
+ break;
488
+
489
+ case "ConditionalExpression":
490
+ case "IfStatement":
491
+ state.pushChoiceContext("test", false);
492
+ break;
493
+
494
+ case "SwitchStatement":
495
+ state.pushSwitchContext(
496
+ node.cases.some(isCaseNode),
497
+ getLabel(node),
498
+ );
499
+ break;
500
+
501
+ case "TryStatement":
502
+ state.pushTryContext(Boolean(node.finalizer));
503
+ break;
504
+
505
+ case "SwitchCase":
506
+ /*
507
+ * Fork if this node is after the 2st node in `cases`.
508
+ * It's similar to `else` blocks.
509
+ * The next `test` node is processed in this path.
510
+ */
511
+ if (parent.discriminant !== node && parent.cases[0] !== node) {
512
+ state.forkPath();
513
+ }
514
+ break;
515
+
516
+ case "WhileStatement":
517
+ case "DoWhileStatement":
518
+ case "ForStatement":
519
+ case "ForInStatement":
520
+ case "ForOfStatement":
521
+ state.pushLoopContext(node.type, getLabel(node));
522
+ break;
523
+
524
+ case "LabeledStatement":
525
+ if (!breakableTypePattern.test(node.body.type)) {
526
+ state.pushBreakContext(false, node.label.name);
527
+ }
528
+ break;
529
+
530
+ default:
531
+ break;
532
+ }
533
+
534
+ // Emits onCodePathSegmentStart events if updated.
535
+ forwardCurrentToHead(analyzer, node);
536
+ debug.dumpState(node, state, false);
537
+ }
538
+
539
+ /**
540
+ * Updates the code path due to the type of a given node in leaving.
541
+ * @param {CodePathAnalyzer} analyzer The instance.
542
+ * @param {ASTNode} node The current AST node.
543
+ * @returns {void}
544
+ */
545
+ function processCodePathToExit(analyzer, node) {
546
+ const codePath = analyzer.codePath;
547
+ const state = CodePath.getState(codePath);
548
+ let dontForward = false;
549
+
550
+ switch (node.type) {
551
+ case "ChainExpression":
552
+ state.popChainContext();
553
+ break;
554
+
555
+ case "IfStatement":
556
+ case "ConditionalExpression":
557
+ state.popChoiceContext();
558
+ break;
559
+
560
+ case "LogicalExpression":
561
+ if (isHandledLogicalOperator(node.operator)) {
562
+ state.popChoiceContext();
563
+ }
564
+ break;
565
+
566
+ case "AssignmentExpression":
567
+ if (isLogicalAssignmentOperator(node.operator)) {
568
+ state.popChoiceContext();
569
+ }
570
+ break;
571
+
572
+ case "SwitchStatement":
573
+ state.popSwitchContext();
574
+ break;
575
+
576
+ case "SwitchCase":
577
+ /*
578
+ * This is the same as the process at the 1st `consequent` node in
579
+ * `preprocess` function.
580
+ * Must do if this `consequent` is empty.
581
+ */
582
+ if (node.consequent.length === 0) {
583
+ state.makeSwitchCaseBody(true, !node.test);
584
+ }
585
+ if (state.forkContext.reachable) {
586
+ dontForward = true;
587
+ }
588
+ break;
589
+
590
+ case "TryStatement":
591
+ state.popTryContext();
592
+ break;
593
+
594
+ case "BreakStatement":
595
+ forwardCurrentToHead(analyzer, node);
596
+ state.makeBreak(node.label && node.label.name);
597
+ dontForward = true;
598
+ break;
599
+
600
+ case "ContinueStatement":
601
+ forwardCurrentToHead(analyzer, node);
602
+ state.makeContinue(node.label && node.label.name);
603
+ dontForward = true;
604
+ break;
605
+
606
+ case "ReturnStatement":
607
+ forwardCurrentToHead(analyzer, node);
608
+ state.makeReturn();
609
+ dontForward = true;
610
+ break;
611
+
612
+ case "ThrowStatement":
613
+ forwardCurrentToHead(analyzer, node);
614
+ state.makeThrow();
615
+ dontForward = true;
616
+ break;
617
+
618
+ case "Identifier":
619
+ if (isIdentifierReference(node)) {
620
+ state.makeFirstThrowablePathInTryBlock();
621
+ dontForward = true;
622
+ }
623
+ break;
624
+
625
+ case "CallExpression":
626
+ case "ImportExpression":
627
+ case "MemberExpression":
628
+ case "NewExpression":
629
+ case "YieldExpression":
630
+ state.makeFirstThrowablePathInTryBlock();
631
+ break;
632
+
633
+ case "WhileStatement":
634
+ case "DoWhileStatement":
635
+ case "ForStatement":
636
+ case "ForInStatement":
637
+ case "ForOfStatement":
638
+ state.popLoopContext();
639
+ break;
640
+
641
+ case "AssignmentPattern":
642
+ state.popForkContext();
643
+ break;
644
+
645
+ case "LabeledStatement":
646
+ if (!breakableTypePattern.test(node.body.type)) {
647
+ state.popBreakContext();
648
+ }
649
+ break;
650
+
651
+ default:
652
+ break;
653
+ }
654
+
655
+ // Emits onCodePathSegmentStart events if updated.
656
+ if (!dontForward) {
657
+ forwardCurrentToHead(analyzer, node);
658
+ }
659
+ debug.dumpState(node, state, true);
660
+ }
661
+
662
+ /**
663
+ * Updates the code path to finalize the current code path.
664
+ * @param {CodePathAnalyzer} analyzer The instance.
665
+ * @param {ASTNode} node The current AST node.
666
+ * @returns {void}
667
+ */
668
+ function postprocess(analyzer, node) {
669
+ /**
670
+ * Ends the code path for the current node.
671
+ * @returns {void}
672
+ */
673
+ function endCodePath() {
674
+ let codePath = analyzer.codePath;
675
+
676
+ // Mark the current path as the final node.
677
+ CodePath.getState(codePath).makeFinal();
678
+
679
+ // Emits onCodePathSegmentEnd event of the current segments.
680
+ leaveFromCurrentSegment(analyzer, node);
681
+
682
+ // Emits onCodePathEnd event of this code path.
683
+ debug.dump(`onCodePathEnd ${codePath.id}`);
684
+ analyzer.emit("onCodePathEnd", [codePath, node]);
685
+ debug.dumpDot(codePath);
686
+
687
+ codePath = analyzer.codePath = analyzer.codePath.upper;
688
+ if (codePath) {
689
+ debug.dumpState(node, CodePath.getState(codePath), true);
690
+ }
691
+ }
692
+
693
+ switch (node.type) {
694
+ case "Program":
695
+ case "FunctionDeclaration":
696
+ case "FunctionExpression":
697
+ case "ArrowFunctionExpression":
698
+ case "StaticBlock": {
699
+ endCodePath();
700
+ break;
701
+ }
702
+
703
+ // The `arguments.length >= 1` case is in `preprocess` function.
704
+ case "CallExpression":
705
+ if (node.optional === true && node.arguments.length === 0) {
706
+ CodePath.getState(analyzer.codePath).makeOptionalRight();
707
+ }
708
+ break;
709
+
710
+ default:
711
+ break;
712
+ }
713
+
714
+ /*
715
+ * Special case: The right side of class field initializer is considered
716
+ * to be its own function, so we need to end a code path in this
717
+ * case.
718
+ *
719
+ * We need to check after the other checks in order to close the
720
+ * code paths in the correct order for code like this:
721
+ *
722
+ *
723
+ * class Foo {
724
+ * a = () => {}
725
+ * }
726
+ *
727
+ * In this case, The ArrowFunctionExpression code path is closed first
728
+ * and then we need to close the code path for the PropertyDefinition
729
+ * value.
730
+ */
731
+ if (isPropertyDefinitionValue(node)) {
732
+ endCodePath();
733
+ }
734
+ }
735
+
736
+ //------------------------------------------------------------------------------
737
+ // Public Interface
738
+ //------------------------------------------------------------------------------
739
+
740
+ /**
741
+ * The class to analyze code paths.
742
+ * This class implements the EventGenerator interface.
743
+ */
744
+ class CodePathAnalyzer {
745
+ /**
746
+ * @param {EventGenerator} eventGenerator An event generator to wrap.
747
+ */
748
+ constructor(eventGenerator) {
749
+ this.original = eventGenerator;
750
+ this.emit = eventGenerator.emit;
751
+ this.codePath = null;
752
+ this.idGenerator = new IdGenerator("s");
753
+ this.currentNode = null;
754
+ this.onLooped = this.onLooped.bind(this);
755
+ }
756
+
757
+ /**
758
+ * Does the process to enter a given AST node.
759
+ * This updates state of analysis and calls `enterNode` of the wrapped.
760
+ * @param {ASTNode} node A node which is entering.
761
+ * @returns {void}
762
+ */
763
+ enterNode(node) {
764
+ this.currentNode = node;
765
+
766
+ // Updates the code path due to node's position in its parent node.
767
+ if (node.parent) {
768
+ preprocess(this, node);
769
+ }
770
+
771
+ /*
772
+ * Updates the code path.
773
+ * And emits onCodePathStart/onCodePathSegmentStart events.
774
+ */
775
+ processCodePathToEnter(this, node);
776
+
777
+ // Emits node events.
778
+ this.original.enterNode(node);
779
+
780
+ this.currentNode = null;
781
+ }
782
+
783
+ /**
784
+ * Does the process to leave a given AST node.
785
+ * This updates state of analysis and calls `leaveNode` of the wrapped.
786
+ * @param {ASTNode} node A node which is leaving.
787
+ * @returns {void}
788
+ */
789
+ leaveNode(node) {
790
+ this.currentNode = node;
791
+
792
+ /*
793
+ * Updates the code path.
794
+ * And emits onCodePathStart/onCodePathSegmentStart events.
795
+ */
796
+ processCodePathToExit(this, node);
797
+
798
+ // Emits node events.
799
+ this.original.leaveNode(node);
800
+
801
+ // Emits the last onCodePathStart/onCodePathSegmentStart events.
802
+ postprocess(this, node);
803
+
804
+ this.currentNode = null;
805
+ }
806
+
807
+ /**
808
+ * This is called on a code path looped.
809
+ * Then this raises a looped event.
810
+ * @param {CodePathSegment} fromSegment A segment of prev.
811
+ * @param {CodePathSegment} toSegment A segment of next.
812
+ * @returns {void}
813
+ */
814
+ onLooped(fromSegment, toSegment) {
815
+ if (fromSegment.reachable && toSegment.reachable) {
816
+ debug.dump(
817
+ `onCodePathSegmentLoop ${fromSegment.id} -> ${toSegment.id}`,
818
+ );
819
+ this.emit("onCodePathSegmentLoop", [
820
+ fromSegment,
821
+ toSegment,
822
+ this.currentNode,
823
+ ]);
824
+ }
825
+ }
826
+ }
827
+
828
+ module.exports = CodePathAnalyzer;