@ttsc/lint 0.13.1 → 0.14.0-dev.20260528.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,114 @@
1
+ // unicorn/prefer-native-coercion-functions: an arrow that does nothing
2
+ // but pass its parameter to `String` / `Number` / `Boolean` / `BigInt`
3
+ // / `Symbol` is a wrapper around a function that already has the same
4
+ // signature. Passing the built-in reference directly drops a closure
5
+ // allocation, a stack frame, and a layer of indirection at every call
6
+ // site while reading as the operation it actually performs.
7
+ //
8
+ // AST-only: visit `KindArrowFunction` and `KindFunctionExpression`. Fire
9
+ // when the function takes exactly one bare-identifier parameter AND its
10
+ // body is either an arrow expression body that calls one of the named
11
+ // constructors with the parameter as the sole argument, or a block body
12
+ // with a single `return <Name>(<param>);` statement.
13
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-native-coercion-functions.md
14
+ package linthost
15
+
16
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
17
+
18
+ type unicornPreferNativeCoercionFunctions struct{}
19
+
20
+ func (unicornPreferNativeCoercionFunctions) Name() string {
21
+ return "unicorn/prefer-native-coercion-functions"
22
+ }
23
+ func (unicornPreferNativeCoercionFunctions) Visits() []shimast.Kind {
24
+ return []shimast.Kind{shimast.KindArrowFunction, shimast.KindFunctionExpression}
25
+ }
26
+ func (unicornPreferNativeCoercionFunctions) Check(ctx *Context, node *shimast.Node) {
27
+ params := node.Parameters()
28
+ if len(params) != 1 {
29
+ return
30
+ }
31
+ paramName := parameterIdentifierName(params[0])
32
+ if paramName == "" {
33
+ return
34
+ }
35
+ var body *shimast.Node
36
+ switch node.Kind {
37
+ case shimast.KindArrowFunction:
38
+ if arrow := node.AsArrowFunction(); arrow != nil {
39
+ body = arrow.Body
40
+ }
41
+ case shimast.KindFunctionExpression:
42
+ if fn := node.AsFunctionExpression(); fn != nil {
43
+ body = fn.Body
44
+ }
45
+ }
46
+ if body == nil {
47
+ return
48
+ }
49
+ call := unicornPreferNativeCoercionBodyCall(body)
50
+ if call == nil {
51
+ return
52
+ }
53
+ if !unicornPreferNativeCoercionIsCoercion(call, paramName) {
54
+ return
55
+ }
56
+ ctx.Report(node, "Use the bare `String` / `Number` / `Boolean` / `BigInt` function reference instead of an arrow wrapper.")
57
+ }
58
+
59
+ // unicornPreferNativeCoercionBodyCall normalizes a function body to the
60
+ // inner `CallExpression`. A concise arrow body returns its expression
61
+ // directly; a block body must contain exactly one `return <expr>;` and
62
+ // the returned expression must itself be a call.
63
+ func unicornPreferNativeCoercionBodyCall(body *shimast.Node) *shimast.Node {
64
+ if body == nil {
65
+ return nil
66
+ }
67
+ if body.Kind != shimast.KindBlock {
68
+ expr := stripParens(body)
69
+ if expr == nil || expr.Kind != shimast.KindCallExpression {
70
+ return nil
71
+ }
72
+ return expr
73
+ }
74
+ block := body.AsBlock()
75
+ if block == nil || block.Statements == nil || len(block.Statements.Nodes) != 1 {
76
+ return nil
77
+ }
78
+ stmt := block.Statements.Nodes[0]
79
+ if stmt == nil || stmt.Kind != shimast.KindReturnStatement {
80
+ return nil
81
+ }
82
+ ret := stmt.AsReturnStatement()
83
+ if ret == nil || ret.Expression == nil {
84
+ return nil
85
+ }
86
+ expr := stripParens(ret.Expression)
87
+ if expr == nil || expr.Kind != shimast.KindCallExpression {
88
+ return nil
89
+ }
90
+ return expr
91
+ }
92
+
93
+ // unicornPreferNativeCoercionIsCoercion reports whether `call` is a
94
+ // `String|Number|Boolean|BigInt|Symbol(<param>)` invocation where the
95
+ // single argument is the parameter identifier.
96
+ func unicornPreferNativeCoercionIsCoercion(call *shimast.Node, paramName string) bool {
97
+ c := call.AsCallExpression()
98
+ if c == nil || c.Expression == nil {
99
+ return false
100
+ }
101
+ switch identifierText(c.Expression) {
102
+ case "String", "Number", "Boolean", "BigInt", "Symbol":
103
+ default:
104
+ return false
105
+ }
106
+ if c.Arguments == nil || len(c.Arguments.Nodes) != 1 {
107
+ return false
108
+ }
109
+ return identifierText(stripParens(c.Arguments.Nodes[0])) == paramName
110
+ }
111
+
112
+ func init() {
113
+ Register(unicornPreferNativeCoercionFunctions{})
114
+ }
@@ -0,0 +1,74 @@
1
+ // unicorn/prefer-negative-index: `arr.slice(arr.length - N)` is the
2
+ // long-hand spelling of `arr.slice(-N)`. The subtraction repeats the
3
+ // receiver, allocates an extra read, and obscures the intent. The same
4
+ // idiom shows up across `slice`, `splice`, `toSpliced`, `at`, and
5
+ // `lastIndexOf`; all five accept a negative index that means the same
6
+ // thing the subtraction expresses, so the rule pushes authors there.
7
+ //
8
+ // AST-only: visit `KindCallExpression`. Fire when the callee is
9
+ // `PropertyAccess(_, name)` for one of those five method names AND the
10
+ // first argument is a `KindBinaryExpression` with operator `-`, LHS a
11
+ // `PropertyAccess(_, length)`, and RHS a positive numeric literal.
12
+ // Reports on the offending argument so the diagnostic anchors to the
13
+ // expression the author would rewrite.
14
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-negative-index.md
15
+ package linthost
16
+
17
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
18
+
19
+ type unicornPreferNegativeIndex struct{}
20
+
21
+ func (unicornPreferNegativeIndex) Name() string { return "unicorn/prefer-negative-index" }
22
+ func (unicornPreferNegativeIndex) Visits() []shimast.Kind {
23
+ return []shimast.Kind{shimast.KindCallExpression}
24
+ }
25
+ func (unicornPreferNegativeIndex) Check(ctx *Context, node *shimast.Node) {
26
+ call := node.AsCallExpression()
27
+ if call == nil || call.Expression == nil {
28
+ return
29
+ }
30
+ if call.Expression.Kind != shimast.KindPropertyAccessExpression {
31
+ return
32
+ }
33
+ access := call.Expression.AsPropertyAccessExpression()
34
+ if access == nil {
35
+ return
36
+ }
37
+ switch identifierText(access.Name()) {
38
+ case "slice", "splice", "toSpliced", "at", "lastIndexOf":
39
+ default:
40
+ return
41
+ }
42
+ if call.Arguments == nil || len(call.Arguments.Nodes) == 0 {
43
+ return
44
+ }
45
+ first := stripParens(call.Arguments.Nodes[0])
46
+ if first == nil || first.Kind != shimast.KindBinaryExpression {
47
+ return
48
+ }
49
+ bin := first.AsBinaryExpression()
50
+ if bin == nil || bin.OperatorToken == nil ||
51
+ bin.OperatorToken.Kind != shimast.KindMinusToken {
52
+ return
53
+ }
54
+ left := stripParens(bin.Left)
55
+ if left == nil || left.Kind != shimast.KindPropertyAccessExpression {
56
+ return
57
+ }
58
+ prop := left.AsPropertyAccessExpression()
59
+ if prop == nil || identifierText(prop.Name()) != "length" {
60
+ return
61
+ }
62
+ right := stripParens(bin.Right)
63
+ if right == nil || right.Kind != shimast.KindNumericLiteral {
64
+ return
65
+ }
66
+ if !unicornPreferAtIsPositiveInteger(numericLiteralText(right)) {
67
+ return
68
+ }
69
+ ctx.Report(first, "Use a negative index (`-N`) instead of `arr.length - N`.")
70
+ }
71
+
72
+ func init() {
73
+ Register(unicornPreferNegativeIndex{})
74
+ }
@@ -0,0 +1,122 @@
1
+ // unicorn/prefer-node-protocol: the bare Node built-in specifier
2
+ // (`import "fs"` / `require("fs")`) is ambiguous — a userland package
3
+ // named `fs` on the module path resolves first, silently hijacking
4
+ // what readers assume is the Node built-in. The `node:` prefix removes
5
+ // the ambiguity and is supported by every modern Node release.
6
+ //
7
+ // AST-only: visit `ImportDeclaration` for the static-import case and
8
+ // `CallExpression` for the `require(...)` case. Both reduce to a
9
+ // single string-literal specifier compared against the allowlist of
10
+ // Node built-in module names; matching specifiers (without the
11
+ // `node:` prefix) fire on the literal node itself so the diagnostic
12
+ // underlines the specifier text the reader needs to change.
13
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-node-protocol.md
14
+ package linthost
15
+
16
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
17
+
18
+ // unicornPreferNodeProtocolBuiltins enumerates the bare Node built-in
19
+ // module specifiers that must be rewritten to use the `node:` prefix.
20
+ var unicornPreferNodeProtocolBuiltins = map[string]struct{}{
21
+ "assert": {},
22
+ "assert/strict": {},
23
+ "async_hooks": {},
24
+ "buffer": {},
25
+ "child_process": {},
26
+ "cluster": {},
27
+ "console": {},
28
+ "constants": {},
29
+ "crypto": {},
30
+ "dgram": {},
31
+ "diagnostics_channel": {},
32
+ "dns": {},
33
+ "dns/promises": {},
34
+ "domain": {},
35
+ "events": {},
36
+ "fs": {},
37
+ "fs/promises": {},
38
+ "http": {},
39
+ "http2": {},
40
+ "https": {},
41
+ "inspector": {},
42
+ "module": {},
43
+ "net": {},
44
+ "os": {},
45
+ "path": {},
46
+ "path/posix": {},
47
+ "path/win32": {},
48
+ "perf_hooks": {},
49
+ "process": {},
50
+ "punycode": {},
51
+ "querystring": {},
52
+ "readline": {},
53
+ "readline/promises": {},
54
+ "repl": {},
55
+ "stream": {},
56
+ "stream/consumers": {},
57
+ "stream/promises": {},
58
+ "stream/web": {},
59
+ "string_decoder": {},
60
+ "sys": {},
61
+ "timers": {},
62
+ "timers/promises": {},
63
+ "tls": {},
64
+ "trace_events": {},
65
+ "tty": {},
66
+ "url": {},
67
+ "util": {},
68
+ "util/types": {},
69
+ "v8": {},
70
+ "vm": {},
71
+ "wasi": {},
72
+ "worker_threads": {},
73
+ "zlib": {},
74
+ }
75
+
76
+ type unicornPreferNodeProtocol struct{}
77
+
78
+ func (unicornPreferNodeProtocol) Name() string { return "unicorn/prefer-node-protocol" }
79
+ func (unicornPreferNodeProtocol) Visits() []shimast.Kind {
80
+ return []shimast.Kind{shimast.KindImportDeclaration, shimast.KindCallExpression}
81
+ }
82
+ func (unicornPreferNodeProtocol) Check(ctx *Context, node *shimast.Node) {
83
+ switch node.Kind {
84
+ case shimast.KindImportDeclaration:
85
+ imp := node.AsImportDeclaration()
86
+ if imp == nil || imp.ModuleSpecifier == nil {
87
+ return
88
+ }
89
+ if imp.ModuleSpecifier.Kind != shimast.KindStringLiteral {
90
+ return
91
+ }
92
+ specifier := stringLiteralText(imp.ModuleSpecifier)
93
+ if _, ok := unicornPreferNodeProtocolBuiltins[specifier]; !ok {
94
+ return
95
+ }
96
+ ctx.Report(imp.ModuleSpecifier, "Prefer `node:` protocol when importing Node built-ins.")
97
+ case shimast.KindCallExpression:
98
+ call := node.AsCallExpression()
99
+ if call == nil || call.Expression == nil {
100
+ return
101
+ }
102
+ if identifierText(call.Expression) != "require" {
103
+ return
104
+ }
105
+ if call.Arguments == nil || len(call.Arguments.Nodes) != 1 {
106
+ return
107
+ }
108
+ arg := call.Arguments.Nodes[0]
109
+ if arg == nil || arg.Kind != shimast.KindStringLiteral {
110
+ return
111
+ }
112
+ specifier := stringLiteralText(arg)
113
+ if _, ok := unicornPreferNodeProtocolBuiltins[specifier]; !ok {
114
+ return
115
+ }
116
+ ctx.Report(arg, "Prefer `node:` protocol when importing Node built-ins.")
117
+ }
118
+ }
119
+
120
+ func init() {
121
+ Register(unicornPreferNodeProtocol{})
122
+ }
@@ -0,0 +1,88 @@
1
+ // unicorn/prefer-number-properties: the global functions `isNaN`,
2
+ // `isFinite`, `parseFloat`, `parseInt`, and the global constants `NaN`,
3
+ // `Infinity` were aliased onto the `Number` namespace in ES2015. The
4
+ // `Number.*` forms coerce more predictably (`Number.isNaN("abc")` is
5
+ // `false`, while the global `isNaN("abc")` is `true`) and are more
6
+ // discoverable. The rule pushes authors to the namespaced spellings.
7
+ //
8
+ // AST-only: visit each `Identifier`. The text must be one of the six
9
+ // shadowable names. The identifier must be in a value-expression
10
+ // position — not the name part of a property access (`obj.isNaN`),
11
+ // not the key of a property assignment, and not a binding name. Reports
12
+ // on the identifier.
13
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-number-properties.md
14
+ package linthost
15
+
16
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
17
+
18
+ var unicornPreferNumberPropertiesNames = map[string]struct{}{
19
+ "isNaN": {},
20
+ "isFinite": {},
21
+ "parseFloat": {},
22
+ "parseInt": {},
23
+ "NaN": {},
24
+ "Infinity": {},
25
+ }
26
+
27
+ type unicornPreferNumberProperties struct{}
28
+
29
+ func (unicornPreferNumberProperties) Name() string {
30
+ return "unicorn/prefer-number-properties"
31
+ }
32
+ func (unicornPreferNumberProperties) Visits() []shimast.Kind {
33
+ return []shimast.Kind{shimast.KindIdentifier}
34
+ }
35
+ func (unicornPreferNumberProperties) Check(ctx *Context, node *shimast.Node) {
36
+ name := identifierText(node)
37
+ if _, ok := unicornPreferNumberPropertiesNames[name]; !ok {
38
+ return
39
+ }
40
+ parent := node.Parent
41
+ if parent == nil {
42
+ return
43
+ }
44
+ switch parent.Kind {
45
+ case shimast.KindPropertyAccessExpression:
46
+ // `obj.isNaN` — the identifier is the property name, not a
47
+ // reference to the global. `Number.isNaN(...)` itself also
48
+ // reaches here and must not be flagged.
49
+ access := parent.AsPropertyAccessExpression()
50
+ if access != nil && access.Name() == node {
51
+ return
52
+ }
53
+ case shimast.KindQualifiedName:
54
+ // Type-position `A.B` — same rationale as PropertyAccess.
55
+ return
56
+ case shimast.KindPropertyAssignment,
57
+ shimast.KindShorthandPropertyAssignment,
58
+ shimast.KindMethodDeclaration,
59
+ shimast.KindPropertyDeclaration,
60
+ shimast.KindEnumMember,
61
+ shimast.KindPropertySignature,
62
+ shimast.KindMethodSignature,
63
+ shimast.KindGetAccessor,
64
+ shimast.KindSetAccessor:
65
+ // Member name slots on object/class shapes.
66
+ return
67
+ case shimast.KindParameter,
68
+ shimast.KindVariableDeclaration,
69
+ shimast.KindBindingElement,
70
+ shimast.KindFunctionDeclaration,
71
+ shimast.KindFunctionExpression,
72
+ shimast.KindClassDeclaration,
73
+ shimast.KindClassExpression,
74
+ shimast.KindImportSpecifier,
75
+ shimast.KindImportClause,
76
+ shimast.KindNamespaceImport,
77
+ shimast.KindExportSpecifier,
78
+ shimast.KindTypeParameter,
79
+ shimast.KindLabeledStatement:
80
+ // Binding / declaration names, not references to the global.
81
+ return
82
+ }
83
+ ctx.Report(node, "Prefer `Number.<X>` over the global `<X>` (e.g. `Number.isNaN`, `Number.parseInt`).")
84
+ }
85
+
86
+ func init() {
87
+ Register(unicornPreferNumberProperties{})
88
+ }
@@ -0,0 +1,55 @@
1
+ // unicorn/prefer-object-from-entries: `entries.reduce((acc, [k, v]) =>
2
+ // ({ ...acc, [k]: v }), {})` is the long-hand spelling of
3
+ // `Object.fromEntries(entries)`. The reduce shape allocates a fresh
4
+ // object at every step (O(n^2) total), reads as the operation rather
5
+ // than the intent, and quietly drops to `Object` from whatever type the
6
+ // entry shape implied. `Object.fromEntries` does the same thing in one
7
+ // pass with one allocation and one well-known name.
8
+ //
9
+ // AST-only: visit `KindCallExpression`. Fire when the callee is
10
+ // `PropertyAccess(_, reduce)` AND the call has exactly two arguments AND
11
+ // the second argument is an empty `KindObjectLiteralExpression`. The
12
+ // shape of the reducer is intentionally not inspected: an empty-object
13
+ // seed in a `.reduce` chain is, in practice, the from-entries shape.
14
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-object-from-entries.md
15
+ package linthost
16
+
17
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
18
+
19
+ type unicornPreferObjectFromEntries struct{}
20
+
21
+ func (unicornPreferObjectFromEntries) Name() string {
22
+ return "unicorn/prefer-object-from-entries"
23
+ }
24
+ func (unicornPreferObjectFromEntries) Visits() []shimast.Kind {
25
+ return []shimast.Kind{shimast.KindCallExpression}
26
+ }
27
+ func (unicornPreferObjectFromEntries) Check(ctx *Context, node *shimast.Node) {
28
+ call := node.AsCallExpression()
29
+ if call == nil || call.Expression == nil {
30
+ return
31
+ }
32
+ if call.Expression.Kind != shimast.KindPropertyAccessExpression {
33
+ return
34
+ }
35
+ access := call.Expression.AsPropertyAccessExpression()
36
+ if access == nil || identifierText(access.Name()) != "reduce" {
37
+ return
38
+ }
39
+ if call.Arguments == nil || len(call.Arguments.Nodes) != 2 {
40
+ return
41
+ }
42
+ seed := stripParens(call.Arguments.Nodes[1])
43
+ if seed == nil || seed.Kind != shimast.KindObjectLiteralExpression {
44
+ return
45
+ }
46
+ obj := seed.AsObjectLiteralExpression()
47
+ if obj == nil || obj.Properties == nil || len(obj.Properties.Nodes) != 0 {
48
+ return
49
+ }
50
+ ctx.Report(node, "Prefer `Object.fromEntries(...)` over `.reduce((acc, ...) => ..., {})` patterns.")
51
+ }
52
+
53
+ func init() {
54
+ Register(unicornPreferObjectFromEntries{})
55
+ }
@@ -0,0 +1,62 @@
1
+ // unicorn/prefer-optional-catch-binding: ES2019 introduced optional
2
+ // catch bindings (`catch { ... }`) so that catch clauses that never
3
+ // reference the thrown error don't need to declare a binding at all.
4
+ // Holding onto the binding name keeps a dead local variable in source
5
+ // and signals that the catch body still cares about the error when in
6
+ // fact it doesn't.
7
+ //
8
+ // AST-only: visit each `CatchClause`, restrict to the common-case
9
+ // binding names `e` and `error` (true scope analysis would require a
10
+ // resolver), and confirm the body's source text does not contain the
11
+ // binding name as a word-bounded identifier. The previous substring
12
+ // scan was load-bearing-wrong: `strings.Contains(body, "e")` matches
13
+ // nearly any English identifier, hiding the rule entirely; word
14
+ // boundaries (`\bname\b`) correctly distinguish `e` from `error`,
15
+ // `error` from `errorMessage`, etc. False positives on `name` inside
16
+ // string literals or comments are acceptable because the rule is
17
+ // conservative by design.
18
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-optional-catch-binding.md
19
+ package linthost
20
+
21
+ import (
22
+ "regexp"
23
+
24
+ shimast "github.com/microsoft/typescript-go/shim/ast"
25
+ )
26
+
27
+ var unicornPreferOptionalCatchBindingNamePattern = map[string]*regexp.Regexp{
28
+ "e": regexp.MustCompile(`\be\b`),
29
+ "error": regexp.MustCompile(`\berror\b`),
30
+ }
31
+
32
+ type unicornPreferOptionalCatchBinding struct{}
33
+
34
+ func (unicornPreferOptionalCatchBinding) Name() string {
35
+ return "unicorn/prefer-optional-catch-binding"
36
+ }
37
+ func (unicornPreferOptionalCatchBinding) Visits() []shimast.Kind {
38
+ return []shimast.Kind{shimast.KindCatchClause}
39
+ }
40
+ func (unicornPreferOptionalCatchBinding) Check(ctx *Context, node *shimast.Node) {
41
+ catch := node.AsCatchClause()
42
+ if catch == nil || catch.VariableDeclaration == nil || catch.Block == nil {
43
+ return
44
+ }
45
+ binding := catch.VariableDeclaration.Name()
46
+ if binding == nil || binding.Kind != shimast.KindIdentifier {
47
+ return
48
+ }
49
+ name := identifierText(binding)
50
+ pattern, ok := unicornPreferOptionalCatchBindingNamePattern[name]
51
+ if !ok {
52
+ return
53
+ }
54
+ if pattern.MatchString(nodeText(ctx.File, catch.Block)) {
55
+ return
56
+ }
57
+ ctx.Report(binding, "Prefer optional catch binding `catch { ... }` when the error is unused.")
58
+ }
59
+
60
+ func init() {
61
+ Register(unicornPreferOptionalCatchBinding{})
62
+ }
@@ -0,0 +1,54 @@
1
+ // unicorn/prefer-prototype-methods: `[].slice`, `[].push`,
2
+ // `{}.hasOwnProperty` and similar empty-literal property accesses are
3
+ // shorthand for grabbing a prototype method without typing
4
+ // `Array.prototype.slice` / `Object.prototype.hasOwnProperty`. The
5
+ // shorthand allocates a throwaway literal at every call, hides the
6
+ // intent of borrowing a prototype method, and is slower than the
7
+ // direct prototype lookup.
8
+ //
9
+ // AST-only: visit each `PropertyAccessExpression`, then match the
10
+ // receiver against either an empty `ArrayLiteralExpression` (no
11
+ // elements) or an empty `ObjectLiteralExpression` (no properties).
12
+ // The property name is intentionally not restricted — any borrowed
13
+ // method should switch to the explicit `<Constructor>.prototype.<m>`
14
+ // form.
15
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-prototype-methods.md
16
+ package linthost
17
+
18
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
19
+
20
+ type unicornPreferPrototypeMethods struct{}
21
+
22
+ func (unicornPreferPrototypeMethods) Name() string { return "unicorn/prefer-prototype-methods" }
23
+ func (unicornPreferPrototypeMethods) Visits() []shimast.Kind {
24
+ return []shimast.Kind{shimast.KindPropertyAccessExpression}
25
+ }
26
+ func (unicornPreferPrototypeMethods) Check(ctx *Context, node *shimast.Node) {
27
+ access := node.AsPropertyAccessExpression()
28
+ if access == nil || access.Expression == nil {
29
+ return
30
+ }
31
+ receiver := stripParens(access.Expression)
32
+ if receiver == nil {
33
+ return
34
+ }
35
+ switch receiver.Kind {
36
+ case shimast.KindArrayLiteralExpression:
37
+ arr := receiver.AsArrayLiteralExpression()
38
+ if arr == nil || arr.Elements == nil || len(arr.Elements.Nodes) != 0 {
39
+ return
40
+ }
41
+ case shimast.KindObjectLiteralExpression:
42
+ obj := receiver.AsObjectLiteralExpression()
43
+ if obj == nil || obj.Properties == nil || len(obj.Properties.Nodes) != 0 {
44
+ return
45
+ }
46
+ default:
47
+ return
48
+ }
49
+ ctx.Report(node, "Use `Array.prototype.<method>` / `Object.prototype.<method>` instead of borrowing via an empty literal.")
50
+ }
51
+
52
+ func init() {
53
+ Register(unicornPreferPrototypeMethods{})
54
+ }
@@ -0,0 +1,56 @@
1
+ // unicorn/prefer-query-selector: `getElementById`,
2
+ // `getElementsByClassName`, and `getElementsByTagName` predate the CSS
3
+ // selector family on `Document` and `Element`. Unifying every lookup on
4
+ // `querySelector` / `querySelectorAll` lets callers compose selectors
5
+ // without juggling three different method signatures and live-collection
6
+ // semantics.
7
+ //
8
+ // AST-only: visit each `CallExpression`, match a property-access callee
9
+ // whose method identifier is one of the legacy lookup names, and fire
10
+ // when the call has exactly one string-literal argument. The
11
+ // string-literal gate isolates the canonical id/class/tag shape from
12
+ // runtime-built argument expressions that the rule would mis-suggest a
13
+ // selector for.
14
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-query-selector.md
15
+ package linthost
16
+
17
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
18
+
19
+ var unicornPreferQuerySelectorMethods = map[string]struct{}{
20
+ "getElementById": {},
21
+ "getElementsByClassName": {},
22
+ "getElementsByTagName": {},
23
+ }
24
+
25
+ type unicornPreferQuerySelector struct{}
26
+
27
+ func (unicornPreferQuerySelector) Name() string { return "unicorn/prefer-query-selector" }
28
+ func (unicornPreferQuerySelector) Visits() []shimast.Kind {
29
+ return []shimast.Kind{shimast.KindCallExpression}
30
+ }
31
+ func (unicornPreferQuerySelector) Check(ctx *Context, node *shimast.Node) {
32
+ call := node.AsCallExpression()
33
+ if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
34
+ return
35
+ }
36
+ access := call.Expression.AsPropertyAccessExpression()
37
+ if access == nil {
38
+ return
39
+ }
40
+ method := identifierText(access.Name())
41
+ if _, ok := unicornPreferQuerySelectorMethods[method]; !ok {
42
+ return
43
+ }
44
+ if call.Arguments == nil || len(call.Arguments.Nodes) != 1 {
45
+ return
46
+ }
47
+ arg := call.Arguments.Nodes[0]
48
+ if arg == nil || arg.Kind != shimast.KindStringLiteral {
49
+ return
50
+ }
51
+ ctx.Report(node, "Prefer `querySelector` / `querySelectorAll` over `"+method+"`.")
52
+ }
53
+
54
+ func init() {
55
+ Register(unicornPreferQuerySelector{})
56
+ }
@@ -0,0 +1,36 @@
1
+ // unicorn/prefer-reflect-apply: `Function.prototype.apply.call(fn, thisArg, args)`
2
+ // is the long-hand pre-`Reflect.apply` workaround for invoking `apply`
3
+ // when the receiver may have shadowed it. `Reflect.apply(fn, thisArg, args)`
4
+ // expresses the same intent in a single named operation and survives
5
+ // `apply` being deleted from the prototype chain.
6
+ //
7
+ // AST-only and text-driven: visit each `CallExpression` and match the
8
+ // callee against the exact textual chain `Function.prototype.apply.call`.
9
+ // Comparing against the source text is the cleanest conservative
10
+ // recognition; alternate spellings (computed access, intermediate
11
+ // aliases) are intentionally out of scope.
12
+ // https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-reflect-apply.md
13
+ package linthost
14
+
15
+ import shimast "github.com/microsoft/typescript-go/shim/ast"
16
+
17
+ type unicornPreferReflectApply struct{}
18
+
19
+ func (unicornPreferReflectApply) Name() string { return "unicorn/prefer-reflect-apply" }
20
+ func (unicornPreferReflectApply) Visits() []shimast.Kind {
21
+ return []shimast.Kind{shimast.KindCallExpression}
22
+ }
23
+ func (unicornPreferReflectApply) Check(ctx *Context, node *shimast.Node) {
24
+ call := node.AsCallExpression()
25
+ if call == nil || call.Expression == nil {
26
+ return
27
+ }
28
+ if nodeText(ctx.File, call.Expression) != "Function.prototype.apply.call" {
29
+ return
30
+ }
31
+ ctx.Report(node, "Prefer `Reflect.apply` over `Function.prototype.apply.call`.")
32
+ }
33
+
34
+ func init() {
35
+ Register(unicornPreferReflectApply{})
36
+ }