@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
@@ -10,7 +10,7 @@ import (
10
10
  shimscanner "github.com/microsoft/typescript-go/shim/scanner"
11
11
  )
12
12
 
13
- // no-extra-boolean-cast: `if (!!x)`, `if (Boolean(x))`, `Boolean(!!x)` —
13
+ // noExtraBooleanCast: `if (!!x)`, `if (Boolean(x))`, `Boolean(!!x)` —
14
14
  // the conversion is implicit in a boolean context.
15
15
  // https://eslint.org/docs/latest/rules/no-extra-boolean-cast
16
16
  type noExtraBooleanCast struct{}
@@ -148,7 +148,7 @@ func skipParents(node *shimast.Node) *shimast.Node {
148
148
  return node
149
149
  }
150
150
 
151
- // no-unsafe-negation: `!a in b` and `!a instanceof b` — the parser
151
+ // noUnsafeNegation: `!a in b` and `!a instanceof b` — the parser
152
152
  // applies the negation to `a`, not to the whole comparison.
153
153
  // https://eslint.org/docs/latest/rules/no-unsafe-negation
154
154
  type noUnsafeNegation struct{}
@@ -247,13 +247,13 @@ func comparableLiteralKind(node *shimast.Node) string {
247
247
  return ""
248
248
  }
249
249
 
250
- // use-isnan: `x === NaN` is always false. Use `Number.isNaN(x)`.
250
+ // useIsNaN: `x === NaN` is always false. Use `Number.isNaN(x)`.
251
251
  // https://eslint.org/docs/latest/rules/use-isnan
252
- type useIsnan struct{}
252
+ type useIsNaN struct{}
253
253
 
254
- func (useIsnan) Name() string { return "use-isnan" }
255
- func (useIsnan) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
256
- func (useIsnan) Check(ctx *Context, node *shimast.Node) {
254
+ func (useIsNaN) Name() string { return "use-isnan" }
255
+ func (useIsNaN) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindBinaryExpression} }
256
+ func (useIsNaN) Check(ctx *Context, node *shimast.Node) {
257
257
  expr := node.AsBinaryExpression()
258
258
  if expr == nil || expr.OperatorToken == nil {
259
259
  return
@@ -266,7 +266,7 @@ func (useIsnan) Check(ctx *Context, node *shimast.Node) {
266
266
  }
267
267
  }
268
268
 
269
- // valid-typeof: typeof expressions can only be compared to known type
269
+ // validTypeof: typeof expressions can only be compared to known type
270
270
  // strings. Catches `typeof x === "stirng"`.
271
271
  // https://eslint.org/docs/latest/rules/valid-typeof
272
272
  type validTypeof struct{}
@@ -311,7 +311,7 @@ func isValidTypeofString(value string) bool {
311
311
  return false
312
312
  }
313
313
 
314
- // no-compare-neg-zero: `x === -0`. Comparison ignores the sign — use
314
+ // noCompareNegZero: `x === -0`. Comparison ignores the sign — use
315
315
  // `Object.is(x, -0)` if you really mean it.
316
316
  // https://eslint.org/docs/latest/rules/no-compare-neg-zero
317
317
  type noCompareNegZero struct{}
@@ -342,7 +342,7 @@ func isNegZero(node *shimast.Node) bool {
342
342
  return numericLiteralText(prefix.Operand) == "0"
343
343
  }
344
344
 
345
- // no-cond-assign: `if (a = b)` is almost always a typo for `if (a == b)`.
345
+ // noCondAssign: `if (a = b)` is almost always a typo for `if (a == b)`.
346
346
  // Default mode matches ESLint's `except-parens` — wrapping in `( )`
347
347
  // silences the rule.
348
348
  // https://eslint.org/docs/latest/rules/no-cond-assign
@@ -418,7 +418,7 @@ func isAssignmentOperator(kind shimast.Kind) bool {
418
418
  return false
419
419
  }
420
420
 
421
- // no-constant-condition: `if (true)`, `while (1)`, `if (literal)`. Often
421
+ // noConstantCondition: `if (true)`, `while (1)`, `if (literal)`. Often
422
422
  // the result of leftover debug code or a typo.
423
423
  // https://eslint.org/docs/latest/rules/no-constant-condition
424
424
  type noConstantCondition struct{}
@@ -495,7 +495,7 @@ func init() {
495
495
  Register(noExtraBooleanCast{})
496
496
  Register(noUnsafeNegation{})
497
497
  Register(eqeqeq{})
498
- Register(useIsnan{})
498
+ Register(useIsNaN{})
499
499
  Register(validTypeof{})
500
500
  Register(noCompareNegZero{})
501
501
  Register(noCondAssign{})
@@ -2,7 +2,7 @@ package linthost
2
2
 
3
3
  import shimast "github.com/microsoft/typescript-go/shim/ast"
4
4
 
5
- // for-direction: `for (var i = 10; i < 20; i--)` will never terminate.
5
+ // forDirection: `for (var i = 10; i < 20; i--)` will never terminate.
6
6
  // https://eslint.org/docs/latest/rules/for-direction
7
7
  type forDirection struct{}
8
8
 
@@ -0,0 +1,58 @@
1
+ // maxClassesPerFile: a file that declares many classes is almost
2
+ // always carrying several unrelated responsibilities. Splitting them
3
+ // into their own modules keeps imports honest and reduces the surface
4
+ // each reader has to scan. ESLint's default ceiling is one class per
5
+ // file, which @ttsc/lint mirrors as the only built-in threshold
6
+ // (option-decoding is deferred).
7
+ // https://eslint.org/docs/latest/rules/max-classes-per-file
8
+ //
9
+ // The rule counts both ClassDeclaration and ClassExpression nodes
10
+ // anywhere in the file so a helper class hidden inside an IIFE still
11
+ // contributes to the total. The finding is anchored at the first
12
+ // class that pushed the count past the limit — the second class
13
+ // under the default — so the diagnostic header points at the
14
+ // offending declaration rather than the file's opening line.
15
+ package linthost
16
+
17
+ import (
18
+ "fmt"
19
+
20
+ shimast "github.com/microsoft/typescript-go/shim/ast"
21
+ )
22
+
23
+ // maxClassesPerFileLimit is the class-count ceiling. Above this value
24
+ // the rule fires once for the file. Mirrors the ESLint default.
25
+ const maxClassesPerFileLimit = 1
26
+
27
+ type maxClassesPerFile struct{}
28
+
29
+ func (maxClassesPerFile) Name() string { return "max-classes-per-file" }
30
+ func (maxClassesPerFile) Visits() []shimast.Kind {
31
+ return []shimast.Kind{shimast.KindSourceFile}
32
+ }
33
+ func (maxClassesPerFile) Check(ctx *Context, node *shimast.Node) {
34
+ if node == nil {
35
+ return
36
+ }
37
+ var classes []*shimast.Node
38
+ walkDescendants(node, func(n *shimast.Node) {
39
+ if n == nil {
40
+ return
41
+ }
42
+ switch n.Kind {
43
+ case shimast.KindClassDeclaration, shimast.KindClassExpression:
44
+ classes = append(classes, n)
45
+ }
46
+ })
47
+ if len(classes) <= maxClassesPerFileLimit {
48
+ return
49
+ }
50
+ // Report at the first class that pushed the count over the limit,
51
+ // so the diagnostic anchors on the offending declaration rather
52
+ // than the file's opening byte.
53
+ ctx.Report(classes[maxClassesPerFileLimit], fmt.Sprintf("File has too many classes (%d). Maximum allowed is %d.", len(classes), maxClassesPerFileLimit))
54
+ }
55
+
56
+ func init() {
57
+ Register(maxClassesPerFile{})
58
+ }
@@ -0,0 +1,83 @@
1
+ // maxDepth: deeply nested block statements are a readability tax — the
2
+ // reader must hold every enclosing condition or loop in mind to reason
3
+ // about the innermost statement. ESLint's default is `{ max: 4 }`, which
4
+ // @ttsc/lint mirrors as the only built-in threshold (option-decoding is
5
+ // deferred). Each function body re-starts the depth counter so nested
6
+ // function-like declarations are measured independently.
7
+ // https://eslint.org/docs/latest/rules/max-depth
8
+ package linthost
9
+
10
+ import (
11
+ "fmt"
12
+
13
+ shimast "github.com/microsoft/typescript-go/shim/ast"
14
+ )
15
+
16
+ // maxDepthLimit is the block-nesting ceiling. Above this value the rule
17
+ // fires. Mirrors the ESLint default and matches the threshold documented
18
+ // in the README and website MDX.
19
+ const maxDepthLimit = 4
20
+
21
+ type maxDepth struct{}
22
+
23
+ func (maxDepth) Name() string { return "max-depth" }
24
+ func (maxDepth) Visits() []shimast.Kind {
25
+ return []shimast.Kind{
26
+ shimast.KindFunctionDeclaration,
27
+ shimast.KindFunctionExpression,
28
+ shimast.KindArrowFunction,
29
+ shimast.KindMethodDeclaration,
30
+ }
31
+ }
32
+ func (maxDepth) Check(ctx *Context, node *shimast.Node) {
33
+ if node == nil {
34
+ return
35
+ }
36
+ body := node.Body()
37
+ if body == nil || body.Kind != shimast.KindBlock {
38
+ return
39
+ }
40
+ walkMaxDepthBody(body, node, 0, ctx)
41
+ }
42
+
43
+ // walkMaxDepthBody descends through `root` counting nested block-bearing
44
+ // statements without crossing nested function-like scopes. Each nested
45
+ // function is left for its own visit. The depth counter increments on
46
+ // statements whose bodies introduce a new block: `if`, `else`, `for`,
47
+ // `for-in`, `for-of`, `while`, `do-while`, `switch`, and `try` (plus
48
+ // each `catch` clause). When the depth exceeds the configured limit, a
49
+ // single finding is reported at the offending statement and the
50
+ // recursive walk continues so independent over-limit branches each get
51
+ // their own diagnostic.
52
+ func walkMaxDepthBody(node *shimast.Node, fn *shimast.Node, depth int, ctx *Context) {
53
+ if node == nil {
54
+ return
55
+ }
56
+ if node != fn && isFunctionLikeKind(node) {
57
+ return
58
+ }
59
+ switch node.Kind {
60
+ case shimast.KindIfStatement,
61
+ shimast.KindForStatement,
62
+ shimast.KindForInStatement,
63
+ shimast.KindForOfStatement,
64
+ shimast.KindWhileStatement,
65
+ shimast.KindDoStatement,
66
+ shimast.KindSwitchStatement,
67
+ shimast.KindTryStatement,
68
+ shimast.KindCatchClause,
69
+ shimast.KindWithStatement:
70
+ depth++
71
+ if depth > maxDepthLimit {
72
+ ctx.Report(node, fmt.Sprintf("Blocks are nested too deeply (%d). Maximum allowed is %d.", depth, maxDepthLimit))
73
+ }
74
+ }
75
+ node.ForEachChild(func(child *shimast.Node) bool {
76
+ walkMaxDepthBody(child, fn, depth, ctx)
77
+ return false
78
+ })
79
+ }
80
+
81
+ func init() {
82
+ Register(maxDepth{})
83
+ }
@@ -0,0 +1,101 @@
1
+ // maxLines: very long files are almost always doing more than one
2
+ // thing — the reader cannot hold the whole responsibility in their
3
+ // head, and follow-up changes tend to make the file longer rather than
4
+ // split it. ESLint's default ceiling is 300 lines, which @ttsc/lint
5
+ // mirrors as the only built-in threshold (option-decoding is deferred).
6
+ // https://eslint.org/docs/latest/rules/max-lines
7
+ //
8
+ // The rule counts every line in the file's source text — code,
9
+ // comments, and blank lines alike — because the goal is a hard cap on
10
+ // how much one file can hold, not a heuristic over "real" code. A file
11
+ // with N newline characters has N+1 lines unless the final character
12
+ // itself is a newline; in either case the count corresponds to the
13
+ // line on which the last byte appears. The finding is anchored at the
14
+ // first line that exceeded the limit (line `max+1`), matching ESLint
15
+ // so editor squiggles land on the offending row rather than the file's
16
+ // opening line.
17
+ package linthost
18
+
19
+ import (
20
+ "fmt"
21
+
22
+ shimast "github.com/microsoft/typescript-go/shim/ast"
23
+ )
24
+
25
+ // maxLinesLimit is the line-count ceiling. Above this value the rule
26
+ // fires once for the file. Mirrors the ESLint default.
27
+ const maxLinesLimit = 300
28
+
29
+ type maxLines struct{}
30
+
31
+ func (maxLines) Name() string { return "max-lines" }
32
+ func (maxLines) Visits() []shimast.Kind {
33
+ return []shimast.Kind{shimast.KindSourceFile}
34
+ }
35
+ func (maxLines) Check(ctx *Context, node *shimast.Node) {
36
+ if ctx.File == nil {
37
+ return
38
+ }
39
+ src := ctx.File.Text()
40
+ count := countSourceLines(src)
41
+ if count <= maxLinesLimit {
42
+ return
43
+ }
44
+ // Anchor at the start of line `max+1` — the first line that pushed
45
+ // the file past the limit. ESLint matches this anchor so editor
46
+ // squiggles land on the offending row.
47
+ pos := nthLineStart(src, maxLinesLimit)
48
+ if pos < 0 || pos >= len(src) {
49
+ pos = 0
50
+ }
51
+ end := pos + 1
52
+ if end > len(src) {
53
+ end = len(src)
54
+ }
55
+ if end <= pos {
56
+ end = pos + 1
57
+ }
58
+ ctx.ReportRange(pos, end, fmt.Sprintf("File has too many lines (%d). Maximum allowed is %d.", count, maxLinesLimit))
59
+ }
60
+
61
+ // nthLineStart returns the byte offset where the (`n`+1)-th line
62
+ // begins (0-indexed: passing 0 returns 0, passing 1 returns the byte
63
+ // after the first `\n`). Returns -1 when the file has fewer lines.
64
+ func nthLineStart(src string, n int) int {
65
+ if n <= 0 {
66
+ return 0
67
+ }
68
+ seen := 0
69
+ for i := 0; i < len(src); i++ {
70
+ if src[i] == '\n' {
71
+ seen++
72
+ if seen == n {
73
+ return i + 1
74
+ }
75
+ }
76
+ }
77
+ return -1
78
+ }
79
+
80
+ // countSourceLines returns the number of lines in `src`. Every `\n`
81
+ // terminates a line; a non-empty trailing fragment without a newline
82
+ // counts as one additional line. An empty source has zero lines.
83
+ func countSourceLines(src string) int {
84
+ if len(src) == 0 {
85
+ return 0
86
+ }
87
+ count := 0
88
+ for i := 0; i < len(src); i++ {
89
+ if src[i] == '\n' {
90
+ count++
91
+ }
92
+ }
93
+ if src[len(src)-1] != '\n' {
94
+ count++
95
+ }
96
+ return count
97
+ }
98
+
99
+ func init() {
100
+ Register(maxLines{})
101
+ }
@@ -0,0 +1,57 @@
1
+ // maxLinesPerFunction: a function whose body spans many lines is hard
2
+ // to scan and almost always benefits from extraction. ESLint's default
3
+ // is `{ max: 50 }`, which @ttsc/lint mirrors as the only built-in
4
+ // threshold (option-decoding is deferred). The line-span is measured
5
+ // between the opening and closing braces of the function's block body,
6
+ // inclusive, so the count reflects the real footprint a reader sees in
7
+ // the source — including blank lines and comments.
8
+ // https://eslint.org/docs/latest/rules/max-lines-per-function
9
+ package linthost
10
+
11
+ import (
12
+ "fmt"
13
+
14
+ shimast "github.com/microsoft/typescript-go/shim/ast"
15
+ shimscanner "github.com/microsoft/typescript-go/shim/scanner"
16
+ )
17
+
18
+ // maxLinesPerFunctionLimit is the line-span ceiling. Above this value
19
+ // the rule fires. Mirrors the ESLint default and matches the threshold
20
+ // documented in the README and website MDX.
21
+ const maxLinesPerFunctionLimit = 50
22
+
23
+ type maxLinesPerFunction struct{}
24
+
25
+ func (maxLinesPerFunction) Name() string { return "max-lines-per-function" }
26
+ func (maxLinesPerFunction) Visits() []shimast.Kind {
27
+ return []shimast.Kind{
28
+ shimast.KindFunctionDeclaration,
29
+ shimast.KindFunctionExpression,
30
+ shimast.KindArrowFunction,
31
+ shimast.KindMethodDeclaration,
32
+ }
33
+ }
34
+ func (maxLinesPerFunction) Check(ctx *Context, node *shimast.Node) {
35
+ if node == nil || ctx == nil || ctx.File == nil {
36
+ return
37
+ }
38
+ body := node.Body()
39
+ if body == nil || body.Kind != shimast.KindBlock {
40
+ return
41
+ }
42
+ startPos := shimscanner.SkipTrivia(ctx.File.Text(), body.Pos())
43
+ endPos := body.End()
44
+ if endPos > startPos {
45
+ endPos--
46
+ }
47
+ startLine := shimscanner.GetECMALineOfPosition(ctx.File, startPos)
48
+ endLine := shimscanner.GetECMALineOfPosition(ctx.File, endPos)
49
+ lines := endLine - startLine + 1
50
+ if lines > maxLinesPerFunctionLimit {
51
+ ctx.Report(node, fmt.Sprintf("Function has too many lines (%d). Maximum allowed is %d.", lines, maxLinesPerFunctionLimit))
52
+ }
53
+ }
54
+
55
+ func init() {
56
+ Register(maxLinesPerFunction{})
57
+ }
@@ -0,0 +1,61 @@
1
+ // maxNestedCallbacks: deeply nested anonymous functions are the
2
+ // classic "callback hell" shape — every new layer pushes the actual
3
+ // work further to the right and makes control-flow harder to follow.
4
+ // ESLint's default ceiling is ten levels of nesting, which @ttsc/lint
5
+ // mirrors as the only built-in threshold (option-decoding is deferred).
6
+ // https://eslint.org/docs/latest/rules/max-nested-callbacks
7
+ //
8
+ // A "callback" here is any function-expression or arrow-function node;
9
+ // named FunctionDeclarations are excluded from the count because the
10
+ // rule targets the anonymous-function nesting shape that produces
11
+ // callback hell, matching ESLint's behavior. Depth counts the current
12
+ // node plus every callback ancestor up to the enclosing source file;
13
+ // FunctionDeclaration boundaries are transparent because ESLint never
14
+ // pushes or pops the stack on them.
15
+ package linthost
16
+
17
+ import (
18
+ "fmt"
19
+
20
+ shimast "github.com/microsoft/typescript-go/shim/ast"
21
+ )
22
+
23
+ // maxNestedCallbacksLimit is the callback-nesting ceiling. Above this
24
+ // value the rule fires on the innermost callback. Mirrors the ESLint
25
+ // default of 10.
26
+ const maxNestedCallbacksLimit = 10
27
+
28
+ type maxNestedCallbacks struct{}
29
+
30
+ func (maxNestedCallbacks) Name() string { return "max-nested-callbacks" }
31
+ func (maxNestedCallbacks) Visits() []shimast.Kind {
32
+ return []shimast.Kind{
33
+ shimast.KindArrowFunction,
34
+ shimast.KindFunctionExpression,
35
+ }
36
+ }
37
+ func (maxNestedCallbacks) Check(ctx *Context, node *shimast.Node) {
38
+ if node == nil {
39
+ return
40
+ }
41
+ // Count this callback plus every callback ancestor up to the
42
+ // SourceFile. Only ArrowFunction and FunctionExpression
43
+ // contribute; FunctionDeclaration, methods, and accessors are
44
+ // transparent because ESLint never pushes or pops its callback
45
+ // stack on those node kinds.
46
+ depth := 1
47
+ for cur := node.Parent; cur != nil; cur = cur.Parent {
48
+ switch cur.Kind {
49
+ case shimast.KindArrowFunction, shimast.KindFunctionExpression:
50
+ depth++
51
+ }
52
+ }
53
+ if depth <= maxNestedCallbacksLimit {
54
+ return
55
+ }
56
+ ctx.Report(node, fmt.Sprintf("Too many nested callbacks (%d). Maximum allowed is %d.", depth, maxNestedCallbacksLimit))
57
+ }
58
+
59
+ func init() {
60
+ Register(maxNestedCallbacks{})
61
+ }
@@ -0,0 +1,49 @@
1
+ // maxParams: long parameter lists are almost always a code smell —
2
+ // readers cannot tell at the call site which argument means what, and
3
+ // the function usually wants to receive an options object instead.
4
+ // ESLint's default is `{ max: 3 }`, which @ttsc/lint mirrors as the
5
+ // only built-in threshold (option-decoding is deferred). Every
6
+ // function-like declaration counts: function declarations, function
7
+ // expressions, arrow functions, methods, accessors, and constructors.
8
+ // https://eslint.org/docs/latest/rules/max-params
9
+ package linthost
10
+
11
+ import (
12
+ "fmt"
13
+
14
+ shimast "github.com/microsoft/typescript-go/shim/ast"
15
+ )
16
+
17
+ // maxParamsLimit is the parameter-count ceiling. Above this value the
18
+ // rule fires. Mirrors the ESLint default and matches the threshold
19
+ // documented in the README and website MDX.
20
+ const maxParamsLimit = 3
21
+
22
+ type maxParams struct{}
23
+
24
+ func (maxParams) Name() string { return "max-params" }
25
+ func (maxParams) Visits() []shimast.Kind {
26
+ return []shimast.Kind{
27
+ shimast.KindFunctionDeclaration,
28
+ shimast.KindFunctionExpression,
29
+ shimast.KindArrowFunction,
30
+ shimast.KindMethodDeclaration,
31
+ shimast.KindGetAccessor,
32
+ shimast.KindSetAccessor,
33
+ shimast.KindConstructor,
34
+ }
35
+ }
36
+ func (maxParams) Check(ctx *Context, node *shimast.Node) {
37
+ if node == nil {
38
+ return
39
+ }
40
+ params := node.Parameters()
41
+ if len(params) <= maxParamsLimit {
42
+ return
43
+ }
44
+ ctx.Report(node, fmt.Sprintf("Function has too many parameters (%d). Maximum allowed is %d.", len(params), maxParamsLimit))
45
+ }
46
+
47
+ func init() {
48
+ Register(maxParams{})
49
+ }
@@ -0,0 +1,59 @@
1
+ // maxStatements: a function whose body contains too many statements is
2
+ // almost always doing more than one job. Splitting it into smaller
3
+ // helpers usually improves both readability and testability. ESLint's
4
+ // default is `{ max: 10 }`, which @ttsc/lint mirrors as the only
5
+ // built-in threshold (option-decoding is deferred). Only the function's
6
+ // own block-body statement list is counted — nested function-like
7
+ // declarations contribute exactly one statement (themselves) regardless
8
+ // of how many statements they internally contain.
9
+ // https://eslint.org/docs/latest/rules/max-statements
10
+ package linthost
11
+
12
+ import (
13
+ "fmt"
14
+
15
+ shimast "github.com/microsoft/typescript-go/shim/ast"
16
+ )
17
+
18
+ // maxStatementsLimit is the statement-count ceiling. Above this value
19
+ // the rule fires. Mirrors the ESLint default and matches the threshold
20
+ // documented in the README and website MDX.
21
+ const maxStatementsLimit = 10
22
+
23
+ type maxStatements struct{}
24
+
25
+ func (maxStatements) Name() string { return "max-statements" }
26
+ func (maxStatements) Visits() []shimast.Kind {
27
+ return []shimast.Kind{
28
+ shimast.KindFunctionDeclaration,
29
+ shimast.KindFunctionExpression,
30
+ shimast.KindArrowFunction,
31
+ shimast.KindMethodDeclaration,
32
+ }
33
+ }
34
+ func (maxStatements) Check(ctx *Context, node *shimast.Node) {
35
+ if node == nil {
36
+ return
37
+ }
38
+ body := node.Body()
39
+ if body == nil || body.Kind != shimast.KindBlock {
40
+ return
41
+ }
42
+ block := body.AsBlock()
43
+ if block == nil || block.Statements == nil {
44
+ return
45
+ }
46
+ count := 0
47
+ for _, stmt := range block.Statements.Nodes {
48
+ if stmt != nil {
49
+ count++
50
+ }
51
+ }
52
+ if count > maxStatementsLimit {
53
+ ctx.Report(node, fmt.Sprintf("Function has too many statements (%d). Maximum allowed is %d.", count, maxStatementsLimit))
54
+ }
55
+ }
56
+
57
+ func init() {
58
+ Register(maxStatements{})
59
+ }
@@ -47,7 +47,7 @@ func (radix) Check(ctx *Context, node *shimast.Node) {
47
47
  }
48
48
  }
49
49
 
50
- // no-new-wrappers: `new String("")`, `new Number(0)`, `new Boolean(false)`
50
+ // noNewWrappers: `new String("")`, `new Number(0)`, `new Boolean(false)`
51
51
  // build wrapper objects rarely intended.
52
52
  // https://eslint.org/docs/latest/rules/no-new-wrappers
53
53
  type noNewWrappers struct{}