@ttsc/lint 0.14.0-dev.20260529.2 → 0.14.0

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 (380) hide show
  1. package/README.md +21 -23
  2. package/lib/defaultFormat.d.ts +10 -6
  3. package/lib/defaultFormat.js +10 -6
  4. package/lib/defaultFormat.js.map +1 -1
  5. package/lib/structures/ITtscLintConfig.d.ts +5 -5
  6. package/lib/structures/TtscLintRuleSetting.d.ts +19 -19
  7. package/lib/structures/{ITtscLintFormat.d.ts → format/ITtscLintFormat.d.ts} +45 -70
  8. package/lib/structures/format/ITtscLintFormat.js.map +1 -0
  9. package/lib/structures/format/ITtscLintFormatJsDoc.d.ts +15 -0
  10. package/lib/structures/format/ITtscLintFormatJsDoc.js +3 -0
  11. package/lib/structures/format/ITtscLintFormatJsDoc.js.map +1 -0
  12. package/lib/structures/format/ITtscLintFormatSortImports.d.ts +54 -0
  13. package/lib/structures/format/ITtscLintFormatSortImports.js +3 -0
  14. package/lib/structures/format/ITtscLintFormatSortImports.js.map +1 -0
  15. package/lib/structures/format/index.d.ts +3 -0
  16. package/lib/structures/format/index.js +20 -0
  17. package/lib/structures/format/index.js.map +1 -0
  18. package/lib/structures/index.d.ts +1 -1
  19. package/lib/structures/index.js +1 -1
  20. package/lib/structures/index.js.map +1 -1
  21. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +18 -27
  22. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +4 -5
  23. package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -1
  24. package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +29 -33
  25. package/lib/structures/rules/ITtscLintContributorRules.d.ts +6 -7
  26. package/lib/structures/rules/ITtscLintCoreRules.d.ts +380 -408
  27. package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +5 -5
  28. package/lib/structures/rules/ITtscLintCypressRuleOptions.js +2 -2
  29. package/lib/structures/rules/ITtscLintCypressRules.d.ts +34 -38
  30. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +21 -24
  31. package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +2 -2
  32. package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +51 -56
  33. package/lib/structures/rules/ITtscLintJestRules.d.ts +63 -74
  34. package/lib/structures/rules/ITtscLintJsdocRules.d.ts +47 -54
  35. package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +94 -102
  36. package/lib/structures/rules/ITtscLintNextjsRules.d.ts +50 -55
  37. package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +104 -122
  38. package/lib/structures/rules/ITtscLintPromiseRules.d.ts +62 -71
  39. package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +4 -4
  40. package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +17 -19
  41. package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +8 -10
  42. package/lib/structures/rules/ITtscLintReactRuleOptions.js +1 -2
  43. package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -1
  44. package/lib/structures/rules/ITtscLintReactRules.d.ts +91 -104
  45. package/lib/structures/rules/ITtscLintRegexpRules.d.ts +46 -54
  46. package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +7 -8
  47. package/lib/structures/rules/ITtscLintSecurityRules.d.ts +45 -52
  48. package/lib/structures/rules/ITtscLintSolidRules.d.ts +53 -56
  49. package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +3 -4
  50. package/lib/structures/rules/ITtscLintStorybookRules.d.ts +60 -69
  51. package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +31 -37
  52. package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +2 -3
  53. package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +102 -119
  54. package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +460 -518
  55. package/lib/structures/rules/ITtscLintVitestRules.d.ts +43 -51
  56. package/linthost/config.go +89 -72
  57. package/linthost/config_format.go +265 -99
  58. package/linthost/directives.go +5 -1
  59. package/linthost/display_width.go +72 -0
  60. package/linthost/fix.go +26 -1
  61. package/linthost/format.go +222 -25
  62. package/linthost/format_editor_settings.go +262 -0
  63. package/linthost/lsp.go +8 -4
  64. package/linthost/print_dispatch.go +3 -0
  65. package/linthost/print_doc.go +13 -0
  66. package/linthost/print_engine.go +68 -11
  67. package/linthost/print_nodes_array.go +108 -5
  68. package/linthost/print_nodes_call.go +515 -74
  69. package/linthost/print_nodes_function.go +25 -0
  70. package/linthost/print_nodes_imports.go +47 -14
  71. package/linthost/print_nodes_list.go +191 -8
  72. package/linthost/print_nodes_object.go +12 -6
  73. package/linthost/print_nodes_ternary.go +106 -0
  74. package/linthost/rules_boundaries.go +400 -400
  75. package/linthost/rules_camelcase.go +81 -81
  76. package/linthost/rules_complexity.go +52 -51
  77. package/linthost/rules_consistent_return.go +81 -81
  78. package/linthost/rules_core_extra.go +472 -472
  79. package/linthost/rules_curly.go +43 -43
  80. package/linthost/rules_default_case.go +15 -15
  81. package/linthost/rules_default_case_last.go +22 -22
  82. package/linthost/rules_format_arrow_parens.go +167 -0
  83. package/linthost/rules_format_bracket_spacing.go +117 -0
  84. package/linthost/rules_format_clause_join.go +172 -0
  85. package/linthost/rules_format_declaration_header.go +664 -0
  86. package/linthost/rules_format_indent.go +616 -0
  87. package/linthost/rules_format_jsdoc.go +4 -4
  88. package/linthost/rules_format_orphan_semi.go +106 -0
  89. package/linthost/rules_format_parameter_properties.go +175 -0
  90. package/linthost/rules_format_print_width.go +185 -69
  91. package/linthost/rules_format_quote_props.go +169 -0
  92. package/linthost/rules_format_quotes.go +75 -29
  93. package/linthost/rules_format_semi.go +185 -10
  94. package/linthost/rules_format_sort_imports.go +456 -121
  95. package/linthost/rules_format_statement_split.go +368 -0
  96. package/linthost/rules_format_ternary_nullish_parens.go +77 -0
  97. package/linthost/rules_format_trailing_comma.go +21 -2
  98. package/linthost/rules_format_whitespace.go +336 -0
  99. package/linthost/rules_functional.go +688 -688
  100. package/linthost/rules_gap.go +146 -11
  101. package/linthost/rules_grouped_accessor_pairs.go +60 -60
  102. package/linthost/rules_guard_for_in.go +122 -122
  103. package/linthost/rules_id_length.go +44 -44
  104. package/linthost/rules_imports.go +11 -3
  105. package/linthost/rules_init_declarations.go +25 -25
  106. package/linthost/rules_jsx_a11y.go +844 -844
  107. package/linthost/rules_max_classes_per_file.go +24 -24
  108. package/linthost/rules_max_depth.go +43 -43
  109. package/linthost/rules_max_lines.go +53 -53
  110. package/linthost/rules_max_lines_per_function.go +28 -28
  111. package/linthost/rules_max_nested_callbacks.go +26 -26
  112. package/linthost/rules_max_params.go +20 -20
  113. package/linthost/rules_max_statements.go +29 -29
  114. package/linthost/rules_nextjs.go +5 -5
  115. package/linthost/rules_no_else_return.go +38 -38
  116. package/linthost/rules_no_empty_named_blocks.go +45 -45
  117. package/linthost/rules_no_import_assign.go +96 -96
  118. package/linthost/rules_no_invalid_this.go +19 -19
  119. package/linthost/rules_no_loop_func.go +43 -43
  120. package/linthost/rules_no_magic_numbers.go +60 -60
  121. package/linthost/rules_no_mixed_operators.go +44 -44
  122. package/linthost/rules_no_param_reassign.go +64 -64
  123. package/linthost/rules_no_restricted_imports.go +45 -45
  124. package/linthost/rules_no_restricted_syntax.go +17 -17
  125. package/linthost/rules_no_shadow.go +112 -112
  126. package/linthost/rules_no_unreachable.go +36 -36
  127. package/linthost/rules_no_useless_assignment.go +79 -79
  128. package/linthost/rules_no_useless_constructor.go +167 -167
  129. package/linthost/rules_no_useless_return.go +28 -28
  130. package/linthost/rules_prefer_arrow_callback.go +74 -74
  131. package/linthost/rules_prefer_destructuring.go +61 -61
  132. package/linthost/rules_prefer_named_capture_group.go +87 -87
  133. package/linthost/rules_prefer_rest_params.go +61 -61
  134. package/linthost/rules_promise.go +800 -800
  135. package/linthost/rules_react.go +600 -600
  136. package/linthost/rules_react_extras.go +162 -162
  137. package/linthost/rules_react_hooks.go +2 -2
  138. package/linthost/rules_react_perf.go +231 -231
  139. package/linthost/rules_regexp.go +293 -293
  140. package/linthost/rules_security.go +613 -613
  141. package/linthost/rules_sort_imports.go +37 -37
  142. package/linthost/rules_sort_keys.go +88 -88
  143. package/linthost/rules_suggestions.go +13 -0
  144. package/linthost/rules_ts.go +2 -2
  145. package/linthost/rules_ts_async.go +247 -247
  146. package/linthost/rules_ts_class_literal_property_style.go +64 -64
  147. package/linthost/rules_ts_consistent_type_exports.go +209 -209
  148. package/linthost/rules_ts_explicit_function_return_type.go +35 -35
  149. package/linthost/rules_ts_extra.go +6 -2
  150. package/linthost/rules_ts_no_base_to_string.go +140 -140
  151. package/linthost/rules_ts_no_confusing_void.go +28 -28
  152. package/linthost/rules_ts_no_deprecated.go +110 -110
  153. package/linthost/rules_ts_no_for_in_array.go +45 -45
  154. package/linthost/rules_ts_no_magic_numbers.go +67 -67
  155. package/linthost/rules_ts_no_meaningless_void_operator.go +44 -44
  156. package/linthost/rules_ts_no_misused_spread.go +64 -64
  157. package/linthost/rules_ts_no_redundant_type_constituents.go +72 -72
  158. package/linthost/rules_ts_no_restricted_types.go +28 -28
  159. package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +87 -87
  160. package/linthost/rules_ts_no_unnecessary_condition.go +184 -184
  161. package/linthost/rules_ts_no_unnecessary_qualifier.go +72 -72
  162. package/linthost/rules_ts_no_unnecessary_template_expression.go +120 -120
  163. package/linthost/rules_ts_no_unnecessary_type_arguments.go +171 -171
  164. package/linthost/rules_ts_no_unnecessary_type_assertion.go +90 -90
  165. package/linthost/rules_ts_no_unsafe_argument.go +50 -50
  166. package/linthost/rules_ts_no_unsafe_assignment.go +60 -60
  167. package/linthost/rules_ts_no_unsafe_call.go +40 -40
  168. package/linthost/rules_ts_no_unsafe_enum_comparison.go +147 -147
  169. package/linthost/rules_ts_no_unsafe_member_access.go +29 -29
  170. package/linthost/rules_ts_no_unsafe_return.go +64 -64
  171. package/linthost/rules_ts_no_unsafe_unary_minus.go +42 -42
  172. package/linthost/rules_ts_no_useless_constructor.go +20 -20
  173. package/linthost/rules_ts_non_nullable_type_assertion_style.go +60 -60
  174. package/linthost/rules_ts_parameter_properties.go +10 -10
  175. package/linthost/rules_ts_prefer_find.go +116 -116
  176. package/linthost/rules_ts_prefer_includes.go +173 -173
  177. package/linthost/rules_ts_prefer_nullish_coalescing.go +54 -54
  178. package/linthost/rules_ts_prefer_optional_chain.go +156 -156
  179. package/linthost/rules_ts_prefer_promise_reject_errors.go +104 -104
  180. package/linthost/rules_ts_prefer_readonly.go +31 -31
  181. package/linthost/rules_ts_prefer_reduce_type_parameter.go +74 -74
  182. package/linthost/rules_ts_prefer_regexp_exec.go +69 -69
  183. package/linthost/rules_ts_prefer_return_this_type.go +79 -79
  184. package/linthost/rules_ts_prefer_string_starts_ends_with.go +237 -237
  185. package/linthost/rules_ts_promise_function_async.go +41 -41
  186. package/linthost/rules_ts_related_getter_setter_pairs.go +61 -61
  187. package/linthost/rules_ts_require_array_sort_compare.go +58 -58
  188. package/linthost/rules_ts_restrict_plus_operands.go +82 -82
  189. package/linthost/rules_ts_restrict_template_expressions.go +50 -50
  190. package/linthost/rules_ts_simple.go +249 -249
  191. package/linthost/rules_ts_sort_type_constituents.go +88 -88
  192. package/linthost/rules_ts_strict_boolean_expressions.go +103 -103
  193. package/linthost/rules_ts_switch_exhaustiveness_check.go +90 -90
  194. package/linthost/rules_ts_unbound_method.go +65 -65
  195. package/linthost/rules_tsdoc.go +88 -88
  196. package/linthost/rules_unicorn_better_regex.go +1 -1
  197. package/linthost/rules_unicorn_catch_error_name.go +19 -19
  198. package/linthost/rules_unicorn_consistent_assert.go +20 -20
  199. package/linthost/rules_unicorn_consistent_date_clone.go +27 -27
  200. package/linthost/rules_unicorn_consistent_destructuring.go +3 -3
  201. package/linthost/rules_unicorn_consistent_empty_array_spread.go +34 -34
  202. package/linthost/rules_unicorn_consistent_existence_index_check.go +42 -42
  203. package/linthost/rules_unicorn_consistent_function_scoping.go +3 -3
  204. package/linthost/rules_unicorn_consistent_template_literal_escape.go +3 -3
  205. package/linthost/rules_unicorn_custom_error_definition.go +92 -92
  206. package/linthost/rules_unicorn_empty_brace_spaces.go +47 -47
  207. package/linthost/rules_unicorn_error_message.go +34 -34
  208. package/linthost/rules_unicorn_escape_case.go +14 -14
  209. package/linthost/rules_unicorn_expiring_todo_comments.go +36 -36
  210. package/linthost/rules_unicorn_explicit_length_check.go +51 -51
  211. package/linthost/rules_unicorn_filename_case.go +1 -1
  212. package/linthost/rules_unicorn_import_style.go +1 -1
  213. package/linthost/rules_unicorn_isolated_functions.go +2 -2
  214. package/linthost/rules_unicorn_new_for_builtins.go +49 -49
  215. package/linthost/rules_unicorn_no_abusive_eslint_disable.go +31 -31
  216. package/linthost/rules_unicorn_no_accessor_recursion.go +69 -69
  217. package/linthost/rules_unicorn_no_anonymous_default_export.go +40 -40
  218. package/linthost/rules_unicorn_no_array_callback_reference.go +33 -33
  219. package/linthost/rules_unicorn_no_array_for_each.go +14 -14
  220. package/linthost/rules_unicorn_no_array_method_this_argument.go +29 -29
  221. package/linthost/rules_unicorn_no_array_reduce.go +15 -15
  222. package/linthost/rules_unicorn_no_array_reverse.go +17 -17
  223. package/linthost/rules_unicorn_no_array_sort.go +17 -17
  224. package/linthost/rules_unicorn_no_await_expression_member.go +12 -12
  225. package/linthost/rules_unicorn_no_await_in_promise_methods.go +38 -38
  226. package/linthost/rules_unicorn_no_console_spaces.go +30 -30
  227. package/linthost/rules_unicorn_no_document_cookie.go +13 -13
  228. package/linthost/rules_unicorn_no_empty_file.go +16 -16
  229. package/linthost/rules_unicorn_no_for_loop.go +58 -58
  230. package/linthost/rules_unicorn_no_hex_escape.go +11 -11
  231. package/linthost/rules_unicorn_no_immediate_mutation.go +55 -55
  232. package/linthost/rules_unicorn_no_instanceof_builtins.go +34 -34
  233. package/linthost/rules_unicorn_no_invalid_fetch_options.go +52 -52
  234. package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +25 -25
  235. package/linthost/rules_unicorn_no_keyword_prefix.go +56 -56
  236. package/linthost/rules_unicorn_no_lonely_if.go +21 -21
  237. package/linthost/rules_unicorn_no_magic_array_flat_depth.go +22 -22
  238. package/linthost/rules_unicorn_no_named_default.go +25 -25
  239. package/linthost/rules_unicorn_no_negated_condition.go +54 -54
  240. package/linthost/rules_unicorn_no_negation_in_equality_check.go +23 -23
  241. package/linthost/rules_unicorn_no_nested_ternary.go +15 -15
  242. package/linthost/rules_unicorn_no_new_array.go +5 -5
  243. package/linthost/rules_unicorn_no_new_buffer.go +5 -5
  244. package/linthost/rules_unicorn_no_null.go +2 -2
  245. package/linthost/rules_unicorn_no_object_as_default_parameter.go +19 -19
  246. package/linthost/rules_unicorn_no_process_exit.go +17 -17
  247. package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +29 -29
  248. package/linthost/rules_unicorn_no_static_only_class.go +27 -27
  249. package/linthost/rules_unicorn_no_thenable.go +47 -47
  250. package/linthost/rules_unicorn_no_this_assignment.go +10 -10
  251. package/linthost/rules_unicorn_no_typeof_undefined.go +31 -31
  252. package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +23 -23
  253. package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +37 -37
  254. package/linthost/rules_unicorn_no_unnecessary_await.go +24 -24
  255. package/linthost/rules_unicorn_no_unnecessary_slice_end.go +22 -22
  256. package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +67 -67
  257. package/linthost/rules_unicorn_no_unreadable_iife.go +22 -22
  258. package/linthost/rules_unicorn_no_useless_collection_argument.go +34 -34
  259. package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +18 -18
  260. package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +49 -49
  261. package/linthost/rules_unicorn_no_useless_iterator_to_array.go +41 -41
  262. package/linthost/rules_unicorn_no_useless_length_check.go +82 -82
  263. package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +42 -42
  264. package/linthost/rules_unicorn_no_useless_spread.go +38 -38
  265. package/linthost/rules_unicorn_no_useless_switch_case.go +29 -29
  266. package/linthost/rules_unicorn_no_useless_undefined.go +25 -25
  267. package/linthost/rules_unicorn_no_zero_fractions.go +17 -17
  268. package/linthost/rules_unicorn_number_literal_case.go +33 -33
  269. package/linthost/rules_unicorn_numeric_separators_style.go +36 -36
  270. package/linthost/rules_unicorn_prefer_add_event_listener.go +30 -30
  271. package/linthost/rules_unicorn_prefer_array_find.go +27 -27
  272. package/linthost/rules_unicorn_prefer_array_flat.go +25 -25
  273. package/linthost/rules_unicorn_prefer_array_flat_map.go +37 -37
  274. package/linthost/rules_unicorn_prefer_array_index_of.go +108 -108
  275. package/linthost/rules_unicorn_prefer_array_some.go +43 -43
  276. package/linthost/rules_unicorn_prefer_at.go +42 -42
  277. package/linthost/rules_unicorn_prefer_bigint_literals.go +42 -42
  278. package/linthost/rules_unicorn_prefer_blob_reading_methods.go +15 -15
  279. package/linthost/rules_unicorn_prefer_class_fields.go +57 -57
  280. package/linthost/rules_unicorn_prefer_classlist_toggle.go +76 -76
  281. package/linthost/rules_unicorn_prefer_code_point.go +21 -21
  282. package/linthost/rules_unicorn_prefer_date_now.go +47 -47
  283. package/linthost/rules_unicorn_prefer_default_parameters.go +96 -96
  284. package/linthost/rules_unicorn_prefer_dom_node_append.go +14 -14
  285. package/linthost/rules_unicorn_prefer_dom_node_dataset.go +27 -27
  286. package/linthost/rules_unicorn_prefer_dom_node_remove.go +17 -17
  287. package/linthost/rules_unicorn_prefer_dom_node_text_content.go +11 -11
  288. package/linthost/rules_unicorn_prefer_event_target.go +10 -10
  289. package/linthost/rules_unicorn_prefer_export_from.go +99 -99
  290. package/linthost/rules_unicorn_prefer_global_this.go +91 -91
  291. package/linthost/rules_unicorn_prefer_import_meta_properties.go +38 -38
  292. package/linthost/rules_unicorn_prefer_includes.go +108 -108
  293. package/linthost/rules_unicorn_prefer_json_parse_buffer.go +37 -37
  294. package/linthost/rules_unicorn_prefer_keyboard_event_key.go +10 -10
  295. package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +20 -20
  296. package/linthost/rules_unicorn_prefer_math_min_max.go +33 -33
  297. package/linthost/rules_unicorn_prefer_math_trunc.go +32 -32
  298. package/linthost/rules_unicorn_prefer_modern_dom_apis.go +18 -18
  299. package/linthost/rules_unicorn_prefer_modern_math_apis.go +38 -38
  300. package/linthost/rules_unicorn_prefer_module.go +22 -22
  301. package/linthost/rules_unicorn_prefer_native_coercion_functions.go +73 -73
  302. package/linthost/rules_unicorn_prefer_negative_index.go +46 -46
  303. package/linthost/rules_unicorn_prefer_node_protocol.go +90 -90
  304. package/linthost/rules_unicorn_prefer_number_properties.go +57 -57
  305. package/linthost/rules_unicorn_prefer_object_from_entries.go +26 -26
  306. package/linthost/rules_unicorn_prefer_optional_catch_binding.go +24 -24
  307. package/linthost/rules_unicorn_prefer_prototype_methods.go +25 -25
  308. package/linthost/rules_unicorn_prefer_query_selector.go +25 -25
  309. package/linthost/rules_unicorn_prefer_reflect_apply.go +10 -10
  310. package/linthost/rules_unicorn_prefer_regexp_test_rule.go +47 -47
  311. package/linthost/rules_unicorn_prefer_response_static_json.go +26 -26
  312. package/linthost/rules_unicorn_prefer_set_has.go +16 -16
  313. package/linthost/rules_unicorn_prefer_set_size.go +22 -22
  314. package/linthost/rules_unicorn_prefer_simple_condition_first.go +3 -3
  315. package/linthost/rules_unicorn_prefer_single_call.go +59 -59
  316. package/linthost/rules_unicorn_prefer_spread.go +24 -24
  317. package/linthost/rules_unicorn_prefer_string_raw.go +12 -12
  318. package/linthost/rules_unicorn_prefer_string_replace_all.go +46 -46
  319. package/linthost/rules_unicorn_prefer_string_slice.go +17 -17
  320. package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +104 -104
  321. package/linthost/rules_unicorn_prefer_string_trim_start_end.go +21 -21
  322. package/linthost/rules_unicorn_prefer_structured_clone.go +36 -36
  323. package/linthost/rules_unicorn_prefer_switch.go +65 -65
  324. package/linthost/rules_unicorn_prefer_ternary.go +35 -35
  325. package/linthost/rules_unicorn_prefer_top_level_await.go +34 -34
  326. package/linthost/rules_unicorn_prefer_type_error.go +84 -84
  327. package/linthost/rules_unicorn_prevent_abbreviations.go +68 -68
  328. package/linthost/rules_unicorn_relative_url_style.go +19 -19
  329. package/linthost/rules_unicorn_require_array_join_separator.go +18 -18
  330. package/linthost/rules_unicorn_require_module_attributes.go +25 -25
  331. package/linthost/rules_unicorn_require_module_specifiers.go +28 -28
  332. package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +18 -18
  333. package/linthost/rules_unicorn_require_post_message_target_origin.go +18 -18
  334. package/linthost/rules_unicorn_string_content.go +1 -1
  335. package/linthost/rules_unicorn_switch_case_braces.go +16 -16
  336. package/linthost/rules_unicorn_switch_case_break_position.go +3 -3
  337. package/linthost/rules_unicorn_template_indent.go +1 -1
  338. package/linthost/rules_unicorn_text_encoding_identifier_case.go +36 -36
  339. package/linthost/rules_unicorn_throw_new_error.go +30 -30
  340. package/linthost/rules_var.go +273 -3
  341. package/package.json +3 -3
  342. package/src/defaultFormat.ts +11 -7
  343. package/src/structures/ITtscLintConfig.ts +5 -5
  344. package/src/structures/TtscLintRuleSetting.ts +19 -19
  345. package/src/structures/{ITtscLintFormat.ts → format/ITtscLintFormat.ts} +48 -75
  346. package/src/structures/format/ITtscLintFormatJsDoc.ts +16 -0
  347. package/src/structures/format/ITtscLintFormatSortImports.ts +62 -0
  348. package/src/structures/format/index.ts +3 -0
  349. package/src/structures/index.ts +1 -1
  350. package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +20 -31
  351. package/src/structures/rules/ITtscLintBoundariesRules.ts +32 -36
  352. package/src/structures/rules/ITtscLintContributorRules.ts +6 -7
  353. package/src/structures/rules/ITtscLintCoreRules.ts +380 -408
  354. package/src/structures/rules/ITtscLintCypressRuleOptions.ts +5 -5
  355. package/src/structures/rules/ITtscLintCypressRules.ts +34 -38
  356. package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +28 -41
  357. package/src/structures/rules/ITtscLintFunctionalRules.ts +51 -56
  358. package/src/structures/rules/ITtscLintJestRules.ts +63 -74
  359. package/src/structures/rules/ITtscLintJsdocRules.ts +47 -54
  360. package/src/structures/rules/ITtscLintJsxA11yRules.ts +94 -102
  361. package/src/structures/rules/ITtscLintNextjsRules.ts +50 -55
  362. package/src/structures/rules/ITtscLintPlaywrightRules.ts +104 -122
  363. package/src/structures/rules/ITtscLintPromiseRules.ts +62 -71
  364. package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +4 -4
  365. package/src/structures/rules/ITtscLintReactPerfRules.ts +17 -19
  366. package/src/structures/rules/ITtscLintReactRuleOptions.ts +8 -10
  367. package/src/structures/rules/ITtscLintReactRules.ts +91 -104
  368. package/src/structures/rules/ITtscLintRegexpRules.ts +46 -54
  369. package/src/structures/rules/ITtscLintRuleOptionsMap.ts +7 -8
  370. package/src/structures/rules/ITtscLintSecurityRules.ts +45 -52
  371. package/src/structures/rules/ITtscLintSolidRules.ts +53 -56
  372. package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +3 -4
  373. package/src/structures/rules/ITtscLintStorybookRules.ts +60 -69
  374. package/src/structures/rules/ITtscLintTanstackQueryRules.ts +31 -37
  375. package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +2 -3
  376. package/src/structures/rules/ITtscLintTestingLibraryRules.ts +102 -119
  377. package/src/structures/rules/ITtscLintTypeScriptRules.ts +460 -518
  378. package/src/structures/rules/ITtscLintVitestRules.ts +43 -51
  379. package/lib/structures/ITtscLintFormat.js.map +0 -1
  380. /package/lib/structures/{ITtscLintFormat.js → format/ITtscLintFormat.js} +0 -0
@@ -14,10 +14,10 @@
14
14
  package linthost
15
15
 
16
16
  import (
17
- "strings"
17
+ "strings"
18
18
 
19
- shimast "github.com/microsoft/typescript-go/shim/ast"
20
- shimchecker "github.com/microsoft/typescript-go/shim/checker"
19
+ shimast "github.com/microsoft/typescript-go/shim/ast"
20
+ shimchecker "github.com/microsoft/typescript-go/shim/checker"
21
21
  )
22
22
 
23
23
  // truthState is the lattice value the rule tracks for each constituent of
@@ -35,73 +35,73 @@ import (
35
35
  type truthState int
36
36
 
37
37
  const (
38
- truthStateUnknowable truthState = iota
39
- truthStateAlwaysTruthy
40
- truthStateAlwaysFalsy
41
- truthStateMixed
38
+ truthStateUnknowable truthState = iota
39
+ truthStateAlwaysTruthy
40
+ truthStateAlwaysFalsy
41
+ truthStateMixed
42
42
  )
43
43
 
44
44
  type noUnnecessaryCondition struct{}
45
45
 
46
46
  func (noUnnecessaryCondition) Name() string { return "typescript/no-unnecessary-condition" }
47
47
  func (noUnnecessaryCondition) NeedsTypeChecker() bool {
48
- return true
48
+ return true
49
49
  }
50
50
  func (noUnnecessaryCondition) Visits() []shimast.Kind {
51
- return []shimast.Kind{
52
- shimast.KindIfStatement,
53
- shimast.KindWhileStatement,
54
- shimast.KindDoStatement,
55
- shimast.KindForStatement,
56
- shimast.KindConditionalExpression,
57
- shimast.KindBinaryExpression,
58
- shimast.KindPrefixUnaryExpression,
59
- }
51
+ return []shimast.Kind{
52
+ shimast.KindIfStatement,
53
+ shimast.KindWhileStatement,
54
+ shimast.KindDoStatement,
55
+ shimast.KindForStatement,
56
+ shimast.KindConditionalExpression,
57
+ shimast.KindBinaryExpression,
58
+ shimast.KindPrefixUnaryExpression,
59
+ }
60
60
  }
61
61
  func (noUnnecessaryCondition) Check(ctx *Context, node *shimast.Node) {
62
- if ctx.Checker == nil {
63
- return
64
- }
65
- switch node.Kind {
66
- case shimast.KindIfStatement:
67
- if stmt := node.AsIfStatement(); stmt != nil {
68
- noUnnecessaryConditionReport(ctx, stmt.Expression)
69
- }
70
- case shimast.KindWhileStatement:
71
- if stmt := node.AsWhileStatement(); stmt != nil {
72
- noUnnecessaryConditionReport(ctx, stmt.Expression)
73
- }
74
- case shimast.KindDoStatement:
75
- if stmt := node.AsDoStatement(); stmt != nil {
76
- noUnnecessaryConditionReport(ctx, stmt.Expression)
77
- }
78
- case shimast.KindForStatement:
79
- if stmt := node.AsForStatement(); stmt != nil {
80
- noUnnecessaryConditionReport(ctx, stmt.Condition)
81
- }
82
- case shimast.KindConditionalExpression:
83
- if expr := node.AsConditionalExpression(); expr != nil {
84
- noUnnecessaryConditionReport(ctx, expr.Condition)
85
- }
86
- case shimast.KindPrefixUnaryExpression:
87
- expr := node.AsPrefixUnaryExpression()
88
- if expr != nil && expr.Operator == shimast.KindExclamationToken {
89
- noUnnecessaryConditionReport(ctx, expr.Operand)
90
- }
91
- case shimast.KindBinaryExpression:
92
- bin := node.AsBinaryExpression()
93
- if bin == nil || bin.OperatorToken == nil {
94
- return
95
- }
96
- // Only `&&` / `||` test their left operand for truthiness. `??`
97
- // short-circuits on nullish, not on falsy, and is intentionally
98
- // out of scope — its dedicated rule
99
- // `no-unnecessary-nullish-coalescing` covers that pattern.
100
- switch bin.OperatorToken.Kind {
101
- case shimast.KindAmpersandAmpersandToken, shimast.KindBarBarToken:
102
- noUnnecessaryConditionReport(ctx, bin.Left)
103
- }
104
- }
62
+ if ctx.Checker == nil {
63
+ return
64
+ }
65
+ switch node.Kind {
66
+ case shimast.KindIfStatement:
67
+ if stmt := node.AsIfStatement(); stmt != nil {
68
+ noUnnecessaryConditionReport(ctx, stmt.Expression)
69
+ }
70
+ case shimast.KindWhileStatement:
71
+ if stmt := node.AsWhileStatement(); stmt != nil {
72
+ noUnnecessaryConditionReport(ctx, stmt.Expression)
73
+ }
74
+ case shimast.KindDoStatement:
75
+ if stmt := node.AsDoStatement(); stmt != nil {
76
+ noUnnecessaryConditionReport(ctx, stmt.Expression)
77
+ }
78
+ case shimast.KindForStatement:
79
+ if stmt := node.AsForStatement(); stmt != nil {
80
+ noUnnecessaryConditionReport(ctx, stmt.Condition)
81
+ }
82
+ case shimast.KindConditionalExpression:
83
+ if expr := node.AsConditionalExpression(); expr != nil {
84
+ noUnnecessaryConditionReport(ctx, expr.Condition)
85
+ }
86
+ case shimast.KindPrefixUnaryExpression:
87
+ expr := node.AsPrefixUnaryExpression()
88
+ if expr != nil && expr.Operator == shimast.KindExclamationToken {
89
+ noUnnecessaryConditionReport(ctx, expr.Operand)
90
+ }
91
+ case shimast.KindBinaryExpression:
92
+ bin := node.AsBinaryExpression()
93
+ if bin == nil || bin.OperatorToken == nil {
94
+ return
95
+ }
96
+ // Only `&&` / `||` test their left operand for truthiness. `??`
97
+ // short-circuits on nullish, not on falsy, and is intentionally
98
+ // out of scope — its dedicated rule
99
+ // `no-unnecessary-nullish-coalescing` covers that pattern.
100
+ switch bin.OperatorToken.Kind {
101
+ case shimast.KindAmpersandAmpersandToken, shimast.KindBarBarToken:
102
+ noUnnecessaryConditionReport(ctx, bin.Left)
103
+ }
104
+ }
105
105
  }
106
106
 
107
107
  // noUnnecessaryConditionReport flags `expr` when its static type proves
@@ -110,34 +110,34 @@ func (noUnnecessaryCondition) Check(ctx *Context, node *shimast.Node) {
110
110
  // only checks Left, so the recursion here picks up Right too. Wrapping
111
111
  // parens are skipped via stripParens.
112
112
  func noUnnecessaryConditionReport(ctx *Context, expr *shimast.Node) {
113
- if expr == nil {
114
- return
115
- }
116
- expr = stripParens(expr)
117
- if expr == nil {
118
- return
119
- }
120
- if expr.Kind == shimast.KindBinaryExpression {
121
- bin := expr.AsBinaryExpression()
122
- if bin != nil && bin.OperatorToken != nil {
123
- switch bin.OperatorToken.Kind {
124
- case shimast.KindAmpersandAmpersandToken, shimast.KindBarBarToken:
125
- noUnnecessaryConditionReport(ctx, bin.Left)
126
- noUnnecessaryConditionReport(ctx, bin.Right)
127
- return
128
- }
129
- }
130
- }
131
- t := ctx.Checker.GetTypeAtLocation(expr)
132
- if t == nil {
133
- return
134
- }
135
- switch noUnnecessaryConditionEvaluate(ctx.Checker, t) {
136
- case truthStateAlwaysTruthy:
137
- ctx.Report(expr, "Unnecessary conditional, value is always truthy.")
138
- case truthStateAlwaysFalsy:
139
- ctx.Report(expr, "Unnecessary conditional, value is always falsy.")
140
- }
113
+ if expr == nil {
114
+ return
115
+ }
116
+ expr = stripParens(expr)
117
+ if expr == nil {
118
+ return
119
+ }
120
+ if expr.Kind == shimast.KindBinaryExpression {
121
+ bin := expr.AsBinaryExpression()
122
+ if bin != nil && bin.OperatorToken != nil {
123
+ switch bin.OperatorToken.Kind {
124
+ case shimast.KindAmpersandAmpersandToken, shimast.KindBarBarToken:
125
+ noUnnecessaryConditionReport(ctx, bin.Left)
126
+ noUnnecessaryConditionReport(ctx, bin.Right)
127
+ return
128
+ }
129
+ }
130
+ }
131
+ t := ctx.Checker.GetTypeAtLocation(expr)
132
+ if t == nil {
133
+ return
134
+ }
135
+ switch noUnnecessaryConditionEvaluate(ctx.Checker, t) {
136
+ case truthStateAlwaysTruthy:
137
+ ctx.Report(expr, "Unnecessary conditional, value is always truthy.")
138
+ case truthStateAlwaysFalsy:
139
+ ctx.Report(expr, "Unnecessary conditional, value is always falsy.")
140
+ }
141
141
  }
142
142
 
143
143
  // noUnnecessaryConditionEvaluate folds a type into a single truthState by
@@ -148,103 +148,103 @@ func noUnnecessaryConditionReport(ctx *Context, expr *shimast.Node) {
148
148
  // because the Checker may resolve them into shapes (e.g. branded
149
149
  // primitives) the rule cannot reason about safely.
150
150
  func noUnnecessaryConditionEvaluate(checker *shimchecker.Checker, t *shimchecker.Type) truthState {
151
- if checker == nil || t == nil {
152
- return truthStateUnknowable
153
- }
154
- flags := t.Flags()
155
- if flags&(shimchecker.TypeFlagsAny|shimchecker.TypeFlagsUnknown|shimchecker.TypeFlagsNever) != 0 {
156
- return truthStateUnknowable
157
- }
158
- if flags&shimchecker.TypeFlagsIntersection != 0 {
159
- // Intersections such as `Foo & { brand: "x" }` carry semantics the
160
- // rule cannot prove without a deeper Checker walk, so we keep the
161
- // conservative bail.
162
- return truthStateUnknowable
163
- }
164
- if flags&shimchecker.TypeFlagsUnion != 0 {
165
- parts := t.Types()
166
- if len(parts) == 0 {
167
- return truthStateUnknowable
168
- }
169
- combined := truthState(-1)
170
- for _, part := range parts {
171
- if part == nil {
172
- return truthStateUnknowable
173
- }
174
- state := noUnnecessaryConditionEvaluate(checker, part)
175
- if state == truthStateUnknowable || state == truthStateMixed {
176
- // A union with even one constituent we can't pin breaks the
177
- // "always X" guarantee — bail.
178
- return state
179
- }
180
- if combined == truthState(-1) {
181
- combined = state
182
- continue
183
- }
184
- if combined != state {
185
- // `string | null` has both a falsy ("") and a always-falsy
186
- // (null) outcome that disagree across constituents — fall
187
- // back to mixed so the rule stays silent.
188
- return truthStateMixed
189
- }
190
- }
191
- if combined == truthState(-1) {
192
- return truthStateUnknowable
193
- }
194
- return combined
195
- }
196
- // Atomic types.
197
- if flags&(shimchecker.TypeFlagsNull|shimchecker.TypeFlagsUndefined|shimchecker.TypeFlagsVoid) != 0 {
198
- return truthStateAlwaysFalsy
199
- }
200
- if flags&shimchecker.TypeFlagsBooleanLiteral != 0 {
201
- text := checker.TypeToString(t)
202
- if strings.TrimSpace(text) == "false" {
203
- return truthStateAlwaysFalsy
204
- }
205
- if strings.TrimSpace(text) == "true" {
206
- return truthStateAlwaysTruthy
207
- }
208
- return truthStateUnknowable
209
- }
210
- if flags&shimchecker.TypeFlagsStringLiteral != 0 {
211
- text := strings.TrimSpace(checker.TypeToString(t))
212
- if text == `""` || text == `''` {
213
- return truthStateAlwaysFalsy
214
- }
215
- return truthStateAlwaysTruthy
216
- }
217
- if flags&shimchecker.TypeFlagsNumberLiteral != 0 {
218
- text := strings.TrimSpace(checker.TypeToString(t))
219
- // `0`, `0.0`, `-0` all stringify as `0`; everything else is truthy.
220
- // `NaN` is not representable as a literal type, so it cannot reach
221
- // this branch.
222
- if text == "0" {
223
- return truthStateAlwaysFalsy
224
- }
225
- return truthStateAlwaysTruthy
226
- }
227
- if flags&shimchecker.TypeFlagsBigIntLiteral != 0 {
228
- text := strings.TrimSpace(checker.TypeToString(t))
229
- if text == "0n" {
230
- return truthStateAlwaysFalsy
231
- }
232
- return truthStateAlwaysTruthy
233
- }
234
- if flags&shimchecker.TypeFlagsObject != 0 {
235
- // A non-nullable object value is always truthy. `{}`, arrays,
236
- // class instances, functions, and structural records all share
237
- // this contract; only `null` / `undefined` make an object position
238
- // falsy and those flags route to the always-falsy branch above.
239
- return truthStateAlwaysTruthy
240
- }
241
- // Plain `string` / `number` / `boolean` / `bigint` / enum / symbol /
242
- // type parameter / index / template literal — every one of these can
243
- // hold both truthy and falsy values (or escapes static reasoning), so
244
- // the rule must stay silent.
245
- return truthStateMixed
151
+ if checker == nil || t == nil {
152
+ return truthStateUnknowable
153
+ }
154
+ flags := t.Flags()
155
+ if flags&(shimchecker.TypeFlagsAny|shimchecker.TypeFlagsUnknown|shimchecker.TypeFlagsNever) != 0 {
156
+ return truthStateUnknowable
157
+ }
158
+ if flags&shimchecker.TypeFlagsIntersection != 0 {
159
+ // Intersections such as `Foo & { brand: "x" }` carry semantics the
160
+ // rule cannot prove without a deeper Checker walk, so we keep the
161
+ // conservative bail.
162
+ return truthStateUnknowable
163
+ }
164
+ if flags&shimchecker.TypeFlagsUnion != 0 {
165
+ parts := t.Types()
166
+ if len(parts) == 0 {
167
+ return truthStateUnknowable
168
+ }
169
+ combined := truthState(-1)
170
+ for _, part := range parts {
171
+ if part == nil {
172
+ return truthStateUnknowable
173
+ }
174
+ state := noUnnecessaryConditionEvaluate(checker, part)
175
+ if state == truthStateUnknowable || state == truthStateMixed {
176
+ // A union with even one constituent we can't pin breaks the
177
+ // "always X" guarantee — bail.
178
+ return state
179
+ }
180
+ if combined == truthState(-1) {
181
+ combined = state
182
+ continue
183
+ }
184
+ if combined != state {
185
+ // `string | null` has both a falsy ("") and a always-falsy
186
+ // (null) outcome that disagree across constituents — fall
187
+ // back to mixed so the rule stays silent.
188
+ return truthStateMixed
189
+ }
190
+ }
191
+ if combined == truthState(-1) {
192
+ return truthStateUnknowable
193
+ }
194
+ return combined
195
+ }
196
+ // Atomic types.
197
+ if flags&(shimchecker.TypeFlagsNull|shimchecker.TypeFlagsUndefined|shimchecker.TypeFlagsVoid) != 0 {
198
+ return truthStateAlwaysFalsy
199
+ }
200
+ if flags&shimchecker.TypeFlagsBooleanLiteral != 0 {
201
+ text := checker.TypeToString(t)
202
+ if strings.TrimSpace(text) == "false" {
203
+ return truthStateAlwaysFalsy
204
+ }
205
+ if strings.TrimSpace(text) == "true" {
206
+ return truthStateAlwaysTruthy
207
+ }
208
+ return truthStateUnknowable
209
+ }
210
+ if flags&shimchecker.TypeFlagsStringLiteral != 0 {
211
+ text := strings.TrimSpace(checker.TypeToString(t))
212
+ if text == `""` || text == `''` {
213
+ return truthStateAlwaysFalsy
214
+ }
215
+ return truthStateAlwaysTruthy
216
+ }
217
+ if flags&shimchecker.TypeFlagsNumberLiteral != 0 {
218
+ text := strings.TrimSpace(checker.TypeToString(t))
219
+ // `0`, `0.0`, `-0` all stringify as `0`; everything else is truthy.
220
+ // `NaN` is not representable as a literal type, so it cannot reach
221
+ // this branch.
222
+ if text == "0" {
223
+ return truthStateAlwaysFalsy
224
+ }
225
+ return truthStateAlwaysTruthy
226
+ }
227
+ if flags&shimchecker.TypeFlagsBigIntLiteral != 0 {
228
+ text := strings.TrimSpace(checker.TypeToString(t))
229
+ if text == "0n" {
230
+ return truthStateAlwaysFalsy
231
+ }
232
+ return truthStateAlwaysTruthy
233
+ }
234
+ if flags&shimchecker.TypeFlagsObject != 0 {
235
+ // A non-nullable object value is always truthy. `{}`, arrays,
236
+ // class instances, functions, and structural records all share
237
+ // this contract; only `null` / `undefined` make an object position
238
+ // falsy and those flags route to the always-falsy branch above.
239
+ return truthStateAlwaysTruthy
240
+ }
241
+ // Plain `string` / `number` / `boolean` / `bigint` / enum / symbol /
242
+ // type parameter / index / template literal — every one of these can
243
+ // hold both truthy and falsy values (or escapes static reasoning), so
244
+ // the rule must stay silent.
245
+ return truthStateMixed
246
246
  }
247
247
 
248
248
  func init() {
249
- Register(noUnnecessaryCondition{})
249
+ Register(noUnnecessaryCondition{})
250
250
  }
@@ -7,7 +7,7 @@
7
7
  package linthost
8
8
 
9
9
  import (
10
- shimast "github.com/microsoft/typescript-go/shim/ast"
10
+ shimast "github.com/microsoft/typescript-go/shim/ast"
11
11
  )
12
12
 
13
13
  // noUnnecessaryQualifier inspects every two-segment qualified reference
@@ -22,23 +22,23 @@ import (
22
22
  type noUnnecessaryQualifier struct{}
23
23
 
24
24
  func (noUnnecessaryQualifier) Name() string {
25
- return "typescript/no-unnecessary-qualifier"
25
+ return "typescript/no-unnecessary-qualifier"
26
26
  }
27
27
  func (noUnnecessaryQualifier) Visits() []shimast.Kind {
28
- return []shimast.Kind{
29
- shimast.KindQualifiedName,
30
- shimast.KindPropertyAccessExpression,
31
- }
28
+ return []shimast.Kind{
29
+ shimast.KindQualifiedName,
30
+ shimast.KindPropertyAccessExpression,
31
+ }
32
32
  }
33
33
  func (noUnnecessaryQualifier) Check(ctx *Context, node *shimast.Node) {
34
- head := noUnnecessaryQualifierHead(node)
35
- if head == "" {
36
- return
37
- }
38
- if !noUnnecessaryQualifierHasEnclosingScope(node, head) {
39
- return
40
- }
41
- ctx.Report(node, "Qualifier `"+head+"` is the enclosing namespace or enum — drop the qualifier.")
34
+ head := noUnnecessaryQualifierHead(node)
35
+ if head == "" {
36
+ return
37
+ }
38
+ if !noUnnecessaryQualifierHasEnclosingScope(node, head) {
39
+ return
40
+ }
41
+ ctx.Report(node, "Qualifier `"+head+"` is the enclosing namespace or enum — drop the qualifier.")
42
42
  }
43
43
 
44
44
  // noUnnecessaryQualifierHead returns the LHS identifier text when the
@@ -47,35 +47,35 @@ func (noUnnecessaryQualifier) Check(ctx *Context, node *shimast.Node) {
47
47
  // accesses, or non-identifier heads — those shapes don't match the
48
48
  // "qualifier names the enclosing scope" pattern.
49
49
  func noUnnecessaryQualifierHead(node *shimast.Node) string {
50
- if node == nil {
51
- return ""
52
- }
53
- switch node.Kind {
54
- case shimast.KindQualifiedName:
55
- qn := node.AsQualifiedName()
56
- if qn == nil || qn.Left == nil {
57
- return ""
58
- }
59
- if qn.Left.Kind != shimast.KindIdentifier {
60
- return ""
61
- }
62
- return identifierText(qn.Left)
63
- case shimast.KindPropertyAccessExpression:
64
- pa := node.AsPropertyAccessExpression()
65
- if pa == nil || pa.Expression == nil || pa.Name() == nil {
66
- return ""
67
- }
68
- // Optional chains (`Foo?.Bar`) aren't redundant in the same
69
- // sense — the `?.` changes runtime behavior, so leave them be.
70
- if pa.QuestionDotToken != nil {
71
- return ""
72
- }
73
- if pa.Expression.Kind != shimast.KindIdentifier {
74
- return ""
75
- }
76
- return identifierText(pa.Expression)
77
- }
78
- return ""
50
+ if node == nil {
51
+ return ""
52
+ }
53
+ switch node.Kind {
54
+ case shimast.KindQualifiedName:
55
+ qn := node.AsQualifiedName()
56
+ if qn == nil || qn.Left == nil {
57
+ return ""
58
+ }
59
+ if qn.Left.Kind != shimast.KindIdentifier {
60
+ return ""
61
+ }
62
+ return identifierText(qn.Left)
63
+ case shimast.KindPropertyAccessExpression:
64
+ pa := node.AsPropertyAccessExpression()
65
+ if pa == nil || pa.Expression == nil || pa.Name() == nil {
66
+ return ""
67
+ }
68
+ // Optional chains (`Foo?.Bar`) aren't redundant in the same
69
+ // sense — the `?.` changes runtime behavior, so leave them be.
70
+ if pa.QuestionDotToken != nil {
71
+ return ""
72
+ }
73
+ if pa.Expression.Kind != shimast.KindIdentifier {
74
+ return ""
75
+ }
76
+ return identifierText(pa.Expression)
77
+ }
78
+ return ""
79
79
  }
80
80
 
81
81
  // noUnnecessaryQualifierHasEnclosingScope reports whether `node`
@@ -83,36 +83,36 @@ func noUnnecessaryQualifierHead(node *shimast.Node) string {
83
83
  // declaration body. The walk climbs `Parent` links until it finds a
84
84
  // matching block or hits the SourceFile root.
85
85
  func noUnnecessaryQualifierHasEnclosingScope(node *shimast.Node, head string) bool {
86
- for cur := node.Parent; cur != nil; cur = cur.Parent {
87
- switch cur.Kind {
88
- case shimast.KindModuleDeclaration:
89
- decl := cur.AsModuleDeclaration()
90
- if decl == nil || decl.Name() == nil {
91
- continue
92
- }
93
- // `declare module "fs"` carries a string-literal name and
94
- // does not bind an identifier in the surrounding scope —
95
- // skip those entirely. The rule only fires when the head
96
- // matches the enclosing namespace's identifier name.
97
- if decl.Name().Kind != shimast.KindIdentifier {
98
- continue
99
- }
100
- if identifierText(decl.Name()) == head {
101
- return true
102
- }
103
- case shimast.KindEnumDeclaration:
104
- decl := cur.AsEnumDeclaration()
105
- if decl == nil || decl.Name() == nil {
106
- continue
107
- }
108
- if identifierText(decl.Name()) == head {
109
- return true
110
- }
111
- }
112
- }
113
- return false
86
+ for cur := node.Parent; cur != nil; cur = cur.Parent {
87
+ switch cur.Kind {
88
+ case shimast.KindModuleDeclaration:
89
+ decl := cur.AsModuleDeclaration()
90
+ if decl == nil || decl.Name() == nil {
91
+ continue
92
+ }
93
+ // `declare module "fs"` carries a string-literal name and
94
+ // does not bind an identifier in the surrounding scope —
95
+ // skip those entirely. The rule only fires when the head
96
+ // matches the enclosing namespace's identifier name.
97
+ if decl.Name().Kind != shimast.KindIdentifier {
98
+ continue
99
+ }
100
+ if identifierText(decl.Name()) == head {
101
+ return true
102
+ }
103
+ case shimast.KindEnumDeclaration:
104
+ decl := cur.AsEnumDeclaration()
105
+ if decl == nil || decl.Name() == nil {
106
+ continue
107
+ }
108
+ if identifierText(decl.Name()) == head {
109
+ return true
110
+ }
111
+ }
112
+ }
113
+ return false
114
114
  }
115
115
 
116
116
  func init() {
117
- Register(noUnnecessaryQualifier{})
117
+ Register(noUnnecessaryQualifier{})
118
118
  }