@ttsc/lint 0.14.0-dev.20260529.2 → 0.14.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 (380) hide show
  1. package/README.md +23 -25
  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 +167 -5
  68. package/linthost/print_nodes_call.go +786 -77
  69. package/linthost/print_nodes_function.go +43 -0
  70. package/linthost/print_nodes_imports.go +64 -14
  71. package/linthost/print_nodes_list.go +214 -8
  72. package/linthost/print_nodes_object.go +14 -6
  73. package/linthost/print_nodes_ternary.go +147 -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 +213 -0
  83. package/linthost/rules_format_bracket_spacing.go +117 -0
  84. package/linthost/rules_format_clause_join.go +179 -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 +180 -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 +517 -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
@@ -7,64 +7,64 @@
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
  type curly struct{}
14
14
 
15
15
  func (curly) Name() string { return "curly" }
16
16
  func (curly) Visits() []shimast.Kind {
17
- return []shimast.Kind{
18
- shimast.KindIfStatement,
19
- shimast.KindWhileStatement,
20
- shimast.KindDoStatement,
21
- shimast.KindForStatement,
22
- shimast.KindForInStatement,
23
- shimast.KindForOfStatement,
24
- }
17
+ return []shimast.Kind{
18
+ shimast.KindIfStatement,
19
+ shimast.KindWhileStatement,
20
+ shimast.KindDoStatement,
21
+ shimast.KindForStatement,
22
+ shimast.KindForInStatement,
23
+ shimast.KindForOfStatement,
24
+ }
25
25
  }
26
26
  func (curly) Check(ctx *Context, node *shimast.Node) {
27
- switch node.Kind {
28
- case shimast.KindIfStatement:
29
- stmt := node.AsIfStatement()
30
- if stmt == nil {
31
- return
32
- }
33
- curlyReportNonBlock(ctx, stmt.ThenStatement, "if")
34
- // Allow `else if (...)` — the else branch carries another
35
- // IfStatement that is itself visited and reported separately.
36
- if stmt.ElseStatement != nil && stmt.ElseStatement.Kind != shimast.KindIfStatement {
37
- curlyReportNonBlock(ctx, stmt.ElseStatement, "else")
38
- }
39
- case shimast.KindWhileStatement:
40
- if stmt := node.AsWhileStatement(); stmt != nil {
41
- curlyReportNonBlock(ctx, stmt.Statement, "while")
42
- }
43
- case shimast.KindDoStatement:
44
- if stmt := node.AsDoStatement(); stmt != nil {
45
- curlyReportNonBlock(ctx, stmt.Statement, "do")
46
- }
47
- case shimast.KindForStatement:
48
- if stmt := node.AsForStatement(); stmt != nil {
49
- curlyReportNonBlock(ctx, stmt.Statement, "for")
50
- }
51
- case shimast.KindForInStatement, shimast.KindForOfStatement:
52
- if stmt := node.AsForInOrOfStatement(); stmt != nil {
53
- curlyReportNonBlock(ctx, stmt.Statement, "for")
54
- }
55
- }
27
+ switch node.Kind {
28
+ case shimast.KindIfStatement:
29
+ stmt := node.AsIfStatement()
30
+ if stmt == nil {
31
+ return
32
+ }
33
+ curlyReportNonBlock(ctx, stmt.ThenStatement, "if")
34
+ // Allow `else if (...)` — the else branch carries another
35
+ // IfStatement that is itself visited and reported separately.
36
+ if stmt.ElseStatement != nil && stmt.ElseStatement.Kind != shimast.KindIfStatement {
37
+ curlyReportNonBlock(ctx, stmt.ElseStatement, "else")
38
+ }
39
+ case shimast.KindWhileStatement:
40
+ if stmt := node.AsWhileStatement(); stmt != nil {
41
+ curlyReportNonBlock(ctx, stmt.Statement, "while")
42
+ }
43
+ case shimast.KindDoStatement:
44
+ if stmt := node.AsDoStatement(); stmt != nil {
45
+ curlyReportNonBlock(ctx, stmt.Statement, "do")
46
+ }
47
+ case shimast.KindForStatement:
48
+ if stmt := node.AsForStatement(); stmt != nil {
49
+ curlyReportNonBlock(ctx, stmt.Statement, "for")
50
+ }
51
+ case shimast.KindForInStatement, shimast.KindForOfStatement:
52
+ if stmt := node.AsForInOrOfStatement(); stmt != nil {
53
+ curlyReportNonBlock(ctx, stmt.Statement, "for")
54
+ }
55
+ }
56
56
  }
57
57
 
58
58
  // curlyReportNonBlock reports `body` when it is a single bare statement
59
59
  // instead of a Block. A nil body means there is nothing to wrap (e.g. an
60
60
  // IfStatement with no else clause), so it is silently skipped.
61
61
  func curlyReportNonBlock(ctx *Context, body *shimast.Node, keyword string) {
62
- if body == nil || body.Kind == shimast.KindBlock {
63
- return
64
- }
65
- ctx.Report(body, "Expected { after '"+keyword+"' condition.")
62
+ if body == nil || body.Kind == shimast.KindBlock {
63
+ return
64
+ }
65
+ ctx.Report(body, "Expected { after '"+keyword+"' condition.")
66
66
  }
67
67
 
68
68
  func init() {
69
- Register(curly{})
69
+ Register(curly{})
70
70
  }
@@ -18,22 +18,22 @@ type defaultCase struct{}
18
18
  func (defaultCase) Name() string { return "default-case" }
19
19
  func (defaultCase) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSwitchStatement} }
20
20
  func (defaultCase) Check(ctx *Context, node *shimast.Node) {
21
- sw := node.AsSwitchStatement()
22
- if sw == nil || sw.CaseBlock == nil {
23
- return
24
- }
25
- block := sw.CaseBlock.AsCaseBlock()
26
- if block == nil || block.Clauses == nil {
27
- return
28
- }
29
- for _, clause := range block.Clauses.Nodes {
30
- if clause != nil && clause.Kind == shimast.KindDefaultClause {
31
- return
32
- }
33
- }
34
- ctx.Report(node, "Expected a default case.")
21
+ sw := node.AsSwitchStatement()
22
+ if sw == nil || sw.CaseBlock == nil {
23
+ return
24
+ }
25
+ block := sw.CaseBlock.AsCaseBlock()
26
+ if block == nil || block.Clauses == nil {
27
+ return
28
+ }
29
+ for _, clause := range block.Clauses.Nodes {
30
+ if clause != nil && clause.Kind == shimast.KindDefaultClause {
31
+ return
32
+ }
33
+ }
34
+ ctx.Report(node, "Expected a default case.")
35
35
  }
36
36
 
37
37
  func init() {
38
- Register(defaultCase{})
38
+ Register(defaultCase{})
39
39
  }
@@ -16,31 +16,31 @@ type defaultCaseLast struct{}
16
16
 
17
17
  func (defaultCaseLast) Name() string { return "default-case-last" }
18
18
  func (defaultCaseLast) Visits() []shimast.Kind {
19
- return []shimast.Kind{shimast.KindSwitchStatement}
19
+ return []shimast.Kind{shimast.KindSwitchStatement}
20
20
  }
21
21
  func (defaultCaseLast) Check(ctx *Context, node *shimast.Node) {
22
- sw := node.AsSwitchStatement()
23
- if sw == nil || sw.CaseBlock == nil {
24
- return
25
- }
26
- block := sw.CaseBlock.AsCaseBlock()
27
- if block == nil || block.Clauses == nil {
28
- return
29
- }
30
- clauses := block.Clauses.Nodes
31
- if len(clauses) == 0 {
32
- return
33
- }
34
- last := clauses[len(clauses)-1]
35
- for i := 0; i < len(clauses)-1; i++ {
36
- clause := clauses[i]
37
- if clause != nil && clause.Kind == shimast.KindDefaultClause {
38
- _ = last
39
- ctx.Report(clause, "Default clause should be the last clause.")
40
- }
41
- }
22
+ sw := node.AsSwitchStatement()
23
+ if sw == nil || sw.CaseBlock == nil {
24
+ return
25
+ }
26
+ block := sw.CaseBlock.AsCaseBlock()
27
+ if block == nil || block.Clauses == nil {
28
+ return
29
+ }
30
+ clauses := block.Clauses.Nodes
31
+ if len(clauses) == 0 {
32
+ return
33
+ }
34
+ last := clauses[len(clauses)-1]
35
+ for i := 0; i < len(clauses)-1; i++ {
36
+ clause := clauses[i]
37
+ if clause != nil && clause.Kind == shimast.KindDefaultClause {
38
+ _ = last
39
+ ctx.Report(clause, "Default clause should be the last clause.")
40
+ }
41
+ }
42
42
  }
43
43
 
44
44
  func init() {
45
- Register(defaultCaseLast{})
45
+ Register(defaultCaseLast{})
46
46
  }
@@ -0,0 +1,213 @@
1
+ package linthost
2
+
3
+ import (
4
+ shimast "github.com/microsoft/typescript-go/shim/ast"
5
+ shimscanner "github.com/microsoft/typescript-go/shim/scanner"
6
+ )
7
+
8
+ // formatArrowParens normalizes the parentheses around a single-parameter
9
+ // arrow function, mirroring Prettier's `arrowParens`:
10
+ //
11
+ // - prefer "always" (Prettier default): a bare `x => x` gains parens,
12
+ // becoming `(x) => x`.
13
+ // - prefer "avoid": `(x) => x` drops them, becoming `x => x`.
14
+ //
15
+ // Only a single parameter that is a plain identifier with no type
16
+ // annotation, default, rest, optional `?`, or modifier is affected, every
17
+ // other shape (`(x: T)`, `({ x })`, `(...x)`, `(x = 1)`, `(x?)`, `(x, y)`,
18
+ // `()`) keeps its parentheses in both modes, exactly as Prettier does.
19
+ // `async x => x` is handled too: the modifier sits before the parameter, so
20
+ // the parameter-name span is unaffected.
21
+ //
22
+ // The rule rewrites only the parameter span (`x` <-> `(x)`), never the body
23
+ // or the `=>`, so a chained arrow `a => b => …` has each eligible arm
24
+ // normalized independently. Idempotent: a parameter already in the
25
+ // preferred shape compares equal and emits nothing.
26
+ type formatArrowParens struct{}
27
+
28
+ type formatArrowParensOptions struct {
29
+ Prefer string `json:"prefer"`
30
+ }
31
+
32
+ func (formatArrowParens) Name() string { return "format/arrow-parens" }
33
+ func (formatArrowParens) IsFormat() bool { return true }
34
+
35
+ func (formatArrowParens) Visits() []shimast.Kind {
36
+ return []shimast.Kind{shimast.KindArrowFunction}
37
+ }
38
+
39
+ func (formatArrowParens) Check(ctx *Context, node *shimast.Node) {
40
+ if ctx == nil || ctx.File == nil || node == nil {
41
+ return
42
+ }
43
+ arrow := node.AsArrowFunction()
44
+ if arrow == nil || arrow.Parameters == nil {
45
+ return
46
+ }
47
+ params := arrow.Parameters.Nodes
48
+ if len(params) != 1 || params[0] == nil {
49
+ return
50
+ }
51
+ param := params[0]
52
+ if !isBareIdentifierParam(param) {
53
+ return
54
+ }
55
+ // A type-parameter list (`<T>(x) => …`) forces the parameter parens in
56
+ // both modes (a bare `<T>x =>` is not valid), so leave such an arrow
57
+ // alone, its parens are mandatory, not stylistic.
58
+ if arrow.TypeParameters != nil && len(arrow.TypeParameters.Nodes) > 0 {
59
+ return
60
+ }
61
+ // A return-type annotation (`(x): T => …`) also requires the parens.
62
+ if arrow.Type != nil {
63
+ return
64
+ }
65
+
66
+ var opts formatArrowParensOptions
67
+ _ = ctx.DecodeOptions(&opts)
68
+ prefer := opts.Prefer
69
+ if prefer != "avoid" {
70
+ prefer = "always"
71
+ }
72
+
73
+ src := ctx.File.Text()
74
+ nameStart := shimscanner.SkipTrivia(src, param.Pos())
75
+ nameEnd := param.End()
76
+ if nameStart < 0 || nameEnd <= nameStart || nameEnd > len(src) {
77
+ return
78
+ }
79
+
80
+ // A comment in the parameter region (leading trivia, or between the name and
81
+ // its `)`/`=>`) defeats the whitespace-only paren scan below: the scan stops
82
+ // at the comment byte and reports "not wrapped", so the "always" branch would
83
+ // wrap an already-parenthesized name a second time and emit invalid
84
+ // `(/* c */ (x)) => x`. Prettier leaves such an arrow alone
85
+ // (canPrintParamsWithoutParens requires `!hasComment(parameters[0])`), so
86
+ // abstain rather than corrupt.
87
+ if arrowParamRegionHasComment(src, param.Pos(), nameStart, nameEnd) {
88
+ return
89
+ }
90
+
91
+ // Is the parameter already wrapped in `(` … `)`? Scan over whitespace on
92
+ // each side; the sole parameter of an arrow is delimited by the
93
+ // parameter-list parens when present.
94
+ openParen := scanBackForByte(src, nameStart, '(')
95
+ closeParen := scanForwardForByte(src, nameEnd, ')')
96
+ wrapped := openParen >= 0 && closeParen >= 0
97
+
98
+ switch prefer {
99
+ case "avoid":
100
+ if !wrapped {
101
+ return // already bare
102
+ }
103
+ // Replace `( … name … )` with just the name.
104
+ ctx.ReportRangeFix(
105
+ openParen,
106
+ closeParen+1,
107
+ "Single-parameter arrow should omit parentheses.",
108
+ TextEdit{Pos: openParen, End: closeParen + 1, Text: src[nameStart:nameEnd]},
109
+ )
110
+ default: // always
111
+ if wrapped {
112
+ return // already parenthesized
113
+ }
114
+ ctx.ReportRangeFix(
115
+ nameStart,
116
+ nameEnd,
117
+ "Single-parameter arrow should keep parentheses.",
118
+ TextEdit{Pos: nameStart, End: nameEnd, Text: "(" + src[nameStart:nameEnd] + ")"},
119
+ )
120
+ }
121
+ }
122
+
123
+ // isBareIdentifierParam reports whether `param` is a plain identifier
124
+ // parameter: no rest `...`, no optional `?`, no type annotation, no default,
125
+ // no modifier (a parameter property), and an identifier name. Only such a
126
+ // parameter is eligible for arrow-paren normalization; every richer shape
127
+ // keeps its parentheses in both Prettier modes.
128
+ func isBareIdentifierParam(param *shimast.Node) bool {
129
+ decl := param.AsParameterDeclaration()
130
+ if decl == nil {
131
+ return false
132
+ }
133
+ if decl.DotDotDotToken != nil || decl.QuestionToken != nil ||
134
+ decl.Type != nil || decl.Initializer != nil {
135
+ return false
136
+ }
137
+ if mods := param.Modifiers(); mods != nil && len(mods.Nodes) > 0 {
138
+ return false
139
+ }
140
+ name := param.Name()
141
+ return name != nil && name.Kind == shimast.KindIdentifier
142
+ }
143
+
144
+ // scanBackForByte returns the offset of the nearest `target` byte at or
145
+ // before `from`-1, scanning over whitespace only; -1 if a non-whitespace,
146
+ // non-target byte is reached first.
147
+ func scanBackForByte(src string, from int, target byte) int {
148
+ for i := from - 1; i >= 0; i-- {
149
+ c := src[i]
150
+ if c == target {
151
+ return i
152
+ }
153
+ if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
154
+ return -1
155
+ }
156
+ }
157
+ return -1
158
+ }
159
+
160
+ // scanForwardForByte returns the offset of the nearest `target` byte at or
161
+ // after `from`, scanning over whitespace only; -1 if a non-whitespace,
162
+ // non-target byte is reached first.
163
+ func scanForwardForByte(src string, from int, target byte) int {
164
+ for i := from; i < len(src); i++ {
165
+ c := src[i]
166
+ if c == target {
167
+ return i
168
+ }
169
+ if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
170
+ return -1
171
+ }
172
+ }
173
+ return -1
174
+ }
175
+
176
+ // arrowParamRegionHasComment reports whether a `//` or `/*` comment sits in the
177
+ // single parameter's region — its leading trivia (`[paramPos, nameStart)`) or
178
+ // the trailing trivia after the name up to the first real token (`)` or `=>`).
179
+ // The byte scan is safe here because a bare-identifier parameter region holds
180
+ // only comments, whitespace, the identifier, and parentheses (no strings:
181
+ // typed/defaulted params are already excluded by isBareIdentifierParam).
182
+ func arrowParamRegionHasComment(src string, paramPos, nameStart, nameEnd int) bool {
183
+ for i := paramPos; i+1 < nameStart && i+1 < len(src); i++ {
184
+ if src[i] == '/' && (src[i+1] == '*' || src[i+1] == '/') {
185
+ return true
186
+ }
187
+ }
188
+ // Trailing trivia after the identifier, up to `=>`. Tolerate one closing
189
+ // paren so a comment between `)` and `=>` (`(x) /* c */ => x`) — which in
190
+ // "avoid" mode would otherwise be stranded when the parens are stripped — is
191
+ // also detected (Prettier keeps the parens of an arrow with such a dangling
192
+ // comment).
193
+ sawParen := false
194
+ for i := nameEnd; i+1 < len(src); i++ {
195
+ c := src[i]
196
+ if c == ' ' || c == '\t' || c == '\r' || c == '\n' {
197
+ continue
198
+ }
199
+ if c == '/' && (src[i+1] == '*' || src[i+1] == '/') {
200
+ return true
201
+ }
202
+ if c == ')' && !sawParen {
203
+ sawParen = true
204
+ continue
205
+ }
206
+ break
207
+ }
208
+ return false
209
+ }
210
+
211
+ func init() {
212
+ Register(formatArrowParens{})
213
+ }
@@ -0,0 +1,117 @@
1
+ package linthost
2
+
3
+ import (
4
+ shimast "github.com/microsoft/typescript-go/shim/ast"
5
+ shimscanner "github.com/microsoft/typescript-go/shim/scanner"
6
+ )
7
+
8
+ // formatBracketSpacing normalizes the inner padding of single-line brace
9
+ // pairs, mirroring Prettier's `bracketSpacing`:
10
+ //
11
+ // - prefer true (Prettier default): one space just inside the braces,
12
+ // `{ x: 1 }`, `{ a, b }`, `import { foo } from "m"`.
13
+ // - prefer false: no inner space, `{x: 1}`, `{a, b}`, `import {foo}`.
14
+ //
15
+ // It applies to object literals, object binding patterns (destructuring),
16
+ // named imports/exports, and type literals, the brace kinds Prettier's
17
+ // bracketSpacing governs. Block, class, interface, enum, and module braces
18
+ // are NOT affected (their layout is owned by the indentation rules).
19
+ //
20
+ // The rule touches only a brace pair that opens and closes on the SAME
21
+ // line: a multi-line container's interior is the indentation rules' surface,
22
+ // and an empty `{}` has no interior to pad. It rewrites just the whitespace
23
+ // run immediately inside each brace, so it never disturbs the contents.
24
+ // Idempotent: a pair already in the preferred shape compares equal.
25
+ type formatBracketSpacing struct{}
26
+
27
+ type formatBracketSpacingOptions struct {
28
+ Spacing *bool `json:"spacing"`
29
+ }
30
+
31
+ func (formatBracketSpacing) Name() string { return "format/bracket-spacing" }
32
+ func (formatBracketSpacing) IsFormat() bool { return true }
33
+
34
+ func (formatBracketSpacing) Visits() []shimast.Kind {
35
+ return []shimast.Kind{
36
+ shimast.KindObjectLiteralExpression,
37
+ shimast.KindObjectBindingPattern,
38
+ shimast.KindNamedImports,
39
+ shimast.KindNamedExports,
40
+ shimast.KindTypeLiteral,
41
+ }
42
+ }
43
+
44
+ func (formatBracketSpacing) Check(ctx *Context, node *shimast.Node) {
45
+ if ctx == nil || ctx.File == nil || node == nil {
46
+ return
47
+ }
48
+ var opts formatBracketSpacingOptions
49
+ _ = ctx.DecodeOptions(&opts)
50
+ spacing := true
51
+ if opts.Spacing != nil {
52
+ spacing = *opts.Spacing
53
+ }
54
+
55
+ src := ctx.File.Text()
56
+ start := shimscanner.SkipTrivia(src, node.Pos())
57
+ end := node.End()
58
+ if start < 0 || end <= start || end > len(src) {
59
+ return
60
+ }
61
+ // The node's first byte should be `{` and last `}`; a parenthesized or
62
+ // otherwise-wrapped form is out of scope.
63
+ if src[start] != '{' || src[end-1] != '}' {
64
+ return
65
+ }
66
+ inner := src[start+1 : end-1]
67
+ if len(inner) == 0 {
68
+ return // empty `{}`, nothing to pad
69
+ }
70
+ // Multi-line: the interior belongs to the indentation rules.
71
+ for i := 0; i < len(inner); i++ {
72
+ if inner[i] == '\n' || inner[i] == '\r' {
73
+ return
74
+ }
75
+ }
76
+ // Only-whitespace interior (`{ }`) is treated as empty: collapse to the
77
+ // canonical empty form rather than padding nothing.
78
+ trimmed := trimASCIISpace(inner)
79
+ if len(trimmed) == 0 {
80
+ return
81
+ }
82
+
83
+ // Compute the desired interior: exactly one leading+trailing space when
84
+ // spacing is on, none when off.
85
+ var want string
86
+ if spacing {
87
+ want = " " + trimmed + " "
88
+ } else {
89
+ want = trimmed
90
+ }
91
+ if inner == want {
92
+ return
93
+ }
94
+ ctx.ReportRangeFix(
95
+ start+1,
96
+ end-1,
97
+ "Normalize brace spacing to match bracketSpacing.",
98
+ TextEdit{Pos: start + 1, End: end - 1, Text: want},
99
+ )
100
+ }
101
+
102
+ // trimASCIISpace strips leading and trailing spaces and tabs from s.
103
+ func trimASCIISpace(s string) string {
104
+ i := 0
105
+ for i < len(s) && (s[i] == ' ' || s[i] == '\t') {
106
+ i++
107
+ }
108
+ j := len(s)
109
+ for j > i && (s[j-1] == ' ' || s[j-1] == '\t') {
110
+ j--
111
+ }
112
+ return s[i:j]
113
+ }
114
+
115
+ func init() {
116
+ Register(formatBracketSpacing{})
117
+ }