@ttsc/lint 0.13.1 → 0.14.0-dev.20260528

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 (464) hide show
  1. package/README.md +948 -69
  2. package/lib/defaultFormat.d.ts +9 -6
  3. package/lib/defaultFormat.js +9 -6
  4. package/lib/defaultFormat.js.map +1 -1
  5. package/lib/index.d.ts +46 -0
  6. package/lib/index.js +35 -10
  7. package/lib/index.js.map +1 -1
  8. package/lib/structures/ITtscLintConfig.d.ts +12 -6
  9. package/lib/structures/{ITtscLintFormatConfig.d.ts → ITtscLintFormat.d.ts} +2 -2
  10. package/lib/structures/{TtscLintRuleMap.js → ITtscLintFormat.js} +1 -1
  11. package/lib/structures/ITtscLintFormat.js.map +1 -0
  12. package/lib/structures/TtscLintRuleSetting.d.ts +49 -0
  13. package/lib/structures/{TtscLintRuleOptions.js → TtscLintRuleSetting.js} +1 -1
  14. package/lib/structures/TtscLintRuleSetting.js.map +1 -0
  15. package/lib/structures/index.d.ts +3 -4
  16. package/lib/structures/index.js +3 -4
  17. package/lib/structures/index.js.map +1 -1
  18. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +104 -0
  19. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +14 -0
  20. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -0
  21. package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +79 -0
  22. package/lib/structures/rules/ITtscLintBoundariesRules.js +3 -0
  23. package/lib/structures/rules/ITtscLintBoundariesRules.js.map +1 -0
  24. package/lib/structures/rules/ITtscLintContributorRules.d.ts +17 -0
  25. package/lib/structures/rules/ITtscLintContributorRules.js +3 -0
  26. package/lib/structures/rules/ITtscLintContributorRules.js.map +1 -0
  27. package/lib/structures/rules/ITtscLintCoreRules.d.ts +1257 -0
  28. package/lib/structures/{ITtscLintFormatConfig.js → rules/ITtscLintCoreRules.js} +1 -1
  29. package/lib/structures/rules/ITtscLintCoreRules.js.map +1 -0
  30. package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +17 -0
  31. package/lib/structures/rules/ITtscLintCypressRuleOptions.js +10 -0
  32. package/lib/structures/rules/ITtscLintCypressRuleOptions.js.map +1 -0
  33. package/lib/structures/rules/ITtscLintCypressRules.d.ts +129 -0
  34. package/lib/structures/rules/ITtscLintCypressRules.js +3 -0
  35. package/lib/structures/rules/ITtscLintCypressRules.js.map +1 -0
  36. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +157 -0
  37. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +13 -0
  38. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js.map +1 -0
  39. package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +167 -0
  40. package/lib/structures/rules/ITtscLintFunctionalRules.js +3 -0
  41. package/lib/structures/rules/ITtscLintFunctionalRules.js.map +1 -0
  42. package/lib/structures/rules/ITtscLintJestRules.d.ts +201 -0
  43. package/lib/structures/rules/ITtscLintJestRules.js +3 -0
  44. package/lib/structures/rules/ITtscLintJestRules.js.map +1 -0
  45. package/lib/structures/rules/ITtscLintJsdocRules.d.ts +140 -0
  46. package/lib/structures/rules/ITtscLintJsdocRules.js +3 -0
  47. package/lib/structures/rules/ITtscLintJsdocRules.js.map +1 -0
  48. package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +302 -0
  49. package/lib/structures/rules/ITtscLintJsxA11yRules.js +3 -0
  50. package/lib/structures/rules/ITtscLintJsxA11yRules.js.map +1 -0
  51. package/lib/structures/rules/ITtscLintNextjsRules.d.ts +185 -0
  52. package/lib/structures/rules/ITtscLintNextjsRules.js +3 -0
  53. package/lib/structures/rules/ITtscLintNextjsRules.js.map +1 -0
  54. package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +330 -0
  55. package/lib/structures/rules/ITtscLintPlaywrightRules.js +3 -0
  56. package/lib/structures/rules/ITtscLintPlaywrightRules.js.map +1 -0
  57. package/lib/structures/rules/ITtscLintPromiseRules.d.ts +188 -0
  58. package/lib/structures/rules/ITtscLintPromiseRules.js +3 -0
  59. package/lib/structures/rules/ITtscLintPromiseRules.js.map +1 -0
  60. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +18 -0
  61. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js +8 -0
  62. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js.map +1 -0
  63. package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +51 -0
  64. package/lib/structures/rules/ITtscLintReactPerfRules.js +3 -0
  65. package/lib/structures/rules/ITtscLintReactPerfRules.js.map +1 -0
  66. package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +39 -0
  67. package/lib/structures/rules/ITtscLintReactRuleOptions.js +12 -0
  68. package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -0
  69. package/lib/structures/rules/ITtscLintReactRules.d.ts +289 -0
  70. package/lib/structures/rules/ITtscLintReactRules.js +3 -0
  71. package/lib/structures/rules/ITtscLintReactRules.js.map +1 -0
  72. package/lib/structures/rules/ITtscLintRegexpRules.d.ts +190 -0
  73. package/lib/structures/rules/ITtscLintRegexpRules.js +3 -0
  74. package/lib/structures/rules/ITtscLintRegexpRules.js.map +1 -0
  75. package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +66 -0
  76. package/lib/structures/rules/ITtscLintRuleOptionsMap.js +3 -0
  77. package/lib/structures/rules/ITtscLintRuleOptionsMap.js.map +1 -0
  78. package/lib/structures/rules/ITtscLintRules.d.ts +55 -0
  79. package/lib/structures/{TtscLintRule.js → rules/ITtscLintRules.js} +1 -1
  80. package/lib/structures/rules/ITtscLintRules.js.map +1 -0
  81. package/lib/structures/rules/ITtscLintSecurityRules.d.ts +148 -0
  82. package/lib/structures/rules/ITtscLintSecurityRules.js +3 -0
  83. package/lib/structures/rules/ITtscLintSecurityRules.js.map +1 -0
  84. package/lib/structures/rules/ITtscLintSolidRules.d.ts +181 -0
  85. package/lib/structures/rules/ITtscLintSolidRules.js +3 -0
  86. package/lib/structures/rules/ITtscLintSolidRules.js.map +1 -0
  87. package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +21 -0
  88. package/lib/structures/rules/ITtscLintStorybookRuleOptions.js +9 -0
  89. package/lib/structures/rules/ITtscLintStorybookRuleOptions.js.map +1 -0
  90. package/lib/structures/rules/ITtscLintStorybookRules.d.ts +174 -0
  91. package/lib/structures/rules/ITtscLintStorybookRules.js +3 -0
  92. package/lib/structures/rules/ITtscLintStorybookRules.js.map +1 -0
  93. package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +94 -0
  94. package/lib/structures/rules/ITtscLintTanstackQueryRules.js +3 -0
  95. package/lib/structures/rules/ITtscLintTanstackQueryRules.js.map +1 -0
  96. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +22 -0
  97. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js +10 -0
  98. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js.map +1 -0
  99. package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +310 -0
  100. package/lib/structures/rules/ITtscLintTestingLibraryRules.js +3 -0
  101. package/lib/structures/rules/ITtscLintTestingLibraryRules.js.map +1 -0
  102. package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +1132 -0
  103. package/lib/structures/rules/ITtscLintTypeScriptRules.js +3 -0
  104. package/lib/structures/rules/ITtscLintTypeScriptRules.js.map +1 -0
  105. package/lib/structures/rules/ITtscLintUnicornRules.d.ts +997 -0
  106. package/lib/structures/rules/ITtscLintUnicornRules.js +3 -0
  107. package/lib/structures/rules/ITtscLintUnicornRules.js.map +1 -0
  108. package/lib/structures/rules/ITtscLintVitestRules.d.ts +141 -0
  109. package/lib/structures/rules/ITtscLintVitestRules.js +3 -0
  110. package/lib/structures/rules/ITtscLintVitestRules.js.map +1 -0
  111. package/lib/structures/rules/index.d.ts +31 -0
  112. package/lib/structures/rules/index.js +48 -0
  113. package/lib/structures/rules/index.js.map +1 -0
  114. package/linthost/ast_helpers.go +30 -5
  115. package/linthost/config.go +48 -17
  116. package/linthost/config_format.go +9 -9
  117. package/linthost/directives.go +67 -25
  118. package/linthost/dispatch.go +14 -3
  119. package/linthost/engine.go +152 -31
  120. package/linthost/fix.go +2 -2
  121. package/linthost/lsp.go +747 -0
  122. package/linthost/print_dispatch.go +2 -2
  123. package/linthost/print_nodes_function.go +2 -2
  124. package/linthost/print_nodes_object.go +1 -1
  125. package/linthost/rule_names.go +14 -0
  126. package/linthost/rules_arrays.go +2 -2
  127. package/linthost/rules_boundaries.go +532 -0
  128. package/linthost/rules_camelcase.go +133 -0
  129. package/linthost/rules_complexity.go +94 -0
  130. package/linthost/rules_consistent_return.go +130 -0
  131. package/linthost/rules_console.go +1 -1
  132. package/linthost/rules_core_extra.go +739 -0
  133. package/linthost/rules_curly.go +70 -0
  134. package/linthost/rules_cypress.go +608 -0
  135. package/linthost/rules_debugger.go +2 -2
  136. package/linthost/rules_default_case.go +39 -0
  137. package/linthost/rules_default_case_last.go +46 -0
  138. package/linthost/rules_dupes.go +3 -3
  139. package/linthost/rules_empty.go +3 -3
  140. package/linthost/rules_escape.go +44 -24
  141. package/linthost/rules_eval.go +2 -2
  142. package/linthost/rules_finally.go +2 -2
  143. package/linthost/rules_format_jsdoc.go +1 -1
  144. package/linthost/rules_format_print_width.go +9 -9
  145. package/linthost/rules_format_quotes.go +1 -1
  146. package/linthost/rules_format_semi.go +1 -1
  147. package/linthost/rules_format_sort_imports.go +1 -1
  148. package/linthost/rules_format_trailing_comma.go +1 -1
  149. package/linthost/rules_functional.go +967 -0
  150. package/linthost/rules_gap.go +24 -45
  151. package/linthost/rules_grouped_accessor_pairs.go +87 -0
  152. package/linthost/rules_guard_for_in.go +198 -0
  153. package/linthost/rules_id_length.go +77 -0
  154. package/linthost/rules_imports.go +70 -2
  155. package/linthost/rules_init_declarations.go +53 -0
  156. package/linthost/rules_jest.go +618 -0
  157. package/linthost/rules_jsdoc.go +502 -0
  158. package/linthost/rules_jsx_a11y.go +1264 -0
  159. package/linthost/rules_logic.go +12 -12
  160. package/linthost/rules_loops.go +1 -1
  161. package/linthost/rules_max_classes_per_file.go +58 -0
  162. package/linthost/rules_max_depth.go +83 -0
  163. package/linthost/rules_max_lines.go +101 -0
  164. package/linthost/rules_max_lines_per_function.go +57 -0
  165. package/linthost/rules_max_nested_callbacks.go +61 -0
  166. package/linthost/rules_max_params.go +49 -0
  167. package/linthost/rules_max_statements.go +59 -0
  168. package/linthost/rules_misc.go +1 -1
  169. package/linthost/rules_nextjs.go +697 -0
  170. package/linthost/rules_no_else_return.go +75 -0
  171. package/linthost/rules_no_empty_named_blocks.go +91 -0
  172. package/linthost/rules_no_extend_native.go +51 -0
  173. package/linthost/rules_no_import_assign.go +140 -0
  174. package/linthost/rules_no_invalid_this.go +52 -0
  175. package/linthost/rules_no_loop_func.go +85 -0
  176. package/linthost/rules_no_magic_numbers.go +123 -0
  177. package/linthost/rules_no_mixed_operators.go +80 -0
  178. package/linthost/rules_no_param_reassign.go +98 -0
  179. package/linthost/rules_no_redeclare.go +270 -0
  180. package/linthost/rules_no_restricted_imports.go +105 -0
  181. package/linthost/rules_no_restricted_syntax.go +49 -0
  182. package/linthost/rules_no_shadow.go +147 -0
  183. package/linthost/rules_no_unreachable.go +77 -0
  184. package/linthost/rules_no_useless_assignment.go +120 -0
  185. package/linthost/rules_no_useless_constructor.go +245 -0
  186. package/linthost/rules_no_useless_return.go +51 -0
  187. package/linthost/rules_params.go +1 -1
  188. package/linthost/rules_playwright.go +788 -0
  189. package/linthost/rules_prefer_arrow_callback.go +124 -0
  190. package/linthost/rules_prefer_destructuring.go +98 -0
  191. package/linthost/rules_prefer_named_capture_group.go +129 -0
  192. package/linthost/rules_prefer_rest_params.go +94 -0
  193. package/linthost/rules_problems.go +41 -30
  194. package/linthost/rules_promise.go +1128 -73
  195. package/linthost/rules_protos.go +2 -2
  196. package/linthost/rules_react.go +773 -0
  197. package/linthost/rules_react_extras.go +227 -0
  198. package/linthost/rules_react_hooks.go +848 -0
  199. package/linthost/rules_react_perf.go +293 -0
  200. package/linthost/rules_react_refresh.go +583 -0
  201. package/linthost/rules_regexp.go +410 -0
  202. package/linthost/rules_security.go +830 -0
  203. package/linthost/rules_self.go +2 -2
  204. package/linthost/rules_solid.go +1073 -0
  205. package/linthost/rules_sort_imports.go +69 -0
  206. package/linthost/rules_sort_keys.go +134 -0
  207. package/linthost/rules_storybook.go +1176 -0
  208. package/linthost/rules_strings.go +4 -4
  209. package/linthost/rules_suggestions.go +38 -38
  210. package/linthost/rules_tanstack_query.go +844 -0
  211. package/linthost/rules_testing_library.go +1204 -0
  212. package/linthost/rules_throw.go +1 -1
  213. package/linthost/rules_ts.go +19 -19
  214. package/linthost/rules_ts_async.go +399 -0
  215. package/linthost/rules_ts_class_literal_property_style.go +115 -0
  216. package/linthost/rules_ts_consistent_type_exports.go +256 -0
  217. package/linthost/rules_ts_explicit_function_return_type.go +67 -0
  218. package/linthost/rules_ts_extra.go +155 -36
  219. package/linthost/rules_ts_no_base_to_string.go +218 -0
  220. package/linthost/rules_ts_no_confusing_void.go +72 -0
  221. package/linthost/rules_ts_no_deprecated.go +195 -0
  222. package/linthost/rules_ts_no_for_in_array.go +84 -0
  223. package/linthost/rules_ts_no_magic_numbers.go +124 -0
  224. package/linthost/rules_ts_no_meaningless_void_operator.go +84 -0
  225. package/linthost/rules_ts_no_misused_spread.go +104 -0
  226. package/linthost/rules_ts_no_redundant_type_constituents.go +113 -0
  227. package/linthost/rules_ts_no_restricted_types.go +62 -0
  228. package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +129 -0
  229. package/linthost/rules_ts_no_unnecessary_condition.go +250 -0
  230. package/linthost/rules_ts_no_unnecessary_qualifier.go +118 -0
  231. package/linthost/rules_ts_no_unnecessary_template_expression.go +178 -0
  232. package/linthost/rules_ts_no_unnecessary_type_arguments.go +234 -0
  233. package/linthost/rules_ts_no_unnecessary_type_assertion.go +157 -0
  234. package/linthost/rules_ts_no_unsafe_argument.go +82 -0
  235. package/linthost/rules_ts_no_unsafe_assignment.go +102 -0
  236. package/linthost/rules_ts_no_unsafe_call.go +82 -0
  237. package/linthost/rules_ts_no_unsafe_enum_comparison.go +235 -0
  238. package/linthost/rules_ts_no_unsafe_member_access.go +58 -0
  239. package/linthost/rules_ts_no_unsafe_return.go +126 -0
  240. package/linthost/rules_ts_no_unsafe_unary_minus.go +81 -0
  241. package/linthost/rules_ts_no_useless_constructor.go +52 -0
  242. package/linthost/rules_ts_non_nullable_type_assertion_style.go +108 -0
  243. package/linthost/rules_ts_parameter_properties.go +38 -0
  244. package/linthost/rules_ts_prefer_find.go +178 -0
  245. package/linthost/rules_ts_prefer_includes.go +255 -0
  246. package/linthost/rules_ts_prefer_nullish_coalescing.go +104 -0
  247. package/linthost/rules_ts_prefer_optional_chain.go +228 -0
  248. package/linthost/rules_ts_prefer_promise_reject_errors.go +176 -0
  249. package/linthost/rules_ts_prefer_readonly.go +73 -0
  250. package/linthost/rules_ts_prefer_reduce_type_parameter.go +116 -0
  251. package/linthost/rules_ts_prefer_regexp_exec.go +122 -0
  252. package/linthost/rules_ts_prefer_return_this_type.go +135 -0
  253. package/linthost/rules_ts_prefer_string_starts_ends_with.go +360 -0
  254. package/linthost/rules_ts_promise_function_async.go +77 -0
  255. package/linthost/rules_ts_related_getter_setter_pairs.go +113 -0
  256. package/linthost/rules_ts_require_array_sort_compare.go +96 -0
  257. package/linthost/rules_ts_restrict_plus_operands.go +127 -0
  258. package/linthost/rules_ts_restrict_template_expressions.go +95 -0
  259. package/linthost/rules_ts_simple.go +387 -0
  260. package/linthost/rules_ts_sort_type_constituents.go +144 -0
  261. package/linthost/rules_ts_strict_boolean_expressions.go +157 -0
  262. package/linthost/rules_ts_switch_exhaustiveness_check.go +147 -0
  263. package/linthost/rules_ts_unbound_method.go +126 -0
  264. package/linthost/rules_tsdoc.go +136 -0
  265. package/linthost/rules_unicorn_better_regex.go +27 -0
  266. package/linthost/rules_unicorn_catch_error_name.go +46 -0
  267. package/linthost/rules_unicorn_consistent_assert.go +47 -0
  268. package/linthost/rules_unicorn_consistent_date_clone.go +54 -0
  269. package/linthost/rules_unicorn_consistent_destructuring.go +25 -0
  270. package/linthost/rules_unicorn_consistent_empty_array_spread.go +62 -0
  271. package/linthost/rules_unicorn_consistent_existence_index_check.go +80 -0
  272. package/linthost/rules_unicorn_consistent_function_scoping.go +25 -0
  273. package/linthost/rules_unicorn_consistent_template_literal_escape.go +25 -0
  274. package/linthost/rules_unicorn_custom_error_definition.go +138 -0
  275. package/linthost/rules_unicorn_empty_brace_spaces.go +73 -0
  276. package/linthost/rules_unicorn_error_message.go +64 -0
  277. package/linthost/rules_unicorn_escape_case.go +51 -0
  278. package/linthost/rules_unicorn_expiring_todo_comments.go +78 -0
  279. package/linthost/rules_unicorn_explicit_length_check.go +88 -0
  280. package/linthost/rules_unicorn_filename_case.go +29 -0
  281. package/linthost/rules_unicorn_import_style.go +28 -0
  282. package/linthost/rules_unicorn_isolated_functions.go +29 -0
  283. package/linthost/rules_unicorn_new_for_builtins.go +87 -0
  284. package/linthost/rules_unicorn_no_abusive_eslint_disable.go +63 -0
  285. package/linthost/rules_unicorn_no_accessor_recursion.go +115 -0
  286. package/linthost/rules_unicorn_no_anonymous_default_export.go +74 -0
  287. package/linthost/rules_unicorn_no_array_callback_reference.go +65 -0
  288. package/linthost/rules_unicorn_no_array_for_each.go +40 -0
  289. package/linthost/rules_unicorn_no_array_method_this_argument.go +61 -0
  290. package/linthost/rules_unicorn_no_array_reduce.go +41 -0
  291. package/linthost/rules_unicorn_no_array_reverse.go +44 -0
  292. package/linthost/rules_unicorn_no_array_sort.go +43 -0
  293. package/linthost/rules_unicorn_no_await_expression_member.go +40 -0
  294. package/linthost/rules_unicorn_no_await_in_promise_methods.go +69 -0
  295. package/linthost/rules_unicorn_no_console_spaces.go +61 -0
  296. package/linthost/rules_unicorn_no_document_cookie.go +41 -0
  297. package/linthost/rules_unicorn_no_empty_file.go +44 -0
  298. package/linthost/rules_unicorn_no_for_loop.go +102 -0
  299. package/linthost/rules_unicorn_no_hex_escape.go +42 -0
  300. package/linthost/rules_unicorn_no_immediate_mutation.go +90 -0
  301. package/linthost/rules_unicorn_no_instanceof_builtins.go +66 -0
  302. package/linthost/rules_unicorn_no_invalid_fetch_options.go +79 -0
  303. package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +51 -0
  304. package/linthost/rules_unicorn_no_keyword_prefix.go +101 -0
  305. package/linthost/rules_unicorn_no_lonely_if.go +44 -0
  306. package/linthost/rules_unicorn_no_magic_array_flat_depth.go +51 -0
  307. package/linthost/rules_unicorn_no_named_default.go +54 -0
  308. package/linthost/rules_unicorn_no_negated_condition.go +85 -0
  309. package/linthost/rules_unicorn_no_negation_in_equality_check.go +50 -0
  310. package/linthost/rules_unicorn_no_nested_ternary.go +43 -0
  311. package/linthost/rules_unicorn_no_new_array.go +30 -0
  312. package/linthost/rules_unicorn_no_new_buffer.go +31 -0
  313. package/linthost/rules_unicorn_no_null.go +24 -0
  314. package/linthost/rules_unicorn_no_object_as_default_parameter.go +48 -0
  315. package/linthost/rules_unicorn_no_process_exit.go +43 -0
  316. package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +59 -0
  317. package/linthost/rules_unicorn_no_static_only_class.go +56 -0
  318. package/linthost/rules_unicorn_no_thenable.go +74 -0
  319. package/linthost/rules_unicorn_no_this_assignment.go +35 -0
  320. package/linthost/rules_unicorn_no_typeof_undefined.go +58 -0
  321. package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +49 -0
  322. package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +70 -0
  323. package/linthost/rules_unicorn_no_unnecessary_await.go +51 -0
  324. package/linthost/rules_unicorn_no_unnecessary_polyfills.go +32 -0
  325. package/linthost/rules_unicorn_no_unnecessary_slice_end.go +48 -0
  326. package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +115 -0
  327. package/linthost/rules_unicorn_no_unreadable_iife.go +50 -0
  328. package/linthost/rules_unicorn_no_unused_properties.go +30 -0
  329. package/linthost/rules_unicorn_no_useless_collection_argument.go +63 -0
  330. package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +46 -0
  331. package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +81 -0
  332. package/linthost/rules_unicorn_no_useless_iterator_to_array.go +72 -0
  333. package/linthost/rules_unicorn_no_useless_length_check.go +144 -0
  334. package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +81 -0
  335. package/linthost/rules_unicorn_no_useless_spread.go +67 -0
  336. package/linthost/rules_unicorn_no_useless_switch_case.go +55 -0
  337. package/linthost/rules_unicorn_no_useless_undefined.go +55 -0
  338. package/linthost/rules_unicorn_no_zero_fractions.go +52 -0
  339. package/linthost/rules_unicorn_number_literal_case.go +69 -0
  340. package/linthost/rules_unicorn_numeric_separators_style.go +75 -0
  341. package/linthost/rules_unicorn_prefer_add_event_listener.go +66 -0
  342. package/linthost/rules_unicorn_prefer_array_find.go +51 -0
  343. package/linthost/rules_unicorn_prefer_array_flat.go +52 -0
  344. package/linthost/rules_unicorn_prefer_array_flat_map.go +63 -0
  345. package/linthost/rules_unicorn_prefer_array_index_of.go +147 -0
  346. package/linthost/rules_unicorn_prefer_array_some.go +67 -0
  347. package/linthost/rules_unicorn_prefer_at.go +77 -0
  348. package/linthost/rules_unicorn_prefer_bigint_literals.go +77 -0
  349. package/linthost/rules_unicorn_prefer_blob_reading_methods.go +44 -0
  350. package/linthost/rules_unicorn_prefer_class_fields.go +93 -0
  351. package/linthost/rules_unicorn_prefer_classlist_toggle.go +120 -0
  352. package/linthost/rules_unicorn_prefer_code_point.go +49 -0
  353. package/linthost/rules_unicorn_prefer_date_now.go +78 -0
  354. package/linthost/rules_unicorn_prefer_default_parameters.go +144 -0
  355. package/linthost/rules_unicorn_prefer_dom_node_append.go +40 -0
  356. package/linthost/rules_unicorn_prefer_dom_node_dataset.go +55 -0
  357. package/linthost/rules_unicorn_prefer_dom_node_remove.go +41 -0
  358. package/linthost/rules_unicorn_prefer_dom_node_text_content.go +37 -0
  359. package/linthost/rules_unicorn_prefer_event_target.go +36 -0
  360. package/linthost/rules_unicorn_prefer_export_from.go +129 -0
  361. package/linthost/rules_unicorn_prefer_global_this.go +127 -0
  362. package/linthost/rules_unicorn_prefer_import_meta_properties.go +66 -0
  363. package/linthost/rules_unicorn_prefer_includes.go +149 -0
  364. package/linthost/rules_unicorn_prefer_json_parse_buffer.go +65 -0
  365. package/linthost/rules_unicorn_prefer_keyboard_event_key.go +38 -0
  366. package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +48 -0
  367. package/linthost/rules_unicorn_prefer_math_min_max.go +60 -0
  368. package/linthost/rules_unicorn_prefer_math_trunc.go +62 -0
  369. package/linthost/rules_unicorn_prefer_modern_dom_apis.go +47 -0
  370. package/linthost/rules_unicorn_prefer_modern_math_apis.go +70 -0
  371. package/linthost/rules_unicorn_prefer_module.go +50 -0
  372. package/linthost/rules_unicorn_prefer_native_coercion_functions.go +114 -0
  373. package/linthost/rules_unicorn_prefer_negative_index.go +74 -0
  374. package/linthost/rules_unicorn_prefer_node_protocol.go +122 -0
  375. package/linthost/rules_unicorn_prefer_number_properties.go +88 -0
  376. package/linthost/rules_unicorn_prefer_object_from_entries.go +55 -0
  377. package/linthost/rules_unicorn_prefer_optional_catch_binding.go +62 -0
  378. package/linthost/rules_unicorn_prefer_prototype_methods.go +54 -0
  379. package/linthost/rules_unicorn_prefer_query_selector.go +56 -0
  380. package/linthost/rules_unicorn_prefer_reflect_apply.go +36 -0
  381. package/linthost/rules_unicorn_prefer_regexp_test_rule.go +80 -0
  382. package/linthost/rules_unicorn_prefer_response_static_json.go +53 -0
  383. package/linthost/rules_unicorn_prefer_set_has.go +42 -0
  384. package/linthost/rules_unicorn_prefer_set_size.go +48 -0
  385. package/linthost/rules_unicorn_prefer_simple_condition_first.go +34 -0
  386. package/linthost/rules_unicorn_prefer_single_call.go +96 -0
  387. package/linthost/rules_unicorn_prefer_spread.go +51 -0
  388. package/linthost/rules_unicorn_prefer_string_raw.go +43 -0
  389. package/linthost/rules_unicorn_prefer_string_replace_all.go +95 -0
  390. package/linthost/rules_unicorn_prefer_string_slice.go +43 -0
  391. package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +148 -0
  392. package/linthost/rules_unicorn_prefer_string_trim_start_end.go +48 -0
  393. package/linthost/rules_unicorn_prefer_structured_clone.go +71 -0
  394. package/linthost/rules_unicorn_prefer_switch.go +103 -0
  395. package/linthost/rules_unicorn_prefer_ternary.go +71 -0
  396. package/linthost/rules_unicorn_prefer_top_level_await.go +72 -0
  397. package/linthost/rules_unicorn_prefer_type_error.go +127 -0
  398. package/linthost/rules_unicorn_prevent_abbreviations.go +127 -0
  399. package/linthost/rules_unicorn_relative_url_style.go +49 -0
  400. package/linthost/rules_unicorn_require_array_join_separator.go +45 -0
  401. package/linthost/rules_unicorn_require_module_attributes.go +54 -0
  402. package/linthost/rules_unicorn_require_module_specifiers.go +55 -0
  403. package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +43 -0
  404. package/linthost/rules_unicorn_require_post_message_target_origin.go +44 -0
  405. package/linthost/rules_unicorn_string_content.go +27 -0
  406. package/linthost/rules_unicorn_switch_case_braces.go +42 -0
  407. package/linthost/rules_unicorn_switch_case_break_position.go +31 -0
  408. package/linthost/rules_unicorn_template_indent.go +28 -0
  409. package/linthost/rules_unicorn_text_encoding_identifier_case.go +72 -0
  410. package/linthost/rules_unicorn_throw_new_error.go +61 -0
  411. package/linthost/rules_var.go +4 -4
  412. package/linthost/rules_vitest.go +568 -0
  413. package/package.json +3 -3
  414. package/plugin/main.go +49 -3
  415. package/rule/astutil/astutil.go +10 -3
  416. package/rule/rule.go +12 -10
  417. package/src/defaultFormat.ts +11 -8
  418. package/src/index.ts +40 -16
  419. package/src/structures/ITtscLintConfig.ts +12 -6
  420. package/src/structures/{ITtscLintFormatConfig.ts → ITtscLintFormat.ts} +2 -2
  421. package/src/structures/TtscLintRuleSetting.ts +55 -0
  422. package/src/structures/index.ts +3 -4
  423. package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +128 -0
  424. package/src/structures/rules/ITtscLintBoundariesRules.ts +95 -0
  425. package/src/structures/rules/ITtscLintContributorRules.ts +21 -0
  426. package/src/structures/rules/ITtscLintCoreRules.ts +1406 -0
  427. package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
  428. package/src/structures/rules/ITtscLintCypressRules.ts +145 -0
  429. package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +213 -0
  430. package/src/structures/rules/ITtscLintFunctionalRules.ts +202 -0
  431. package/src/structures/rules/ITtscLintJestRules.ts +220 -0
  432. package/src/structures/rules/ITtscLintJsdocRules.ts +153 -0
  433. package/src/structures/rules/ITtscLintJsxA11yRules.ts +339 -0
  434. package/src/structures/rules/ITtscLintNextjsRules.ts +206 -0
  435. package/src/structures/rules/ITtscLintPlaywrightRules.ts +361 -0
  436. package/src/structures/rules/ITtscLintPromiseRules.ts +205 -0
  437. package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
  438. package/src/structures/rules/ITtscLintReactPerfRules.ts +55 -0
  439. package/src/structures/rules/ITtscLintReactRuleOptions.ts +43 -0
  440. package/src/structures/rules/ITtscLintReactRules.ts +321 -0
  441. package/src/structures/rules/ITtscLintRegexpRules.ts +212 -0
  442. package/src/structures/rules/ITtscLintRuleOptionsMap.ts +89 -0
  443. package/src/structures/rules/ITtscLintRules.ts +77 -0
  444. package/src/structures/rules/ITtscLintSecurityRules.ts +162 -0
  445. package/src/structures/rules/ITtscLintSolidRules.ts +202 -0
  446. package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +23 -0
  447. package/src/structures/rules/ITtscLintStorybookRules.ts +193 -0
  448. package/src/structures/rules/ITtscLintTanstackQueryRules.ts +102 -0
  449. package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +24 -0
  450. package/src/structures/rules/ITtscLintTestingLibraryRules.ts +342 -0
  451. package/src/structures/rules/ITtscLintTypeScriptRules.ts +1230 -0
  452. package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
  453. package/src/structures/rules/ITtscLintVitestRules.ts +154 -0
  454. package/src/structures/rules/index.ts +31 -0
  455. package/lib/structures/ITtscLintFormatConfig.js.map +0 -1
  456. package/lib/structures/TtscLintRule.d.ts +0 -17
  457. package/lib/structures/TtscLintRule.js.map +0 -1
  458. package/lib/structures/TtscLintRuleMap.d.ts +0 -46
  459. package/lib/structures/TtscLintRuleMap.js.map +0 -1
  460. package/lib/structures/TtscLintRuleOptions.d.ts +0 -137
  461. package/lib/structures/TtscLintRuleOptions.js.map +0 -1
  462. package/src/structures/TtscLintRule.ts +0 -160
  463. package/src/structures/TtscLintRuleMap.ts +0 -55
  464. package/src/structures/TtscLintRuleOptions.ts +0 -151
@@ -0,0 +1,195 @@
1
+ // typescript/no-deprecated: flag references to declarations annotated
2
+ // `@deprecated` in their JSDoc. The deprecation marker is the API
3
+ // owner's signal that a binding is on its way out; callers that keep
4
+ // reaching for it accumulate work to undo later, and the rule surfaces
5
+ // the dependency at the reference site. typescript-eslint:
6
+ // https://typescript-eslint.io/rules/no-deprecated/
7
+ //
8
+ // Type-aware. The rule visits the AST kinds that name a symbol —
9
+ // bare identifiers, property-access expressions, call / new
10
+ // expressions, and JSX opening / self-closing tag names — and asks the
11
+ // Checker for the symbol at the reference location. When any of the
12
+ // symbol's declarations carries a `@deprecated` JSDoc tag (attached
13
+ // either to the declaration itself or to its declaration block — e.g.
14
+ // JSDoc on a VariableStatement covers the inner VariableDeclaration),
15
+ // the rule reports at the reference with the deprecation comment when
16
+ // one is present.
17
+ //
18
+ // To avoid double-firing and silencing the deprecation site itself:
19
+ //
20
+ // - identifiers at a declaration-name position (`function foo`,
21
+ // `const foo`, `class Foo`, …) are skipped — they are the marker,
22
+ // not a reference;
23
+ // - the bare-identifier arm reports the canonical reference position
24
+ // for property-access tails, JSX tag names, and call / new callees,
25
+ // so the CallExpression, NewExpression, PropertyAccessExpression,
26
+ // and JSX-element arms register only to keep the rule honest about
27
+ // what it inspects — they don't report a second time.
28
+ package linthost
29
+
30
+ import (
31
+ "strings"
32
+
33
+ shimast "github.com/microsoft/typescript-go/shim/ast"
34
+ )
35
+
36
+ type noDeprecated struct{}
37
+
38
+ func (noDeprecated) Name() string { return "typescript/no-deprecated" }
39
+ func (noDeprecated) NeedsTypeChecker() bool {
40
+ return true
41
+ }
42
+ func (noDeprecated) Visits() []shimast.Kind {
43
+ return []shimast.Kind{
44
+ shimast.KindIdentifier,
45
+ shimast.KindPropertyAccessExpression,
46
+ shimast.KindCallExpression,
47
+ shimast.KindNewExpression,
48
+ shimast.KindJsxOpeningElement,
49
+ shimast.KindJsxSelfClosingElement,
50
+ }
51
+ }
52
+ func (noDeprecated) Check(ctx *Context, node *shimast.Node) {
53
+ if ctx.Checker == nil {
54
+ return
55
+ }
56
+ // All non-identifier kinds delegate to the identifier walk for
57
+ // reporting — they're listed in Visits() to keep the contract
58
+ // explicit about which structural shapes carry symbol references,
59
+ // but the actual diagnostic is emitted once per identifier so a
60
+ // chain like `obj.method()` reports the `method` identifier, not
61
+ // the surrounding PropertyAccess and CallExpression as well.
62
+ if node.Kind != shimast.KindIdentifier {
63
+ return
64
+ }
65
+ if noDeprecatedSkipIdentifier(node) {
66
+ return
67
+ }
68
+ symbol := ctx.Checker.GetSymbolAtLocation(node)
69
+ if symbol == nil {
70
+ return
71
+ }
72
+ tag := findDeprecatedJSDocTag(symbol)
73
+ if tag == nil {
74
+ return
75
+ }
76
+ // Don't report when this identifier IS the name of one of the
77
+ // symbol's declarations — that's the deprecation marker itself.
78
+ if noDeprecatedLocationIsDeclarationName(node, symbol) {
79
+ return
80
+ }
81
+ name := identifierText(node)
82
+ if name == "" {
83
+ name = symbol.Name
84
+ }
85
+ message := "`" + name + "` is deprecated."
86
+ if comment := jsdocDeprecatedComment(tag); comment != "" {
87
+ message = message + " " + comment
88
+ }
89
+ ctx.Report(node, message)
90
+ }
91
+
92
+ // noDeprecatedSkipIdentifier reports whether an identifier visit
93
+ // should be skipped. The skipped positions are:
94
+ //
95
+ // - the LHS of a QualifiedName (`A.B` — only `B` resolves to the
96
+ // referenced symbol).
97
+ //
98
+ // The general "is this identifier the declaration name?" gate is
99
+ // applied later against the resolved symbol's declarations — see
100
+ // `noDeprecatedLocationIsDeclarationName` — which handles every
101
+ // declaration kind without enumerating each one here.
102
+ func noDeprecatedSkipIdentifier(node *shimast.Node) bool {
103
+ parent := node.Parent
104
+ if parent == nil {
105
+ return false
106
+ }
107
+ if parent.Kind == shimast.KindQualifiedName {
108
+ qn := parent.AsQualifiedName()
109
+ if qn != nil && qn.Left == node {
110
+ return true
111
+ }
112
+ }
113
+ return false
114
+ }
115
+
116
+ // noDeprecatedLocationIsDeclarationName reports whether `loc` is the
117
+ // name node of one of `symbol`'s declarations — i.e. the deprecation
118
+ // marker itself rather than a reference site.
119
+ func noDeprecatedLocationIsDeclarationName(loc *shimast.Node, symbol *shimast.Symbol) bool {
120
+ if loc == nil || symbol == nil {
121
+ return false
122
+ }
123
+ for _, decl := range symbol.Declarations {
124
+ if decl == nil {
125
+ continue
126
+ }
127
+ if decl.Name() == loc {
128
+ return true
129
+ }
130
+ }
131
+ return false
132
+ }
133
+
134
+ // findDeprecatedJSDocTag walks the symbol's declarations for a
135
+ // `@deprecated` JSDoc tag and returns the first one found. The walk
136
+ // climbs each declaration's ancestors up to the SourceFile because
137
+ // JSDoc on a VariableDeclaration is attached to the enclosing
138
+ // VariableStatement, and JSDoc on an ExportSpecifier may be on the
139
+ // outer ExportDeclaration.
140
+ func findDeprecatedJSDocTag(symbol *shimast.Symbol) *shimast.Node {
141
+ if symbol == nil {
142
+ return nil
143
+ }
144
+ for _, decl := range symbol.Declarations {
145
+ if tag := deprecatedJSDocTagOnNodeOrAncestors(decl); tag != nil {
146
+ return tag
147
+ }
148
+ }
149
+ return nil
150
+ }
151
+
152
+ // deprecatedJSDocTagOnNodeOrAncestors walks up from `node` looking for
153
+ // a `@deprecated` JSDoc tag attached to any ancestor. Returns the
154
+ // first matching tag, or nil.
155
+ func deprecatedJSDocTagOnNodeOrAncestors(node *shimast.Node) *shimast.Node {
156
+ for n := node; n != nil; n = n.Parent {
157
+ for _, jsdoc := range n.JSDoc(nil) {
158
+ data := jsdoc.AsJSDoc()
159
+ if data == nil || data.Tags == nil {
160
+ continue
161
+ }
162
+ for _, tag := range data.Tags.Nodes {
163
+ if tag.Kind == shimast.KindJSDocDeprecatedTag {
164
+ return tag
165
+ }
166
+ }
167
+ }
168
+ if n.Kind == shimast.KindSourceFile {
169
+ return nil
170
+ }
171
+ }
172
+ return nil
173
+ }
174
+
175
+ // jsdocDeprecatedComment returns the textual comment that follows the
176
+ // `@deprecated` token in `tag`'s source range, trimmed of surrounding
177
+ // whitespace. Empty when the tag has no comment.
178
+ func jsdocDeprecatedComment(tag *shimast.Node) string {
179
+ if tag == nil {
180
+ return ""
181
+ }
182
+ src := strings.TrimSpace(shimast.NodeText(tag))
183
+ if src == "" {
184
+ return ""
185
+ }
186
+ const prefix = "@deprecated"
187
+ if strings.HasPrefix(src, prefix) {
188
+ src = src[len(prefix):]
189
+ }
190
+ return strings.TrimSpace(src)
191
+ }
192
+
193
+ func init() {
194
+ Register(noDeprecated{})
195
+ }
@@ -0,0 +1,84 @@
1
+ // typescript/no-for-in-array: `for (const k in arr)` iterates the
2
+ // enumerable property NAMES of `arr` — including inherited members and any
3
+ // custom properties someone has attached to `Array.prototype` — and yields
4
+ // them as strings, not as numeric indices. The author almost always meant
5
+ // `for...of` (values) or a plain index loop (numeric keys). typescript-eslint:
6
+ // https://typescript-eslint.io/rules/no-for-in-array/
7
+ package linthost
8
+
9
+ import (
10
+ shimast "github.com/microsoft/typescript-go/shim/ast"
11
+ shimchecker "github.com/microsoft/typescript-go/shim/checker"
12
+ )
13
+
14
+ // noForInArray fires on `for (... in <expr>)` when the Checker reports that
15
+ // `<expr>` is an array or tuple type. Type-aware: without a Checker the rule
16
+ // cannot tell an array from a plain record-shaped object, so it bails to
17
+ // avoid false positives. The constituent-recursion shape mirrors
18
+ // `requireArraySortCompareIsArrayLike` — a union like `number[] | string[]`
19
+ // is still array-like because every constituent is.
20
+ type noForInArray struct{}
21
+
22
+ func (noForInArray) Name() string { return "typescript/no-for-in-array" }
23
+ func (noForInArray) NeedsTypeChecker() bool {
24
+ return true
25
+ }
26
+ func (noForInArray) Visits() []shimast.Kind {
27
+ return []shimast.Kind{shimast.KindForInStatement}
28
+ }
29
+ func (noForInArray) Check(ctx *Context, node *shimast.Node) {
30
+ if ctx.Checker == nil {
31
+ return
32
+ }
33
+ stmt := node.AsForInOrOfStatement()
34
+ if stmt == nil || stmt.Expression == nil {
35
+ return
36
+ }
37
+ t := ctx.Checker.GetTypeAtLocation(stmt.Expression)
38
+ if t == nil {
39
+ return
40
+ }
41
+ if !noForInArrayIsArrayLike(ctx.Checker, t) {
42
+ return
43
+ }
44
+ ctx.Report(node, "Iterating an array with `for...in` yields enumerable property names (as strings), including inherited members. Use `for...of`, `forEach`, or an indexed `for` loop instead.")
45
+ }
46
+
47
+ // noForInArrayIsArrayLike reports whether t is provably an array or tuple.
48
+ // Mirrors `requireArraySortCompareIsArrayLike`: recurse into union /
49
+ // intersection constituents and consider the whole type array-like only when
50
+ // every constituent is. `any` / `unknown` / `never` are intentionally NOT
51
+ // treated as array-like — they leak from generic helpers and would explode
52
+ // the false-positive volume on otherwise legitimate `for...in` over a
53
+ // genuinely-keyed object.
54
+ func noForInArrayIsArrayLike(checker *shimchecker.Checker, t *shimchecker.Type) bool {
55
+ if checker == nil || t == nil {
56
+ return false
57
+ }
58
+ flags := t.Flags()
59
+ if flags&(shimchecker.TypeFlagsAny|shimchecker.TypeFlagsUnknown|shimchecker.TypeFlagsNever) != 0 {
60
+ return false
61
+ }
62
+ if flags&(shimchecker.TypeFlagsUnion|shimchecker.TypeFlagsIntersection) != 0 {
63
+ for _, part := range t.Types() {
64
+ if part == nil {
65
+ continue
66
+ }
67
+ if !noForInArrayIsArrayLike(checker, part) {
68
+ return false
69
+ }
70
+ }
71
+ return true
72
+ }
73
+ if shimchecker.Checker_isArrayType(checker, t) {
74
+ return true
75
+ }
76
+ if shimchecker.IsTupleType(t) {
77
+ return true
78
+ }
79
+ return false
80
+ }
81
+
82
+ func init() {
83
+ Register(noForInArray{})
84
+ }
@@ -0,0 +1,124 @@
1
+ // typescript/no-magic-numbers: TS-aware extension of the core
2
+ // `no-magic-numbers` rule. Numeric literals that appear inline in
3
+ // expressions tend to be unexplained constants — `if (count > 86400)`
4
+ // is opaque, `if (count > SECONDS_PER_DAY)` is not. The rule asks the
5
+ // author to lift those values into a named constant or enum.
6
+ // typescript-eslint:
7
+ // https://typescript-eslint.io/rules/no-magic-numbers/
8
+ //
9
+ // AST-only. The trigger is a `KindNumericLiteral` (or a numeric literal
10
+ // wrapped in a unary `+` / `-`). The TS variant differs from the core
11
+ // rule in one detail that this implementation enforces: numeric
12
+ // literals used as enum member initializers are NOT magic — an
13
+ // `enum Status { OK = 200 }` declaration IS the lifting step the rule
14
+ // pushes authors toward, so flagging the `200` would be backwards.
15
+ //
16
+ // Type-position numeric literals are also skipped: a literal that
17
+ // appears inside a `KindLiteralType` (e.g. `type N = 5`) is a type, not
18
+ // a runtime constant, and the rule's concern is runtime magic numbers.
19
+ // The well-known unit values `-1`, `0`, and `1` pass through because
20
+ // they almost always carry intrinsic meaning (sentinel, identity,
21
+ // step) and treating them as magic produces only noise.
22
+ package linthost
23
+
24
+ import (
25
+ shimast "github.com/microsoft/typescript-go/shim/ast"
26
+ )
27
+
28
+ type tsNoMagicNumbers struct{}
29
+
30
+ func (tsNoMagicNumbers) Name() string { return "typescript/no-magic-numbers" }
31
+ func (tsNoMagicNumbers) Visits() []shimast.Kind {
32
+ return []shimast.Kind{shimast.KindNumericLiteral}
33
+ }
34
+ func (tsNoMagicNumbers) Check(ctx *Context, node *shimast.Node) {
35
+ if node == nil {
36
+ return
37
+ }
38
+ // Identify the surface node that represents the numeric value:
39
+ // either the literal itself or the wrapping `+lit` / `-lit` unary.
40
+ surface := node
41
+ if parent := node.Parent; parent != nil && parent.Kind == shimast.KindPrefixUnaryExpression {
42
+ prefix := parent.AsPrefixUnaryExpression()
43
+ if prefix != nil && (prefix.Operator == shimast.KindMinusToken || prefix.Operator == shimast.KindPlusToken) && prefix.Operand == node {
44
+ surface = parent
45
+ }
46
+ }
47
+ // Skip when the literal lives inside a type position. A literal type
48
+ // (`type N = 5`, `Array<10>`) is not a runtime constant — the
49
+ // rule's concern is unexplained runtime values.
50
+ if isInsideTypePosition(surface) {
51
+ return
52
+ }
53
+ // TS extension: enum member initializers are themselves the named
54
+ // constant the rule is asking for. `enum S { OK = 200 }` lifts the
55
+ // value into `S.OK`; flagging the `200` would push authors to
56
+ // double-wrap an already-named constant.
57
+ if isEnumMemberInitializer(surface) {
58
+ return
59
+ }
60
+ // Whitelisted unit values: -1 / 0 / 1 carry intrinsic meaning (not
61
+ // found, identity, step) in almost every codebase. Treating them as
62
+ // magic produces only noise.
63
+ if isWellKnownUnitNumber(ctx.File, surface) {
64
+ return
65
+ }
66
+ ctx.Report(surface, "No magic number: extract into a named constant or enum member.")
67
+ }
68
+
69
+ // isEnumMemberInitializer reports whether surface is the initializer
70
+ // expression of an enum member (`enum X { A = 1 }`). The literal node
71
+ // itself (or its unary wrapper) is the EnumMember.Initializer in that
72
+ // case, which is exactly the position the TS extension whitelists.
73
+ func isEnumMemberInitializer(surface *shimast.Node) bool {
74
+ parent := surface.Parent
75
+ if parent == nil || parent.Kind != shimast.KindEnumMember {
76
+ return false
77
+ }
78
+ member := parent.AsEnumMember()
79
+ return member != nil && member.Initializer == surface
80
+ }
81
+
82
+ // isInsideTypePosition reports whether `surface` is reached only
83
+ // through type-syntax ancestors before hitting a value-bearing node.
84
+ // Literal types, type arguments, and type aliases are type positions;
85
+ // the rule has nothing to say about literals that never reach runtime.
86
+ func isInsideTypePosition(surface *shimast.Node) bool {
87
+ for p := surface.Parent; p != nil; p = p.Parent {
88
+ switch p.Kind {
89
+ case shimast.KindLiteralType,
90
+ shimast.KindTypeReference,
91
+ shimast.KindTypeAliasDeclaration,
92
+ shimast.KindUnionType,
93
+ shimast.KindIntersectionType,
94
+ shimast.KindTypeOperator,
95
+ shimast.KindIndexedAccessType,
96
+ shimast.KindMappedType,
97
+ shimast.KindConditionalType,
98
+ shimast.KindTypeParameter:
99
+ return true
100
+ case shimast.KindPrefixUnaryExpression,
101
+ shimast.KindParenthesizedExpression:
102
+ continue
103
+ }
104
+ return false
105
+ }
106
+ return false
107
+ }
108
+
109
+ // isWellKnownUnitNumber reports whether `surface` is the literal `0`,
110
+ // `1`, or `-1`. The match is on source text to keep handling of `0.0`
111
+ // vs `0` and `1e0` vs `1` consistent with what the author actually
112
+ // wrote — only the bare textual form is whitelisted.
113
+ func isWellKnownUnitNumber(file *shimast.SourceFile, surface *shimast.Node) bool {
114
+ text := nodeText(file, surface)
115
+ switch text {
116
+ case "0", "1", "-1":
117
+ return true
118
+ }
119
+ return false
120
+ }
121
+
122
+ func init() {
123
+ Register(tsNoMagicNumbers{})
124
+ }
@@ -0,0 +1,84 @@
1
+ // typescript/no-meaningless-void-operator reports `void X` where the
2
+ // operand `X` is already statically typed `void`. The `void` operator
3
+ // always evaluates to `undefined`; if the operand was going to produce
4
+ // `undefined` anyway, the operator adds nothing and obscures the
5
+ // intent. The most common shape is `void someVoidReturningCall()`
6
+ // somewhere a `void` discard would be useful for a non-void operand
7
+ // (e.g. fire-and-forget Promise) — but a `void`-typed operand is
8
+ // already discarded.
9
+ // https://typescript-eslint.io/rules/no-meaningless-void-operator/
10
+ //
11
+ // Type-aware. Without a Checker the rule cannot tell `void` from any
12
+ // other type, so Context.Checker == nil short-circuits the Check to a
13
+ // no-op the way the other type-aware rules do. The upstream
14
+ // `checkNever` option is left at its default of `false`: only the
15
+ // `void` operand triggers, `never` does not.
16
+ package linthost
17
+
18
+ import (
19
+ shimast "github.com/microsoft/typescript-go/shim/ast"
20
+ shimchecker "github.com/microsoft/typescript-go/shim/checker"
21
+ )
22
+
23
+ type noMeaninglessVoidOperator struct{}
24
+
25
+ func (noMeaninglessVoidOperator) Name() string {
26
+ return "typescript/no-meaningless-void-operator"
27
+ }
28
+ func (noMeaninglessVoidOperator) NeedsTypeChecker() bool { return true }
29
+ func (noMeaninglessVoidOperator) Visits() []shimast.Kind {
30
+ return []shimast.Kind{shimast.KindVoidExpression}
31
+ }
32
+ func (noMeaninglessVoidOperator) Check(ctx *Context, node *shimast.Node) {
33
+ if ctx.Checker == nil {
34
+ return
35
+ }
36
+ expr := node.AsVoidExpression()
37
+ if expr == nil || expr.Expression == nil {
38
+ return
39
+ }
40
+ operand := stripParens(expr.Expression)
41
+ if operand == nil {
42
+ return
43
+ }
44
+ t := ctx.Checker.GetTypeAtLocation(operand)
45
+ if t == nil {
46
+ return
47
+ }
48
+ if !isVoidOnlyType(t) {
49
+ return
50
+ }
51
+ ctx.Report(node, "The `void` operator on a value already typed `void` adds nothing — drop the operator.")
52
+ }
53
+
54
+ // isVoidOnlyType reports whether t is the bare `void` type or a union
55
+ // composed entirely of `void` constituents. The upstream rule fires
56
+ // only when the operand carries no non-void member; a mixed `void |
57
+ // number` operand still needs the operator to discard the runtime
58
+ // value, so it is left alone.
59
+ func isVoidOnlyType(t *shimchecker.Type) bool {
60
+ if t == nil {
61
+ return false
62
+ }
63
+ flags := t.Flags()
64
+ if flags&shimchecker.TypeFlagsVoid != 0 {
65
+ return true
66
+ }
67
+ if flags&shimchecker.TypeFlagsUnion != 0 {
68
+ parts := t.Types()
69
+ if len(parts) == 0 {
70
+ return false
71
+ }
72
+ for _, part := range parts {
73
+ if !isVoidOnlyType(part) {
74
+ return false
75
+ }
76
+ }
77
+ return true
78
+ }
79
+ return false
80
+ }
81
+
82
+ func init() {
83
+ Register(noMeaninglessVoidOperator{})
84
+ }
@@ -0,0 +1,104 @@
1
+ // AST-only subset of the upstream `typescript/no-misused-spread` rule.
2
+ //
3
+ // The full upstream rule needs the type checker to decide whether the
4
+ // spread operand is actually iterable (or a plain object). This subset
5
+ // catches the three syntactic shapes that are unambiguously wrong even
6
+ // without type information:
7
+ //
8
+ // 1. Object literal spread inside an array literal — `[...{ a: 1 }]`.
9
+ // Object literals are not iterable, so this is always a TypeError
10
+ // at runtime.
11
+ // 2. Object literal spread as a call/construct argument —
12
+ // `f(...{ a: 1 })`, `new Set(...{ a: 1 })`. Same reason: the
13
+ // callee receives the spread via iteration.
14
+ // 3. Array literal spread inside an object literal — `{ ...[1, 2] }`.
15
+ // The array's numeric indices become string keys (`"0"`, `"1"`,
16
+ // …) which is almost never what the author intended.
17
+ //
18
+ // https://typescript-eslint.io/rules/no-misused-spread/
19
+ package linthost
20
+
21
+ import (
22
+ shimast "github.com/microsoft/typescript-go/shim/ast"
23
+ )
24
+
25
+ type noMisusedSpread struct{}
26
+
27
+ func (noMisusedSpread) Name() string { return "typescript/no-misused-spread" }
28
+ func (noMisusedSpread) Visits() []shimast.Kind {
29
+ return []shimast.Kind{
30
+ shimast.KindArrayLiteralExpression,
31
+ shimast.KindObjectLiteralExpression,
32
+ shimast.KindCallExpression,
33
+ shimast.KindNewExpression,
34
+ }
35
+ }
36
+ func (noMisusedSpread) Check(ctx *Context, node *shimast.Node) {
37
+ switch node.Kind {
38
+ case shimast.KindArrayLiteralExpression:
39
+ arr := node.AsArrayLiteralExpression()
40
+ if arr == nil || arr.Elements == nil {
41
+ return
42
+ }
43
+ for _, elem := range arr.Elements.Nodes {
44
+ reportObjectSpreadInIterable(ctx, elem)
45
+ }
46
+ case shimast.KindCallExpression:
47
+ call := node.AsCallExpression()
48
+ if call == nil || call.Arguments == nil {
49
+ return
50
+ }
51
+ for _, arg := range call.Arguments.Nodes {
52
+ reportObjectSpreadInIterable(ctx, arg)
53
+ }
54
+ case shimast.KindNewExpression:
55
+ ne := node.AsNewExpression()
56
+ if ne == nil || ne.Arguments == nil {
57
+ return
58
+ }
59
+ for _, arg := range ne.Arguments.Nodes {
60
+ reportObjectSpreadInIterable(ctx, arg)
61
+ }
62
+ case shimast.KindObjectLiteralExpression:
63
+ obj := node.AsObjectLiteralExpression()
64
+ if obj == nil || obj.Properties == nil {
65
+ return
66
+ }
67
+ for _, prop := range obj.Properties.Nodes {
68
+ if prop == nil || prop.Kind != shimast.KindSpreadAssignment {
69
+ continue
70
+ }
71
+ spread := prop.AsSpreadAssignment()
72
+ if spread == nil {
73
+ continue
74
+ }
75
+ inner := stripParens(spread.Expression)
76
+ if inner != nil && inner.Kind == shimast.KindArrayLiteralExpression {
77
+ ctx.Report(prop, "Spreading an array literal into an object literal coerces numeric indices to string keys — likely a mistake.")
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ // reportObjectSpreadInIterable reports the spread element when its
84
+ // operand is an object literal in a position that consumes the spread
85
+ // via iteration (array literal element or function/constructor
86
+ // argument).
87
+ func reportObjectSpreadInIterable(ctx *Context, elem *shimast.Node) {
88
+ if elem == nil || elem.Kind != shimast.KindSpreadElement {
89
+ return
90
+ }
91
+ spread := elem.AsSpreadElement()
92
+ if spread == nil {
93
+ return
94
+ }
95
+ inner := stripParens(spread.Expression)
96
+ if inner == nil || inner.Kind != shimast.KindObjectLiteralExpression {
97
+ return
98
+ }
99
+ ctx.Report(elem, "Spread of an object literal into an iterable context is meaningless — object literals are not iterable.")
100
+ }
101
+
102
+ func init() {
103
+ Register(noMisusedSpread{})
104
+ }