@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.
- package/README.md +23 -25
- package/lib/defaultFormat.d.ts +10 -6
- package/lib/defaultFormat.js +10 -6
- package/lib/defaultFormat.js.map +1 -1
- package/lib/structures/ITtscLintConfig.d.ts +5 -5
- package/lib/structures/TtscLintRuleSetting.d.ts +19 -19
- package/lib/structures/{ITtscLintFormat.d.ts → format/ITtscLintFormat.d.ts} +45 -70
- package/lib/structures/format/ITtscLintFormat.js.map +1 -0
- package/lib/structures/format/ITtscLintFormatJsDoc.d.ts +15 -0
- package/lib/structures/format/ITtscLintFormatJsDoc.js +3 -0
- package/lib/structures/format/ITtscLintFormatJsDoc.js.map +1 -0
- package/lib/structures/format/ITtscLintFormatSortImports.d.ts +54 -0
- package/lib/structures/format/ITtscLintFormatSortImports.js +3 -0
- package/lib/structures/format/ITtscLintFormatSortImports.js.map +1 -0
- package/lib/structures/format/index.d.ts +3 -0
- package/lib/structures/format/index.js +20 -0
- package/lib/structures/format/index.js.map +1 -0
- package/lib/structures/index.d.ts +1 -1
- package/lib/structures/index.js +1 -1
- package/lib/structures/index.js.map +1 -1
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +18 -27
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +4 -5
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -1
- package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +29 -33
- package/lib/structures/rules/ITtscLintContributorRules.d.ts +6 -7
- package/lib/structures/rules/ITtscLintCoreRules.d.ts +380 -408
- package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +5 -5
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js +2 -2
- package/lib/structures/rules/ITtscLintCypressRules.d.ts +34 -38
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +21 -24
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +2 -2
- package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +51 -56
- package/lib/structures/rules/ITtscLintJestRules.d.ts +63 -74
- package/lib/structures/rules/ITtscLintJsdocRules.d.ts +47 -54
- package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +94 -102
- package/lib/structures/rules/ITtscLintNextjsRules.d.ts +50 -55
- package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +104 -122
- package/lib/structures/rules/ITtscLintPromiseRules.d.ts +62 -71
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +4 -4
- package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +17 -19
- package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +8 -10
- package/lib/structures/rules/ITtscLintReactRuleOptions.js +1 -2
- package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -1
- package/lib/structures/rules/ITtscLintReactRules.d.ts +91 -104
- package/lib/structures/rules/ITtscLintRegexpRules.d.ts +46 -54
- package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +7 -8
- package/lib/structures/rules/ITtscLintSecurityRules.d.ts +45 -52
- package/lib/structures/rules/ITtscLintSolidRules.d.ts +53 -56
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +3 -4
- package/lib/structures/rules/ITtscLintStorybookRules.d.ts +60 -69
- package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +31 -37
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +2 -3
- package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +102 -119
- package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +460 -518
- package/lib/structures/rules/ITtscLintVitestRules.d.ts +43 -51
- package/linthost/config.go +89 -72
- package/linthost/config_format.go +265 -99
- package/linthost/directives.go +5 -1
- package/linthost/display_width.go +72 -0
- package/linthost/fix.go +26 -1
- package/linthost/format.go +222 -25
- package/linthost/format_editor_settings.go +262 -0
- package/linthost/lsp.go +8 -4
- package/linthost/print_dispatch.go +3 -0
- package/linthost/print_doc.go +13 -0
- package/linthost/print_engine.go +68 -11
- package/linthost/print_nodes_array.go +167 -5
- package/linthost/print_nodes_call.go +786 -77
- package/linthost/print_nodes_function.go +43 -0
- package/linthost/print_nodes_imports.go +64 -14
- package/linthost/print_nodes_list.go +214 -8
- package/linthost/print_nodes_object.go +14 -6
- package/linthost/print_nodes_ternary.go +147 -0
- package/linthost/rules_boundaries.go +400 -400
- package/linthost/rules_camelcase.go +81 -81
- package/linthost/rules_complexity.go +52 -51
- package/linthost/rules_consistent_return.go +81 -81
- package/linthost/rules_core_extra.go +472 -472
- package/linthost/rules_curly.go +43 -43
- package/linthost/rules_default_case.go +15 -15
- package/linthost/rules_default_case_last.go +22 -22
- package/linthost/rules_format_arrow_parens.go +213 -0
- package/linthost/rules_format_bracket_spacing.go +117 -0
- package/linthost/rules_format_clause_join.go +179 -0
- package/linthost/rules_format_declaration_header.go +664 -0
- package/linthost/rules_format_indent.go +616 -0
- package/linthost/rules_format_jsdoc.go +4 -4
- package/linthost/rules_format_orphan_semi.go +106 -0
- package/linthost/rules_format_parameter_properties.go +175 -0
- package/linthost/rules_format_print_width.go +180 -69
- package/linthost/rules_format_quote_props.go +169 -0
- package/linthost/rules_format_quotes.go +75 -29
- package/linthost/rules_format_semi.go +185 -10
- package/linthost/rules_format_sort_imports.go +517 -121
- package/linthost/rules_format_statement_split.go +368 -0
- package/linthost/rules_format_ternary_nullish_parens.go +77 -0
- package/linthost/rules_format_trailing_comma.go +21 -2
- package/linthost/rules_format_whitespace.go +336 -0
- package/linthost/rules_functional.go +688 -688
- package/linthost/rules_gap.go +146 -11
- package/linthost/rules_grouped_accessor_pairs.go +60 -60
- package/linthost/rules_guard_for_in.go +122 -122
- package/linthost/rules_id_length.go +44 -44
- package/linthost/rules_imports.go +11 -3
- package/linthost/rules_init_declarations.go +25 -25
- package/linthost/rules_jsx_a11y.go +844 -844
- package/linthost/rules_max_classes_per_file.go +24 -24
- package/linthost/rules_max_depth.go +43 -43
- package/linthost/rules_max_lines.go +53 -53
- package/linthost/rules_max_lines_per_function.go +28 -28
- package/linthost/rules_max_nested_callbacks.go +26 -26
- package/linthost/rules_max_params.go +20 -20
- package/linthost/rules_max_statements.go +29 -29
- package/linthost/rules_nextjs.go +5 -5
- package/linthost/rules_no_else_return.go +38 -38
- package/linthost/rules_no_empty_named_blocks.go +45 -45
- package/linthost/rules_no_import_assign.go +96 -96
- package/linthost/rules_no_invalid_this.go +19 -19
- package/linthost/rules_no_loop_func.go +43 -43
- package/linthost/rules_no_magic_numbers.go +60 -60
- package/linthost/rules_no_mixed_operators.go +44 -44
- package/linthost/rules_no_param_reassign.go +64 -64
- package/linthost/rules_no_restricted_imports.go +45 -45
- package/linthost/rules_no_restricted_syntax.go +17 -17
- package/linthost/rules_no_shadow.go +112 -112
- package/linthost/rules_no_unreachable.go +36 -36
- package/linthost/rules_no_useless_assignment.go +79 -79
- package/linthost/rules_no_useless_constructor.go +167 -167
- package/linthost/rules_no_useless_return.go +28 -28
- package/linthost/rules_prefer_arrow_callback.go +74 -74
- package/linthost/rules_prefer_destructuring.go +61 -61
- package/linthost/rules_prefer_named_capture_group.go +87 -87
- package/linthost/rules_prefer_rest_params.go +61 -61
- package/linthost/rules_promise.go +800 -800
- package/linthost/rules_react.go +600 -600
- package/linthost/rules_react_extras.go +162 -162
- package/linthost/rules_react_hooks.go +2 -2
- package/linthost/rules_react_perf.go +231 -231
- package/linthost/rules_regexp.go +293 -293
- package/linthost/rules_security.go +613 -613
- package/linthost/rules_sort_imports.go +37 -37
- package/linthost/rules_sort_keys.go +88 -88
- package/linthost/rules_suggestions.go +13 -0
- package/linthost/rules_ts.go +2 -2
- package/linthost/rules_ts_async.go +247 -247
- package/linthost/rules_ts_class_literal_property_style.go +64 -64
- package/linthost/rules_ts_consistent_type_exports.go +209 -209
- package/linthost/rules_ts_explicit_function_return_type.go +35 -35
- package/linthost/rules_ts_extra.go +6 -2
- package/linthost/rules_ts_no_base_to_string.go +140 -140
- package/linthost/rules_ts_no_confusing_void.go +28 -28
- package/linthost/rules_ts_no_deprecated.go +110 -110
- package/linthost/rules_ts_no_for_in_array.go +45 -45
- package/linthost/rules_ts_no_magic_numbers.go +67 -67
- package/linthost/rules_ts_no_meaningless_void_operator.go +44 -44
- package/linthost/rules_ts_no_misused_spread.go +64 -64
- package/linthost/rules_ts_no_redundant_type_constituents.go +72 -72
- package/linthost/rules_ts_no_restricted_types.go +28 -28
- package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +87 -87
- package/linthost/rules_ts_no_unnecessary_condition.go +184 -184
- package/linthost/rules_ts_no_unnecessary_qualifier.go +72 -72
- package/linthost/rules_ts_no_unnecessary_template_expression.go +120 -120
- package/linthost/rules_ts_no_unnecessary_type_arguments.go +171 -171
- package/linthost/rules_ts_no_unnecessary_type_assertion.go +90 -90
- package/linthost/rules_ts_no_unsafe_argument.go +50 -50
- package/linthost/rules_ts_no_unsafe_assignment.go +60 -60
- package/linthost/rules_ts_no_unsafe_call.go +40 -40
- package/linthost/rules_ts_no_unsafe_enum_comparison.go +147 -147
- package/linthost/rules_ts_no_unsafe_member_access.go +29 -29
- package/linthost/rules_ts_no_unsafe_return.go +64 -64
- package/linthost/rules_ts_no_unsafe_unary_minus.go +42 -42
- package/linthost/rules_ts_no_useless_constructor.go +20 -20
- package/linthost/rules_ts_non_nullable_type_assertion_style.go +60 -60
- package/linthost/rules_ts_parameter_properties.go +10 -10
- package/linthost/rules_ts_prefer_find.go +116 -116
- package/linthost/rules_ts_prefer_includes.go +173 -173
- package/linthost/rules_ts_prefer_nullish_coalescing.go +54 -54
- package/linthost/rules_ts_prefer_optional_chain.go +156 -156
- package/linthost/rules_ts_prefer_promise_reject_errors.go +104 -104
- package/linthost/rules_ts_prefer_readonly.go +31 -31
- package/linthost/rules_ts_prefer_reduce_type_parameter.go +74 -74
- package/linthost/rules_ts_prefer_regexp_exec.go +69 -69
- package/linthost/rules_ts_prefer_return_this_type.go +79 -79
- package/linthost/rules_ts_prefer_string_starts_ends_with.go +237 -237
- package/linthost/rules_ts_promise_function_async.go +41 -41
- package/linthost/rules_ts_related_getter_setter_pairs.go +61 -61
- package/linthost/rules_ts_require_array_sort_compare.go +58 -58
- package/linthost/rules_ts_restrict_plus_operands.go +82 -82
- package/linthost/rules_ts_restrict_template_expressions.go +50 -50
- package/linthost/rules_ts_simple.go +249 -249
- package/linthost/rules_ts_sort_type_constituents.go +88 -88
- package/linthost/rules_ts_strict_boolean_expressions.go +103 -103
- package/linthost/rules_ts_switch_exhaustiveness_check.go +90 -90
- package/linthost/rules_ts_unbound_method.go +65 -65
- package/linthost/rules_tsdoc.go +88 -88
- package/linthost/rules_unicorn_better_regex.go +1 -1
- package/linthost/rules_unicorn_catch_error_name.go +19 -19
- package/linthost/rules_unicorn_consistent_assert.go +20 -20
- package/linthost/rules_unicorn_consistent_date_clone.go +27 -27
- package/linthost/rules_unicorn_consistent_destructuring.go +3 -3
- package/linthost/rules_unicorn_consistent_empty_array_spread.go +34 -34
- package/linthost/rules_unicorn_consistent_existence_index_check.go +42 -42
- package/linthost/rules_unicorn_consistent_function_scoping.go +3 -3
- package/linthost/rules_unicorn_consistent_template_literal_escape.go +3 -3
- package/linthost/rules_unicorn_custom_error_definition.go +92 -92
- package/linthost/rules_unicorn_empty_brace_spaces.go +47 -47
- package/linthost/rules_unicorn_error_message.go +34 -34
- package/linthost/rules_unicorn_escape_case.go +14 -14
- package/linthost/rules_unicorn_expiring_todo_comments.go +36 -36
- package/linthost/rules_unicorn_explicit_length_check.go +51 -51
- package/linthost/rules_unicorn_filename_case.go +1 -1
- package/linthost/rules_unicorn_import_style.go +1 -1
- package/linthost/rules_unicorn_isolated_functions.go +2 -2
- package/linthost/rules_unicorn_new_for_builtins.go +49 -49
- package/linthost/rules_unicorn_no_abusive_eslint_disable.go +31 -31
- package/linthost/rules_unicorn_no_accessor_recursion.go +69 -69
- package/linthost/rules_unicorn_no_anonymous_default_export.go +40 -40
- package/linthost/rules_unicorn_no_array_callback_reference.go +33 -33
- package/linthost/rules_unicorn_no_array_for_each.go +14 -14
- package/linthost/rules_unicorn_no_array_method_this_argument.go +29 -29
- package/linthost/rules_unicorn_no_array_reduce.go +15 -15
- package/linthost/rules_unicorn_no_array_reverse.go +17 -17
- package/linthost/rules_unicorn_no_array_sort.go +17 -17
- package/linthost/rules_unicorn_no_await_expression_member.go +12 -12
- package/linthost/rules_unicorn_no_await_in_promise_methods.go +38 -38
- package/linthost/rules_unicorn_no_console_spaces.go +30 -30
- package/linthost/rules_unicorn_no_document_cookie.go +13 -13
- package/linthost/rules_unicorn_no_empty_file.go +16 -16
- package/linthost/rules_unicorn_no_for_loop.go +58 -58
- package/linthost/rules_unicorn_no_hex_escape.go +11 -11
- package/linthost/rules_unicorn_no_immediate_mutation.go +55 -55
- package/linthost/rules_unicorn_no_instanceof_builtins.go +34 -34
- package/linthost/rules_unicorn_no_invalid_fetch_options.go +52 -52
- package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +25 -25
- package/linthost/rules_unicorn_no_keyword_prefix.go +56 -56
- package/linthost/rules_unicorn_no_lonely_if.go +21 -21
- package/linthost/rules_unicorn_no_magic_array_flat_depth.go +22 -22
- package/linthost/rules_unicorn_no_named_default.go +25 -25
- package/linthost/rules_unicorn_no_negated_condition.go +54 -54
- package/linthost/rules_unicorn_no_negation_in_equality_check.go +23 -23
- package/linthost/rules_unicorn_no_nested_ternary.go +15 -15
- package/linthost/rules_unicorn_no_new_array.go +5 -5
- package/linthost/rules_unicorn_no_new_buffer.go +5 -5
- package/linthost/rules_unicorn_no_null.go +2 -2
- package/linthost/rules_unicorn_no_object_as_default_parameter.go +19 -19
- package/linthost/rules_unicorn_no_process_exit.go +17 -17
- package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +29 -29
- package/linthost/rules_unicorn_no_static_only_class.go +27 -27
- package/linthost/rules_unicorn_no_thenable.go +47 -47
- package/linthost/rules_unicorn_no_this_assignment.go +10 -10
- package/linthost/rules_unicorn_no_typeof_undefined.go +31 -31
- package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +23 -23
- package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +37 -37
- package/linthost/rules_unicorn_no_unnecessary_await.go +24 -24
- package/linthost/rules_unicorn_no_unnecessary_slice_end.go +22 -22
- package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +67 -67
- package/linthost/rules_unicorn_no_unreadable_iife.go +22 -22
- package/linthost/rules_unicorn_no_useless_collection_argument.go +34 -34
- package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +18 -18
- package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +49 -49
- package/linthost/rules_unicorn_no_useless_iterator_to_array.go +41 -41
- package/linthost/rules_unicorn_no_useless_length_check.go +82 -82
- package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +42 -42
- package/linthost/rules_unicorn_no_useless_spread.go +38 -38
- package/linthost/rules_unicorn_no_useless_switch_case.go +29 -29
- package/linthost/rules_unicorn_no_useless_undefined.go +25 -25
- package/linthost/rules_unicorn_no_zero_fractions.go +17 -17
- package/linthost/rules_unicorn_number_literal_case.go +33 -33
- package/linthost/rules_unicorn_numeric_separators_style.go +36 -36
- package/linthost/rules_unicorn_prefer_add_event_listener.go +30 -30
- package/linthost/rules_unicorn_prefer_array_find.go +27 -27
- package/linthost/rules_unicorn_prefer_array_flat.go +25 -25
- package/linthost/rules_unicorn_prefer_array_flat_map.go +37 -37
- package/linthost/rules_unicorn_prefer_array_index_of.go +108 -108
- package/linthost/rules_unicorn_prefer_array_some.go +43 -43
- package/linthost/rules_unicorn_prefer_at.go +42 -42
- package/linthost/rules_unicorn_prefer_bigint_literals.go +42 -42
- package/linthost/rules_unicorn_prefer_blob_reading_methods.go +15 -15
- package/linthost/rules_unicorn_prefer_class_fields.go +57 -57
- package/linthost/rules_unicorn_prefer_classlist_toggle.go +76 -76
- package/linthost/rules_unicorn_prefer_code_point.go +21 -21
- package/linthost/rules_unicorn_prefer_date_now.go +47 -47
- package/linthost/rules_unicorn_prefer_default_parameters.go +96 -96
- package/linthost/rules_unicorn_prefer_dom_node_append.go +14 -14
- package/linthost/rules_unicorn_prefer_dom_node_dataset.go +27 -27
- package/linthost/rules_unicorn_prefer_dom_node_remove.go +17 -17
- package/linthost/rules_unicorn_prefer_dom_node_text_content.go +11 -11
- package/linthost/rules_unicorn_prefer_event_target.go +10 -10
- package/linthost/rules_unicorn_prefer_export_from.go +99 -99
- package/linthost/rules_unicorn_prefer_global_this.go +91 -91
- package/linthost/rules_unicorn_prefer_import_meta_properties.go +38 -38
- package/linthost/rules_unicorn_prefer_includes.go +108 -108
- package/linthost/rules_unicorn_prefer_json_parse_buffer.go +37 -37
- package/linthost/rules_unicorn_prefer_keyboard_event_key.go +10 -10
- package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +20 -20
- package/linthost/rules_unicorn_prefer_math_min_max.go +33 -33
- package/linthost/rules_unicorn_prefer_math_trunc.go +32 -32
- package/linthost/rules_unicorn_prefer_modern_dom_apis.go +18 -18
- package/linthost/rules_unicorn_prefer_modern_math_apis.go +38 -38
- package/linthost/rules_unicorn_prefer_module.go +22 -22
- package/linthost/rules_unicorn_prefer_native_coercion_functions.go +73 -73
- package/linthost/rules_unicorn_prefer_negative_index.go +46 -46
- package/linthost/rules_unicorn_prefer_node_protocol.go +90 -90
- package/linthost/rules_unicorn_prefer_number_properties.go +57 -57
- package/linthost/rules_unicorn_prefer_object_from_entries.go +26 -26
- package/linthost/rules_unicorn_prefer_optional_catch_binding.go +24 -24
- package/linthost/rules_unicorn_prefer_prototype_methods.go +25 -25
- package/linthost/rules_unicorn_prefer_query_selector.go +25 -25
- package/linthost/rules_unicorn_prefer_reflect_apply.go +10 -10
- package/linthost/rules_unicorn_prefer_regexp_test_rule.go +47 -47
- package/linthost/rules_unicorn_prefer_response_static_json.go +26 -26
- package/linthost/rules_unicorn_prefer_set_has.go +16 -16
- package/linthost/rules_unicorn_prefer_set_size.go +22 -22
- package/linthost/rules_unicorn_prefer_simple_condition_first.go +3 -3
- package/linthost/rules_unicorn_prefer_single_call.go +59 -59
- package/linthost/rules_unicorn_prefer_spread.go +24 -24
- package/linthost/rules_unicorn_prefer_string_raw.go +12 -12
- package/linthost/rules_unicorn_prefer_string_replace_all.go +46 -46
- package/linthost/rules_unicorn_prefer_string_slice.go +17 -17
- package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +104 -104
- package/linthost/rules_unicorn_prefer_string_trim_start_end.go +21 -21
- package/linthost/rules_unicorn_prefer_structured_clone.go +36 -36
- package/linthost/rules_unicorn_prefer_switch.go +65 -65
- package/linthost/rules_unicorn_prefer_ternary.go +35 -35
- package/linthost/rules_unicorn_prefer_top_level_await.go +34 -34
- package/linthost/rules_unicorn_prefer_type_error.go +84 -84
- package/linthost/rules_unicorn_prevent_abbreviations.go +68 -68
- package/linthost/rules_unicorn_relative_url_style.go +19 -19
- package/linthost/rules_unicorn_require_array_join_separator.go +18 -18
- package/linthost/rules_unicorn_require_module_attributes.go +25 -25
- package/linthost/rules_unicorn_require_module_specifiers.go +28 -28
- package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +18 -18
- package/linthost/rules_unicorn_require_post_message_target_origin.go +18 -18
- package/linthost/rules_unicorn_string_content.go +1 -1
- package/linthost/rules_unicorn_switch_case_braces.go +16 -16
- package/linthost/rules_unicorn_switch_case_break_position.go +3 -3
- package/linthost/rules_unicorn_template_indent.go +1 -1
- package/linthost/rules_unicorn_text_encoding_identifier_case.go +36 -36
- package/linthost/rules_unicorn_throw_new_error.go +30 -30
- package/linthost/rules_var.go +273 -3
- package/package.json +3 -3
- package/src/defaultFormat.ts +11 -7
- package/src/structures/ITtscLintConfig.ts +5 -5
- package/src/structures/TtscLintRuleSetting.ts +19 -19
- package/src/structures/{ITtscLintFormat.ts → format/ITtscLintFormat.ts} +48 -75
- package/src/structures/format/ITtscLintFormatJsDoc.ts +16 -0
- package/src/structures/format/ITtscLintFormatSortImports.ts +62 -0
- package/src/structures/format/index.ts +3 -0
- package/src/structures/index.ts +1 -1
- package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +20 -31
- package/src/structures/rules/ITtscLintBoundariesRules.ts +32 -36
- package/src/structures/rules/ITtscLintContributorRules.ts +6 -7
- package/src/structures/rules/ITtscLintCoreRules.ts +380 -408
- package/src/structures/rules/ITtscLintCypressRuleOptions.ts +5 -5
- package/src/structures/rules/ITtscLintCypressRules.ts +34 -38
- package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +28 -41
- package/src/structures/rules/ITtscLintFunctionalRules.ts +51 -56
- package/src/structures/rules/ITtscLintJestRules.ts +63 -74
- package/src/structures/rules/ITtscLintJsdocRules.ts +47 -54
- package/src/structures/rules/ITtscLintJsxA11yRules.ts +94 -102
- package/src/structures/rules/ITtscLintNextjsRules.ts +50 -55
- package/src/structures/rules/ITtscLintPlaywrightRules.ts +104 -122
- package/src/structures/rules/ITtscLintPromiseRules.ts +62 -71
- package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +4 -4
- package/src/structures/rules/ITtscLintReactPerfRules.ts +17 -19
- package/src/structures/rules/ITtscLintReactRuleOptions.ts +8 -10
- package/src/structures/rules/ITtscLintReactRules.ts +91 -104
- package/src/structures/rules/ITtscLintRegexpRules.ts +46 -54
- package/src/structures/rules/ITtscLintRuleOptionsMap.ts +7 -8
- package/src/structures/rules/ITtscLintSecurityRules.ts +45 -52
- package/src/structures/rules/ITtscLintSolidRules.ts +53 -56
- package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +3 -4
- package/src/structures/rules/ITtscLintStorybookRules.ts +60 -69
- package/src/structures/rules/ITtscLintTanstackQueryRules.ts +31 -37
- package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +2 -3
- package/src/structures/rules/ITtscLintTestingLibraryRules.ts +102 -119
- package/src/structures/rules/ITtscLintTypeScriptRules.ts +460 -518
- package/src/structures/rules/ITtscLintVitestRules.ts +43 -51
- package/lib/structures/ITtscLintFormat.js.map +0 -1
- /package/lib/structures/{ITtscLintFormat.js → format/ITtscLintFormat.js} +0 -0
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
package linthost
|
|
15
15
|
|
|
16
16
|
import (
|
|
17
|
-
|
|
17
|
+
"strings"
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
20
20
|
)
|
|
21
21
|
|
|
22
22
|
type unicornTextEncodingIdentifierCase struct{}
|
|
@@ -25,48 +25,48 @@ type unicornTextEncodingIdentifierCase struct{}
|
|
|
25
25
|
// spelling. Authors who already wrote the canonical form pass; anything
|
|
26
26
|
// else with the same lowercased label fires.
|
|
27
27
|
var unicornCanonicalTextEncodings = map[string]string{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
"utf-8": "utf-8",
|
|
29
|
+
"utf-16le": "utf-16le",
|
|
30
|
+
"utf-16be": "utf-16be",
|
|
31
|
+
"ascii": "ascii",
|
|
32
|
+
"latin1": "latin1",
|
|
33
|
+
"iso-8859-1": "iso-8859-1",
|
|
34
|
+
"windows-1252": "windows-1252",
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
func (unicornTextEncodingIdentifierCase) Name() string {
|
|
38
|
-
|
|
38
|
+
return "unicorn/text-encoding-identifier-case"
|
|
39
39
|
}
|
|
40
40
|
func (unicornTextEncodingIdentifierCase) Visits() []shimast.Kind {
|
|
41
|
-
|
|
41
|
+
return []shimast.Kind{shimast.KindStringLiteral, shimast.KindNoSubstitutionTemplateLiteral}
|
|
42
42
|
}
|
|
43
43
|
func (unicornTextEncodingIdentifierCase) Check(ctx *Context, node *shimast.Node) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
44
|
+
text := stringLiteralText(node)
|
|
45
|
+
if text == "" {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
lower := strings.ToLower(text)
|
|
49
|
+
canonical, ok := unicornCanonicalTextEncodings[lower]
|
|
50
|
+
if !ok {
|
|
51
|
+
// `utf8`/`UTF8` share a canonical form with `utf-8` but lowercase
|
|
52
|
+
// differently — handle the hyphen-stripped aliases explicitly.
|
|
53
|
+
switch lower {
|
|
54
|
+
case "utf8":
|
|
55
|
+
canonical = "utf-8"
|
|
56
|
+
case "utf16le":
|
|
57
|
+
canonical = "utf-16le"
|
|
58
|
+
case "utf16be":
|
|
59
|
+
canonical = "utf-16be"
|
|
60
|
+
default:
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if text == canonical {
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
ctx.Report(node, "Use the canonical lowercase form for text-encoding identifiers (e.g. `utf-8`).")
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
func init() {
|
|
71
|
-
|
|
71
|
+
Register(unicornTextEncodingIdentifierCase{})
|
|
72
72
|
}
|
|
@@ -17,45 +17,45 @@ package linthost
|
|
|
17
17
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
18
18
|
|
|
19
19
|
var unicornThrowNewErrorBuiltinNames = map[string]struct{}{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
"Error": {},
|
|
21
|
+
"TypeError": {},
|
|
22
|
+
"RangeError": {},
|
|
23
|
+
"SyntaxError": {},
|
|
24
|
+
"ReferenceError": {},
|
|
25
|
+
"EvalError": {},
|
|
26
|
+
"URIError": {},
|
|
27
|
+
"AggregateError": {},
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
type unicornThrowNewError struct{}
|
|
31
31
|
|
|
32
32
|
func (unicornThrowNewError) Name() string { return "unicorn/throw-new-error" }
|
|
33
33
|
func (unicornThrowNewError) Visits() []shimast.Kind {
|
|
34
|
-
|
|
34
|
+
return []shimast.Kind{shimast.KindThrowStatement}
|
|
35
35
|
}
|
|
36
36
|
func (unicornThrowNewError) Check(ctx *Context, node *shimast.Node) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
37
|
+
throw := node.AsThrowStatement()
|
|
38
|
+
if throw == nil {
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
expr := stripParens(throw.Expression)
|
|
42
|
+
if expr == nil || expr.Kind != shimast.KindCallExpression {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
call := expr.AsCallExpression()
|
|
46
|
+
if call == nil {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
name := identifierText(call.Expression)
|
|
50
|
+
if name == "" {
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
if _, ok := unicornThrowNewErrorBuiltinNames[name]; !ok {
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
ctx.Report(expr, "Use `new` when throwing an error.")
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
func init() {
|
|
60
|
-
|
|
60
|
+
Register(unicornThrowNewError{})
|
|
61
61
|
}
|
package/linthost/rules_var.go
CHANGED
|
@@ -20,20 +20,272 @@ func (noVar) Check(ctx *Context, node *shimast.Node) {
|
|
|
20
20
|
return
|
|
21
21
|
}
|
|
22
22
|
if shimast.IsVar(stmt.DeclarationList) {
|
|
23
|
+
const message = "Unexpected var, use let or const instead."
|
|
23
24
|
start := keywordStart(ctx.File, stmt.DeclarationList, "var")
|
|
24
|
-
if start >= 0 {
|
|
25
|
+
if start >= 0 && isNoVarAutoFixSafe(ctx, node) {
|
|
25
26
|
ctx.ReportRangeFix(
|
|
26
27
|
start,
|
|
27
28
|
start+len("var"),
|
|
28
|
-
|
|
29
|
+
message,
|
|
29
30
|
TextEdit{Pos: start, End: start + len("var"), Text: "let"},
|
|
30
31
|
)
|
|
31
32
|
return
|
|
32
33
|
}
|
|
33
|
-
ctx.Report(node,
|
|
34
|
+
ctx.Report(node, message)
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
// isNoVarAutoFixSafe reports whether rewriting a `var` statement's keyword to
|
|
39
|
+
// `let` is safe using only AST-local information (no scope/data-flow engine).
|
|
40
|
+
// It mirrors the conservative posture of isEqeqeqAutoFixSafe: over-declining
|
|
41
|
+
// is fine, corrupting source is not. Blindly turning every `var` into `let`
|
|
42
|
+
// breaks two real shapes that `var` hoisting tolerates but `let` does not:
|
|
43
|
+
// - redeclaration (`var x=1; var x=2;`) → two `let x` is a SyntaxError;
|
|
44
|
+
// - use-before-declaration (a binding referenced above its own line) →
|
|
45
|
+
// `let` makes that reference a TDZ ReferenceError.
|
|
46
|
+
//
|
|
47
|
+
// Five corruption holes were patched piecemeal here before (var-vs-var,
|
|
48
|
+
// for-header var, function/class redeclaration, mixed destructuring sibling,
|
|
49
|
+
// object-literal shorthand, use-before-declaration). That whack-a-mole is
|
|
50
|
+
// replaced by one conservative rule with two preconditions; the fix is
|
|
51
|
+
// emitted only if BOTH hold:
|
|
52
|
+
//
|
|
53
|
+
// 1. Single binding in the whole file. The declared name is introduced by
|
|
54
|
+
// EXACTLY ONE binding position anywhere in the source — counting every
|
|
55
|
+
// binding-introducing slot of that identifier: variable declarations and
|
|
56
|
+
// destructuring leaves, function/class/enum/module declarations,
|
|
57
|
+
// parameters and catch bindings, and import bindings. More than one such
|
|
58
|
+
// position → decline. This single count subsumes every prior
|
|
59
|
+
// redeclaration arm (var-vs-var, var-vs-param, var-vs-function, mixed
|
|
60
|
+
// destructure siblings, for-header var, …). It over-declines harmless
|
|
61
|
+
// cross-scope same-name bindings, which never corrupts.
|
|
62
|
+
// 2. No use-before-declaration / TDZ. The declared name is not referenced as
|
|
63
|
+
// a VALUE before the statement's Pos(). A non-reference occurrence of the
|
|
64
|
+
// same text — a member name (`o.x`), an object-literal key (`{x:1}`), a
|
|
65
|
+
// statement label (`x:`), or a type reference (`: x`) — binds no value and
|
|
66
|
+
// must not force a decline; isValueReferenceIdentifier classifies these.
|
|
67
|
+
//
|
|
68
|
+
// The var statement being fixed must itself be a single plain identifier
|
|
69
|
+
// declarator so the keyword rewrite has a simple `let x` rename target; a
|
|
70
|
+
// destructuring var (`var {a}=o`) or a multi-binding list is declined here
|
|
71
|
+
// even though its names might each bind only once.
|
|
72
|
+
func isNoVarAutoFixSafe(ctx *Context, node *shimast.Node) bool {
|
|
73
|
+
if ctx == nil || ctx.File == nil {
|
|
74
|
+
return false
|
|
75
|
+
}
|
|
76
|
+
// Precondition: the var being fixed is a single plain identifier declarator.
|
|
77
|
+
// variableStatementBindingNames returns plain identifier names only, so a
|
|
78
|
+
// destructuring declarator yields zero names; requiring exactly one name AND
|
|
79
|
+
// exactly one VariableDeclaration node rejects both multi-binding lists and
|
|
80
|
+
// any destructured (or destructured-sibling) declarator.
|
|
81
|
+
names := variableStatementBindingNames(node)
|
|
82
|
+
if len(names) != 1 {
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
if list := node.AsVariableStatement().DeclarationList.AsVariableDeclarationList(); list == nil ||
|
|
86
|
+
list.Declarations == nil || len(list.Declarations.Nodes) != 1 {
|
|
87
|
+
return false
|
|
88
|
+
}
|
|
89
|
+
target := names[0]
|
|
90
|
+
|
|
91
|
+
declPos := node.Pos()
|
|
92
|
+
// The single declarator's initializer subtree. A value reference to `target`
|
|
93
|
+
// inside this range is a self-reference that runs while `target` is still in
|
|
94
|
+
// its temporal dead zone under `let` (`var x = typeof x;`, `var x = x;`,
|
|
95
|
+
// `var x = (() => x)();`), so it must also force a decline even though its
|
|
96
|
+
// Pos() is AFTER the statement's start. initStart/initEnd are -1 when the
|
|
97
|
+
// declarator has no initializer, which disables the range check.
|
|
98
|
+
initStart, initEnd := -1, -1
|
|
99
|
+
if list := node.AsVariableStatement().DeclarationList.AsVariableDeclarationList(); list != nil &&
|
|
100
|
+
list.Declarations != nil && len(list.Declarations.Nodes) == 1 {
|
|
101
|
+
if decl := list.Declarations.Nodes[0].AsVariableDeclaration(); decl != nil && decl.Initializer != nil {
|
|
102
|
+
initStart, initEnd = decl.Initializer.Pos(), decl.Initializer.End()
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
bindingCount := 0
|
|
106
|
+
referencedBefore := false
|
|
107
|
+
walkDescendants(ctx.File.AsNode(), func(child *shimast.Node) {
|
|
108
|
+
// Binding count: every position that introduces the name `target` as a
|
|
109
|
+
// binding (a declaration), not a value reference. Two or more positions
|
|
110
|
+
// anywhere in the file decline the fix.
|
|
111
|
+
for _, name := range bindingNamesIntroducedBy(child) {
|
|
112
|
+
if name == target {
|
|
113
|
+
bindingCount++
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// TDZ: a value reference to `target` turns into a ReferenceError under
|
|
117
|
+
// `let` when it executes while `target` is still in its temporal dead
|
|
118
|
+
// zone. Two cases decline:
|
|
119
|
+
// - a reference BEFORE the var's own position (`log(x); var x = 1;`);
|
|
120
|
+
// - a self-reference WITHIN the declarator's own initializer range
|
|
121
|
+
// (`var x = typeof x;`). Conservatively, any value reference inside
|
|
122
|
+
// the initializer declines — including a deferred read in a nested
|
|
123
|
+
// closure (`var f = () => f;`) that is actually safe — because the
|
|
124
|
+
// AST-local gate does not track whether that closure runs during
|
|
125
|
+
// initialization. Over-declining never corrupts source.
|
|
126
|
+
if child.Kind == shimast.KindIdentifier && identifierText(child) == target &&
|
|
127
|
+
isValueReferenceIdentifier(child) {
|
|
128
|
+
pos := child.Pos()
|
|
129
|
+
if pos < declPos || (initStart >= 0 && pos >= initStart && pos < initEnd) {
|
|
130
|
+
referencedBefore = true
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
if referencedBefore {
|
|
135
|
+
return false
|
|
136
|
+
}
|
|
137
|
+
return bindingCount == 1
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// bindingNamesIntroducedBy returns every plain identifier name that `node`
|
|
141
|
+
// introduces as a binding in its OWN slot — never the names bound by its
|
|
142
|
+
// descendants, which the file-wide walk visits independently. The classifier
|
|
143
|
+
// is by AST kind and slot so a value reference, member name, object-literal
|
|
144
|
+
// key, label, or type reference of the same text is excluded; only genuine
|
|
145
|
+
// declarations contribute.
|
|
146
|
+
//
|
|
147
|
+
// A destructuring declarator (`var { a } = o`, `function f([a]) {}`) is NOT
|
|
148
|
+
// flattened here: its leaf names belong to the BindingElement descendants,
|
|
149
|
+
// which the walk visits on their own, so each leaf is counted exactly once at
|
|
150
|
+
// its own position. Declaration nodes therefore contribute only when their
|
|
151
|
+
// own name slot is a plain identifier.
|
|
152
|
+
//
|
|
153
|
+
// Returns nil for any node that introduces no binding in its own slot. Type
|
|
154
|
+
// aliases and interfaces are intentionally absent: they live in the type
|
|
155
|
+
// namespace and merge with a same-name value binding without a `let`
|
|
156
|
+
// duplicate-declaration error.
|
|
157
|
+
func bindingNamesIntroducedBy(node *shimast.Node) []string {
|
|
158
|
+
if node == nil {
|
|
159
|
+
return nil
|
|
160
|
+
}
|
|
161
|
+
switch node.Kind {
|
|
162
|
+
case shimast.KindVariableDeclaration:
|
|
163
|
+
if decl := node.AsVariableDeclaration(); decl != nil {
|
|
164
|
+
if name := identifierText(decl.Name()); name != "" {
|
|
165
|
+
return []string{name}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
case shimast.KindParameter:
|
|
169
|
+
if decl := node.AsParameterDeclaration(); decl != nil {
|
|
170
|
+
if name := identifierText(decl.Name()); name != "" {
|
|
171
|
+
return []string{name}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
case shimast.KindBindingElement:
|
|
175
|
+
// A leaf of a destructuring pattern (`{ a }`, `[a]`, `{ k: a }`,
|
|
176
|
+
// `...rest`). Only the element's own bound name counts; nested patterns
|
|
177
|
+
// are their own BindingElement descendants, and the default-value
|
|
178
|
+
// initializer is a value reference, not a binding.
|
|
179
|
+
if elem := node.AsBindingElement(); elem != nil {
|
|
180
|
+
if name := identifierText(elem.Name()); name != "" {
|
|
181
|
+
return []string{name}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
case shimast.KindFunctionDeclaration:
|
|
185
|
+
if decl := node.AsFunctionDeclaration(); decl != nil && decl.Body != nil {
|
|
186
|
+
if name := identifierText(decl.Name()); name != "" {
|
|
187
|
+
return []string{name}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
case shimast.KindClassDeclaration:
|
|
191
|
+
if name := identifierText(node.Name()); name != "" {
|
|
192
|
+
return []string{name}
|
|
193
|
+
}
|
|
194
|
+
case shimast.KindEnumDeclaration, shimast.KindModuleDeclaration:
|
|
195
|
+
if name := identifierText(node.Name()); name != "" {
|
|
196
|
+
return []string{name}
|
|
197
|
+
}
|
|
198
|
+
case shimast.KindCatchClause:
|
|
199
|
+
// `catch (e)` — the catch binding. A destructured catch binding
|
|
200
|
+
// (`catch ({ e })`) has its leaves counted via the BindingElement
|
|
201
|
+
// descendants, so only a plain identifier binding counts here.
|
|
202
|
+
if catch := node.AsCatchClause(); catch != nil && catch.VariableDeclaration != nil {
|
|
203
|
+
if name := identifierText(catch.VariableDeclaration.Name()); name != "" {
|
|
204
|
+
return []string{name}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
case shimast.KindImportClause:
|
|
208
|
+
// `import foo from "m"` — the default import binding. Named and
|
|
209
|
+
// namespace bindings are their own ImportSpecifier / NamespaceImport
|
|
210
|
+
// descendants, visited separately.
|
|
211
|
+
if name := identifierText(node.Name()); name != "" {
|
|
212
|
+
return []string{name}
|
|
213
|
+
}
|
|
214
|
+
case shimast.KindNamespaceImport:
|
|
215
|
+
// `import * as ns from "m"`.
|
|
216
|
+
if name := identifierText(node.Name()); name != "" {
|
|
217
|
+
return []string{name}
|
|
218
|
+
}
|
|
219
|
+
case shimast.KindImportSpecifier:
|
|
220
|
+
// `import { a } from "m"` / `import { a as b } from "m"` — the local
|
|
221
|
+
// binding is the specifier's Name(), not the PropertyName.
|
|
222
|
+
if name := identifierText(node.Name()); name != "" {
|
|
223
|
+
return []string{name}
|
|
224
|
+
}
|
|
225
|
+
case shimast.KindImportEqualsDeclaration:
|
|
226
|
+
// `import x = require("m")` / `import x = A.B`.
|
|
227
|
+
if name := identifierText(node.Name()); name != "" {
|
|
228
|
+
return []string{name}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return nil
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// isValueReferenceIdentifier reports whether an Identifier node occupies a
|
|
235
|
+
// value-reference position rather than a non-reference role that merely
|
|
236
|
+
// reuses the same text. The use-before-declaration gate in
|
|
237
|
+
// isNoVarAutoFixSafe matches identifiers by text alone, so it would
|
|
238
|
+
// otherwise decline on positions that bind no value:
|
|
239
|
+
//
|
|
240
|
+
// - the `name` of a property access (`o.x`) or qualified name (`A.x`);
|
|
241
|
+
// - an object-literal property key (`{ x: 1 }`) or shorthand key;
|
|
242
|
+
// - a statement label (`x:` / `break x`);
|
|
243
|
+
// - a type reference (`: x`) whose `TypeName` is the identifier.
|
|
244
|
+
//
|
|
245
|
+
// Classification is by the identifier's parent node kind and slot, never
|
|
246
|
+
// by text. Any unrecognized parent is treated as a value reference
|
|
247
|
+
// (safety first: an unclassified position keeps declining).
|
|
248
|
+
func isValueReferenceIdentifier(node *shimast.Node) bool {
|
|
249
|
+
parent := node.Parent
|
|
250
|
+
if parent == nil {
|
|
251
|
+
return true
|
|
252
|
+
}
|
|
253
|
+
switch parent.Kind {
|
|
254
|
+
case shimast.KindPropertyAccessExpression:
|
|
255
|
+
// `o.x`: only the object expression is a reference; the member name
|
|
256
|
+
// is a property, not a binding.
|
|
257
|
+
access := parent.AsPropertyAccessExpression()
|
|
258
|
+
return access == nil || access.Name() != node
|
|
259
|
+
case shimast.KindQualifiedName:
|
|
260
|
+
// `A.x` in type position: the right side is a property name.
|
|
261
|
+
qn := parent.AsQualifiedName()
|
|
262
|
+
return qn == nil || qn.Right != node
|
|
263
|
+
case shimast.KindPropertyAssignment:
|
|
264
|
+
// `{ x: target }`: the key is not a reference; the value is.
|
|
265
|
+
assign := parent.AsPropertyAssignment()
|
|
266
|
+
return assign == nil || assign.Name() != node
|
|
267
|
+
// `{ x }`: an object-literal shorthand is a VALUE READ of binding `x`
|
|
268
|
+
// (object destructuring parses as KindBindingElement and is handled
|
|
269
|
+
// elsewhere). It falls through to the default `true` so the
|
|
270
|
+
// use-before-declaration gate sees the forward reference and declines.
|
|
271
|
+
case shimast.KindLabeledStatement:
|
|
272
|
+
// `x:` label — a statement label shares no namespace with values.
|
|
273
|
+
lbl := parent.AsLabeledStatement()
|
|
274
|
+
return lbl == nil || lbl.Label != node
|
|
275
|
+
case shimast.KindBreakStatement:
|
|
276
|
+
brk := parent.AsBreakStatement()
|
|
277
|
+
return brk == nil || brk.Label != node
|
|
278
|
+
case shimast.KindContinueStatement:
|
|
279
|
+
cont := parent.AsContinueStatement()
|
|
280
|
+
return cont == nil || cont.Label != node
|
|
281
|
+
case shimast.KindTypeReference:
|
|
282
|
+
// `: x` — a type reference lives in the type namespace.
|
|
283
|
+
ref := parent.AsTypeReferenceNode()
|
|
284
|
+
return ref == nil || ref.TypeName != node
|
|
285
|
+
}
|
|
286
|
+
return true
|
|
287
|
+
}
|
|
288
|
+
|
|
37
289
|
// preferConst: flag `let` declarations whose binding is never reassigned.
|
|
38
290
|
// This follows ESLint's core rule for the common AST-local cases. It is
|
|
39
291
|
// intentionally conservative: destructuring and declaration-only `let`
|
|
@@ -100,6 +352,24 @@ func (preferConst) Check(ctx *Context, node *shimast.Node) {
|
|
|
100
352
|
assigned[name] = true
|
|
101
353
|
}
|
|
102
354
|
}
|
|
355
|
+
case shimast.KindForOfStatement, shimast.KindForInStatement:
|
|
356
|
+
// `for (x of …)` / `for (x in …)` reassigns the existing binding `x`
|
|
357
|
+
// on every iteration. When the initializer IS a
|
|
358
|
+
// VariableDeclarationList (`for (const y of …)`) it declares a fresh
|
|
359
|
+
// binding instead, so only a non-declaration initializer counts as a
|
|
360
|
+
// reassignment target. Missing this lets a pre-existing `let` be
|
|
361
|
+
// rewritten to `const` that the loop then assigns to — a TS error and
|
|
362
|
+
// runtime TypeError.
|
|
363
|
+
stmt := child.AsForInOrOfStatement()
|
|
364
|
+
if stmt == nil || stmt.Initializer == nil {
|
|
365
|
+
return
|
|
366
|
+
}
|
|
367
|
+
if stmt.Initializer.Kind == shimast.KindVariableDeclarationList {
|
|
368
|
+
return
|
|
369
|
+
}
|
|
370
|
+
for _, name := range assignmentTargetNames(stmt.Initializer) {
|
|
371
|
+
assigned[name] = true
|
|
372
|
+
}
|
|
103
373
|
}
|
|
104
374
|
})
|
|
105
375
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttsc/lint",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "Reference ttsc plugin: ESLint-style lint rules hosted in the same Program/Checker as the type-check pass.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"src"
|
|
34
34
|
],
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
36
|
+
"@typescript/native-preview": "7.0.0-dev.20260519.1",
|
|
37
37
|
"@types/node": "^25.3.0",
|
|
38
38
|
"rimraf": "^6.1.2",
|
|
39
|
-
"ttsc": "0.14.
|
|
39
|
+
"ttsc": "0.14.1"
|
|
40
40
|
},
|
|
41
41
|
"repository": {
|
|
42
42
|
"type": "git",
|
package/src/defaultFormat.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import type { ITtscLintFormat } from "./structures/ITtscLintFormat";
|
|
1
|
+
import type { ITtscLintFormat } from "./structures/format/ITtscLintFormat";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Documented defaults for the `format` block's _always-on_ rules
|
|
5
|
-
* (`format/semi`, `format/quotes`, `format/
|
|
5
|
+
* (`format/semi`, `format/quotes`, `format/arrow-parens`,
|
|
6
|
+
* `format/bracket-spacing`, `format/quote-props`, `format/trailing-comma`,
|
|
6
7
|
* `format/print-width`).
|
|
7
8
|
*
|
|
8
9
|
* Exported so users can spread defaults next to overrides:
|
|
9
10
|
*
|
|
10
11
|
* ```ts
|
|
11
|
-
* import {
|
|
12
|
+
* import { type ITtscLintConfig, defaultFormat } from "@ttsc/lint";
|
|
12
13
|
*
|
|
13
14
|
* export default {
|
|
14
15
|
* format: { ...defaultFormat, printWidth: 100 },
|
|
@@ -18,15 +19,18 @@ import type { ITtscLintFormat } from "./structures/ITtscLintFormat";
|
|
|
18
19
|
* The values mirror Prettier 1:1 except for the documented `endOfLine`
|
|
19
20
|
* narrowing (no `"cr"` / `"auto"`).
|
|
20
21
|
*
|
|
21
|
-
* Notably absent: `
|
|
22
|
-
* `
|
|
23
|
-
* const documents only the
|
|
24
|
-
* non-empty `format` block
|
|
22
|
+
* Notably absent: `sortImports`. Import sorting is opt-in by setting
|
|
23
|
+
* `sortImports`; JSDoc normalization is always on (set `jsDoc: false` to opt
|
|
24
|
+
* out). This const documents only the keys that turn on unconditionally with a
|
|
25
|
+
* non-empty `format` block; the Go host owns runtime activation.
|
|
25
26
|
*/
|
|
26
27
|
export const defaultFormat = Object.freeze({
|
|
27
28
|
severity: "off",
|
|
28
29
|
semi: true,
|
|
29
30
|
singleQuote: false,
|
|
31
|
+
arrowParens: "always",
|
|
32
|
+
bracketSpacing: true,
|
|
33
|
+
quoteProps: "as-needed",
|
|
30
34
|
trailingComma: "all",
|
|
31
35
|
printWidth: 80,
|
|
32
36
|
tabWidth: 2,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ITtscLintFormat } from "./ITtscLintFormat";
|
|
2
1
|
import type { ITtscLintPlugin } from "./ITtscLintPlugin";
|
|
2
|
+
import type { ITtscLintFormat } from "./format/ITtscLintFormat";
|
|
3
3
|
import type { ITtscLintRules } from "./rules/ITtscLintRules";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -22,8 +22,8 @@ export interface ITtscLintConfig {
|
|
|
22
22
|
*/
|
|
23
23
|
extends?: string;
|
|
24
24
|
|
|
25
|
-
/**
|
|
26
|
-
|
|
25
|
+
/** Prettier-style flat configuration for the format rules. */
|
|
26
|
+
format?: ITtscLintFormat;
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Kebab-case built-in rule severities plus namespaced contributor rules.
|
|
@@ -34,6 +34,6 @@ export interface ITtscLintConfig {
|
|
|
34
34
|
*/
|
|
35
35
|
rules?: ITtscLintRules;
|
|
36
36
|
|
|
37
|
-
/**
|
|
38
|
-
|
|
37
|
+
/** Contributor plugin objects keyed by namespace. */
|
|
38
|
+
plugins?: Record<string, ITtscLintPlugin>;
|
|
39
39
|
}
|
|
@@ -6,12 +6,12 @@ import type { TtscLintSeverity } from "./TtscLintSeverity";
|
|
|
6
6
|
*
|
|
7
7
|
* A rule may be configured either as a bare severity string (`"error"`,
|
|
8
8
|
* `"warning"`, `"off"`) or as a single-element tuple containing the same
|
|
9
|
-
* severity. Both forms are equivalent at runtime; the tuple form exists so
|
|
10
|
-
*
|
|
9
|
+
* severity. Both forms are equivalent at runtime; the tuple form exists so that
|
|
10
|
+
* severity-only rules and options-bearing rules look uniform when read
|
|
11
11
|
* top-to-bottom in a `ttsc.lint.config.ts` file.
|
|
12
12
|
*
|
|
13
|
-
* Use {@link TtscLintRuleOptionsSetting} when the rule accepts a typed
|
|
14
|
-
*
|
|
13
|
+
* Use {@link TtscLintRuleOptionsSetting} when the rule accepts a typed options
|
|
14
|
+
* object.
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
17
17
|
* const config: ITtscLintConfig = {
|
|
@@ -30,25 +30,25 @@ export type TtscLintRuleSetting =
|
|
|
30
30
|
* Per-rule severity-plus-options setting for rules that accept a typed options
|
|
31
31
|
* object.
|
|
32
32
|
*
|
|
33
|
-
* This is the tuple form ESLint users know — `[severity, options]` —
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* @typeParam TOptions - The rule's options shape. Each rule supplies its
|
|
40
|
-
* own interface from `TtscLintRuleOptions.ts` (for example
|
|
41
|
-
* `ITtscLintBoundariesElementTypesRuleOptions`).
|
|
33
|
+
* This is the tuple form ESLint users know — `[severity, options]` — kept
|
|
34
|
+
* strongly typed by way of the rule's dedicated options interface (see
|
|
35
|
+
* `TtscLintRuleOptions.ts`). The bare {@link TtscLintRuleSetting} forms remain
|
|
36
|
+
* accepted; omitting the options object means "use the rule's default
|
|
37
|
+
* options".
|
|
42
38
|
*
|
|
43
39
|
* @example
|
|
44
40
|
* const config: ITtscLintConfig = {
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
41
|
+
* rules: {
|
|
42
|
+
* "boundaries/element-types": [
|
|
43
|
+
* "error",
|
|
44
|
+
* { default: "disallow", rules: [...] },
|
|
45
|
+
* ],
|
|
46
|
+
* },
|
|
51
47
|
* };
|
|
48
|
+
*
|
|
49
|
+
* @typeParam TOptions - The rule's options shape. Each rule supplies its own
|
|
50
|
+
* interface from `TtscLintRuleOptions.ts` (for example
|
|
51
|
+
* `ITtscLintBoundariesElementTypesRuleOptions`).
|
|
52
52
|
*/
|
|
53
53
|
export type TtscLintRuleOptionsSetting<TOptions> =
|
|
54
54
|
| TtscLintRuleSetting
|