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,603 @@
1
+ /**
2
+ * @fileoverview Rule to flag constant comparisons and logical expressions that always/never short circuit
3
+ * @author Jordan Eldredge <https://jordaneldredge.com>
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const {
9
+ isNullLiteral,
10
+ isConstant,
11
+ isReferenceToGlobalVariable,
12
+ isLogicalAssignmentOperator,
13
+ ECMASCRIPT_GLOBALS,
14
+ } = require("./utils/ast-utils");
15
+
16
+ const NUMERIC_OR_STRING_BINARY_OPERATORS = new Set([
17
+ "+",
18
+ "-",
19
+ "*",
20
+ "/",
21
+ "%",
22
+ "|",
23
+ "^",
24
+ "&",
25
+ "**",
26
+ "<<",
27
+ ">>",
28
+ ">>>",
29
+ ]);
30
+
31
+ //------------------------------------------------------------------------------
32
+ // Helpers
33
+ //------------------------------------------------------------------------------
34
+
35
+ /**
36
+ * Checks whether or not a node is `null` or `undefined`. Similar to the one
37
+ * found in ast-utils.js, but this one correctly handles the edge case that
38
+ * `undefined` has been redefined.
39
+ * @param {Scope} scope Scope in which the expression was found.
40
+ * @param {ASTNode} node A node to check.
41
+ * @returns {boolean} Whether or not the node is a `null` or `undefined`.
42
+ * @public
43
+ */
44
+ function isNullOrUndefined(scope, node) {
45
+ return (
46
+ isNullLiteral(node) ||
47
+ (node.type === "Identifier" &&
48
+ node.name === "undefined" &&
49
+ isReferenceToGlobalVariable(scope, node)) ||
50
+ (node.type === "UnaryExpression" && node.operator === "void")
51
+ );
52
+ }
53
+
54
+ /**
55
+ * Test if an AST node has a statically knowable constant nullishness. Meaning,
56
+ * it will always resolve to a constant value of either: `null`, `undefined`
57
+ * or not `null` _or_ `undefined`. An expression that can vary between those
58
+ * three states at runtime would return `false`.
59
+ * @param {Scope} scope The scope in which the node was found.
60
+ * @param {ASTNode} node The AST node being tested.
61
+ * @param {boolean} nonNullish if `true` then nullish values are not considered constant.
62
+ * @returns {boolean} Does `node` have constant nullishness?
63
+ */
64
+ function hasConstantNullishness(scope, node, nonNullish) {
65
+ if (nonNullish && isNullOrUndefined(scope, node)) {
66
+ return false;
67
+ }
68
+
69
+ switch (node.type) {
70
+ case "ObjectExpression": // Objects are never nullish
71
+ case "ArrayExpression": // Arrays are never nullish
72
+ case "ArrowFunctionExpression": // Functions never nullish
73
+ case "FunctionExpression": // Functions are never nullish
74
+ case "ClassExpression": // Classes are never nullish
75
+ case "NewExpression": // Objects are never nullish
76
+ case "Literal": // Nullish, or non-nullish, literals never change
77
+ case "TemplateLiteral": // A string is never nullish
78
+ case "UpdateExpression": // Numbers are never nullish
79
+ case "BinaryExpression": // Numbers, strings, or booleans are never nullish
80
+ return true;
81
+ case "CallExpression": {
82
+ if (node.callee.type !== "Identifier") {
83
+ return false;
84
+ }
85
+ const functionName = node.callee.name;
86
+
87
+ return (
88
+ (functionName === "Boolean" ||
89
+ functionName === "String" ||
90
+ functionName === "Number") &&
91
+ isReferenceToGlobalVariable(scope, node.callee)
92
+ );
93
+ }
94
+ case "LogicalExpression": {
95
+ return (
96
+ node.operator === "??" &&
97
+ hasConstantNullishness(scope, node.right, true)
98
+ );
99
+ }
100
+ case "AssignmentExpression":
101
+ if (node.operator === "=") {
102
+ return hasConstantNullishness(scope, node.right, nonNullish);
103
+ }
104
+
105
+ /*
106
+ * Handling short-circuiting assignment operators would require
107
+ * walking the scope. We won't attempt that (for now...) /
108
+ */
109
+ if (isLogicalAssignmentOperator(node.operator)) {
110
+ return false;
111
+ }
112
+
113
+ /*
114
+ * The remaining assignment expressions all result in a numeric or
115
+ * string (non-nullish) value:
116
+ * "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "|=", "^=", "&="
117
+ */
118
+
119
+ return true;
120
+ case "UnaryExpression":
121
+ /*
122
+ * "void" Always returns `undefined`
123
+ * "typeof" All types are strings, and thus non-nullish
124
+ * "!" Boolean is never nullish
125
+ * "delete" Returns a boolean, which is never nullish
126
+ * Math operators always return numbers or strings, neither of which
127
+ * are non-nullish "+", "-", "~"
128
+ */
129
+
130
+ return true;
131
+ case "SequenceExpression": {
132
+ const last = node.expressions.at(-1);
133
+
134
+ return hasConstantNullishness(scope, last, nonNullish);
135
+ }
136
+ case "Identifier":
137
+ return (
138
+ node.name === "undefined" &&
139
+ isReferenceToGlobalVariable(scope, node)
140
+ );
141
+ case "JSXElement": // ESLint has a policy of not assuming any specific JSX behavior.
142
+ case "JSXFragment":
143
+ return false;
144
+ default:
145
+ return false;
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Test if an AST node is a boolean value that never changes. Specifically we
151
+ * test for:
152
+ * 1. Literal booleans (`true` or `false`)
153
+ * 2. Unary `!` expressions with a constant value
154
+ * 3. Constant booleans created via the `Boolean` global function
155
+ * @param {Scope} scope The scope in which the node was found.
156
+ * @param {ASTNode} node The node to test
157
+ * @returns {boolean} Is `node` guaranteed to be a boolean?
158
+ */
159
+ function isStaticBoolean(scope, node) {
160
+ switch (node.type) {
161
+ case "Literal":
162
+ return typeof node.value === "boolean";
163
+ case "CallExpression":
164
+ return (
165
+ node.callee.type === "Identifier" &&
166
+ node.callee.name === "Boolean" &&
167
+ isReferenceToGlobalVariable(scope, node.callee) &&
168
+ (node.arguments.length === 0 ||
169
+ isConstant(scope, node.arguments[0], true))
170
+ );
171
+ case "UnaryExpression":
172
+ return (
173
+ node.operator === "!" && isConstant(scope, node.argument, true)
174
+ );
175
+ default:
176
+ return false;
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Test if an AST node will always give the same result when compared to a
182
+ * boolean value. Note that comparison to boolean values is different than
183
+ * truthiness.
184
+ * https://262.ecma-international.org/5.1/#sec-11.9.3
185
+ *
186
+ * JavaScript `==` operator works by converting the boolean to `1` (true) or
187
+ * `+0` (false) and then checks the values `==` equality to that number.
188
+ * @param {Scope} scope The scope in which node was found.
189
+ * @param {ASTNode} node The node to test.
190
+ * @returns {boolean} Will `node` always coerce to the same boolean value?
191
+ */
192
+ function hasConstantLooseBooleanComparison(scope, node) {
193
+ switch (node.type) {
194
+ case "ObjectExpression":
195
+ case "ClassExpression":
196
+ /**
197
+ * In theory objects like:
198
+ *
199
+ * `{toString: () => a}`
200
+ * `{valueOf: () => a}`
201
+ *
202
+ * Or a classes like:
203
+ *
204
+ * `class { static toString() { return a } }`
205
+ * `class { static valueOf() { return a } }`
206
+ *
207
+ * Are not constant verifiably when `inBooleanPosition` is
208
+ * false, but it's an edge case we've opted not to handle.
209
+ */
210
+ return true;
211
+ case "ArrayExpression": {
212
+ const nonSpreadElements = node.elements.filter(
213
+ e =>
214
+ // Elements can be `null` in sparse arrays: `[,,]`;
215
+ e !== null && e.type !== "SpreadElement",
216
+ );
217
+
218
+ /*
219
+ * Possible future direction if needed: We could check if the
220
+ * single value would result in variable boolean comparison.
221
+ * For now we will err on the side of caution since `[x]` could
222
+ * evaluate to `[0]` or `[1]`.
223
+ */
224
+ return node.elements.length === 0 || nonSpreadElements.length > 1;
225
+ }
226
+ case "ArrowFunctionExpression":
227
+ case "FunctionExpression":
228
+ return true;
229
+ case "UnaryExpression":
230
+ if (
231
+ node.operator === "void" || // Always returns `undefined`
232
+ node.operator === "typeof" // All `typeof` strings, when coerced to number, are not 0 or 1.
233
+ ) {
234
+ return true;
235
+ }
236
+ if (node.operator === "!") {
237
+ return isConstant(scope, node.argument, true);
238
+ }
239
+
240
+ /*
241
+ * We won't try to reason about +, -, ~, or delete
242
+ * In theory, for the mathematical operators, we could look at the
243
+ * argument and try to determine if it coerces to a constant numeric
244
+ * value.
245
+ */
246
+ return false;
247
+ case "NewExpression": // Objects might have custom `.valueOf` or `.toString`.
248
+ return false;
249
+ case "CallExpression": {
250
+ if (
251
+ node.callee.type === "Identifier" &&
252
+ node.callee.name === "Boolean" &&
253
+ isReferenceToGlobalVariable(scope, node.callee)
254
+ ) {
255
+ return (
256
+ node.arguments.length === 0 ||
257
+ isConstant(scope, node.arguments[0], true)
258
+ );
259
+ }
260
+ return false;
261
+ }
262
+ case "Literal": // True or false, literals never change
263
+ return true;
264
+ case "Identifier":
265
+ return (
266
+ node.name === "undefined" &&
267
+ isReferenceToGlobalVariable(scope, node)
268
+ );
269
+ case "TemplateLiteral":
270
+ /*
271
+ * In theory we could try to check if the quasi are sufficient to
272
+ * prove that the expression will always be true, but it would be
273
+ * tricky to get right. For example: `000.${foo}000`
274
+ */
275
+ return node.expressions.length === 0;
276
+ case "AssignmentExpression":
277
+ if (node.operator === "=") {
278
+ return hasConstantLooseBooleanComparison(scope, node.right);
279
+ }
280
+
281
+ /*
282
+ * Handling short-circuiting assignment operators would require
283
+ * walking the scope. We won't attempt that (for now...)
284
+ *
285
+ * The remaining assignment expressions all result in a numeric or
286
+ * string (non-nullish) values which could be truthy or falsy:
287
+ * "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "|=", "^=", "&="
288
+ */
289
+ return false;
290
+ case "SequenceExpression": {
291
+ const last = node.expressions.at(-1);
292
+
293
+ return hasConstantLooseBooleanComparison(scope, last);
294
+ }
295
+ case "JSXElement": // ESLint has a policy of not assuming any specific JSX behavior.
296
+ case "JSXFragment":
297
+ return false;
298
+ default:
299
+ return false;
300
+ }
301
+ }
302
+
303
+ /**
304
+ * Test if an AST node will always give the same result when _strictly_ compared
305
+ * to a boolean value. This can happen if the expression can never be boolean, or
306
+ * if it is always the same boolean value.
307
+ * @param {Scope} scope The scope in which the node was found.
308
+ * @param {ASTNode} node The node to test
309
+ * @returns {boolean} Will `node` always give the same result when compared to a
310
+ * static boolean value?
311
+ */
312
+ function hasConstantStrictBooleanComparison(scope, node) {
313
+ switch (node.type) {
314
+ case "ObjectExpression": // Objects are not booleans
315
+ case "ArrayExpression": // Arrays are not booleans
316
+ case "ArrowFunctionExpression": // Functions are not booleans
317
+ case "FunctionExpression":
318
+ case "ClassExpression": // Classes are not booleans
319
+ case "NewExpression": // Objects are not booleans
320
+ case "TemplateLiteral": // Strings are not booleans
321
+ case "Literal": // True, false, or not boolean, literals never change.
322
+ case "UpdateExpression": // Numbers are not booleans
323
+ return true;
324
+ case "BinaryExpression":
325
+ return NUMERIC_OR_STRING_BINARY_OPERATORS.has(node.operator);
326
+ case "UnaryExpression": {
327
+ if (node.operator === "delete") {
328
+ return false;
329
+ }
330
+ if (node.operator === "!") {
331
+ return isConstant(scope, node.argument, true);
332
+ }
333
+
334
+ /*
335
+ * The remaining operators return either strings or numbers, neither
336
+ * of which are boolean.
337
+ */
338
+ return true;
339
+ }
340
+ case "SequenceExpression": {
341
+ const last = node.expressions.at(-1);
342
+
343
+ return hasConstantStrictBooleanComparison(scope, last);
344
+ }
345
+ case "Identifier":
346
+ return (
347
+ node.name === "undefined" &&
348
+ isReferenceToGlobalVariable(scope, node)
349
+ );
350
+ case "AssignmentExpression":
351
+ if (node.operator === "=") {
352
+ return hasConstantStrictBooleanComparison(scope, node.right);
353
+ }
354
+
355
+ /*
356
+ * Handling short-circuiting assignment operators would require
357
+ * walking the scope. We won't attempt that (for now...)
358
+ */
359
+ if (isLogicalAssignmentOperator(node.operator)) {
360
+ return false;
361
+ }
362
+
363
+ /*
364
+ * The remaining assignment expressions all result in either a number
365
+ * or a string, neither of which can ever be boolean.
366
+ */
367
+ return true;
368
+ case "CallExpression": {
369
+ if (node.callee.type !== "Identifier") {
370
+ return false;
371
+ }
372
+ const functionName = node.callee.name;
373
+
374
+ if (
375
+ (functionName === "String" || functionName === "Number") &&
376
+ isReferenceToGlobalVariable(scope, node.callee)
377
+ ) {
378
+ return true;
379
+ }
380
+ if (
381
+ functionName === "Boolean" &&
382
+ isReferenceToGlobalVariable(scope, node.callee)
383
+ ) {
384
+ return (
385
+ node.arguments.length === 0 ||
386
+ isConstant(scope, node.arguments[0], true)
387
+ );
388
+ }
389
+ return false;
390
+ }
391
+ case "JSXElement": // ESLint has a policy of not assuming any specific JSX behavior.
392
+ case "JSXFragment":
393
+ return false;
394
+ default:
395
+ return false;
396
+ }
397
+ }
398
+
399
+ /**
400
+ * Test if an AST node will always result in a newly constructed object
401
+ * @param {Scope} scope The scope in which the node was found.
402
+ * @param {ASTNode} node The node to test
403
+ * @returns {boolean} Will `node` always be new?
404
+ */
405
+ function isAlwaysNew(scope, node) {
406
+ switch (node.type) {
407
+ case "ObjectExpression":
408
+ case "ArrayExpression":
409
+ case "ArrowFunctionExpression":
410
+ case "FunctionExpression":
411
+ case "ClassExpression":
412
+ return true;
413
+ case "NewExpression": {
414
+ if (node.callee.type !== "Identifier") {
415
+ return false;
416
+ }
417
+
418
+ /*
419
+ * All the built-in constructors are always new, but
420
+ * user-defined constructors could return a sentinel
421
+ * object.
422
+ *
423
+ * Catching these is especially useful for primitive constructors
424
+ * which return boxed values, a surprising gotcha' in JavaScript.
425
+ */
426
+ return (
427
+ Object.hasOwn(ECMASCRIPT_GLOBALS, node.callee.name) &&
428
+ isReferenceToGlobalVariable(scope, node.callee)
429
+ );
430
+ }
431
+ case "Literal":
432
+ // Regular expressions are objects, and thus always new
433
+ return typeof node.regex === "object";
434
+ case "SequenceExpression": {
435
+ const last = node.expressions.at(-1);
436
+
437
+ return isAlwaysNew(scope, last);
438
+ }
439
+ case "AssignmentExpression":
440
+ if (node.operator === "=") {
441
+ return isAlwaysNew(scope, node.right);
442
+ }
443
+ return false;
444
+ case "ConditionalExpression":
445
+ return (
446
+ isAlwaysNew(scope, node.consequent) &&
447
+ isAlwaysNew(scope, node.alternate)
448
+ );
449
+ case "JSXElement": // ESLint has a policy of not assuming any specific JSX behavior.
450
+ case "JSXFragment":
451
+ return false;
452
+ default:
453
+ return false;
454
+ }
455
+ }
456
+
457
+ /**
458
+ * Checks if one operand will cause the result to be constant.
459
+ * @param {Scope} scope Scope in which the expression was found.
460
+ * @param {ASTNode} a One side of the expression
461
+ * @param {ASTNode} b The other side of the expression
462
+ * @param {string} operator The binary expression operator
463
+ * @returns {ASTNode | null} The node which will cause the expression to have a constant result.
464
+ */
465
+ function findBinaryExpressionConstantOperand(scope, a, b, operator) {
466
+ if (operator === "==" || operator === "!=") {
467
+ if (
468
+ (isNullOrUndefined(scope, a) &&
469
+ hasConstantNullishness(scope, b, false)) ||
470
+ (isStaticBoolean(scope, a) &&
471
+ hasConstantLooseBooleanComparison(scope, b))
472
+ ) {
473
+ return b;
474
+ }
475
+ } else if (operator === "===" || operator === "!==") {
476
+ if (
477
+ (isNullOrUndefined(scope, a) &&
478
+ hasConstantNullishness(scope, b, false)) ||
479
+ (isStaticBoolean(scope, a) &&
480
+ hasConstantStrictBooleanComparison(scope, b))
481
+ ) {
482
+ return b;
483
+ }
484
+ }
485
+ return null;
486
+ }
487
+
488
+ //------------------------------------------------------------------------------
489
+ // Rule Definition
490
+ //------------------------------------------------------------------------------
491
+
492
+ /** @type {import('../types').Rule.RuleModule} */
493
+ module.exports = {
494
+ meta: {
495
+ type: "problem",
496
+ docs: {
497
+ description:
498
+ "Disallow expressions where the operation doesn't affect the value",
499
+ recommended: true,
500
+ url: "https://eslint.org/docs/latest/rules/no-constant-binary-expression",
501
+ },
502
+ schema: [],
503
+ messages: {
504
+ constantBinaryOperand:
505
+ "Unexpected constant binary expression. Compares constantly with the {{otherSide}}-hand side of the `{{operator}}`.",
506
+ constantShortCircuit:
507
+ "Unexpected constant {{property}} on the left-hand side of a `{{operator}}` expression.",
508
+ alwaysNew:
509
+ "Unexpected comparison to newly constructed object. These two values can never be equal.",
510
+ bothAlwaysNew:
511
+ "Unexpected comparison of two newly constructed objects. These two values can never be equal.",
512
+ },
513
+ },
514
+
515
+ create(context) {
516
+ const sourceCode = context.sourceCode;
517
+
518
+ return {
519
+ LogicalExpression(node) {
520
+ const { operator, left } = node;
521
+ const scope = sourceCode.getScope(node);
522
+
523
+ if (
524
+ (operator === "&&" || operator === "||") &&
525
+ isConstant(scope, left, true)
526
+ ) {
527
+ context.report({
528
+ node: left,
529
+ messageId: "constantShortCircuit",
530
+ data: { property: "truthiness", operator },
531
+ });
532
+ } else if (
533
+ operator === "??" &&
534
+ hasConstantNullishness(scope, left, false)
535
+ ) {
536
+ context.report({
537
+ node: left,
538
+ messageId: "constantShortCircuit",
539
+ data: { property: "nullishness", operator },
540
+ });
541
+ }
542
+ },
543
+ BinaryExpression(node) {
544
+ const scope = sourceCode.getScope(node);
545
+ const { right, left, operator } = node;
546
+ const rightConstantOperand =
547
+ findBinaryExpressionConstantOperand(
548
+ scope,
549
+ left,
550
+ right,
551
+ operator,
552
+ );
553
+ const leftConstantOperand = findBinaryExpressionConstantOperand(
554
+ scope,
555
+ right,
556
+ left,
557
+ operator,
558
+ );
559
+
560
+ if (rightConstantOperand) {
561
+ context.report({
562
+ node: rightConstantOperand,
563
+ messageId: "constantBinaryOperand",
564
+ data: { operator, otherSide: "left" },
565
+ });
566
+ } else if (leftConstantOperand) {
567
+ context.report({
568
+ node: leftConstantOperand,
569
+ messageId: "constantBinaryOperand",
570
+ data: { operator, otherSide: "right" },
571
+ });
572
+ } else if (operator === "===" || operator === "!==") {
573
+ if (isAlwaysNew(scope, left)) {
574
+ context.report({ node: left, messageId: "alwaysNew" });
575
+ } else if (isAlwaysNew(scope, right)) {
576
+ context.report({ node: right, messageId: "alwaysNew" });
577
+ }
578
+ } else if (operator === "==" || operator === "!=") {
579
+ /*
580
+ * If both sides are "new", then both sides are objects and
581
+ * therefore they will be compared by reference even with `==`
582
+ * equality.
583
+ */
584
+ if (isAlwaysNew(scope, left) && isAlwaysNew(scope, right)) {
585
+ context.report({
586
+ node: left,
587
+ messageId: "bothAlwaysNew",
588
+ });
589
+ }
590
+ }
591
+ },
592
+
593
+ /*
594
+ * In theory we could handle short-circuiting assignment operators,
595
+ * for some constant values, but that would require walking the
596
+ * scope to find the value of the variable being assigned. This is
597
+ * dependent on https://github.com/eslint/eslint/issues/13776
598
+ *
599
+ * AssignmentExpression() {},
600
+ */
601
+ };
602
+ },
603
+ };