@ttsc/lint 0.30.4 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +753 -741
- package/go.mod +7 -5
- package/internal/rulecode/rule_code_allocator_is_order_independent_and_append_only_test.go +119 -0
- package/internal/rulecode/rule_code_allocator_rejects_invalid_or_exhausted_ledgers_test.go +60 -0
- package/internal/rulecode/rulecode.go +18 -0
- package/lib/createTtscPlugin.d.ts +84 -0
- package/lib/createTtscPlugin.js +2704 -0
- package/lib/createTtscPlugin.js.map +1 -0
- package/lib/index.d.ts +1 -74
- package/lib/index.js +4 -2644
- package/lib/index.js.map +1 -1
- package/lib/internal/configEvaluatorFailure.d.ts +17 -9
- package/lib/internal/configEvaluatorFailure.js +17 -9
- package/lib/internal/configEvaluatorFailure.js.map +1 -1
- package/lib/internal/lintTrace.d.ts +18 -0
- package/lib/internal/lintTrace.js +99 -0
- package/lib/internal/lintTrace.js.map +1 -0
- package/lib/internal/normalizeContributors.d.ts +25 -0
- package/lib/internal/normalizeContributors.js +65 -0
- package/lib/internal/normalizeContributors.js.map +1 -0
- package/lib/structures/ITtscLintConfig.d.ts +25 -8
- package/lib/structures/ITtscLintPlugin.d.ts +13 -8
- package/lib/structures/ITtscLintPluginConfig.d.ts +18 -7
- package/lib/structures/ITtscLintPluginMeta.d.ts +10 -7
- package/lib/structures/TtscLintRuleSetting.d.ts +18 -13
- package/lib/structures/TtscLintSeverity.d.ts +5 -0
- package/lib/structures/format/ITtscLintFormat.d.ts +14 -8
- package/lib/structures/format/ITtscLintFormatJsDoc.d.ts +8 -1
- package/lib/structures/format/ITtscLintFormatSortImports.d.ts +14 -8
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +133 -25
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +3 -3
- package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +10 -5
- package/lib/structures/rules/ITtscLintContributorRules.d.ts +20 -13
- package/lib/structures/rules/ITtscLintCoreRuleOptions.d.ts +212 -24
- package/lib/structures/rules/ITtscLintCoreRules.d.ts +92 -72
- package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +8 -1
- package/lib/structures/rules/ITtscLintCypressRules.d.ts +24 -21
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +140 -24
- package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +20 -12
- package/lib/structures/rules/ITtscLintJestRules.d.ts +22 -16
- package/lib/structures/rules/ITtscLintJsdocRules.d.ts +5 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +24 -21
- package/lib/structures/rules/ITtscLintNextjsRules.d.ts +40 -42
- package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +24 -14
- package/lib/structures/rules/ITtscLintPromiseRules.d.ts +23 -14
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +8 -1
- package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +18 -15
- package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +14 -4
- package/lib/structures/rules/ITtscLintReactRules.d.ts +33 -27
- package/lib/structures/rules/ITtscLintRegexpRules.d.ts +18 -4
- package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +88 -15
- package/lib/structures/rules/ITtscLintRules.d.ts +13 -9
- package/lib/structures/rules/ITtscLintSecurityRules.d.ts +33 -23
- package/lib/structures/rules/ITtscLintSolidRules.d.ts +57 -47
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +10 -2
- package/lib/structures/rules/ITtscLintStorybookRules.d.ts +52 -62
- package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +34 -30
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +12 -3
- package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +20 -15
- package/lib/structures/rules/ITtscLintTypeScriptRuleOptions.d.ts +105 -16
- package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +62 -51
- package/lib/structures/rules/ITtscLintUnicornRuleOptions.d.ts +234 -46
- package/lib/structures/rules/ITtscLintUnicornRules.d.ts +97 -44
- package/lib/structures/rules/ITtscLintVitestRules.d.ts +19 -11
- package/lib/structures/rules/TtscLintContributorOverlay.d.ts +34 -0
- package/lib/structures/rules/TtscLintContributorOverlay.js +3 -0
- package/lib/structures/rules/TtscLintContributorOverlay.js.map +1 -0
- package/lib/structures/rules/index.d.ts +1 -0
- package/lib/structures/rules/index.js +1 -0
- package/lib/structures/rules/index.js.map +1 -1
- package/linthost/all_rule_names_returns_sorted_caller_owned_enumeration_test.go +72 -0
- package/linthost/as_bool_rejects_non_boolean_value_test.go +39 -0
- package/linthost/as_int_accepts_all_integer_types_and_rejects_fractional_test.go +77 -0
- package/linthost/as_string_rejects_non_string_value_test.go +35 -0
- package/linthost/as_string_slice_rejects_non_array_and_non_string_elements_test.go +45 -0
- package/linthost/ast_helpers.go +28 -89
- package/linthost/ast_helpers_destructuring_target_rejects_reads_inside_member_and_call_test.go +61 -0
- package/linthost/ast_selector_expression_class_excludes_type_literals_test.go +32 -0
- package/linthost/ast_selector_matcher.go +5 -0
- package/linthost/ast_selector_parser.go +5 -0
- package/linthost/astutil_find_keyword_is_identifier_aware_test.go +89 -0
- package/linthost/astutil_keyword_start_locates_leading_keyword_test.go +79 -0
- package/linthost/astutil_node_text_strips_leading_trivia_test.go +48 -0
- package/linthost/astutil_token_range_strips_leading_trivia_test.go +58 -0
- package/linthost/async_query_event_and_util_promises_test.go +55 -0
- package/linthost/await_thenable_await_expression_offers_exact_suggestion_test.go +40 -0
- package/linthost/await_thenable_await_union_with_promise_allows_test.go +42 -0
- package/linthost/await_thenable_await_using_async_disposable_allows_test.go +65 -0
- package/linthost/await_thenable_await_using_async_method_under_dispose_symbol_reports_test.go +57 -0
- package/linthost/await_thenable_await_using_helpers_test.go +44 -0
- package/linthost/await_thenable_await_using_multi_declarator_reports_only_sync_resource_test.go +65 -0
- package/linthost/await_thenable_await_using_protocol_abstractions_allows_test.go +67 -0
- package/linthost/await_thenable_await_using_protocol_abstractions_reports_test.go +75 -0
- package/linthost/await_thenable_await_using_sync_disposable_reports_test.go +62 -0
- package/linthost/await_thenable_await_using_sync_only_union_reports_test.go +64 -0
- package/linthost/await_thenable_await_using_union_with_async_disposable_allows_test.go +56 -0
- package/linthost/await_thenable_awaitability_type_parameter_boundaries_test.go +51 -0
- package/linthost/await_thenable_for_await_of_async_iterable_allows_test.go +63 -0
- package/linthost/await_thenable_for_await_of_protocol_abstractions_allows_test.go +67 -0
- package/linthost/await_thenable_for_await_of_protocol_abstractions_reports_test.go +75 -0
- package/linthost/await_thenable_for_await_of_sync_iterable_reports_test.go +65 -0
- package/linthost/await_thenable_for_await_of_sync_only_union_reports_test.go +55 -0
- package/linthost/await_thenable_preserves_migrated_all_family_contexts_test.go +20 -0
- package/linthost/await_thenable_promise_aggregator_awaitable_inputs_allow_test.go +50 -0
- package/linthost/await_thenable_promise_aggregator_container_shapes_report_test.go +53 -0
- package/linthost/await_thenable_promise_aggregator_generic_constraint_reports_test.go +45 -0
- package/linthost/await_thenable_promise_aggregator_iteration_yields_allow_test.go +50 -0
- package/linthost/await_thenable_promise_aggregator_iteration_yields_report_test.go +64 -0
- package/linthost/await_thenable_promise_aggregator_literal_members_report_test.go +56 -0
- package/linthost/await_thenable_promise_aggregator_native_identity_test.go +60 -0
- package/linthost/await_thenable_promise_aggregator_native_methods_report_test.go +50 -0
- package/linthost/await_thenable_promise_aggregator_noniterable_boundaries_allow_test.go +39 -0
- package/linthost/await_thenable_protocol_members_must_be_callable_test.go +70 -0
- package/linthost/await_thenable_structural_thenable_signature_boundary_test.go +53 -0
- package/linthost/ban_ts_comment_block_comment_ignores_directive_before_last_line_test.go +32 -0
- package/linthost/ban_ts_comment_block_comment_reports_directive_on_last_line_test.go +57 -0
- package/linthost/ban_ts_comment_block_comment_splits_last_line_on_all_line_terminators_test.go +55 -0
- package/linthost/ban_ts_comment_default_allows_described_expect_error_test.go +27 -0
- package/linthost/ban_ts_comment_default_allows_ts_check_test.go +26 -0
- package/linthost/ban_ts_comment_default_allows_ts_nocheck_after_first_statement_test.go +32 -0
- package/linthost/ban_ts_comment_default_does_not_fix_ts_ignore_test.go +25 -0
- package/linthost/ban_ts_comment_default_reports_ignore_with_upgrade_message_test.go +56 -0
- package/linthost/ban_ts_comment_default_reports_indented_ignore_with_position_test.go +39 -0
- package/linthost/ban_ts_comment_default_reports_ts_nocheck_before_code_test.go +44 -0
- package/linthost/ban_ts_comment_default_reports_ts_nocheck_without_statements_test.go +34 -0
- package/linthost/ban_ts_comment_default_requires_description_for_bare_expect_error_test.go +51 -0
- package/linthost/ban_ts_comment_description_length_counts_grapheme_clusters_test.go +58 -0
- package/linthost/ban_ts_comment_description_length_follows_unicode_16_graphemes_test.go +91 -0
- package/linthost/ban_ts_comment_follows_regex_in_nested_template_test.go +39 -0
- package/linthost/ban_ts_comment_ignores_directive_text_inside_strings_and_templates_test.go +48 -0
- package/linthost/ban_ts_comment_ignores_prose_and_near_miss_comments_test.go +34 -0
- package/linthost/ban_ts_comment_option_description_format_accepts_matching_description_test.go +36 -0
- package/linthost/ban_ts_comment_option_description_format_checks_length_first_test.go +49 -0
- package/linthost/ban_ts_comment_option_description_format_reports_mismatch_test.go +46 -0
- package/linthost/ban_ts_comment_option_empty_object_directive_allows_directive_test.go +26 -0
- package/linthost/ban_ts_comment_option_expect_error_false_allows_directive_test.go +28 -0
- package/linthost/ban_ts_comment_option_expect_error_true_reports_despite_description_test.go +41 -0
- package/linthost/ban_ts_comment_option_invalid_description_format_keeps_length_gate_test.go +52 -0
- package/linthost/ban_ts_comment_option_minimum_description_length_boundary_test.go +67 -0
- package/linthost/ban_ts_comment_option_ts_check_true_reports_pragma_anywhere_test.go +50 -0
- package/linthost/ban_ts_comment_option_ts_ignore_allow_with_description_test.go +57 -0
- package/linthost/ban_ts_comment_option_ts_nocheck_allow_with_description_test.go +57 -0
- package/linthost/ban_ts_comment_option_ts_nocheck_false_allows_directive_test.go +27 -0
- package/linthost/ban_ts_comment_option_unrecognized_value_keeps_default_policy_test.go +53 -0
- package/linthost/ban_ts_comment_pragma_ignores_block_comments_test.go +33 -0
- package/linthost/ban_ts_comment_pragma_requires_two_or_three_slashes_test.go +49 -0
- package/linthost/ban_ts_comment_pragma_wins_over_error_suppression_match_test.go +29 -0
- package/linthost/ban_ts_comment_preserves_migrated_defaults_and_options_test.go +29 -0
- package/linthost/ban_ts_comment_respects_inline_disable_next_line_test.go +28 -0
- package/linthost/ban_ts_comment_suggestion_compiler_error_boundary_test.go +56 -0
- package/linthost/ban_ts_comment_suggestion_rewrites_block_comment_ignore_test.go +40 -0
- package/linthost/ban_ts_comment_suggestion_rewrites_many_slash_line_comment_test.go +41 -0
- package/linthost/base_chain_walk_crosses_generic_boundary_test.go +165 -0
- package/linthost/behavioral_witness_audit_accepts_production_prerequisite_kinds_test.go +57 -0
- package/linthost/behavioral_witness_audit_publishes_one_deterministic_route_per_rule_test.go +45 -0
- package/linthost/behavioral_witness_audit_rejects_inert_public_rule_test.go +46 -0
- package/linthost/behavioral_witness_audit_rejects_invalid_non_canonical_candidate_test.go +49 -0
- package/linthost/behavioral_witness_coverage_test.go +379 -0
- package/linthost/behavioral_witness_kind_follows_rule_checker_requirement_test.go +69 -0
- package/linthost/binding_diagnostic_sites_helpers_test.go +31 -0
- package/linthost/blank_line_between_statements_returns_false_for_out_of_range_test.go +51 -0
- package/linthost/block_has_non_statement_comment_returns_false_for_out_of_range_test.go +56 -0
- package/linthost/block_has_non_statement_comment_skips_nil_stmts_test.go +42 -0
- package/linthost/boundaries_dependencies_alias_resolution_test.go +60 -0
- package/linthost/boundaries_dependencies_bare_core_builtin_test.go +36 -0
- package/linthost/boundaries_dependencies_command_test.go +67 -0
- package/linthost/boundaries_dependencies_declaration_file_test.go +50 -0
- package/linthost/boundaries_dependencies_default_test.go +36 -0
- package/linthost/boundaries_dependencies_from_to_test.go +66 -0
- package/linthost/boundaries_dependencies_import_kind_test.go +46 -0
- package/linthost/boundaries_dependencies_import_type_kinds_test.go +56 -0
- package/linthost/boundaries_dependencies_legacy_to_direction_test.go +43 -0
- package/linthost/boundaries_dependencies_local_gates_test.go +43 -0
- package/linthost/boundaries_dependencies_messages_test.go +58 -0
- package/linthost/boundaries_dependencies_options_test.go +66 -0
- package/linthost/boundaries_dependencies_origins_test.go +38 -0
- package/linthost/boundaries_dependencies_path_separators_test.go +36 -0
- package/linthost/boundaries_dependencies_policy_order_test.go +41 -0
- package/linthost/boundaries_dependencies_syntax_test.go +86 -0
- package/linthost/boundaries_dependencies_test.go +38 -0
- package/linthost/boundaries_dependencies_visibility_selectors_test.go +52 -0
- package/linthost/boundaries_element_types_deny_only_names_nothing_test.go +36 -0
- package/linthost/boundaries_element_types_ignores_dynamic_syntax_test.go +44 -0
- package/linthost/boundaries_element_types_names_the_allowed_set_test.go +40 -0
- package/linthost/boundaries_element_types_rejects_disallowed_import_test.go +43 -0
- package/linthost/boundaries_entry_point_rejects_non_entry_import_test.go +43 -0
- package/linthost/boundaries_external_deny_only_names_nothing_test.go +25 -0
- package/linthost/boundaries_external_names_the_allowed_set_test.go +30 -0
- package/linthost/boundaries_external_rejects_disallowed_package_test.go +34 -0
- package/linthost/boundaries_helpers_test.go +162 -0
- package/linthost/boundaries_no_private_rejects_cross_element_private_import_test.go +39 -0
- package/linthost/boundaries_no_unknown_rejects_unknown_import_target_test.go +43 -0
- package/linthost/check_observations.go +236 -0
- package/linthost/check_observations_retains_failed_program_and_raw_inputs_test.go +266 -0
- package/linthost/check_serve.go +23 -3
- package/linthost/check_serve_reuses_program_and_matches_cold_cycles_test.go +168 -0
- package/linthost/check_tag_names_publishes_canonical_hints_test.go +62 -0
- package/linthost/check_tag_names_test.go +30 -0
- package/linthost/check_values_test.go +31 -0
- package/linthost/command_build_emits_project_output_test.go +55 -0
- package/linthost/command_build_rejects_conflicting_emit_flags_test.go +32 -0
- package/linthost/command_check_applies_a_forwarded_null_reset_test.go +62 -0
- package/linthost/command_check_applies_forwarded_tsgo_flag_test.go +61 -0
- package/linthost/command_check_corpus_clean_project_exits_zero_test.go +41 -0
- package/linthost/command_check_corpus_ignores_future_optional_flags_test.go +34 -0
- package/linthost/command_check_corpus_reports_unknown_rule_names_test.go +25 -0
- package/linthost/command_check_honors_no_restricted_syntax_options_test.go +59 -0
- package/linthost/command_check_no_param_reassign_honors_props_config_test.go +46 -0
- package/linthost/command_check_no_restricted_imports_uses_real_config_options_test.go +53 -0
- package/linthost/command_check_preserves_compiler_argument_cwd_test.go +78 -0
- package/linthost/command_check_preserves_severity_exit_contract_test.go +54 -0
- package/linthost/command_check_rejects_invalid_no_param_reassign_options_before_linting_test.go +85 -0
- package/linthost/command_check_rejects_invalid_no_restricted_imports_options_before_linting_test.go +52 -0
- package/linthost/command_check_rejects_invalid_no_restricted_syntax_selector_test.go +41 -0
- package/linthost/command_check_relates_files_to_the_project_directory_test.go +40 -0
- package/linthost/command_check_reports_imported_sibling_workspace_source_test.go +45 -0
- package/linthost/command_check_reports_lint_diagnostic_test.go +44 -0
- package/linthost/command_check_reports_the_malformed_brace_it_used_to_bless_test.go +31 -0
- package/linthost/command_check_scopes_extends_rule_options_per_file_test.go +70 -0
- package/linthost/command_check_uses_parser_context_for_comment_consumers_test.go +61 -0
- package/linthost/command_check_warns_unknown_rules_test.go +41 -0
- package/linthost/command_fix_applies_both_lint_and_format_rule_edits_test.go +51 -0
- package/linthost/command_fix_applies_native_autofixes_test.go +48 -0
- package/linthost/command_fix_leaves_suggestion_only_rules_unchanged_test.go +46 -0
- package/linthost/command_fix_owns_its_source_reached_through_a_link_test.go +63 -0
- package/linthost/command_fix_rejects_emit_flag_test.go +39 -0
- package/linthost/command_fix_reports_but_never_rewrites_imported_sibling_source_test.go +65 -0
- package/linthost/command_fix_skips_default_formatting_that_format_applies_test.go +87 -0
- package/linthost/command_fix_unicorn_prevent_abbreviations_keeps_cross_file_merges_diagnostic_only_test.go +44 -0
- package/linthost/command_fix_unicorn_prevent_abbreviations_reparses_and_is_idempotent_test.go +37 -0
- package/linthost/command_fix_unicorn_switch_case_break_position_converges_and_is_idempotent_test.go +58 -0
- package/linthost/command_fix_unicorn_template_indent_converges_and_is_idempotent_test.go +43 -0
- package/linthost/command_format_applies_format_block_reflow_test.go +50 -0
- package/linthost/command_format_applies_format_rule_edits_test.go +54 -0
- package/linthost/command_format_arg_hugging_test.go +329 -0
- package/linthost/command_format_array_of_arrays_break_test.go +62 -0
- package/linthost/command_format_blank_line_in_list_test.go +69 -0
- package/linthost/command_format_brace_ownership_negative_twins_test.go +94 -0
- package/linthost/command_format_cedes_chained_arrow_body_test.go +50 -0
- package/linthost/command_format_cedes_closing_brace_under_wrapped_head_test.go +54 -0
- package/linthost/command_format_class_heritage_break_test.go +108 -0
- package/linthost/command_format_converges_on_leading_semi_guard_in_callback_test.go +69 -0
- package/linthost/command_format_decorated_declaration_indent_is_idempotent_test.go +57 -0
- package/linthost/command_format_default_import_single_specifier_break_test.go +26 -0
- package/linthost/command_format_display_width_test.go +33 -0
- package/linthost/command_format_expands_expression_nested_block_test.go +86 -0
- package/linthost/command_format_expression_nested_block_honors_crlf_test.go +39 -0
- package/linthost/command_format_fixture_corpus_test.go +179 -0
- package/linthost/command_format_honors_entry_ignores_alongside_rules_test.go +79 -0
- package/linthost/command_format_import_multi_specifier_from_overflow_break_test.go +27 -0
- package/linthost/command_format_indent_idempotency_helper_test.go +57 -0
- package/linthost/command_format_keeps_commented_statement_body_whole_test.go +23 -0
- package/linthost/command_format_keeps_empty_expression_nested_block_test.go +29 -0
- package/linthost/command_format_lays_out_a_statement_body_test.go +90 -0
- package/linthost/command_format_leaves_a_braceless_control_flow_body_alone_test.go +30 -0
- package/linthost/command_format_leaves_imported_sibling_source_untouched_test.go +68 -0
- package/linthost/command_format_leaves_prettier_shaped_mapped_types_untouched_test.go +39 -0
- package/linthost/command_format_leaves_prettier_shaped_type_members_untouched_test.go +41 -0
- package/linthost/command_format_leaves_token_spacing_untouched_test.go +66 -0
- package/linthost/command_format_multiple_callbacks_test.go +150 -0
- package/linthost/command_format_nested_ternary_indent_test.go +67 -0
- package/linthost/command_format_nested_ternary_parens_test.go +74 -0
- package/linthost/command_format_numeric_array_fill_test.go +94 -0
- package/linthost/command_format_preserves_braceless_for_body_indent_test.go +28 -0
- package/linthost/command_format_preserves_braceless_if_try_body_indent_test.go +30 -0
- package/linthost/command_format_preserves_class_typeparam_heritage_inline_test.go +27 -0
- package/linthost/command_format_preserves_comments_in_reflow_test.go +66 -0
- package/linthost/command_format_preserves_crlf_across_reflow_rules_test.go +73 -0
- package/linthost/command_format_preserves_generic_arg_multiline_type_literal_indent_test.go +30 -0
- package/linthost/command_format_preserves_generic_arg_type_literal_indent_test.go +30 -0
- package/linthost/command_format_preserves_interface_qualified_heritage_own_line_test.go +28 -0
- package/linthost/command_format_preserves_intersection_generic_type_literal_indent_test.go +36 -0
- package/linthost/command_format_preserves_multi_type_heritage_empty_body_test.go +28 -0
- package/linthost/command_format_preserves_multiline_type_param_heritage_test.go +30 -0
- package/linthost/command_format_preserves_nested_variable_type_literal_indent_test.go +27 -0
- package/linthost/command_format_preserves_param_type_literal_indent_test.go +62 -0
- package/linthost/command_format_preserves_union_member_type_literal_indent_test.go +28 -0
- package/linthost/command_format_print_width_abstains_inside_binary_expression_test.go +84 -0
- package/linthost/command_format_print_width_cascades_with_semi_and_quotes_test.go +62 -0
- package/linthost/command_format_print_width_converges_on_unbraced_control_flow_test.go +176 -0
- package/linthost/command_format_rejects_emit_flag_test.go +39 -0
- package/linthost/command_format_respects_resolved_entry_applicability_test.go +219 -0
- package/linthost/command_format_restores_class_member_indent_from_flat_test.go +61 -0
- package/linthost/command_format_restores_closing_braces_from_flat_test.go +64 -0
- package/linthost/command_format_restores_decorated_member_indent_from_flat_test.go +61 -0
- package/linthost/command_format_restores_decorated_namespace_class_indent_from_flat_test.go +62 -0
- package/linthost/command_format_restores_decorated_nested_class_indent_from_flat_test.go +64 -0
- package/linthost/command_format_restores_decorated_nested_function_indent_from_flat_test.go +60 -0
- package/linthost/command_format_restores_decorated_nested_interface_indent_from_flat_test.go +59 -0
- package/linthost/command_format_restores_nested_class_indent_from_flat_test.go +60 -0
- package/linthost/command_format_restores_stranded_brace_from_one_line_block_test.go +140 -0
- package/linthost/command_format_restores_switch_indent_from_flat_test.go +63 -0
- package/linthost/command_format_return_typed_arrow_hug_test.go +74 -0
- package/linthost/command_format_round2_coverage_test.go +57 -0
- package/linthost/command_format_round2_hug_fixes_test.go +70 -0
- package/linthost/command_format_round3_force_break_test.go +49 -0
- package/linthost/command_format_settles_a_member_terminator_on_a_padded_line_test.go +34 -0
- package/linthost/command_format_single_specifier_abstain_does_not_block_multi_break_test.go +56 -0
- package/linthost/command_format_single_specifier_stays_inline_test.go +60 -0
- package/linthost/command_format_split_call_collapses_flat_once_isolated_test.go +54 -0
- package/linthost/command_format_spread_comment_test.go +36 -0
- package/linthost/command_format_stranded_brace_honors_crlf_test.go +51 -0
- package/linthost/command_format_structural_rules_are_idempotent_on_their_own_output_test.go +51 -0
- package/linthost/command_format_structural_rules_converge_on_headline_input_test.go +56 -0
- package/linthost/command_format_structural_rules_converge_on_nested_block_test.go +56 -0
- package/linthost/command_format_switch_case_block_indent_test.go +80 -0
- package/linthost/command_format_terminates_a_split_interface_member_test.go +34 -0
- package/linthost/command_format_test_call_hug_test.go +92 -0
- package/linthost/command_format_wrapped_function_body_indent_test.go +43 -0
- package/linthost/command_lint_corpus_semantics_helpers_test.go +29 -0
- package/linthost/command_prints_version_test.go +38 -0
- package/linthost/command_rejects_conflicting_emit_flags_test.go +33 -0
- package/linthost/command_rejects_unknown_test.go +32 -0
- package/linthost/command_requires_argument_test.go +32 -0
- package/linthost/command_transform_normalizes_dot_segments_in_file_path_test.go +49 -0
- package/linthost/command_transform_outputs_requested_file_test.go +43 -0
- package/linthost/command_transform_requires_file_test.go +32 -0
- package/linthost/comment_scan.go +3 -2
- package/linthost/comment_scan_handles_malformed_parser_recovery_test.go +59 -0
- package/linthost/comment_scan_uses_parser_lexical_ranges_across_source_modes_test.go +109 -0
- package/linthost/compile.go +177 -38
- package/linthost/compile_user_pattern_caches_option_regex_test.go +70 -0
- package/linthost/config.go +954 -269
- package/linthost/config_cache_does_not_memoize_failed_evaluation_test.go +63 -0
- package/linthost/config_cache_portable_dependency_policies_test.go +471 -0
- package/linthost/config_cache_preserves_pattern_precedence_test.go +96 -0
- package/linthost/config_cache_reuses_evaluation_until_content_changes_test.go +81 -0
- package/linthost/config_fixture_helpers_test.go +70 -0
- package/linthost/config_format.go +5 -5
- package/linthost/config_glob.go +517 -0
- package/linthost/config_glob_bounds_matching_work_test.go +115 -0
- package/linthost/config_glob_preserves_expansion_semantics_test.go +128 -0
- package/linthost/config_glob_preserves_stored_case_recovery_test.go +64 -0
- package/linthost/config_json.go +85 -0
- package/linthost/config_loader_sources_escape_every_literal_percent_test.go +81 -0
- package/linthost/config_store_option_fold_honors_both_entry_orders_test.go +70 -0
- package/linthost/config_store_resolves_options_with_entry_scope_test.go +95 -0
- package/linthost/config_store_severity_only_override_inherits_matching_options_test.go +53 -0
- package/linthost/config_store_validates_every_scoped_option_variant_test.go +55 -0
- package/linthost/consistent_return_accepts_functions_that_return_on_every_path_through_switch_and_try_test.go +43 -0
- package/linthost/context_report_range_suggestion_separates_opt_in_edits_test.go +76 -0
- package/linthost/contrib_adapter.go +3 -1
- package/linthost/contrib_adapter_to_internal_text_edits_returns_nil_for_empty_input_test.go +34 -0
- package/linthost/contrib_adapter_to_internal_text_edits_round_trips_three_edits_test.go +40 -0
- package/linthost/contributor_ast_only_marker_skips_standalone_checker_test.go +52 -0
- package/linthost/contributor_bootstrap_is_single_owner_for_reusable_main_test.go +425 -0
- package/linthost/contributor_cannot_mutate_later_invocation_options_test.go +55 -0
- package/linthost/contributor_diagnostic_ranges_are_bounded_test.go +139 -0
- package/linthost/contributor_generic_accepts_options_method_keeps_legacy_payload_test.go +81 -0
- package/linthost/contributor_metadata_panic_is_rejected_test.go +84 -0
- package/linthost/contributor_optionless_marker_rejects_payload_test.go +63 -0
- package/linthost/contributor_panics_preserve_other_rules_in_process_test.go +111 -0
- package/linthost/contributor_range_fix_bounds_diagnostic_independently_from_edit_test.go +52 -0
- package/linthost/contributor_report_related_reaches_finding_test.go +101 -0
- package/linthost/contributor_rule_decodes_options_through_public_context_test.go +75 -0
- package/linthost/contributor_rule_opt_out_skips_declaration_files_test.go +56 -0
- package/linthost/contributor_rule_receives_and_reports_configured_severity_test.go +65 -0
- package/linthost/contributor_rules_visit_declaration_files_by_default_test.go +50 -0
- package/linthost/contributor_tagged_rule_marks_findings_test.go +78 -0
- package/linthost/contributor_type_aware_marker_keeps_checker_test.go +50 -0
- package/linthost/contributor_without_tag_marker_leaves_findings_untagged_test.go +61 -0
- package/linthost/cypress_assertion_before_screenshot_allows_immediately_prior_assertion_test.go +33 -0
- package/linthost/cypress_assertion_before_screenshot_allows_same_chain_assertion_test.go +31 -0
- package/linthost/cypress_assertion_before_screenshot_reports_unchecked_screenshot_test.go +34 -0
- package/linthost/cypress_assertion_before_screenshot_reports_unrelated_prior_assertion_test.go +36 -0
- package/linthost/cypress_finding_helpers_test.go +14 -0
- package/linthost/cypress_no_and_reports_chain_starting_and_test.go +35 -0
- package/linthost/cypress_no_assigning_return_values_reports_cy_assignment_test.go +35 -0
- package/linthost/cypress_no_async_before_reports_async_before_each_test.go +37 -0
- package/linthost/cypress_no_async_tests_reports_async_it_test.go +37 -0
- package/linthost/cypress_no_chained_get_reports_second_get_test.go +34 -0
- package/linthost/cypress_no_debug_reports_debug_command_test.go +34 -0
- package/linthost/cypress_no_force_reports_force_true_option_test.go +34 -0
- package/linthost/cypress_no_pause_reports_pause_command_test.go +34 -0
- package/linthost/cypress_no_unnecessary_waiting_reports_numeric_wait_test.go +35 -0
- package/linthost/cypress_no_xpath_reports_xpath_command_test.go +34 -0
- package/linthost/cypress_require_data_selectors_reports_class_selector_test.go +36 -0
- package/linthost/cypress_unsafe_to_chain_command_reports_action_middle_test.go +35 -0
- package/linthost/declaration_file_allowlist_names_are_registered_rules_test.go +50 -0
- package/linthost/default_case_accepts_block_comment_marker_test.go +28 -0
- package/linthost/default_case_accepts_case_insensitive_marker_test.go +28 -0
- package/linthost/default_case_accepts_empty_switch_test.go +24 -0
- package/linthost/default_case_accepts_existing_default_clause_test.go +29 -0
- package/linthost/default_case_accepts_no_default_marker_test.go +28 -0
- package/linthost/default_case_custom_pattern_replaces_default_marker_test.go +30 -0
- package/linthost/default_case_helpers_test.go +58 -0
- package/linthost/default_case_honors_custom_comment_pattern_test.go +28 -0
- package/linthost/default_case_invalid_comment_pattern_falls_back_to_default_test.go +28 -0
- package/linthost/default_case_rejects_marker_with_trailing_text_test.go +28 -0
- package/linthost/default_case_rejects_unrelated_trailing_comment_test.go +28 -0
- package/linthost/default_case_reports_switch_without_default_test.go +27 -0
- package/linthost/default_case_requires_marker_to_be_last_comment_test.go +30 -0
- package/linthost/diagnostic_codes_distinguish_former_collision_across_cli_and_lsp_test.go +97 -0
- package/linthost/dispatch.go +29 -9
- package/linthost/dispatch_array_literal_breaks_when_overflows_test.go +38 -0
- package/linthost/dispatch_array_literal_falls_back_when_element_nil_test.go +53 -0
- package/linthost/dispatch_array_literal_falls_back_when_elements_nil_test.go +48 -0
- package/linthost/dispatch_array_literal_flat_when_fits_test.go +34 -0
- package/linthost/dispatch_array_literal_returns_empty_for_nil_node_test.go +31 -0
- package/linthost/dispatch_arrow_function_block_body_reindents_consistently_test.go +41 -0
- package/linthost/dispatch_arrow_function_returns_covered_for_nil_node_test.go +38 -0
- package/linthost/dispatch_arrow_function_returns_verbatim_for_nil_body_test.go +46 -0
- package/linthost/dispatch_block_collapses_empty_body_to_braces_test.go +40 -0
- package/linthost/dispatch_block_keeps_covered_for_single_line_statements_test.go +42 -0
- package/linthost/dispatch_block_preserves_blank_line_between_statements_test.go +41 -0
- package/linthost/dispatch_block_reports_uncovered_for_comment_only_body_test.go +37 -0
- package/linthost/dispatch_block_reports_uncovered_for_inter_statement_comment_test.go +37 -0
- package/linthost/dispatch_block_returns_covered_for_nil_node_test.go +34 -0
- package/linthost/dispatch_block_returns_verbatim_for_nil_statement_test.go +47 -0
- package/linthost/dispatch_block_returns_verbatim_for_nil_statements_test.go +44 -0
- package/linthost/dispatch_call_breaks_expression_body_arrow_argument_when_overflows_test.go +44 -0
- package/linthost/dispatch_call_breaks_hugged_object_when_flat_form_overflows_test.go +42 -0
- package/linthost/dispatch_call_explodes_when_hugged_callback_header_overflows_test.go +45 -0
- package/linthost/dispatch_call_explodes_when_hugged_object_header_overflows_test.go +43 -0
- package/linthost/dispatch_call_expression_breaks_arguments_when_overflows_test.go +40 -0
- package/linthost/dispatch_call_expression_flat_when_fits_test.go +33 -0
- package/linthost/dispatch_call_hugs_last_callback_argument_test.go +41 -0
- package/linthost/dispatch_call_keeps_hugged_object_flat_when_it_fits_test.go +40 -0
- package/linthost/dispatch_expression_statement_returns_covered_for_nil_node_test.go +36 -0
- package/linthost/dispatch_expression_statement_returns_verbatim_for_dirty_tail_test.go +44 -0
- package/linthost/dispatch_expression_statement_returns_verbatim_for_nil_expression_test.go +44 -0
- package/linthost/dispatch_function_expression_block_body_reindents_test.go +43 -0
- package/linthost/dispatch_function_expression_returns_covered_for_nil_node_test.go +36 -0
- package/linthost/dispatch_function_expression_returns_verbatim_for_nil_body_test.go +44 -0
- package/linthost/dispatch_function_like_returns_verbatim_for_out_of_range_body_test.go +50 -0
- package/linthost/dispatch_function_like_taints_covered_for_multiline_signature_test.go +38 -0
- package/linthost/dispatch_import_declaration_falls_back_for_default_import_test.go +32 -0
- package/linthost/dispatch_import_declaration_falls_back_for_import_attributes_test.go +33 -0
- package/linthost/dispatch_import_declaration_falls_back_for_namespace_import_test.go +37 -0
- package/linthost/dispatch_import_declaration_falls_back_for_side_effect_import_test.go +36 -0
- package/linthost/dispatch_import_declaration_omits_semicolon_when_absent_test.go +37 -0
- package/linthost/dispatch_import_declaration_preserves_type_only_keyword_test.go +34 -0
- package/linthost/dispatch_import_declaration_returns_empty_for_nil_node_test.go +30 -0
- package/linthost/dispatch_import_declaration_threads_clauses_test.go +35 -0
- package/linthost/dispatch_named_exports_breaks_when_overflows_test.go +38 -0
- package/linthost/dispatch_named_exports_falls_back_when_elements_nil_test.go +49 -0
- package/linthost/dispatch_named_exports_falls_back_when_specifier_nil_test.go +51 -0
- package/linthost/dispatch_named_exports_flat_when_fits_test.go +33 -0
- package/linthost/dispatch_named_exports_returns_empty_for_nil_node_test.go +31 -0
- package/linthost/dispatch_named_imports_breaks_when_overflows_test.go +37 -0
- package/linthost/dispatch_named_imports_falls_back_when_elements_nil_test.go +50 -0
- package/linthost/dispatch_named_imports_falls_back_when_specifier_nil_test.go +54 -0
- package/linthost/dispatch_named_imports_flat_when_fits_test.go +34 -0
- package/linthost/dispatch_named_imports_returns_empty_for_nil_node_test.go +30 -0
- package/linthost/dispatch_nested_callback_reflows_at_every_depth_test.go +52 -0
- package/linthost/dispatch_new_expression_breaks_arguments_when_overflows_test.go +39 -0
- package/linthost/dispatch_new_expression_flat_when_fits_test.go +36 -0
- package/linthost/dispatch_object_literal_breaks_when_overflows_test.go +40 -0
- package/linthost/dispatch_object_literal_falls_back_when_properties_nil_test.go +49 -0
- package/linthost/dispatch_object_literal_falls_back_when_property_nil_test.go +52 -0
- package/linthost/dispatch_object_literal_flat_when_fits_test.go +33 -0
- package/linthost/dispatch_object_literal_returns_empty_for_nil_node_test.go +31 -0
- package/linthost/dispatch_parenthesized_expression_reflows_inner_test.go +42 -0
- package/linthost/dispatch_parenthesized_expression_returns_covered_for_nil_node_test.go +35 -0
- package/linthost/dispatch_parenthesized_expression_returns_verbatim_for_nil_inner_test.go +44 -0
- package/linthost/dispatch_reports_uncovered_for_multiline_verbatim_subtree_test.go +42 -0
- package/linthost/dispatch_return_statement_reflows_returned_expression_test.go +45 -0
- package/linthost/dispatch_return_statement_returns_covered_for_nil_node_test.go +36 -0
- package/linthost/dispatch_return_statement_returns_verbatim_for_bare_return_test.go +41 -0
- package/linthost/dispatch_return_statement_returns_verbatim_for_dirty_tail_test.go +43 -0
- package/linthost/dispatch_verbatim_fallback_preserves_unknown_kinds_test.go +41 -0
- package/linthost/display_width.go +29 -5
- package/linthost/display_width_after_last_newline_measures_tail_test.go +33 -0
- package/linthost/display_width_from_column_expands_tabs_to_stops_test.go +49 -0
- package/linthost/display_width_matches_prettier_get_string_width_test.go +124 -0
- package/linthost/display_width_oracle_preconditions_test.go +32 -0
- package/linthost/doc_join_returns_nil_for_empty_parts_test.go +33 -0
- package/linthost/dot_notation_declines_fix_when_comment_in_bracket_span_test.go +40 -0
- package/linthost/dot_notation_fix_bracket_to_dot_for_identifier_key_test.go +27 -0
- package/linthost/dot_notation_fix_keeps_bracket_for_reserved_word_test.go +28 -0
- package/linthost/dot_notation_fix_spaces_decimal_integer_receiver_test.go +76 -0
- package/linthost/dot_notation_offers_reserved_word_collapse_as_suggestion_test.go +36 -0
- package/linthost/dot_notation_offers_withheld_bracket_collapse_as_suggestion_test.go +37 -0
- package/linthost/dot_notation_skips_invalid_identifier_key_test.go +27 -0
- package/linthost/editor_format_overrides_accepts_utf8_bom_test.go +155 -0
- package/linthost/editor_format_overrides_combined_sections_follow_source_order_test.go +58 -0
- package/linthost/editor_format_overrides_drive_idempotent_output_test.go +69 -0
- package/linthost/editor_format_overrides_duplicate_language_section_uses_last_value_test.go +55 -0
- package/linthost/editor_format_overrides_equivalent_exact_sections_use_last_scope_test.go +52 -0
- package/linthost/editor_format_overrides_language_section_wins_test.go +37 -0
- package/linthost/editor_format_overrides_normalize_full_language_selectors_test.go +44 -0
- package/linthost/editor_format_overrides_reads_vscode_settings_test.go +45 -0
- package/linthost/editor_format_overrides_reject_malformed_language_selectors_test.go +36 -0
- package/linthost/editor_format_overrides_single_language_precedence_is_deterministic_test.go +51 -0
- package/linthost/editor_format_overrides_supported_language_ids_test.go +60 -0
- package/linthost/empty_tags_test.go +27 -0
- package/linthost/engine.go +523 -91
- package/linthost/engine_accepts_null_tuple_slot_as_absent_options_test.go +37 -0
- package/linthost/engine_accepts_payload_for_option_rule_test.go +36 -0
- package/linthost/engine_accepts_severity_only_optionless_rule_test.go +28 -0
- package/linthost/engine_align_uses_current_column_test.go +27 -0
- package/linthost/engine_block_disable_after_code_does_not_suppress_earlier_same_line_test.go +47 -0
- package/linthost/engine_conditional_group_empty_renders_nothing_test.go +24 -0
- package/linthost/engine_conditional_group_falls_back_to_last_option_test.go +30 -0
- package/linthost/engine_conditional_group_picks_first_fitting_option_test.go +31 -0
- package/linthost/engine_crlf_terminator_emits_carriage_returns_test.go +24 -0
- package/linthost/engine_dedupes_duplicate_kinds_in_visits_test.go +64 -0
- package/linthost/engine_detects_files_without_enabled_rules_test.go +40 -0
- package/linthost/engine_directive_accepts_typescript_namespace_prefix_test.go +48 -0
- package/linthost/engine_directive_after_template_expression_test.go +37 -0
- package/linthost/engine_directive_records_unknown_rule_in_unknown_channel_test.go +65 -0
- package/linthost/engine_directive_rejects_legacy_typescript_eslint_prefix_test.go +50 -0
- package/linthost/engine_directive_without_rules_disables_all_rules_on_target_line_test.go +57 -0
- package/linthost/engine_disable_line_multiline_block_comment_targets_end_line_test.go +50 -0
- package/linthost/engine_dispatches_only_to_interested_rules_test.go +81 -0
- package/linthost/engine_end_of_line_defaults_to_lf_when_empty_test.go +23 -0
- package/linthost/engine_fits_first_line_counts_flat_group_lines_test.go +25 -0
- package/linthost/engine_fits_first_line_stops_at_first_break_test.go +85 -0
- package/linthost/engine_fits_measures_conditional_group_as_first_option_test.go +25 -0
- package/linthost/engine_fits_rejects_forced_break_group_test.go +22 -0
- package/linthost/engine_fits_returns_false_when_remaining_negative_test.go +21 -0
- package/linthost/engine_fits_treats_indent_align_as_transparent_in_flat_test.go +34 -0
- package/linthost/engine_flatten_resolves_breaks_to_flat_form_test.go +57 -0
- package/linthost/engine_group_break_flag_forces_broken_layout_test.go +29 -0
- package/linthost/engine_group_breaks_when_overflows_width_test.go +30 -0
- package/linthost/engine_group_collapses_when_fits_width_test.go +28 -0
- package/linthost/engine_hardline_forces_break_regardless_of_width_test.go +23 -0
- package/linthost/engine_ifbreak_picks_broken_branch_when_group_breaks_test.go +32 -0
- package/linthost/engine_ifbreak_picks_flat_branch_when_group_fits_test.go +28 -0
- package/linthost/engine_ignores_directive_text_inside_strings_test.go +45 -0
- package/linthost/engine_ignores_jsx_text_inline_disable_markers_test.go +54 -0
- package/linthost/engine_indent_compounds_inside_group_test.go +20 -0
- package/linthost/engine_line_suffix_attaches_to_next_break_test.go +33 -0
- package/linthost/engine_line_suffix_drain_preserves_embedded_newline_test.go +23 -0
- package/linthost/engine_line_suffix_drains_inline_when_no_break_follows_test.go +28 -0
- package/linthost/engine_line_suffix_flush_preserves_embedded_newline_test.go +28 -0
- package/linthost/engine_literalline_emits_newline_at_column_zero_test.go +24 -0
- package/linthost/engine_preserves_migrated_disable_directive_population_test.go +46 -0
- package/linthost/engine_print_width_defaults_when_zero_test.go +39 -0
- package/linthost/engine_quarantines_panicking_rule_per_file_test.go +110 -0
- package/linthost/engine_records_unknown_rules_test.go +42 -0
- package/linthost/engine_recovers_from_rule_panic_test.go +68 -0
- package/linthost/engine_rejects_legacy_typescript_eslint_prefix_test.go +39 -0
- package/linthost/engine_rejects_optionless_payload_while_rule_is_off_test.go +37 -0
- package/linthost/engine_rejects_payload_shapes_for_optionless_rule_test.go +46 -0
- package/linthost/engine_requires_type_checker_for_contributor_rule_test.go +43 -0
- package/linthost/engine_requires_type_checker_for_prefer_const_test.go +33 -0
- package/linthost/engine_requires_type_checker_for_type_aware_rule_test.go +35 -0
- package/linthost/engine_respects_block_disable_enable_test.go +48 -0
- package/linthost/engine_respects_eslint_disable_line_test.go +45 -0
- package/linthost/engine_respects_eslint_disable_next_line_test.go +48 -0
- package/linthost/engine_respects_lint_disable_next_line_alias_test.go +46 -0
- package/linthost/engine_run_parallel_matches_serial_finding_set_test.go +86 -0
- package/linthost/engine_runs_format_rules_on_declaration_files_test.go +37 -0
- package/linthost/engine_runs_opt_in_rules_on_declaration_files_test.go +39 -0
- package/linthost/engine_skips_off_rules_test.go +41 -0
- package/linthost/engine_skips_type_checker_for_ast_only_rule_test.go +35 -0
- package/linthost/engine_skips_value_rules_on_declaration_files_test.go +40 -0
- package/linthost/engine_softline_emits_newline_when_group_breaks_test.go +23 -0
- package/linthost/engine_softline_renders_empty_when_flat_test.go +22 -0
- package/linthost/engine_starting_indent_offsets_break_decision_test.go +29 -0
- package/linthost/engine_tab_width_defaults_when_zero_test.go +24 -0
- package/linthost/engine_text_renders_verbatim_test.go +29 -0
- package/linthost/engine_text_with_embedded_newline_forces_break_test.go +24 -0
- package/linthost/engine_use_tabs_emits_remainder_spaces_test.go +27 -0
- package/linthost/engine_use_tabs_emits_tab_characters_test.go +24 -0
- package/linthost/eqeqeq_offers_unsafe_operator_rewrite_as_suggestion_test.go +45 -0
- package/linthost/expect_matchers_without_argument_do_not_panic_test.go +50 -0
- package/linthost/file_path_from_uri_preserves_literal_percent_escapes_test.go +36 -0
- package/linthost/file_url_matches_node_shape_test.go +64 -0
- package/linthost/files_selector_scopes_rules_away_from_an_imported_sibling_test.go +70 -0
- package/linthost/filter_format_findings_keeps_only_format_rule_findings_test.go +56 -0
- package/linthost/filter_known_flags_preserves_known_values_and_skips_unknowns_test.go +49 -0
- package/linthost/filter_known_flags_resolves_names_case_insensitively_test.go +43 -0
- package/linthost/filter_lint_findings_drops_format_rule_findings_test.go +43 -0
- package/linthost/find_lint_config_file_discovers_nearest_ancestor_test.go +37 -0
- package/linthost/find_lint_config_file_discovers_plain_lint_config_test.go +37 -0
- package/linthost/find_lint_config_file_falls_back_to_cwd_for_out_of_tree_tsconfig_test.go +43 -0
- package/linthost/find_lint_config_file_prefers_nearest_directory_test.go +38 -0
- package/linthost/find_lint_config_file_rejects_same_directory_conflicts_test.go +38 -0
- package/linthost/find_lint_config_file_uses_tsconfig_directory_when_outside_cwd_test.go +45 -0
- package/linthost/find_lint_entry_accepts_sorted_check_plugin_payload_test.go +53 -0
- package/linthost/fix.go +37 -11
- package/linthost/fix_eqeqeq_replaces_same_type_literal_operator_test.go +26 -0
- package/linthost/fix_eqeqeq_replaces_typeof_operator_test.go +26 -0
- package/linthost/fix_eqeqeq_requires_both_operands_to_share_a_primitive_kind_test.go +29 -0
- package/linthost/fix_eqeqeq_skips_unsafe_identifier_comparison_test.go +25 -0
- package/linthost/fix_interleaved_import_type_and_bracket_spacing_stays_valid_test.go +113 -0
- package/linthost/fix_no_extra_bind_removes_safe_member_and_call_syntax_test.go +45 -0
- package/linthost/fix_no_extra_bind_skips_effectful_or_commented_removals_test.go +55 -0
- package/linthost/fix_no_extra_non_null_assertion_drops_trailing_bang_test.go +39 -0
- package/linthost/fix_no_import_type_side_effects_hoists_type_keyword_test.go +29 -0
- package/linthost/fix_no_import_type_side_effects_preserves_leading_comment_test.go +30 -0
- package/linthost/fix_no_import_type_side_effects_skips_comment_import_keyword_test.go +31 -0
- package/linthost/fix_no_import_type_side_effects_skips_mixed_import_test.go +28 -0
- package/linthost/fix_no_unnecessary_type_constraint_disambiguates_cts_generic_arrow_test.go +20 -0
- package/linthost/fix_no_unnecessary_type_constraint_disambiguates_mts_generic_arrow_test.go +20 -0
- package/linthost/fix_no_unnecessary_type_constraint_disambiguates_tsx_generic_arrow_test.go +20 -0
- package/linthost/fix_no_unnecessary_type_constraint_drops_extends_clause_test.go +28 -0
- package/linthost/fix_no_unnecessary_type_constraint_keeps_default_unambiguous_test.go +20 -0
- package/linthost/fix_no_unnecessary_type_constraint_keeps_multiple_parameters_unambiguous_test.go +20 -0
- package/linthost/fix_no_unnecessary_type_constraint_keeps_non_arrow_declarations_minimal_test.go +28 -0
- package/linthost/fix_no_unnecessary_type_constraint_keeps_ts_generic_arrow_minimal_test.go +20 -0
- package/linthost/fix_no_unnecessary_type_constraint_preserves_comma_comments_test.go +22 -0
- package/linthost/fix_no_unnecessary_type_constraint_preserves_existing_trailing_comma_test.go +20 -0
- package/linthost/fix_no_useless_escape_drops_backslash_test.go +28 -0
- package/linthost/fix_no_useless_escape_drops_nondigit_neighbors_of_octal_exemption_test.go +31 -0
- package/linthost/fix_no_useless_escape_skips_backslash_digit_escapes_test.go +48 -0
- package/linthost/fix_no_useless_escape_skips_tagged_template_test.go +29 -0
- package/linthost/fix_no_useless_escape_skips_template_substitution_escape_test.go +45 -0
- package/linthost/fix_no_useless_rename_drops_rename_tail_test.go +39 -0
- package/linthost/fix_no_useless_rename_skips_string_literal_alias_test.go +34 -0
- package/linthost/fix_no_var_fixes_despite_label_before_test.go +30 -0
- package/linthost/fix_no_var_fixes_despite_member_name_before_test.go +29 -0
- package/linthost/fix_no_var_fixes_despite_object_key_before_test.go +30 -0
- package/linthost/fix_no_var_fixes_despite_type_reference_before_test.go +32 -0
- package/linthost/fix_no_var_keeps_bindings_observable_by_direct_eval_test.go +41 -0
- package/linthost/fix_no_var_preserves_script_global_object_bindings_test.go +30 -0
- package/linthost/fix_no_var_replaces_closure_reference_without_loop_test.go +30 -0
- package/linthost/fix_no_var_replaces_for_header_binding_test.go +31 -0
- package/linthost/fix_no_var_replaces_for_in_header_binding_test.go +31 -0
- package/linthost/fix_no_var_replaces_for_of_header_binding_test.go +31 -0
- package/linthost/fix_no_var_replaces_loop_local_without_closure_test.go +30 -0
- package/linthost/fix_no_var_replaces_namespace_block_binding_test.go +28 -0
- package/linthost/fix_no_var_replaces_reassigned_binding_test.go +30 -0
- package/linthost/fix_no_var_replaces_reference_in_nested_block_test.go +30 -0
- package/linthost/fix_no_var_replaces_reference_inside_with_body_test.go +30 -0
- package/linthost/fix_no_var_replaces_same_block_references_test.go +30 -0
- package/linthost/fix_no_var_replaces_same_case_clause_references_test.go +30 -0
- package/linthost/fix_no_var_replaces_unique_binding_test.go +30 -0
- package/linthost/fix_no_var_replaces_var_keyword_test.go +28 -0
- package/linthost/fix_no_var_skips_block_scope_escape_test.go +37 -0
- package/linthost/fix_no_var_skips_catch_binding_redeclaration_test.go +36 -0
- package/linthost/fix_no_var_skips_class_field_capture_in_loop_test.go +38 -0
- package/linthost/fix_no_var_skips_cross_case_reference_test.go +36 -0
- package/linthost/fix_no_var_skips_cross_scope_same_name_over_decline_test.go +36 -0
- package/linthost/fix_no_var_skips_deferred_self_reference_in_init_test.go +45 -0
- package/linthost/fix_no_var_skips_direct_self_reference_in_init_test.go +37 -0
- package/linthost/fix_no_var_skips_for_header_closure_capture_test.go +38 -0
- package/linthost/fix_no_var_skips_for_header_multi_declarator_test.go +32 -0
- package/linthost/fix_no_var_skips_for_header_redeclaration_test.go +36 -0
- package/linthost/fix_no_var_skips_for_header_use_after_loop_test.go +37 -0
- package/linthost/fix_no_var_skips_for_in_annex_b_initializer_test.go +33 -0
- package/linthost/fix_no_var_skips_for_in_header_expression_self_reference_test.go +37 -0
- package/linthost/fix_no_var_skips_for_of_destructuring_header_test.go +32 -0
- package/linthost/fix_no_var_skips_for_of_header_closure_capture_test.go +38 -0
- package/linthost/fix_no_var_skips_for_of_header_expression_self_reference_test.go +36 -0
- package/linthost/fix_no_var_skips_function_declaration_redeclaration_test.go +39 -0
- package/linthost/fix_no_var_skips_function_scope_escape_test.go +28 -0
- package/linthost/fix_no_var_skips_iife_self_reference_in_init_test.go +39 -0
- package/linthost/fix_no_var_skips_let_as_binding_name_test.go +32 -0
- package/linthost/fix_no_var_skips_loop_closure_capture_test.go +37 -0
- package/linthost/fix_no_var_skips_mixed_destructure_redeclaration_test.go +38 -0
- package/linthost/fix_no_var_skips_mixed_destructure_use_before_test.go +36 -0
- package/linthost/fix_no_var_skips_parameter_redeclaration_test.go +28 -0
- package/linthost/fix_no_var_skips_redeclaration_test.go +37 -0
- package/linthost/fix_no_var_skips_shorthand_value_before_test.go +37 -0
- package/linthost/fix_no_var_skips_single_statement_position_test.go +33 -0
- package/linthost/fix_no_var_skips_typeof_self_reference_in_init_test.go +38 -0
- package/linthost/fix_no_var_skips_use_before_declaration_test.go +36 -0
- package/linthost/fix_no_var_skips_use_before_for_header_test.go +36 -0
- package/linthost/fix_no_var_skips_while_loop_closure_capture_test.go +35 -0
- package/linthost/fix_no_var_skips_with_statement_body_test.go +35 -0
- package/linthost/fix_no_wrapper_object_types_replaces_typename_test.go +28 -0
- package/linthost/fix_no_wrapper_object_types_replaces_unshadowed_const_test.go +30 -0
- package/linthost/fix_no_wrapper_object_types_skips_function_shadow_test.go +27 -0
- package/linthost/fix_no_wrapper_object_types_skips_import_equals_shadow_test.go +26 -0
- package/linthost/fix_no_wrapper_object_types_skips_imported_name_test.go +26 -0
- package/linthost/fix_no_wrapper_object_types_skips_user_shadowed_name_test.go +27 -0
- package/linthost/fix_object_shorthand_drops_value_tail_test.go +28 -0
- package/linthost/fix_object_shorthand_preserves_the_prototype_setter_test.go +28 -0
- package/linthost/fix_prefer_as_const_preserves_comment_before_literal_type_test.go +27 -0
- package/linthost/fix_prefer_as_const_replaces_angle_bracket_type_with_const_test.go +27 -0
- package/linthost/fix_prefer_as_const_replaces_literal_type_with_const_test.go +27 -0
- package/linthost/fix_prefer_as_const_replaces_parenthesized_literal_assertion_test.go +28 -0
- package/linthost/fix_prefer_as_const_replaces_parenthesized_literal_type_test.go +28 -0
- package/linthost/fix_prefer_as_const_skips_null_literal_assertion_test.go +26 -0
- package/linthost/fix_prefer_as_const_skips_property_annotation_rewrite_test.go +27 -0
- package/linthost/fix_prefer_as_const_skips_template_literal_assertion_test.go +28 -0
- package/linthost/fix_prefer_as_const_skips_variable_annotation_rewrite_test.go +27 -0
- package/linthost/fix_prefer_const_counts_nested_write_in_shorthand_default_test.go +25 -0
- package/linthost/fix_prefer_const_keeps_nonlocal_rewrites_diagnostic_only_test.go +54 -0
- package/linthost/fix_prefer_const_preserves_assertion_wrapped_assignment_targets_test.go +68 -0
- package/linthost/fix_prefer_const_replaces_let_with_fresh_for_of_binding_test.go +29 -0
- package/linthost/fix_prefer_const_replaces_single_let_keyword_test.go +26 -0
- package/linthost/fix_prefer_const_replaces_wholly_stable_destructuring_keyword_test.go +26 -0
- package/linthost/fix_prefer_const_skips_destructuring_assignment_targets_test.go +42 -0
- package/linthost/fix_prefer_const_skips_for_in_reassignment_test.go +28 -0
- package/linthost/fix_prefer_const_skips_for_of_reassignment_test.go +29 -0
- package/linthost/fix_prefer_const_skips_multi_declaration_list_test.go +32 -0
- package/linthost/fix_prefer_namespace_keyword_replaces_module_keyword_test.go +29 -0
- package/linthost/fix_regexp_no_useless_flag_deletes_the_flag_it_named_test.go +74 -0
- package/linthost/fix_regexp_no_useless_quantifier_drops_exactly_one_repeat_test.go +57 -0
- package/linthost/fix_regexp_no_useless_two_nums_quantifier_collapses_equal_bounds_test.go +50 -0
- package/linthost/fix_regexp_no_zero_quantifier_stays_diagnostic_only_test.go +39 -0
- package/linthost/fix_regexp_prefer_d_replaces_spelled_out_digit_class_test.go +49 -0
- package/linthost/fix_regexp_prefer_plus_quantifier_replaces_open_ended_one_test.go +45 -0
- package/linthost/fix_regexp_prefer_question_quantifier_replaces_zero_to_one_test.go +43 -0
- package/linthost/fix_regexp_prefer_star_quantifier_replaces_open_ended_zero_test.go +43 -0
- package/linthost/fix_regexp_prefer_w_replaces_spelled_out_word_class_test.go +46 -0
- package/linthost/fix_regexp_require_unicode_regexp_offers_u_and_v_suggestions_test.go +71 -0
- package/linthost/fix_regexp_require_unicode_sets_regexp_offers_the_v_flag_test.go +76 -0
- package/linthost/fix_regexp_sort_flags_rewrites_flag_run_in_canonical_order_test.go +48 -0
- package/linthost/fix_regexp_withholds_a_rewrite_the_regex_parser_rejects_test.go +62 -0
- package/linthost/fix_security_detect_new_buffer_offers_three_successors_test.go +93 -0
- package/linthost/fix_security_detect_pseudo_random_bytes_proves_automatic_rename_test.go +95 -0
- package/linthost/fix_select_text_edit_groups_collapses_duplicate_edit_within_finding_test.go +42 -0
- package/linthost/fix_select_text_edit_groups_drops_partially_overlapped_finding_whole_test.go +43 -0
- package/linthost/fix_select_text_edit_groups_drops_self_overlapping_finding_test.go +32 -0
- package/linthost/fix_select_text_edit_groups_keeps_disjoint_multi_edit_finding_whole_test.go +41 -0
- package/linthost/fix_select_text_edits_drops_coincident_zero_width_insert_test.go +57 -0
- package/linthost/fix_select_text_edits_drops_duplicate_edits_test.go +38 -0
- package/linthost/fix_select_text_edits_drops_overlapping_ranges_test.go +32 -0
- package/linthost/fix_solid_imports_rewrites_sole_specifier_module_test.go +65 -0
- package/linthost/fix_solid_no_react_specific_props_renames_react_props_test.go +66 -0
- package/linthost/fix_storybook_no_renderer_packages_offers_framework_packages_test.go +95 -0
- package/linthost/fix_tsx_grammar_keeps_jsx_while_rewriting_var_and_let_test.go +36 -0
- package/linthost/flags_gen.go +2 -2
- package/linthost/for_direction_honors_a_negated_compound_step_test.go +37 -0
- package/linthost/format.go +14 -4
- package/linthost/format_arrow_parens_abstains_on_comment_near_trailing_comma_test.go +68 -0
- package/linthost/format_arrow_parens_abstains_on_param_comment_test.go +44 -0
- package/linthost/format_arrow_parens_avoid_keeps_return_type_parens_test.go +24 -0
- package/linthost/format_arrow_parens_avoid_keeps_type_parameter_parens_test.go +23 -0
- package/linthost/format_arrow_parens_idempotent_on_wrapped_test.go +24 -0
- package/linthost/format_arrow_parens_keeps_destructured_param_under_avoid_test.go +24 -0
- package/linthost/format_arrow_parens_keeps_ineligible_trailing_comma_params_test.go +66 -0
- package/linthost/format_arrow_parens_keeps_trailing_comma_param_under_always_test.go +48 -0
- package/linthost/format_arrow_parens_keeps_typed_param_under_avoid_test.go +24 -0
- package/linthost/format_arrow_parens_strips_async_single_param_test.go +26 -0
- package/linthost/format_arrow_parens_strips_single_param_under_avoid_test.go +24 -0
- package/linthost/format_arrow_parens_strips_trailing_comma_param_under_avoid_test.go +51 -0
- package/linthost/format_arrow_parens_strips_wrapped_param_before_list_comma_test.go +32 -0
- package/linthost/format_arrow_parens_wraps_bare_single_param_test.go +25 -0
- package/linthost/format_block_absent_keeps_format_rules_off_test.go +42 -0
- package/linthost/format_block_default_severity_off_keeps_format_rules_out_of_check_test.go +48 -0
- package/linthost/format_block_drops_format_rule_in_rules_map_test.go +45 -0
- package/linthost/format_block_expands_nil_raw_to_empty_map_test.go +32 -0
- package/linthost/format_block_jsdoc_false_skips_rule_test.go +37 -0
- package/linthost/format_block_propagates_jsdoc_sort_tags_option_test.go +59 -0
- package/linthost/format_block_propagates_prettier_options_to_rule_test.go +159 -0
- package/linthost/format_block_propagates_sort_imports_options_test.go +70 -0
- package/linthost/format_block_rejects_empty_sort_imports_order_test.go +37 -0
- package/linthost/format_block_rejects_invalid_jsdoc_options_test.go +68 -0
- package/linthost/format_block_rejects_invalid_severity_test.go +33 -0
- package/linthost/format_block_rejects_invalid_trailing_comma_value_test.go +36 -0
- package/linthost/format_block_rejects_non_array_sort_imports_order_test.go +32 -0
- package/linthost/format_block_rejects_non_bool_or_object_jsdoc_test.go +36 -0
- package/linthost/format_block_rejects_non_bool_or_object_sort_imports_test.go +30 -0
- package/linthost/format_block_rejects_non_bool_semi_test.go +32 -0
- package/linthost/format_block_rejects_non_bool_single_quote_test.go +31 -0
- package/linthost/format_block_rejects_non_bool_sort_imports_options_test.go +45 -0
- package/linthost/format_block_rejects_non_bool_use_tabs_test.go +31 -0
- package/linthost/format_block_rejects_non_int_print_width_test.go +31 -0
- package/linthost/format_block_rejects_non_int_tab_width_test.go +32 -0
- package/linthost/format_block_rejects_non_string_end_of_line_test.go +48 -0
- package/linthost/format_block_rejects_non_string_trailing_comma_test.go +32 -0
- package/linthost/format_block_rejects_unknown_key_test.go +39 -0
- package/linthost/format_block_rejects_unknown_sort_imports_key_test.go +36 -0
- package/linthost/format_block_severity_warning_enables_check_diagnostics_test.go +48 -0
- package/linthost/format_block_sort_imports_false_keeps_rule_off_test.go +27 -0
- package/linthost/format_block_sort_imports_true_enables_defaults_test.go +37 -0
- package/linthost/format_block_targets_option_accepting_rules_test.go +90 -0
- package/linthost/format_block_threads_end_of_line_into_sort_imports_test.go +55 -0
- package/linthost/format_block_wins_over_vscode_settings_test.go +36 -0
- package/linthost/format_brace_continuation_corrects_a_pushed_keyword_at_the_wrong_column_test.go +28 -0
- package/linthost/format_brace_continuation_honors_crlf_end_of_line_test.go +29 -0
- package/linthost/format_brace_continuation_indents_a_pushed_keyword_to_its_statement_test.go +27 -0
- package/linthost/format_brace_continuation_is_idempotent_in_both_directions_test.go +32 -0
- package/linthost/format_brace_continuation_leaves_an_if_without_an_else_alone_test.go +23 -0
- package/linthost/format_brace_continuation_normalizes_a_zero_width_gap_test.go +27 -0
- package/linthost/format_brace_continuation_pulls_catch_and_finally_onto_their_braces_test.go +28 -0
- package/linthost/format_brace_continuation_pulls_do_while_onto_the_closing_brace_test.go +27 -0
- package/linthost/format_brace_continuation_pulls_else_onto_the_closing_brace_test.go +27 -0
- package/linthost/format_brace_continuation_pulls_finally_onto_a_try_without_a_catch_test.go +28 -0
- package/linthost/format_brace_continuation_pushes_a_do_while_off_a_statement_body_test.go +28 -0
- package/linthost/format_brace_continuation_pushes_else_off_a_statement_consequent_test.go +28 -0
- package/linthost/format_brace_continuation_pushes_past_a_brace_terminated_non_block_test.go +28 -0
- package/linthost/format_brace_continuation_pushes_past_a_label_prefix_test.go +48 -0
- package/linthost/format_brace_continuation_settles_a_shared_line_through_the_cascade_test.go +44 -0
- package/linthost/format_brace_continuation_skips_a_commented_gap_test.go +28 -0
- package/linthost/format_brace_continuation_waits_for_a_statement_to_own_its_line_test.go +27 -0
- package/linthost/format_bracket_spacing_idempotent_on_padded_test.go +23 -0
- package/linthost/format_bracket_spacing_leaves_a_prettier_shaped_type_literal_alone_test.go +27 -0
- package/linthost/format_bracket_spacing_leaves_empty_object_test.go +74 -0
- package/linthost/format_bracket_spacing_pads_an_unspaced_type_literal_test.go +29 -0
- package/linthost/format_bracket_spacing_pads_destructure_test.go +24 -0
- package/linthost/format_bracket_spacing_pads_import_attributes_test.go +28 -0
- package/linthost/format_bracket_spacing_pads_mapped_type_test.go +27 -0
- package/linthost/format_bracket_spacing_pads_named_imports_test.go +24 -0
- package/linthost/format_bracket_spacing_pads_object_literal_test.go +26 -0
- package/linthost/format_bracket_spacing_strips_object_literal_under_false_test.go +26 -0
- package/linthost/format_clause_join_charges_the_else_width_budget_at_its_limit_test.go +37 -0
- package/linthost/format_clause_join_charges_the_shift_to_the_header_lines_indent_test.go +45 -0
- package/linthost/format_clause_join_emits_no_shift_when_the_column_is_unchanged_test.go +50 -0
- package/linthost/format_clause_join_hoists_across_a_multiline_template_without_moving_it_test.go +30 -0
- package/linthost/format_clause_join_idempotent_on_joined_body_test.go +27 -0
- package/linthost/format_clause_join_joins_do_body_test.go +27 -0
- package/linthost/format_clause_join_joins_else_body_test.go +27 -0
- package/linthost/format_clause_join_joins_else_if_chain_across_lines_test.go +44 -0
- package/linthost/format_clause_join_joins_for_and_while_bodies_test.go +32 -0
- package/linthost/format_clause_join_joins_labeled_block_body_test.go +31 -0
- package/linthost/format_clause_join_joins_single_if_body_test.go +28 -0
- package/linthost/format_clause_join_joins_with_body_test.go +27 -0
- package/linthost/format_clause_join_keeps_a_blank_line_inside_a_hoisted_body_test.go +45 -0
- package/linthost/format_clause_join_keeps_overlong_body_broken_test.go +31 -0
- package/linthost/format_clause_join_leaves_a_block_comment_interior_untouched_test.go +45 -0
- package/linthost/format_clause_join_leaves_a_string_continuation_untouched_test.go +45 -0
- package/linthost/format_clause_join_leaves_a_template_literal_type_untouched_test.go +49 -0
- package/linthost/format_clause_join_reindents_a_hoisted_body_inside_a_function_test.go +43 -0
- package/linthost/format_clause_join_reindents_a_hoisted_else_if_chain_test.go +45 -0
- package/linthost/format_clause_join_reindents_a_hoisted_labeled_block_test.go +27 -0
- package/linthost/format_clause_join_reindents_an_indentable_block_comment_test.go +50 -0
- package/linthost/format_clause_join_settles_a_deep_staircase_within_the_cascade_budget_test.go +44 -0
- package/linthost/format_clause_join_shifts_a_tab_indented_body_with_tabs_test.go +44 -0
- package/linthost/format_clause_join_skips_braced_body_test.go +31 -0
- package/linthost/format_clause_join_skips_braced_else_and_do_bodies_test.go +38 -0
- package/linthost/format_clause_join_skips_commented_else_gap_test.go +29 -0
- package/linthost/format_clause_join_skips_empty_else_and_do_bodies_test.go +33 -0
- package/linthost/format_clause_join_skips_empty_statement_body_test.go +36 -0
- package/linthost/format_command_resolver_keeps_configured_options_inside_matching_entry_test.go +64 -0
- package/linthost/format_command_resolver_skips_upgrade_for_entry_ignored_file_test.go +60 -0
- package/linthost/format_command_resolver_skips_upgrade_for_file_outside_entry_files_test.go +61 -0
- package/linthost/format_command_resolver_variants_replace_bare_options_with_reachable_defaults_test.go +34 -0
- package/linthost/format_declaration_header_abstains_on_comment_in_header_test.go +25 -0
- package/linthost/format_declaration_header_abstains_on_type_params_with_multi_clause_test.go +27 -0
- package/linthost/format_declaration_header_breaks_empty_body_at_width_boundary_test.go +32 -0
- package/linthost/format_declaration_header_breaks_generic_heritage_type_args_test.go +28 -0
- package/linthost/format_declaration_header_breaks_multi_type_interface_test.go +29 -0
- package/linthost/format_declaration_header_breaks_multiple_clauses_test.go +25 -0
- package/linthost/format_declaration_header_breaks_single_type_clause_in_multi_clause_test.go +73 -0
- package/linthost/format_declaration_header_breaks_type_param_default_after_equals_test.go +29 -0
- package/linthost/format_declaration_header_collapses_fitting_header_test.go +29 -0
- package/linthost/format_declaration_header_drops_brace_for_class_body_test.go +28 -0
- package/linthost/format_declaration_header_explodes_and_drops_brace_for_class_body_test.go +27 -0
- package/linthost/format_declaration_header_explodes_type_parameters_test.go +26 -0
- package/linthost/format_declaration_header_generic_heritage_honors_crlf_end_of_line_test.go +32 -0
- package/linthost/format_declaration_header_glues_brace_for_empty_body_test.go +27 -0
- package/linthost/format_declaration_header_idempotent_on_broken_clauses_test.go +24 -0
- package/linthost/format_declaration_header_idempotent_on_broken_heritage_type_args_test.go +25 -0
- package/linthost/format_declaration_header_idempotent_on_exploded_class_body_test.go +25 -0
- package/linthost/format_declaration_header_keeps_multi_type_inline_after_break_test.go +30 -0
- package/linthost/format_declaration_header_keeps_single_generic_heritage_arg_inline_test.go +25 -0
- package/linthost/format_declaration_header_keeps_single_heritage_type_inline_test.go +26 -0
- package/linthost/format_declaration_header_multi_clause_honors_crlf_end_of_line_test.go +30 -0
- package/linthost/format_declaration_header_multi_type_honors_crlf_end_of_line_test.go +30 -0
- package/linthost/format_declaration_header_type_param_explode_honors_crlf_end_of_line_test.go +32 -0
- package/linthost/format_defaults_apply_without_format_config_test.go +46 -0
- package/linthost/format_indent_case_block_body_matches_case_depth_test.go +30 -0
- package/linthost/format_indent_cedes_body_under_multiline_arrow_head_test.go +39 -0
- package/linthost/format_indent_cedes_callback_argument_body_test.go +31 -0
- package/linthost/format_indent_defers_shared_line_to_statement_split_test.go +32 -0
- package/linthost/format_indent_honors_custom_tab_width_test.go +28 -0
- package/linthost/format_indent_honors_use_tabs_option_test.go +28 -0
- package/linthost/format_indent_idempotent_on_correct_class_body_test.go +27 -0
- package/linthost/format_indent_idempotent_on_correct_nested_block_test.go +26 -0
- package/linthost/format_indent_idempotent_on_decorated_member_test.go +29 -0
- package/linthost/format_indent_normalizes_class_method_body_depth_test.go +29 -0
- package/linthost/format_indent_normalizes_decorated_member_declaration_line_test.go +31 -0
- package/linthost/format_indent_normalizes_multiple_decorator_lines_test.go +30 -0
- package/linthost/format_indent_normalizes_over_indented_block_statement_test.go +27 -0
- package/linthost/format_indent_normalizes_plain_member_header_test.go +29 -0
- package/linthost/format_indent_normalizes_same_line_decorated_member_test.go +49 -0
- package/linthost/format_indent_normalizes_switch_case_body_depth_test.go +29 -0
- package/linthost/format_indent_still_fixes_single_line_head_arrow_body_test.go +27 -0
- package/linthost/format_indent_strips_leading_indent_from_top_level_statement_test.go +27 -0
- package/linthost/format_jsdoc_honors_custom_tag_synonyms_option_test.go +26 -0
- package/linthost/format_jsdoc_preserves_example_block_body_test.go +63 -0
- package/linthost/format_jsdoc_rejects_malformed_tag_synonym_value_test.go +60 -0
- package/linthost/format_jsdoc_rewrites_arg_synonyms_to_param_test.go +25 -0
- package/linthost/format_jsdoc_rewrites_return_to_returns_test.go +24 -0
- package/linthost/format_jsdoc_skips_canonical_tags_test.go +32 -0
- package/linthost/format_jsdoc_skips_inline_at_text_test.go +34 -0
- package/linthost/format_jsdoc_skips_jsdoc_like_strings_in_source_test.go +41 -0
- package/linthost/format_orphan_semi_inert_under_semi_true_test.go +24 -0
- package/linthost/format_orphan_semi_merges_guard_under_no_semi_test.go +35 -0
- package/linthost/format_orphan_semi_skips_comment_between_guard_and_statement_test.go +28 -0
- package/linthost/format_orphan_semi_skips_non_hazard_successor_test.go +29 -0
- package/linthost/format_parameter_properties_breaks_multi_param_constructor_test.go +30 -0
- package/linthost/format_parameter_properties_breaks_override_only_constructor_test.go +31 -0
- package/linthost/format_parameter_properties_honors_crlf_end_of_line_test.go +29 -0
- package/linthost/format_parameter_properties_idempotent_on_broken_list_test.go +28 -0
- package/linthost/format_parameter_properties_ignores_decorated_plain_params_test.go +31 -0
- package/linthost/format_parameter_properties_ignores_plain_params_test.go +27 -0
- package/linthost/format_parameter_properties_keeps_single_param_inline_test.go +30 -0
- package/linthost/format_prettier_conformance_e2e_test.go +367 -0
- package/linthost/format_print_width_abstains_inside_jsx_expression_test.go +50 -0
- package/linthost/format_print_width_abstains_inside_template_substitution_test.go +31 -0
- package/linthost/format_print_width_abstains_when_callback_body_holds_uncovered_statement_test.go +37 -0
- package/linthost/format_print_width_abstains_when_inter_member_comment_present_test.go +32 -0
- package/linthost/format_print_width_abstains_when_trailing_block_comment_before_close_bracket_test.go +35 -0
- package/linthost/format_print_width_breaks_array_rest_assignment_target_without_comma_test.go +31 -0
- package/linthost/format_print_width_breaks_call_when_trailing_semicolon_overflows_test.go +26 -0
- package/linthost/format_print_width_breaks_default_plus_named_import_shape_test.go +29 -0
- package/linthost/format_print_width_breaks_long_call_arguments_test.go +31 -0
- package/linthost/format_print_width_breaks_long_named_exports_test.go +30 -0
- package/linthost/format_print_width_breaks_long_named_imports_test.go +30 -0
- package/linthost/format_print_width_breaks_long_new_expression_arguments_test.go +31 -0
- package/linthost/format_print_width_breaks_long_object_literal_test.go +27 -0
- package/linthost/format_print_width_breaks_overflowing_react_hook_deps_array_test.go +29 -0
- package/linthost/format_print_width_check_abstains_when_ctx_is_nil_test.go +24 -0
- package/linthost/format_print_width_check_abstains_when_node_is_nil_test.go +48 -0
- package/linthost/format_print_width_check_abstains_when_node_range_exceeds_context_source_test.go +71 -0
- package/linthost/format_print_width_declines_last_arg_hug_after_arrow_lead_test.go +29 -0
- package/linthost/format_print_width_declines_last_arg_hug_after_callback_test.go +28 -0
- package/linthost/format_print_width_default_width_is_80_columns_test.go +31 -0
- package/linthost/format_print_width_explodes_call_when_hugged_header_overflows_test.go +26 -0
- package/linthost/format_print_width_hangs_broken_ternary_arm_under_arm_column_test.go +40 -0
- package/linthost/format_print_width_has_non_child_comments_returns_false_when_node_is_nil_test.go +46 -0
- package/linthost/format_print_width_has_reflow_ancestor_returns_false_when_node_is_nil_test.go +40 -0
- package/linthost/format_print_width_honors_crlf_end_of_line_test.go +30 -0
- package/linthost/format_print_width_honors_custom_tab_width_test.go +27 -0
- package/linthost/format_print_width_honors_tab_leading_source_test.go +27 -0
- package/linthost/format_print_width_honors_use_tabs_option_test.go +25 -0
- package/linthost/format_print_width_hugs_arrow_with_object_body_test.go +32 -0
- package/linthost/format_print_width_hugs_first_callback_argument_test.go +31 -0
- package/linthost/format_print_width_hugs_first_callback_with_array_arg_test.go +27 -0
- package/linthost/format_print_width_hugs_object_argument_despite_long_trailing_suffix_test.go +32 -0
- package/linthost/format_print_width_idempotent_on_already_reflowed_input_test.go +26 -0
- package/linthost/format_print_width_idempotent_on_first_hugged_call_test.go +25 -0
- package/linthost/format_print_width_idempotent_on_hugged_callback_call_test.go +25 -0
- package/linthost/format_print_width_idempotent_on_nested_ternary_staircase_test.go +25 -0
- package/linthost/format_print_width_indents_nested_alternate_ternary_test.go +30 -0
- package/linthost/format_print_width_indents_nested_consequent_ternary_test.go +30 -0
- package/linthost/format_print_width_indents_relative_to_line_leading_indent_test.go +42 -0
- package/linthost/format_print_width_inserts_after_non_rest_object_assignment_target_test.go +30 -0
- package/linthost/format_print_width_inserts_after_object_spread_in_value_literal_test.go +30 -0
- package/linthost/format_print_width_keeps_call_with_trailing_line_comment_inline_test.go +24 -0
- package/linthost/format_print_width_keeps_empty_array_literal_flat_test.go +25 -0
- package/linthost/format_print_width_keeps_empty_object_literal_flat_test.go +28 -0
- package/linthost/format_print_width_keeps_nested_object_that_fits_test.go +24 -0
- package/linthost/format_print_width_keeps_object_rest_assignment_target_without_comma_test.go +29 -0
- package/linthost/format_print_width_keeps_react_hook_hugged_past_open_line_test.go +26 -0
- package/linthost/format_print_width_keeps_short_call_with_callback_hugged_test.go +32 -0
- package/linthost/format_print_width_keeps_short_ternary_flat_test.go +27 -0
- package/linthost/format_print_width_leading_column_returns_zero_when_pos_is_nonpositive_test.go +51 -0
- package/linthost/format_print_width_line_leading_indent_uses_two_when_tab_width_nonpositive_test.go +47 -0
- package/linthost/format_print_width_max_line_width_uses_two_when_tab_width_nonpositive_test.go +47 -0
- package/linthost/format_print_width_preserves_blank_line_in_reflowed_callback_body_test.go +29 -0
- package/linthost/format_print_width_preserves_call_type_arguments_test.go +32 -0
- package/linthost/format_print_width_preserves_leading_jsdoc_above_reflowed_node_test.go +44 -0
- package/linthost/format_print_width_preserves_multiline_object_test.go +30 -0
- package/linthost/format_print_width_preserves_optional_call_token_test.go +32 -0
- package/linthost/format_print_width_preserves_terminator_decision_on_imports_test.go +42 -0
- package/linthost/format_print_width_reflows_call_with_nested_object_argument_test.go +33 -0
- package/linthost/format_print_width_reflows_wide_array_with_slash_strings_test.go +34 -0
- package/linthost/format_print_width_reindents_callback_body_inside_indented_block_test.go +33 -0
- package/linthost/format_print_width_skips_namespace_import_shape_test.go +28 -0
- package/linthost/format_print_width_skips_nested_target_when_ancestor_covers_it_test.go +58 -0
- package/linthost/format_print_width_skips_short_object_literal_test.go +29 -0
- package/linthost/format_print_width_slice_contains_newline_clamps_out_of_range_bounds_test.go +57 -0
- package/linthost/format_print_width_ternary_arm_indent_bonus_test.go +44 -0
- package/linthost/format_print_width_trailing_line_width_excludes_trailing_line_comment_test.go +38 -0
- package/linthost/format_print_width_trailing_line_width_handles_guards_and_tabs_test.go +51 -0
- package/linthost/format_quote_props_consistent_preserves_cooked_identifier_keys_test.go +37 -0
- package/linthost/format_quote_props_consistent_quotes_mixed_object_test.go +28 -0
- package/linthost/format_quote_props_consistent_unquotes_all_identifier_keys_test.go +24 -0
- package/linthost/format_quote_props_consistent_unquotes_proto_with_identifier_keys_test.go +21 -0
- package/linthost/format_quote_props_keeps_non_identifier_key_test.go +24 -0
- package/linthost/format_quote_props_keeps_numeric_key_test.go +20 -0
- package/linthost/format_quote_props_preserve_is_noop_test.go +23 -0
- package/linthost/format_quote_props_unquotes_class_method_test.go +30 -0
- package/linthost/format_quote_props_unquotes_identifier_keys_test.go +25 -0
- package/linthost/format_quote_props_unquotes_interface_member_test.go +28 -0
- package/linthost/format_quote_props_unquotes_proto_key_without_changing_setter_semantics_test.go +21 -0
- package/linthost/format_quote_props_unquotes_reserved_word_key_test.go +25 -0
- package/linthost/format_quote_props_unquotes_type_literal_member_test.go +28 -0
- package/linthost/format_quotes_converts_double_to_single_preserving_apostrophe_escape_test.go +23 -0
- package/linthost/format_quotes_converts_single_to_double_test.go +22 -0
- package/linthost/format_quotes_escapes_double_quote_when_converting_test.go +22 -0
- package/linthost/format_quotes_honors_prefer_single_option_test.go +27 -0
- package/linthost/format_quotes_keeps_double_on_escape_tie_test.go +29 -0
- package/linthost/format_quotes_keeps_double_with_redundant_single_escape_test.go +31 -0
- package/linthost/format_quotes_keeps_single_with_redundant_double_escape_test.go +31 -0
- package/linthost/format_quotes_preserves_strings_with_unescaped_double_quotes_test.go +34 -0
- package/linthost/format_quotes_skips_double_quoted_literals_test.go +24 -0
- package/linthost/format_quotes_skips_jsx_attribute_strings_test.go +44 -0
- package/linthost/format_quotes_skips_template_literals_test.go +38 -0
- package/linthost/format_quotes_switches_double_to_single_to_minimize_escapes_test.go +31 -0
- package/linthost/format_quotes_switches_single_to_double_to_minimize_escapes_test.go +22 -0
- package/linthost/format_quotes_unescapes_apostrophe_when_converting_test.go +30 -0
- package/linthost/format_reflow_preserves_import_default_gap_comment_test.go +29 -0
- package/linthost/format_reflow_preserves_import_type_gap_comment_test.go +29 -0
- package/linthost/format_reflow_preserves_nested_call_arg_comment_test.go +24 -0
- package/linthost/format_reflow_preserves_new_constructee_gap_comment_test.go +21 -0
- package/linthost/format_reflow_preserves_return_comment_test.go +24 -0
- package/linthost/format_reflow_preserves_ternary_paren_comment_test.go +26 -0
- package/linthost/format_semi_fires_for_every_asi_statement_kind_test.go +103 -0
- package/linthost/format_semi_honors_prefer_never_option_test.go +28 -0
- package/linthost/format_semi_idempotent_on_stripped_interface_test.go +28 -0
- package/linthost/format_semi_idempotent_on_terminated_members_test.go +38 -0
- package/linthost/format_semi_inserts_after_missing_terminator_test.go +28 -0
- package/linthost/format_semi_inserts_member_terminator_before_trailing_comment_test.go +29 -0
- package/linthost/format_semi_keeps_a_flat_mapped_type_bare_test.go +31 -0
- package/linthost/format_semi_keeps_a_flat_object_types_last_member_bare_test.go +36 -0
- package/linthost/format_semi_keeps_braced_and_object_literal_accessors_bare_test.go +40 -0
- package/linthost/format_semi_keeps_class_field_semi_before_computed_member_test.go +32 -0
- package/linthost/format_semi_keeps_object_literal_accessor_separators_untouched_test.go +49 -0
- package/linthost/format_semi_keeps_one_line_interface_body_bare_test.go +29 -0
- package/linthost/format_semi_keeps_same_line_type_member_separator_test.go +31 -0
- package/linthost/format_semi_keeps_type_member_semi_before_call_signature_test.go +32 -0
- package/linthost/format_semi_normalizes_a_comma_member_separator_test.go +39 -0
- package/linthost/format_semi_prefer_never_block_comment_is_not_hazard_test.go +49 -0
- package/linthost/format_semi_prefer_never_keeps_a_flat_object_types_separator_test.go +38 -0
- package/linthost/format_semi_prefer_never_keeps_do_while_separator_test.go +32 -0
- package/linthost/format_semi_prefer_never_keeps_same_line_else_separator_test.go +31 -0
- package/linthost/format_semi_prefer_never_keeps_same_line_statement_separator_test.go +29 -0
- package/linthost/format_semi_prefer_never_keeps_semi_before_asi_hazard_test.go +58 -0
- package/linthost/format_semi_prefer_never_keeps_semi_before_regex_hazard_test.go +51 -0
- package/linthost/format_semi_prefer_never_keeps_semi_before_same_line_comment_gap_test.go +30 -0
- package/linthost/format_semi_prefer_never_line_comment_is_not_hazard_test.go +49 -0
- package/linthost/format_semi_prefer_never_normalizes_a_comma_it_must_keep_test.go +37 -0
- package/linthost/format_semi_prefer_never_strips_a_comma_member_separator_test.go +32 -0
- package/linthost/format_semi_prefer_never_strips_a_flat_object_types_trailing_separator_test.go +33 -0
- package/linthost/format_semi_prefer_never_strips_a_mapped_type_terminator_test.go +35 -0
- package/linthost/format_semi_prefer_never_strips_across_crlf_test.go +33 -0
- package/linthost/format_semi_prefer_never_strips_across_multiline_comment_gap_test.go +32 -0
- package/linthost/format_semi_prefer_never_strips_before_same_line_close_brace_test.go +31 -0
- package/linthost/format_semi_prefer_never_strips_member_with_space_test.go +52 -0
- package/linthost/format_semi_reads_a_mapped_types_wrap_at_its_opening_brace_test.go +34 -0
- package/linthost/format_semi_skips_already_terminated_statements_test.go +31 -0
- package/linthost/format_semi_strips_class_field_semicolons_test.go +29 -0
- package/linthost/format_semi_strips_interface_member_semicolons_test.go +29 -0
- package/linthost/format_semi_strips_type_alias_semicolon_test.go +29 -0
- package/linthost/format_semi_terminates_a_broken_mapped_type_test.go +40 -0
- package/linthost/format_semi_terminates_a_mapped_type_across_crlf_test.go +32 -0
- package/linthost/format_semi_terminates_a_mapped_type_around_its_trailing_comment_test.go +37 -0
- package/linthost/format_semi_terminates_a_mapped_type_without_a_type_annotation_test.go +37 -0
- package/linthost/format_semi_terminates_a_member_across_crlf_test.go +31 -0
- package/linthost/format_semi_terminates_a_member_whose_type_ends_in_a_brace_test.go +31 -0
- package/linthost/format_semi_terminates_broken_interface_members_test.go +45 -0
- package/linthost/format_semi_terminates_broken_type_literal_member_test.go +31 -0
- package/linthost/format_semi_terminates_class_index_signature_and_ambient_accessor_test.go +29 -0
- package/linthost/format_sort_imports_alphabetizes_named_specifiers_test.go +31 -0
- package/linthost/format_sort_imports_combine_requires_unsafe_runtime_opt_in_test.go +30 -0
- package/linthost/format_sort_imports_combines_type_and_value_test.go +27 -0
- package/linthost/format_sort_imports_dedupes_repeated_specifier_test.go +28 -0
- package/linthost/format_sort_imports_group_separator_honors_crlf_end_of_line_test.go +40 -0
- package/linthost/format_sort_imports_groups_builtins_first_test.go +29 -0
- package/linthost/format_sort_imports_groups_external_before_relative_test.go +35 -0
- package/linthost/format_sort_imports_groups_type_only_imports_test.go +27 -0
- package/linthost/format_sort_imports_honors_crlf_end_of_line_test.go +40 -0
- package/linthost/format_sort_imports_honors_custom_import_order_test.go +88 -0
- package/linthost/format_sort_imports_keeps_attribute_bearing_imports_unmerged_test.go +24 -0
- package/linthost/format_sort_imports_keeps_commented_list_unmerged_test.go +26 -0
- package/linthost/format_sort_imports_keeps_conflicting_defaults_separate_test.go +34 -0
- package/linthost/format_sort_imports_keeps_default_gap_comment_unmerged_test.go +24 -0
- package/linthost/format_sort_imports_keeps_default_only_gap_comment_unmerged_test.go +24 -0
- package/linthost/format_sort_imports_keeps_empty_named_imports_test.go +31 -0
- package/linthost/format_sort_imports_keeps_identical_commented_imports_unmerged_test.go +35 -0
- package/linthost/format_sort_imports_keeps_identical_namespace_imports_unmerged_test.go +35 -0
- package/linthost/format_sort_imports_keeps_namespace_imports_separate_test.go +34 -0
- package/linthost/format_sort_imports_keeps_trailing_specifier_comment_unmerged_test.go +24 -0
- package/linthost/format_sort_imports_keeps_type_and_value_separate_test.go +31 -0
- package/linthost/format_sort_imports_keeps_type_default_and_type_named_separate_test.go +34 -0
- package/linthost/format_sort_imports_keeps_type_default_and_type_named_separate_when_combining_test.go +34 -0
- package/linthost/format_sort_imports_keeps_type_default_separate_when_combining_test.go +31 -0
- package/linthost/format_sort_imports_merges_default_and_named_test.go +27 -0
- package/linthost/format_sort_imports_merges_duplicate_modules_test.go +28 -0
- package/linthost/format_sort_imports_merges_duplicate_type_only_imports_test.go +24 -0
- package/linthost/format_sort_imports_merges_type_default_with_empty_named_test.go +28 -0
- package/linthost/format_sort_imports_merges_type_named_binding_test.go +33 -0
- package/linthost/format_sort_imports_orders_case_insensitively_by_default_test.go +29 -0
- package/linthost/format_sort_imports_orders_case_sensitively_when_enabled_test.go +29 -0
- package/linthost/format_sort_imports_preserves_comments_between_imports_test.go +43 -0
- package/linthost/format_sort_imports_preserves_comments_between_specifiers_test.go +38 -0
- package/linthost/format_sort_imports_preserves_side_effect_imports_test.go +55 -0
- package/linthost/format_sort_imports_recognizes_exact_builtin_specifiers_test.go +56 -0
- package/linthost/format_sort_imports_scopes_type_group_by_regex_test.go +32 -0
- package/linthost/format_sort_imports_separator_spans_empty_group_test.go +31 -0
- package/linthost/format_sort_imports_skips_already_sorted_files_test.go +40 -0
- package/linthost/format_sort_imports_skips_invalid_regex_group_test.go +30 -0
- package/linthost/format_sort_imports_skips_invalid_types_regex_group_test.go +28 -0
- package/linthost/format_sort_imports_skips_single_import_files_test.go +38 -0
- package/linthost/format_sort_imports_sorts_erased_type_only_block_test.go +26 -0
- package/linthost/format_sort_imports_sorts_named_specifiers_without_reordering_runtime_imports_test.go +28 -0
- package/linthost/format_sort_imports_treats_inline_type_bindings_as_runtime_import_test.go +24 -0
- package/linthost/format_sort_imports_unsafe_option_reorders_runtime_imports_test.go +34 -0
- package/linthost/format_statement_split_abstains_on_empty_statements_test.go +26 -0
- package/linthost/format_statement_split_abstains_when_block_comment_in_gap_test.go +28 -0
- package/linthost/format_statement_split_breaks_statements_sharing_a_line_test.go +28 -0
- package/linthost/format_statement_split_breaks_three_statements_on_one_line_test.go +27 -0
- package/linthost/format_statement_split_honors_crlf_end_of_line_test.go +29 -0
- package/linthost/format_statement_split_indents_split_statement_inside_block_test.go +30 -0
- package/linthost/format_statement_split_keeps_block_on_case_label_line_test.go +28 -0
- package/linthost/format_statement_split_keeps_leading_semi_guard_test.go +31 -0
- package/linthost/format_statement_split_skips_already_one_per_line_test.go +26 -0
- package/linthost/format_ternary_nullish_parens_leaves_logical_and_parenthesized_test.go +30 -0
- package/linthost/format_ternary_nullish_parens_wraps_all_positions_test.go +29 -0
- package/linthost/format_trailing_comma_honors_mode_es5_for_enum_members_test.go +26 -0
- package/linthost/format_trailing_comma_honors_mode_es5_includes_type_level_lists_test.go +26 -0
- package/linthost/format_trailing_comma_honors_mode_es5_option_test.go +28 -0
- package/linthost/format_trailing_comma_honors_mode_es5_skips_arrow_parameter_test.go +29 -0
- package/linthost/format_trailing_comma_honors_mode_es5_skips_call_argument_test.go +28 -0
- package/linthost/format_trailing_comma_honors_mode_es5_skips_constructor_parameter_test.go +29 -0
- package/linthost/format_trailing_comma_honors_mode_es5_skips_function_expression_parameter_test.go +29 -0
- package/linthost/format_trailing_comma_honors_mode_es5_skips_method_parameter_test.go +29 -0
- package/linthost/format_trailing_comma_honors_mode_es5_skips_new_argument_test.go +28 -0
- package/linthost/format_trailing_comma_honors_mode_es5_skips_set_accessor_parameter_test.go +29 -0
- package/linthost/format_trailing_comma_inserts_after_array_spread_in_value_literal_test.go +26 -0
- package/linthost/format_trailing_comma_inserts_after_decorated_parameter_test.go +27 -0
- package/linthost/format_trailing_comma_inserts_after_last_array_element_test.go +25 -0
- package/linthost/format_trailing_comma_inserts_after_last_arrow_parameter_test.go +25 -0
- package/linthost/format_trailing_comma_inserts_after_last_call_argument_test.go +25 -0
- package/linthost/format_trailing_comma_inserts_after_last_call_signature_parameter_test.go +28 -0
- package/linthost/format_trailing_comma_inserts_after_last_construct_signature_parameter_test.go +28 -0
- package/linthost/format_trailing_comma_inserts_after_last_constructor_parameter_test.go +26 -0
- package/linthost/format_trailing_comma_inserts_after_last_constructor_type_parameter_test.go +28 -0
- package/linthost/format_trailing_comma_inserts_after_last_element_in_multiple_lists_test.go +27 -0
- package/linthost/format_trailing_comma_inserts_after_last_function_expression_parameter_test.go +25 -0
- package/linthost/format_trailing_comma_inserts_after_last_function_parameter_test.go +25 -0
- package/linthost/format_trailing_comma_inserts_after_last_function_type_parameter_test.go +28 -0
- package/linthost/format_trailing_comma_inserts_after_last_method_parameter_test.go +26 -0
- package/linthost/format_trailing_comma_inserts_after_last_method_signature_parameter_test.go +28 -0
- package/linthost/format_trailing_comma_inserts_after_last_named_export_test.go +25 -0
- package/linthost/format_trailing_comma_inserts_after_last_named_import_test.go +25 -0
- package/linthost/format_trailing_comma_inserts_after_last_new_argument_test.go +27 -0
- package/linthost/format_trailing_comma_inserts_after_last_object_property_test.go +25 -0
- package/linthost/format_trailing_comma_inserts_after_last_set_accessor_parameter_test.go +26 -0
- package/linthost/format_trailing_comma_inserts_after_last_tuple_element_test.go +25 -0
- package/linthost/format_trailing_comma_inserts_after_last_type_parameter_test.go +28 -0
- package/linthost/format_trailing_comma_inserts_after_non_rest_array_assignment_target_test.go +27 -0
- package/linthost/format_trailing_comma_inserts_after_non_rest_object_assignment_target_test.go +27 -0
- package/linthost/format_trailing_comma_inserts_after_object_spread_in_value_literal_test.go +26 -0
- package/linthost/format_trailing_comma_inserts_after_parameter_property_in_constructor_test.go +28 -0
- package/linthost/format_trailing_comma_mode_none_removes_trailing_comma_test.go +28 -0
- package/linthost/format_trailing_comma_places_comma_before_trailing_line_comment_test.go +31 -0
- package/linthost/format_trailing_comma_removes_call_comma_under_es5_test.go +27 -0
- package/linthost/format_trailing_comma_skips_already_terminated_lists_test.go +31 -0
- package/linthost/format_trailing_comma_skips_array_rest_assignment_target_test.go +28 -0
- package/linthost/format_trailing_comma_skips_call_when_close_paren_shares_line_with_last_argument_test.go +30 -0
- package/linthost/format_trailing_comma_skips_dynamic_import_argument_test.go +28 -0
- package/linthost/format_trailing_comma_skips_empty_lists_test.go +32 -0
- package/linthost/format_trailing_comma_skips_inline_block_comment_before_close_bracket_test.go +31 -0
- package/linthost/format_trailing_comma_skips_object_rest_assignment_target_test.go +28 -0
- package/linthost/format_trailing_comma_skips_rest_parameter_test.go +39 -0
- package/linthost/format_trailing_comma_skips_single_line_lists_test.go +34 -0
- package/linthost/format_trailing_comma_skips_unparenthesized_arrow_with_multiline_body_test.go +28 -0
- package/linthost/format_whitespace_collapses_all_blank_file_to_single_eol_test.go +30 -0
- package/linthost/format_whitespace_collapses_consecutive_blank_lines_test.go +27 -0
- package/linthost/format_whitespace_fixes_missing_final_newline_with_trailing_space_test.go +29 -0
- package/linthost/format_whitespace_inserts_missing_final_newline_test.go +28 -0
- package/linthost/format_whitespace_keeps_blank_line_inside_template_test.go +27 -0
- package/linthost/format_whitespace_normalizes_crlf_to_lf_by_default_test.go +28 -0
- package/linthost/format_whitespace_preserves_crlf_under_crlf_end_of_line_test.go +28 -0
- package/linthost/format_whitespace_preserves_nested_template_content_test.go +28 -0
- package/linthost/format_whitespace_preserves_trailing_space_across_template_substitution_test.go +29 -0
- package/linthost/format_whitespace_preserves_trailing_spaces_inside_template_literal_test.go +35 -0
- package/linthost/format_whitespace_skips_empty_file_test.go +26 -0
- package/linthost/format_whitespace_skips_single_blank_line_test.go +26 -0
- package/linthost/format_whitespace_strips_leading_blank_lines_test.go +27 -0
- package/linthost/format_whitespace_strips_trailing_blank_lines_test.go +27 -0
- package/linthost/format_whitespace_trims_trailing_spaces_test.go +28 -0
- package/linthost/functional_helpers_test.go +88 -0
- package/linthost/functional_immutable_data_ignores_code_pattern_test.go +28 -0
- package/linthost/functional_immutable_data_rejects_property_assignment_test.go +25 -0
- package/linthost/functional_no_class_inheritance_rejects_extends_test.go +24 -0
- package/linthost/functional_no_classes_rejects_class_declaration_test.go +24 -0
- package/linthost/functional_no_conditional_statements_rejects_if_test.go +23 -0
- package/linthost/functional_no_expression_statements_rejects_call_test.go +23 -0
- package/linthost/functional_no_let_ignores_identifier_pattern_test.go +28 -0
- package/linthost/functional_no_let_rejects_let_declaration_test.go +24 -0
- package/linthost/functional_no_loop_statements_rejects_for_test.go +23 -0
- package/linthost/functional_no_mixed_types_check_interfaces_false_skips_interface_test.go +28 -0
- package/linthost/functional_no_mixed_types_check_interfaces_false_still_checks_type_literal_test.go +28 -0
- package/linthost/functional_no_mixed_types_check_type_literals_false_skips_type_literal_test.go +28 -0
- package/linthost/functional_no_mixed_types_check_type_literals_false_still_checks_interface_test.go +28 -0
- package/linthost/functional_no_mixed_types_rejects_method_and_property_test.go +23 -0
- package/linthost/functional_no_promise_reject_rejects_static_call_test.go +23 -0
- package/linthost/functional_no_return_void_allow_null_false_rejects_null_return_type_test.go +27 -0
- package/linthost/functional_no_return_void_allow_undefined_false_rejects_undefined_return_type_test.go +28 -0
- package/linthost/functional_no_return_void_allows_null_return_type_by_default_test.go +23 -0
- package/linthost/functional_no_return_void_allows_undefined_return_type_by_default_test.go +23 -0
- package/linthost/functional_no_return_void_ignore_inferred_types_keeps_annotated_bare_return_test.go +28 -0
- package/linthost/functional_no_return_void_ignore_inferred_types_reads_a_get_accessor_annotation_test.go +30 -0
- package/linthost/functional_no_return_void_ignore_inferred_types_skips_unannotated_bare_return_test.go +28 -0
- package/linthost/functional_no_return_void_ignore_inferred_types_stops_at_the_nearest_function_test.go +29 -0
- package/linthost/functional_no_return_void_rejects_void_annotation_test.go +23 -0
- package/linthost/functional_no_this_expressions_rejects_this_test.go +23 -0
- package/linthost/functional_no_throw_statements_rejects_throw_test.go +23 -0
- package/linthost/functional_no_try_statements_rejects_try_test.go +23 -0
- package/linthost/functional_parameters_ignores_identifier_pattern_test.go +27 -0
- package/linthost/functional_parameters_rejects_rest_parameter_test.go +25 -0
- package/linthost/functional_prefer_immutable_types_ignores_identifier_pattern_test.go +28 -0
- package/linthost/functional_prefer_immutable_types_rejects_array_type_test.go +23 -0
- package/linthost/functional_prefer_immutable_types_rejects_mutable_parameter_array_test.go +24 -0
- package/linthost/functional_prefer_property_signatures_rejects_method_signature_test.go +23 -0
- package/linthost/functional_prefer_readonly_type_allow_mutable_return_type_covers_call_signature_test.go +29 -0
- package/linthost/functional_prefer_readonly_type_allow_mutable_return_type_keeps_parameter_annotation_test.go +28 -0
- package/linthost/functional_prefer_readonly_type_allow_mutable_return_type_skips_return_annotation_test.go +28 -0
- package/linthost/functional_prefer_readonly_type_ignore_class_fields_only_keeps_method_parameter_test.go +34 -0
- package/linthost/functional_prefer_readonly_type_ignore_class_keeps_module_scope_checked_test.go +29 -0
- package/linthost/functional_prefer_readonly_type_ignore_class_skips_class_body_test.go +29 -0
- package/linthost/functional_prefer_readonly_type_ignore_collections_keeps_property_signature_test.go +28 -0
- package/linthost/functional_prefer_readonly_type_ignore_collections_skips_array_type_test.go +28 -0
- package/linthost/functional_prefer_readonly_type_ignore_interface_keeps_type_alias_member_test.go +28 -0
- package/linthost/functional_prefer_readonly_type_ignore_interface_skips_interface_member_test.go +28 -0
- package/linthost/functional_prefer_readonly_type_ignores_code_pattern_test.go +27 -0
- package/linthost/functional_prefer_readonly_type_rejects_array_type_test.go +23 -0
- package/linthost/functional_prefer_tacit_check_member_expressions_false_keeps_identifier_callee_test.go +27 -0
- package/linthost/functional_prefer_tacit_check_member_expressions_false_skips_member_callee_test.go +28 -0
- package/linthost/functional_prefer_tacit_rejects_single_argument_wrapper_test.go +24 -0
- package/linthost/functional_readonly_type_rejects_readonly_array_generic_test.go +23 -0
- package/linthost/functional_type_declaration_immutability_ignores_identifier_pattern_test.go +27 -0
- package/linthost/functional_type_declaration_immutability_rejects_mutable_interface_test.go +23 -0
- package/linthost/getter_return_follows_every_path_through_switch_try_and_loops_test.go +64 -0
- package/linthost/global_ignores_remove_an_imported_source_from_the_read_scope_test.go +60 -0
- package/linthost/graph_nodes.go +12 -2
- package/linthost/graph_nodes_drops_what_a_consumer_cannot_index_test.go +98 -0
- package/linthost/graph_nodes_publishes_nothing_without_a_publisher_test.go +51 -0
- package/linthost/grapheme_break_unicode_16_conformance_test.go +99 -0
- package/linthost/grouped_accessor_pairs_object_literal_message_test.go +75 -0
- package/linthost/guard_for_in_structural_matrix_test.go +74 -0
- package/linthost/has_nil_entry_distinguishes_malformed_and_valid_lists_test.go +35 -0
- package/linthost/has_nil_entry_returns_false_for_nil_list_test.go +26 -0
- package/linthost/helpers_test.go +910 -0
- package/linthost/hints.go +11 -1
- package/linthost/host.go +126 -43
- package/linthost/imported_tsx_source_joins_the_read_scope_test.go +67 -0
- package/linthost/indent_unit_uses_tab_width_when_positive_test.go +49 -0
- package/linthost/inline_resolver_carries_options_in_resolved_config_test.go +36 -0
- package/linthost/input_observation.go +571 -0
- package/linthost/invalid_contributor_range_cannot_panic_inline_directive_filtering_test.go +46 -0
- package/linthost/is_format_rule_detects_marker_interface_test.go +62 -0
- package/linthost/jsdoc_helpers_test.go +30 -0
- package/linthost/jsx_a11y_alt_text_allows_img_spread_props_test.go +21 -0
- package/linthost/jsx_a11y_alt_text_requires_img_alt_test.go +22 -0
- package/linthost/jsx_a11y_anchor_ambiguous_text_test.go +24 -0
- package/linthost/jsx_a11y_anchor_has_content_rejects_empty_anchor_test.go +25 -0
- package/linthost/jsx_a11y_anchor_is_valid_allows_spread_props_test.go +21 -0
- package/linthost/jsx_a11y_anchor_is_valid_rejects_hash_href_despite_spread_test.go +22 -0
- package/linthost/jsx_a11y_anchor_is_valid_rejects_hash_href_test.go +22 -0
- package/linthost/jsx_a11y_aria_activedescendant_has_tabindex_requires_focus_target_test.go +23 -0
- package/linthost/jsx_a11y_aria_props_rejects_unknown_prop_test.go +22 -0
- package/linthost/jsx_a11y_aria_proptypes_rejects_bad_boolean_test.go +23 -0
- package/linthost/jsx_a11y_aria_role_rejects_unknown_role_test.go +22 -0
- package/linthost/jsx_a11y_aria_unsupported_elements_rejects_meta_aria_test.go +23 -0
- package/linthost/jsx_a11y_aria_unsupported_elements_rejects_role_despite_spread_test.go +24 -0
- package/linthost/jsx_a11y_autocomplete_valid_allows_appropriate_input_type_test.go +29 -0
- package/linthost/jsx_a11y_autocomplete_valid_rejects_inappropriate_input_type_test.go +21 -0
- package/linthost/jsx_a11y_autocomplete_valid_rejects_invalid_token_sequence_test.go +26 -0
- package/linthost/jsx_a11y_autocomplete_valid_rejects_unknown_token_test.go +22 -0
- package/linthost/jsx_a11y_click_events_have_key_events_requires_keyboard_handler_test.go +21 -0
- package/linthost/jsx_a11y_control_has_associated_label_requires_button_label_test.go +21 -0
- package/linthost/jsx_a11y_heading_has_content_rejects_empty_heading_test.go +22 -0
- package/linthost/jsx_a11y_helpers_test.go +33 -0
- package/linthost/jsx_a11y_html_has_lang_allows_non_empty_lang_test.go +21 -0
- package/linthost/jsx_a11y_html_has_lang_allows_spread_props_test.go +24 -0
- package/linthost/jsx_a11y_html_has_lang_rejects_empty_lang_test.go +27 -0
- package/linthost/jsx_a11y_html_has_lang_requires_lang_test.go +21 -0
- package/linthost/jsx_a11y_iframe_has_title_allows_spread_props_test.go +23 -0
- package/linthost/jsx_a11y_iframe_has_title_requires_title_test.go +21 -0
- package/linthost/jsx_a11y_img_redundant_alt_rejects_image_word_despite_spread_test.go +25 -0
- package/linthost/jsx_a11y_img_redundant_alt_rejects_image_word_test.go +21 -0
- package/linthost/jsx_a11y_interactive_supports_focus_requires_tabindex_test.go +21 -0
- package/linthost/jsx_a11y_label_has_associated_control_requires_for_or_child_test.go +21 -0
- package/linthost/jsx_a11y_label_has_for_alias_matches_associated_control_test.go +21 -0
- package/linthost/jsx_a11y_lang_allows_valid_bcp47_tag_test.go +22 -0
- package/linthost/jsx_a11y_lang_rejects_empty_lang_test.go +20 -0
- package/linthost/jsx_a11y_lang_rejects_invalid_bcp47_tag_test.go +25 -0
- package/linthost/jsx_a11y_media_has_caption_requires_track_test.go +22 -0
- package/linthost/jsx_a11y_mouse_events_have_key_events_requires_focus_test.go +21 -0
- package/linthost/jsx_a11y_no_access_key_rejects_access_key_test.go +21 -0
- package/linthost/jsx_a11y_no_aria_hidden_on_focusable_rejects_hidden_button_test.go +21 -0
- package/linthost/jsx_a11y_no_autofocus_rejects_autofocus_test.go +21 -0
- package/linthost/jsx_a11y_no_distracting_elements_rejects_marquee_test.go +21 -0
- package/linthost/jsx_a11y_no_interactive_element_to_noninteractive_role_rejects_button_presentation_test.go +21 -0
- package/linthost/jsx_a11y_no_noninteractive_element_interactions_rejects_li_click_test.go +21 -0
- package/linthost/jsx_a11y_no_noninteractive_element_to_interactive_role_rejects_ul_button_test.go +21 -0
- package/linthost/jsx_a11y_no_noninteractive_tabindex_rejects_section_tabindex_test.go +21 -0
- package/linthost/jsx_a11y_no_redundant_roles_rejects_button_role_button_test.go +21 -0
- package/linthost/jsx_a11y_no_static_element_interactions_requires_role_test.go +21 -0
- package/linthost/jsx_a11y_prefer_tag_over_role_rejects_div_button_test.go +21 -0
- package/linthost/jsx_a11y_role_has_required_aria_props_allows_native_checkbox_test.go +21 -0
- package/linthost/jsx_a11y_role_has_required_aria_props_allows_spread_props_test.go +23 -0
- package/linthost/jsx_a11y_role_has_required_aria_props_requires_checkbox_checked_test.go +21 -0
- package/linthost/jsx_a11y_role_supports_aria_props_allows_explicit_button_pressed_test.go +21 -0
- package/linthost/jsx_a11y_role_supports_aria_props_allows_native_button_pressed_test.go +21 -0
- package/linthost/jsx_a11y_role_supports_aria_props_rejects_button_checked_test.go +21 -0
- package/linthost/jsx_a11y_rules_survive_spread_attributes_test.go +60 -0
- package/linthost/jsx_a11y_scope_rejects_scope_on_td_test.go +21 -0
- package/linthost/jsx_a11y_tabindex_no_positive_rejects_positive_tabindex_test.go +21 -0
- package/linthost/known_symbol_property_name_finds_iteration_and_disposal_protocol_members_test.go +112 -0
- package/linthost/legacy_custom_resolver_keeps_rule_options_fallback_test.go +45 -0
- package/linthost/lint_corpus_companions_belong_to_their_own_case_test.go +53 -0
- package/linthost/lint_corpus_diagnostics_are_attributed_to_the_main_source_test.go +51 -0
- package/linthost/lint_corpus_directives_reject_malformed_or_duplicate_markers_test.go +89 -0
- package/linthost/lint_corpus_discovery_classifies_every_typescript_suffix_test.go +56 -0
- package/linthost/lint_corpus_discovery_rejects_invalid_companion_contracts_test.go +50 -0
- package/linthost/lint_corpus_discovery_rejects_unclassified_sources_test.go +39 -0
- package/linthost/lint_corpus_expectation_parser_rejects_malformed_or_targetless_markers_test.go +46 -0
- package/linthost/lint_corpus_expectation_parser_resolves_line_and_jsx_block_markers_test.go +53 -0
- package/linthost/lint_corpus_filename_separators_share_materialized_source_identity_test.go +85 -0
- package/linthost/lint_corpus_loader_helpers_test.go +704 -0
- package/linthost/lint_corpus_project_selects_jsx_mode_for_included_tsx_sources_test.go +118 -0
- package/linthost/lint_corpus_skips_name_one_rule_and_one_harness_test.go +63 -0
- package/linthost/lint_fixture_corpus_test.go +166 -0
- package/linthost/lint_trace.go +202 -0
- package/linthost/lint_trace_preserves_raw_invocation_and_integrity_test.go +139 -0
- package/linthost/load_config_file_rejects_unsupported_extension_test.go +38 -0
- package/linthost/load_config_resolver_compact_globs_preserve_entry_policy_test.go +97 -0
- package/linthost/load_config_resolver_scopes_extends_options_in_engine_test.go +65 -0
- package/linthost/load_json_config_file_rejects_invalid_json_test.go +38 -0
- package/linthost/load_program_keeps_checker_pool_for_type_aware_rules_test.go +184 -0
- package/linthost/load_program_skips_checker_for_ast_only_rules_test.go +59 -0
- package/linthost/load_rule_config_configfile_overrides_discovery_test.go +51 -0
- package/linthost/load_rule_config_discovers_cwd_config_for_out_of_tree_tsconfig_test.go +46 -0
- package/linthost/load_rule_config_discovers_plain_lint_config_test.go +39 -0
- package/linthost/load_rule_config_extends_with_ignores_and_rules_ignores_globally_test.go +141 -0
- package/linthost/load_rule_config_honors_plugin_config_dir_env_test.go +53 -0
- package/linthost/load_rule_config_loads_json_config_file_test.go +55 -0
- package/linthost/load_rule_config_missing_config_error_names_search_origins_test.go +44 -0
- package/linthost/load_rule_config_preserves_json_pattern_precedence_test.go +80 -0
- package/linthost/load_rule_config_rejects_array_rules_test.go +34 -0
- package/linthost/load_rule_config_rejects_empty_extends_test.go +34 -0
- package/linthost/load_rule_config_rejects_extends_cycle_between_two_configs_test.go +71 -0
- package/linthost/load_rule_config_rejects_missing_discovered_config_test.go +37 -0
- package/linthost/load_rule_config_rejects_overly_deep_extends_chain_test.go +53 -0
- package/linthost/load_rule_config_rejects_self_referential_extends_test.go +49 -0
- package/linthost/load_rule_config_resolves_configfile_relative_to_plugin_config_dir_env_test.go +46 -0
- package/linthost/load_rule_config_resolves_linear_extends_chain_test.go +81 -0
- package/linthost/load_rules_ignores_non_lint_plugin_payload_test.go +33 -0
- package/linthost/loader_module_option_follows_the_config_package_type_test.go +103 -0
- package/linthost/loader_rootdir_contains_loader_and_config_test.go +59 -0
- package/linthost/loader_temp_base_stays_on_config_volume_test.go +35 -0
- package/linthost/logic_rules_cover_boolean_call_arguments_undefined_typeof_negative_zero_and_number_nan_test.go +43 -0
- package/linthost/lookup_rule_returns_registered_implementation_or_nil_test.go +49 -0
- package/linthost/lsp.go +185 -34
- package/linthost/lsp_apply_suggestion_rejects_stale_source_test.go +49 -0
- package/linthost/lsp_apply_suggestion_resolves_junction_project_link_test.go +33 -0
- package/linthost/lsp_apply_suggestion_resolves_logical_project_link_test.go +35 -0
- package/linthost/lsp_await_thenable_suggestion_executes_exact_token_test.go +52 -0
- package/linthost/lsp_ban_ts_comment_suggestion_preserves_crlf_block_test.go +52 -0
- package/linthost/lsp_code_action_helpers_test.go +55 -0
- package/linthost/lsp_code_actions_fail_closed_for_invalid_quickfix_range_test.go +88 -0
- package/linthost/lsp_code_actions_reject_more_specific_context_only_test.go +37 -0
- package/linthost/lsp_code_actions_returns_empty_for_node_modules_target_test.go +44 -0
- package/linthost/lsp_code_actions_returns_empty_for_outside_cwd_target_test.go +45 -0
- package/linthost/lsp_code_actions_short_circuits_unowned_context_only_test.go +46 -0
- package/linthost/lsp_code_actions_split_lint_and_format_commands_test.go +41 -0
- package/linthost/lsp_command_discovery_reports_owned_commands_and_kinds_test.go +67 -0
- package/linthost/lsp_command_helpers_test.go +113 -0
- package/linthost/lsp_command_workspace_preserves_nested_dependency_scopes_test.go +77 -0
- package/linthost/lsp_commands_accept_windows_short_cwd_test.go +62 -0
- package/linthost/lsp_diagnostic_omits_code_description_for_contributor_rule_test.go +81 -0
- package/linthost/lsp_diagnostic_tags_drop_unknown_values_test.go +41 -0
- package/linthost/lsp_diagnostic_wire_drops_code_description_key_when_unmapped_test.go +65 -0
- package/linthost/lsp_diagnostics_link_rule_codes_to_documentation_test.go +84 -0
- package/linthost/lsp_document_write_scope_preserves_project_and_sibling_boundaries_test.go +68 -0
- package/linthost/lsp_execute_command_applies_utf16_edit_after_non_bmp_prefix_test.go +48 -0
- package/linthost/lsp_execute_command_cascades_format_fixes_without_mutating_disk_test.go +50 -0
- package/linthost/lsp_execute_command_cascades_lint_fixes_without_mutating_disk_test.go +48 -0
- package/linthost/lsp_execute_command_copies_read_only_file_as_writable_test.go +46 -0
- package/linthost/lsp_execute_command_maps_absolute_config_file_into_temp_workspace_test.go +40 -0
- package/linthost/lsp_execute_command_materializes_duplicate_symlinked_directories_test.go +57 -0
- package/linthost/lsp_execute_command_materializes_junctioned_directory_without_mutating_original_test.go +61 -0
- package/linthost/lsp_execute_command_materializes_symlink_target_without_mutating_original_test.go +55 -0
- package/linthost/lsp_execute_command_materializes_symlinked_directory_without_mutating_original_test.go +56 -0
- package/linthost/lsp_execute_command_rejects_target_outside_cwd_before_read_test.go +61 -0
- package/linthost/lsp_execute_command_returns_null_for_node_modules_target_test.go +59 -0
- package/linthost/lsp_execute_command_returns_null_when_no_edits_test.go +51 -0
- package/linthost/lsp_execute_command_splits_lint_and_format_edits_test.go +43 -0
- package/linthost/lsp_fix_all_leaves_suggestion_only_rewrites_unchanged_test.go +37 -0
- package/linthost/lsp_format_buffer_formats_missing_disk_file_test.go +42 -0
- package/linthost/lsp_format_buffer_helpers_test.go +68 -0
- package/linthost/lsp_format_buffer_ignores_disk_content_test.go +52 -0
- package/linthost/lsp_format_buffer_in_memory_test.go +47 -0
- package/linthost/lsp_format_buffer_type_aware_contributor_test.go +142 -0
- package/linthost/lsp_format_paths_honor_entry_ignores_test.go +45 -0
- package/linthost/lsp_format_paths_use_canonical_defaults_test.go +72 -0
- package/linthost/lsp_format_paths_use_defaults_without_format_block_test.go +28 -0
- package/linthost/lsp_format_paths_use_editor_language_overrides_test.go +34 -0
- package/linthost/lsp_hints_publishes_jsdoc_check_tag_names_corpus_test.go +56 -0
- package/linthost/lsp_hints_skips_the_program_when_nothing_publishes_test.go +46 -0
- package/linthost/lsp_hints_still_loads_the_program_for_a_declared_publisher_test.go +42 -0
- package/linthost/lsp_logical_project_link_helpers_test.go +127 -0
- package/linthost/lsp_position_columns_count_utf16_across_planes_test.go +107 -0
- package/linthost/lsp_position_counts_non_bmp_as_two_utf16_units_test.go +26 -0
- package/linthost/lsp_prefer_as_const_suggestion_executes_selected_range_test.go +51 -0
- package/linthost/lsp_project_diagnostics_recomputes_external_state_without_document_test.go +187 -0
- package/linthost/lsp_serve_answers_hints_from_the_resident_daemon_test.go +73 -0
- package/linthost/lsp_switch_exhaustiveness_suggestions_preserve_default_anchors_test.go +206 -0
- package/linthost/match_any_pattern_accepts_native_and_slash_separators_test.go +47 -0
- package/linthost/match_any_pattern_handles_brace_expansion_test.go +43 -0
- package/linthost/match_any_pattern_matches_dot_directory_globs_test.go +44 -0
- package/linthost/max_nested_callbacks_counts_only_functions_passed_to_calls_test.go +46 -0
- package/linthost/migrated_no_misused_promises_helpers_test.go +30 -0
- package/linthost/migrated_no_unused_expressions_helpers_test.go +50 -0
- package/linthost/migrated_typed_rule_helpers_test.go +46 -0
- package/linthost/misc_testing_library_rules_test.go +63 -0
- package/linthost/mixed_diagnostics_render_empty_is_silent_test.go +29 -0
- package/linthost/mixed_diagnostics_render_interleaves_parser_and_lint_test.go +51 -0
- package/linthost/mixed_diagnostics_render_orders_files_and_ties_test.go +58 -0
- package/linthost/new_print_context_zero_print_width_applies_defaults_test.go +36 -0
- package/linthost/no_array_delete_asks_the_type_not_the_subscript_test.go +70 -0
- package/linthost/no_await_in_loop_complete_semantics_test.go +205 -0
- package/linthost/no_base_to_string_test.go +48 -0
- package/linthost/no_class_assign_test.go +217 -0
- package/linthost/no_container_ignores_unrelated_container_binding_test.go +33 -0
- package/linthost/no_deprecated_test.go +45 -0
- package/linthost/no_dupe_class_members_allows_typescript_overload_signatures_test.go +41 -0
- package/linthost/no_dupe_class_members_rejects_accessor_data_collisions_test.go +28 -0
- package/linthost/no_dupe_else_if_logical_coverage_test.go +152 -0
- package/linthost/no_dupe_keys_computed_key_static_resolution_test.go +72 -0
- package/linthost/no_duplicate_imports_allow_separate_type_imports_allows_value_plus_type_import_test.go +30 -0
- package/linthost/no_duplicate_imports_allow_separate_type_imports_still_reports_type_pairs_test.go +30 -0
- package/linthost/no_duplicate_imports_allow_separate_type_imports_still_reports_value_pairs_test.go +29 -0
- package/linthost/no_duplicate_imports_allows_inline_type_specifier_beside_type_import_test.go +29 -0
- package/linthost/no_duplicate_imports_allows_named_and_namespace_value_imports_test.go +31 -0
- package/linthost/no_duplicate_imports_allows_type_default_and_type_named_imports_test.go +31 -0
- package/linthost/no_duplicate_imports_allows_type_namespace_and_type_named_imports_test.go +28 -0
- package/linthost/no_duplicate_imports_classifies_inline_type_specifier_as_value_test.go +31 -0
- package/linthost/no_duplicate_imports_helpers_test.go +78 -0
- package/linthost/no_duplicate_imports_ignores_misspelled_option_keys_test.go +30 -0
- package/linthost/no_duplicate_imports_ignores_reexports_by_default_test.go +32 -0
- package/linthost/no_duplicate_imports_include_exports_allows_export_star_beside_named_import_test.go +31 -0
- package/linthost/no_duplicate_imports_include_exports_allows_export_star_beside_namespace_reexport_test.go +29 -0
- package/linthost/no_duplicate_imports_include_exports_allows_namespace_reexport_beside_named_import_test.go +29 -0
- package/linthost/no_duplicate_imports_include_exports_reports_both_pairings_on_one_declaration_test.go +34 -0
- package/linthost/no_duplicate_imports_include_exports_reports_export_star_beside_side_effect_import_test.go +35 -0
- package/linthost/no_duplicate_imports_include_exports_reports_import_after_reexport_test.go +30 -0
- package/linthost/no_duplicate_imports_include_exports_reports_reexport_after_import_test.go +30 -0
- package/linthost/no_duplicate_imports_include_exports_reports_repeated_export_star_test.go +30 -0
- package/linthost/no_duplicate_imports_include_exports_reports_second_reexport_test.go +29 -0
- package/linthost/no_duplicate_imports_include_exports_reports_type_reexport_after_value_import_test.go +30 -0
- package/linthost/no_duplicate_imports_include_exports_skips_local_export_without_module_test.go +31 -0
- package/linthost/no_duplicate_imports_include_exports_treats_empty_reexport_clause_as_side_effect_test.go +31 -0
- package/linthost/no_duplicate_imports_include_exports_with_allow_separate_allows_type_reexport_test.go +30 -0
- package/linthost/no_duplicate_imports_preserves_migrated_json_tuple_options_test.go +47 -0
- package/linthost/no_duplicate_imports_reports_default_then_named_value_imports_test.go +31 -0
- package/linthost/no_duplicate_imports_reports_default_then_namespace_value_imports_test.go +30 -0
- package/linthost/no_duplicate_imports_reports_each_later_duplicate_import_test.go +31 -0
- package/linthost/no_duplicate_imports_reports_nonadjacent_duplicate_value_imports_test.go +30 -0
- package/linthost/no_duplicate_imports_reports_repeated_side_effect_imports_test.go +29 -0
- package/linthost/no_duplicate_imports_reports_side_effect_import_after_named_import_test.go +30 -0
- package/linthost/no_duplicate_imports_reports_two_namespace_value_imports_test.go +29 -0
- package/linthost/no_duplicate_imports_reports_two_type_default_imports_test.go +29 -0
- package/linthost/no_duplicate_imports_reports_value_default_then_type_named_import_test.go +33 -0
- package/linthost/no_duplicate_imports_reports_value_then_type_named_import_by_default_test.go +30 -0
- package/linthost/no_duplicate_imports_skips_empty_module_specifiers_test.go +30 -0
- package/linthost/no_duplicate_imports_treats_default_with_empty_named_clause_as_default_test.go +30 -0
- package/linthost/no_duplicate_imports_treats_empty_named_import_clause_as_side_effect_test.go +32 -0
- package/linthost/no_duplicate_imports_trims_module_specifier_whitespace_test.go +29 -0
- package/linthost/no_else_return_allow_else_if_false_reports_else_if_test.go +60 -0
- package/linthost/no_else_return_allows_break_before_else_test.go +34 -0
- package/linthost/no_else_return_allows_continue_before_else_test.go +34 -0
- package/linthost/no_else_return_allows_else_if_return_chain_test.go +34 -0
- package/linthost/no_else_return_allows_throw_before_else_test.go +32 -0
- package/linthost/no_else_return_reports_once_on_terminal_else_test.go +31 -0
- package/linthost/no_else_return_reports_plain_else_after_return_test.go +27 -0
- package/linthost/no_empty_character_class_semantics_test.go +62 -0
- package/linthost/no_empty_complete_semantics_test.go +89 -0
- package/linthost/no_empty_function_comments_preserve_every_kind_test.go +35 -0
- package/linthost/no_empty_function_options_test.go +60 -0
- package/linthost/no_empty_function_typescript_exceptions_and_category_boundaries_test.go +248 -0
- package/linthost/no_empty_static_block_comment_boundaries_test.go +37 -0
- package/linthost/no_extend_native_covers_assignment_and_static_callee_forms_test.go +52 -0
- package/linthost/no_extend_native_covers_every_native_constructor_with_a_prototype_test.go +45 -0
- package/linthost/no_extend_native_define_property_and_computed_test.go +71 -0
- package/linthost/no_extend_native_respects_constructor_bindings_test.go +48 -0
- package/linthost/no_extra_bind_function_body_test.go +72 -0
- package/linthost/no_extra_bind_offers_withheld_removal_as_suggestion_test.go +43 -0
- package/linthost/no_extra_bind_preserves_throwing_receiver_reads_test.go +32 -0
- package/linthost/no_extra_boolean_cast_declines_fix_for_comment_between_bangs_test.go +28 -0
- package/linthost/no_extra_boolean_cast_declines_fix_for_leading_comment_in_call_test.go +29 -0
- package/linthost/no_extra_boolean_cast_declines_fix_for_trailing_comment_in_call_test.go +28 -0
- package/linthost/no_extra_boolean_cast_fix_boolean_call_in_boolean_context_test.go +43 -0
- package/linthost/no_extra_boolean_cast_fix_collapses_nested_boolean_call_test.go +30 -0
- package/linthost/no_extra_boolean_cast_fix_double_bang_in_boolean_context_test.go +28 -0
- package/linthost/no_extra_boolean_cast_fix_keeps_bare_identifier_under_bang_test.go +28 -0
- package/linthost/no_extra_boolean_cast_fix_keeps_parenthesized_argument_without_double_wrap_test.go +28 -0
- package/linthost/no_extra_boolean_cast_fix_parenthesizes_arrow_argument_in_ternary_condition_test.go +30 -0
- package/linthost/no_extra_boolean_cast_fix_parenthesizes_assignment_in_ternary_condition_test.go +28 -0
- package/linthost/no_extra_boolean_cast_fix_parenthesizes_await_argument_under_bang_test.go +28 -0
- package/linthost/no_extra_boolean_cast_fix_parenthesizes_logical_operand_under_bang_test.go +28 -0
- package/linthost/no_extra_boolean_cast_fix_parenthesizes_nested_ternary_condition_test.go +30 -0
- package/linthost/no_extra_boolean_cast_fix_parenthesizes_yield_argument_under_bang_test.go +28 -0
- package/linthost/no_extra_boolean_cast_fix_preserves_comment_inside_argument_test.go +29 -0
- package/linthost/no_extra_boolean_cast_fix_skips_wrap_for_logical_ternary_condition_test.go +29 -0
- package/linthost/no_extra_boolean_cast_fix_skips_wrap_inside_explicit_parens_under_bang_test.go +29 -0
- package/linthost/no_extra_boolean_cast_keeps_meaningful_double_bang_outside_boolean_context_test.go +28 -0
- package/linthost/no_extra_boolean_cast_offers_withheld_splice_as_suggestion_test.go +37 -0
- package/linthost/no_extra_boolean_cast_preserves_shadowed_converters_test.go +76 -0
- package/linthost/no_fallthrough_accepts_adjacent_empty_case_labels_test.go +28 -0
- package/linthost/no_fallthrough_accepts_block_marker_with_trailing_unrelated_comment_test.go +32 -0
- package/linthost/no_fallthrough_accepts_break_in_try_with_normal_finally_test.go +33 -0
- package/linthost/no_fallthrough_accepts_breaking_catch_after_throwing_try_test.go +34 -0
- package/linthost/no_fallthrough_accepts_continue_terminating_case_test.go +33 -0
- package/linthost/no_fallthrough_accepts_do_while_with_always_throwing_body_test.go +33 -0
- package/linthost/no_fallthrough_accepts_empty_case_with_same_line_comment_test.go +29 -0
- package/linthost/no_fallthrough_accepts_if_else_terminating_every_path_test.go +38 -0
- package/linthost/no_fallthrough_accepts_infinite_for_without_break_test.go +31 -0
- package/linthost/no_fallthrough_accepts_infinite_loop_with_labeled_break_to_outer_test.go +35 -0
- package/linthost/no_fallthrough_accepts_infinite_while_without_break_test.go +31 -0
- package/linthost/no_fallthrough_accepts_labeled_break_to_outer_loop_test.go +34 -0
- package/linthost/no_fallthrough_accepts_marked_empty_case_with_blank_gap_test.go +30 -0
- package/linthost/no_fallthrough_accepts_marked_fallthrough_variants_test.go +43 -0
- package/linthost/no_fallthrough_accepts_marker_in_sole_empty_block_test.go +30 -0
- package/linthost/no_fallthrough_accepts_marker_inside_sole_block_statement_test.go +32 -0
- package/linthost/no_fallthrough_accepts_nested_switch_terminating_on_every_path_test.go +38 -0
- package/linthost/no_fallthrough_accepts_terminating_finally_test.go +34 -0
- package/linthost/no_fallthrough_accepts_terminating_try_and_catch_with_normal_finally_test.go +41 -0
- package/linthost/no_fallthrough_accepts_unreachable_labeled_break_in_while_false_test.go +39 -0
- package/linthost/no_fallthrough_accepts_unreachable_labeled_break_in_while_zero_test.go +37 -0
- package/linthost/no_fallthrough_accepts_while_bigint_one_literal_test.go +31 -0
- package/linthost/no_fallthrough_accepts_while_nonempty_string_literal_test.go +31 -0
- package/linthost/no_fallthrough_accepts_while_numeric_one_literal_test.go +31 -0
- package/linthost/no_fallthrough_accepts_while_regex_literal_test.go +31 -0
- package/linthost/no_fallthrough_accepts_with_statement_body_break_test.go +33 -0
- package/linthost/no_fallthrough_allow_empty_case_permits_blank_line_gap_test.go +29 -0
- package/linthost/no_fallthrough_command_composes_nested_try_finally_test.go +124 -0
- package/linthost/no_fallthrough_command_composes_statement_and_loop_throw_edges_test.go +108 -0
- package/linthost/no_fallthrough_command_helpers_test.go +68 -0
- package/linthost/no_fallthrough_command_preserves_bigint_literal_truthiness_test.go +82 -0
- package/linthost/no_fallthrough_command_preserves_catch_break_continue_test.go +66 -0
- package/linthost/no_fallthrough_command_preserves_code_path_boundaries_test.go +136 -0
- package/linthost/no_fallthrough_command_preserves_jsx_code_path_boundaries_test.go +68 -0
- package/linthost/no_fallthrough_command_preserves_markers_across_catch_reachability_test.go +40 -0
- package/linthost/no_fallthrough_command_tracks_binding_reference_edges_test.go +70 -0
- package/linthost/no_fallthrough_command_tracks_return_exception_edges_test.go +79 -0
- package/linthost/no_fallthrough_custom_pattern_replaces_default_marker_test.go +32 -0
- package/linthost/no_fallthrough_directive_suppression_still_wins_test.go +32 -0
- package/linthost/no_fallthrough_helpers_test.go +55 -0
- package/linthost/no_fallthrough_honors_custom_comment_pattern_test.go +30 -0
- package/linthost/no_fallthrough_ignores_switch_without_clauses_test.go +24 -0
- package/linthost/no_fallthrough_ignores_trailing_unreachable_statements_test.go +33 -0
- package/linthost/no_fallthrough_ignores_unreachable_break_in_infinite_loop_test.go +35 -0
- package/linthost/no_fallthrough_invalid_comment_pattern_falls_back_to_default_test.go +31 -0
- package/linthost/no_fallthrough_never_reports_last_open_case_test.go +27 -0
- package/linthost/no_fallthrough_rejects_breakable_conditional_while_test.go +33 -0
- package/linthost/no_fallthrough_rejects_directive_comment_as_marker_test.go +31 -0
- package/linthost/no_fallthrough_rejects_do_while_exited_by_labeled_continue_test.go +34 -0
- package/linthost/no_fallthrough_rejects_do_while_exited_by_unlabeled_continue_test.go +33 -0
- package/linthost/no_fallthrough_rejects_do_while_with_break_test.go +32 -0
- package/linthost/no_fallthrough_rejects_empty_case_followed_by_blank_line_test.go +30 -0
- package/linthost/no_fallthrough_rejects_empty_case_with_comment_line_gap_test.go +31 -0
- package/linthost/no_fallthrough_rejects_empty_statement_case_despite_allow_empty_case_test.go +29 -0
- package/linthost/no_fallthrough_rejects_for_of_with_always_throwing_body_test.go +33 -0
- package/linthost/no_fallthrough_rejects_if_else_with_one_open_branch_test.go +36 -0
- package/linthost/no_fallthrough_rejects_if_without_else_test.go +33 -0
- package/linthost/no_fallthrough_rejects_infinite_loop_broken_by_own_label_test.go +32 -0
- package/linthost/no_fallthrough_rejects_infinite_while_containing_break_test.go +32 -0
- package/linthost/no_fallthrough_rejects_labeled_block_broken_by_own_label_test.go +33 -0
- package/linthost/no_fallthrough_rejects_lint_directive_comment_as_marker_test.go +31 -0
- package/linthost/no_fallthrough_rejects_marker_before_last_statement_test.go +32 -0
- package/linthost/no_fallthrough_rejects_marker_in_block_that_is_not_sole_statement_test.go +31 -0
- package/linthost/no_fallthrough_rejects_marker_inside_nested_inner_block_test.go +31 -0
- package/linthost/no_fallthrough_rejects_nested_switch_exited_by_inner_break_test.go +34 -0
- package/linthost/no_fallthrough_rejects_nested_switch_without_default_test.go +36 -0
- package/linthost/no_fallthrough_rejects_non_literal_constant_condition_test.go +33 -0
- package/linthost/no_fallthrough_rejects_normally_completing_catch_test.go +34 -0
- package/linthost/no_fallthrough_rejects_open_try_with_normal_finally_test.go +34 -0
- package/linthost/no_fallthrough_rejects_return_inside_arrow_test.go +32 -0
- package/linthost/no_fallthrough_rejects_return_inside_function_declaration_test.go +33 -0
- package/linthost/no_fallthrough_rejects_return_inside_function_expression_test.go +33 -0
- package/linthost/no_fallthrough_rejects_unrelated_comment_in_sole_empty_block_test.go +29 -0
- package/linthost/no_fallthrough_rejects_unrelated_trailing_comment_test.go +30 -0
- package/linthost/no_fallthrough_reports_case_message_after_leading_default_test.go +37 -0
- package/linthost/no_fallthrough_reports_default_message_for_default_clause_test.go +35 -0
- package/linthost/no_fallthrough_reports_each_unmarked_transition_once_test.go +32 -0
- package/linthost/no_fallthrough_reports_inner_and_outer_switch_transitions_test.go +37 -0
- package/linthost/no_fallthrough_reports_unused_comment_after_terminating_if_else_test.go +46 -0
- package/linthost/no_fallthrough_reports_unused_comment_inside_sole_block_test.go +36 -0
- package/linthost/no_fallthrough_reports_unused_fallthrough_comment_test.go +38 -0
- package/linthost/no_fallthrough_reports_unused_marker_after_unreachable_catch_test.go +37 -0
- package/linthost/no_fallthrough_requires_marker_to_be_last_comment_test.go +32 -0
- package/linthost/no_fallthrough_unused_check_accepts_real_fallthrough_marker_test.go +30 -0
- package/linthost/no_fallthrough_unused_check_ignores_non_marker_comment_test.go +31 -0
- package/linthost/no_fallthrough_unused_check_skips_last_case_marker_test.go +28 -0
- package/linthost/no_fallthrough_unused_check_skips_reachable_empty_case_test.go +30 -0
- package/linthost/no_fallthrough_unused_comment_ignored_by_default_test.go +31 -0
- package/linthost/no_floating_promises_credits_a_handler_through_an_optional_chain_test.go +55 -0
- package/linthost/no_floating_promises_default_semantics_test.go +48 -0
- package/linthost/no_floating_promises_detects_index_value_type_parameters_test.go +145 -0
- package/linthost/no_floating_promises_handler_chains_test.go +53 -0
- package/linthost/no_floating_promises_helpers_test.go +43 -0
- package/linthost/no_floating_promises_iife_test.go +32 -0
- package/linthost/no_floating_promises_javascript_generic_defaults_test.go +177 -0
- package/linthost/no_floating_promises_mixed_receiver_results_test.go +222 -0
- package/linthost/no_floating_promises_options_test.go +56 -0
- package/linthost/no_floating_promises_preserves_call_resolution_test.go +291 -0
- package/linthost/no_floating_promises_preserves_candidate_context_literals_test.go +289 -0
- package/linthost/no_floating_promises_preserves_contextual_callback_returns_test.go +208 -0
- package/linthost/no_floating_promises_preserves_migrated_default_contexts_test.go +20 -0
- package/linthost/no_floating_promises_preserves_optional_callback_overloads_test.go +42 -0
- package/linthost/no_floating_promises_preserves_subtype_overload_priority_test.go +40 -0
- package/linthost/no_floating_promises_rejects_inapplicable_generic_receiver_branches_test.go +254 -0
- package/linthost/no_floating_promises_rejects_opaque_mapped_type_parameters_test.go +159 -0
- package/linthost/no_floating_promises_safe_calls_in_composites_specifiers_test.go +43 -0
- package/linthost/no_floating_promises_safe_calls_in_composites_test.go +88 -0
- package/linthost/no_floating_promises_specifiers_test.go +108 -0
- package/linthost/no_floating_promises_test.go +46 -0
- package/linthost/no_floating_promises_thenable_scope_follows_check_thenables_test.go +87 -0
- package/linthost/no_floating_promises_type_shapes_test.go +100 -0
- package/linthost/no_for_in_array_test.go +49 -0
- package/linthost/no_func_assign_test.go +195 -0
- package/linthost/no_import_assign_binding_identity_and_complete_writes_test.go +140 -0
- package/linthost/no_import_assign_binding_identity_helpers_test.go +114 -0
- package/linthost/no_import_assign_ignores_resolved_shadows_and_deeper_values_test.go +118 -0
- package/linthost/no_import_assign_recognizes_every_assignment_operator_test.go +36 -0
- package/linthost/no_import_assign_test.go +48 -0
- package/linthost/no_inner_declarations_both_mode_test.go +73 -0
- package/linthost/no_inner_declarations_default_allows_strict_script_block_functions_test.go +33 -0
- package/linthost/no_inner_declarations_default_module_test.go +35 -0
- package/linthost/no_inner_declarations_default_strict_context_test.go +93 -0
- package/linthost/no_inner_declarations_disallow_block_functions_test.go +57 -0
- package/linthost/no_inner_declarations_helpers_test.go +32 -0
- package/linthost/no_invalid_this_accepts_class_field_initializers_test.go +32 -0
- package/linthost/no_irregular_whitespace_allows_string_literals_and_reports_code_test.go +44 -0
- package/linthost/no_loop_func_allows_safe_bindings_and_excluded_headers_test.go +67 -0
- package/linthost/no_loop_func_allows_using_bindings_test.go +52 -0
- package/linthost/no_loop_func_checks_all_runtime_function_forms_test.go +52 -0
- package/linthost/no_loop_func_helpers_test.go +55 -0
- package/linthost/no_loop_func_iife_boundaries_test.go +41 -0
- package/linthost/no_loop_func_reports_only_unsafe_references_test.go +83 -0
- package/linthost/no_loop_func_test.go +68 -0
- package/linthost/no_loop_func_tracks_write_forms_and_symbol_identity_test.go +49 -0
- package/linthost/no_loop_func_treats_class_field_initializers_as_variable_scopes_test.go +46 -0
- package/linthost/no_loss_of_precision_accepts_exact_unsafe_integer_test.go +36 -0
- package/linthost/no_loss_of_precision_handles_every_number_syntax_test.go +93 -0
- package/linthost/no_loss_of_precision_rejects_huge_decimal_integer_test.go +28 -0
- package/linthost/no_meaningless_void_operator_test.go +48 -0
- package/linthost/no_misused_promises_arguments_test.go +82 -0
- package/linthost/no_misused_promises_defaults_test.go +89 -0
- package/linthost/no_misused_promises_helpers_test.go +135 -0
- package/linthost/no_misused_promises_native_array_predicates_test.go +91 -0
- package/linthost/no_misused_promises_options_test.go +103 -0
- package/linthost/no_misused_promises_preserves_migrated_default_contexts_test.go +23 -0
- package/linthost/no_misused_promises_test.go +53 -0
- package/linthost/no_mixed_operators_allow_same_precedence_false_flags_additive_test.go +42 -0
- package/linthost/no_mixed_operators_allows_bitwise_beside_comparison_test.go +26 -0
- package/linthost/no_mixed_operators_allows_bitwise_beside_logical_test.go +25 -0
- package/linthost/no_mixed_operators_allows_parenthesized_inner_test.go +27 -0
- package/linthost/no_mixed_operators_allows_relational_same_precedence_test.go +27 -0
- package/linthost/no_mixed_operators_allows_same_operator_chain_test.go +26 -0
- package/linthost/no_mixed_operators_allows_same_precedence_multiplicative_test.go +26 -0
- package/linthost/no_mixed_operators_allows_ternary_beside_logical_by_default_test.go +27 -0
- package/linthost/no_mixed_operators_custom_groups_omitting_arithmetic_allow_test.go +28 -0
- package/linthost/no_mixed_operators_custom_groups_ternary_flags_logical_test.go +43 -0
- package/linthost/no_mixed_operators_flags_logical_and_left_of_or_test.go +27 -0
- package/linthost/no_mixed_operators_flags_logical_and_right_of_or_test.go +27 -0
- package/linthost/no_mixed_operators_flags_multiplicative_within_additive_test.go +26 -0
- package/linthost/no_mixed_operators_flags_relational_within_equality_test.go +28 -0
- package/linthost/no_mixed_operators_flags_shift_within_bitwise_test.go +28 -0
- package/linthost/no_mixed_operators_reports_both_operator_tokens_test.go +60 -0
- package/linthost/no_namespace_exempts_global_augmentation_test.go +52 -0
- package/linthost/no_param_reassign_complete_semantics_test.go +75 -0
- package/linthost/no_param_reassign_default_props_leaves_property_writes_alone_test.go +38 -0
- package/linthost/no_param_reassign_helpers_test.go +63 -0
- package/linthost/no_param_reassign_options_validation_helpers_test.go +12 -0
- package/linthost/no_param_reassign_options_validation_test.go +58 -0
- package/linthost/no_param_reassign_options_validator_rejects_every_invalid_schema_boundary_test.go +109 -0
- package/linthost/no_param_reassign_props_follows_official_mutation_boundaries_and_ignores_test.go +89 -0
- package/linthost/no_param_reassign_test.go +52 -0
- package/linthost/no_param_reassign_uses_checker_identity_across_nested_scopes_test.go +73 -0
- package/linthost/no_promise_executor_return_allow_void_test.go +80 -0
- package/linthost/no_promise_executor_return_complete_semantics_test.go +145 -0
- package/linthost/no_promise_executor_return_test.go +35 -0
- package/linthost/no_promise_in_fire_event_test.go +36 -0
- package/linthost/no_redeclare_relates_first_definition_test.go +55 -0
- package/linthost/no_render_in_lifecycle_test.go +35 -0
- package/linthost/no_restricted_imports_allow_type_imports_handles_whole_and_inline_type_syntax_test.go +57 -0
- package/linthost/no_restricted_imports_allowed_name_pattern_covers_imports_and_reexports_test.go +32 -0
- package/linthost/no_restricted_imports_allowed_names_reject_only_the_complement_test.go +43 -0
- package/linthost/no_restricted_imports_exact_paths_cover_every_static_module_form_test.go +77 -0
- package/linthost/no_restricted_imports_exact_paths_preserve_module_specifier_whitespace_test.go +31 -0
- package/linthost/no_restricted_imports_groups_keep_gitignore_anchors_globstars_and_unicode_test.go +78 -0
- package/linthost/no_restricted_imports_matches_source_names_and_reports_exact_specifier_ranges_test.go +71 -0
- package/linthost/no_restricted_imports_missing_and_empty_restrictions_are_no_op_test.go +42 -0
- package/linthost/no_restricted_imports_options_helpers_test.go +76 -0
- package/linthost/no_restricted_imports_patterns_honor_negation_case_regex_and_name_patterns_test.go +46 -0
- package/linthost/no_restricted_imports_positional_paths_do_not_reach_dynamic_imports_test.go +32 -0
- package/linthost/no_restricted_imports_string_patterns_keep_gitignore_parent_negation_semantics_test.go +30 -0
- package/linthost/no_restricted_imports_test.go +14 -0
- package/linthost/no_restricted_imports_validator_accepts_every_official_option_branch_test.go +48 -0
- package/linthost/no_restricted_imports_validator_rejects_malformed_configuration_at_the_boundary_test.go +64 -0
- package/linthost/no_restricted_syntax_applies_every_configured_entry_and_custom_message_test.go +45 -0
- package/linthost/no_restricted_syntax_checks_structured_option_uniqueness_by_fields_test.go +40 -0
- package/linthost/no_restricted_syntax_coerces_empty_node_lists_for_numeric_comparisons_test.go +34 -0
- package/linthost/no_restricted_syntax_compares_strings_as_utf16_test.go +37 -0
- package/linthost/no_restricted_syntax_distinguishes_assignment_patterns_from_literals_test.go +81 -0
- package/linthost/no_restricted_syntax_distinguishes_object_binding_properties_from_rest_test.go +44 -0
- package/linthost/no_restricted_syntax_distinguishes_rest_and_spread_aliases_test.go +54 -0
- package/linthost/no_restricted_syntax_exposes_computed_keys_and_property_value_paths_test.go +34 -0
- package/linthost/no_restricted_syntax_exposes_scalar_statement_bodies_test.go +43 -0
- package/linthost/no_restricted_syntax_exposes_switch_case_test_and_consequent_test.go +36 -0
- package/linthost/no_restricted_syntax_helpers_test.go +56 -0
- package/linthost/no_restricted_syntax_inherits_declare_from_variable_statements_test.go +42 -0
- package/linthost/no_restricted_syntax_keeps_template_and_literal_aliases_distinct_test.go +32 -0
- package/linthost/no_restricted_syntax_limits_boolean_properties_and_es_tree_aliases_test.go +51 -0
- package/linthost/no_restricted_syntax_matches_attributes_nested_paths_regex_types_and_lengths_test.go +47 -0
- package/linthost/no_restricted_syntax_matches_classes_alternatives_and_type_script_nodes_test.go +61 -0
- package/linthost/no_restricted_syntax_matches_combinators_fields_pseudos_and_subjects_test.go +111 -0
- package/linthost/no_restricted_syntax_matches_indexed_paths_literal_types_and_prefix_test.go +169 -0
- package/linthost/no_restricted_syntax_preserves_null_across_nested_paths_test.go +35 -0
- package/linthost/no_restricted_syntax_rejects_invalid_configuration_before_dispatch_test.go +58 -0
- package/linthost/no_restricted_syntax_reports_matches_in_source_order_test.go +36 -0
- package/linthost/no_restricted_syntax_stringifies_regular_expression_values_test.go +38 -0
- package/linthost/no_restricted_syntax_test.go +29 -0
- package/linthost/no_restricted_syntax_uses_the_last_message_for_a_repeated_selector_test.go +37 -0
- package/linthost/no_restricted_types_external_config_validates_at_engine_binding_test.go +39 -0
- package/linthost/no_restricted_types_fixes_whole_qualified_generic_and_empty_type_surfaces_test.go +56 -0
- package/linthost/no_restricted_types_has_no_implicit_defaults_test.go +51 -0
- package/linthost/no_restricted_types_helpers_test.go +63 -0
- package/linthost/no_restricted_types_later_whitespace_equivalent_key_wins_test.go +40 -0
- package/linthost/no_restricted_types_matches_every_official_type_surface_exactly_test.go +144 -0
- package/linthost/no_restricted_types_options_accept_complete_runtime_schema_test.go +54 -0
- package/linthost/no_restricted_types_options_reject_malformed_schema_boundaries_test.go +60 -0
- package/linthost/no_restricted_types_rejects_only_exact_type_syntax_test.go +56 -0
- package/linthost/no_restricted_types_runs_on_declaration_files_test.go +36 -0
- package/linthost/no_restricted_types_structured_policy_provides_fix_and_every_suggestion_test.go +172 -0
- package/linthost/no_restricted_types_uses_configured_surface_spelling_across_symbols_test.go +74 -0
- package/linthost/no_restricted_types_validation_helpers_test.go +12 -0
- package/linthost/no_return_assign_allows_parenthesized_assignment_test.go +91 -0
- package/linthost/no_types_test.go +29 -0
- package/linthost/no_undef_init_ignores_const_declarations_test.go +33 -0
- package/linthost/no_uninstalled_addons_test.go +45 -0
- package/linthost/no_unnecessary_act_test.go +38 -0
- package/linthost/no_unnecessary_boolean_literal_compare_test.go +50 -0
- package/linthost/no_unnecessary_condition_test.go +50 -0
- package/linthost/no_unnecessary_qualifier_test.go +121 -0
- package/linthost/no_unnecessary_template_expression_test.go +48 -0
- package/linthost/no_unnecessary_type_arguments_leaves_unresolved_aliases_alone_test.go +42 -0
- package/linthost/no_unnecessary_type_arguments_preserves_callable_semantics_test.go +98 -0
- package/linthost/no_unnecessary_type_arguments_preserves_heritage_defaults_test.go +38 -0
- package/linthost/no_unnecessary_type_arguments_resolves_imported_aliases_test.go +58 -0
- package/linthost/no_unnecessary_type_arguments_test.go +49 -0
- package/linthost/no_unnecessary_type_assertion_test.go +48 -0
- package/linthost/no_unneeded_ternary_fix_false_true_branches_test.go +34 -0
- package/linthost/no_unneeded_ternary_fix_false_true_with_low_precedence_cond_test.go +29 -0
- package/linthost/no_unneeded_ternary_fix_true_false_branches_test.go +28 -0
- package/linthost/no_unneeded_ternary_uses_intrinsic_boolean_coercion_test.go +28 -0
- package/linthost/no_unreachable_reports_one_region_and_exempts_hoisted_declarations_test.go +50 -0
- package/linthost/no_unsafe_argument_test.go +50 -0
- package/linthost/no_unsafe_assignment_aliases_test.go +28 -0
- package/linthost/no_unsafe_assignment_array_destructuring_test.go +33 -0
- package/linthost/no_unsafe_assignment_array_spreads_test.go +29 -0
- package/linthost/no_unsafe_assignment_binding_defaults_test.go +39 -0
- package/linthost/no_unsafe_assignment_class_initializers_test.go +30 -0
- package/linthost/no_unsafe_assignment_destructuring_reassignment_test.go +33 -0
- package/linthost/no_unsafe_assignment_direct_declarations_test.go +28 -0
- package/linthost/no_unsafe_assignment_empty_map_test.go +26 -0
- package/linthost/no_unsafe_assignment_generic_constraints_test.go +33 -0
- package/linthost/no_unsafe_assignment_helpers_test.go +114 -0
- package/linthost/no_unsafe_assignment_jsx_attributes_test.go +31 -0
- package/linthost/no_unsafe_assignment_mapped_types_test.go +29 -0
- package/linthost/no_unsafe_assignment_object_destructuring_test.go +43 -0
- package/linthost/no_unsafe_assignment_object_literals_test.go +31 -0
- package/linthost/no_unsafe_assignment_parameter_defaults_test.go +37 -0
- package/linthost/no_unsafe_assignment_preserves_migrated_assignment_sites_test.go +42 -0
- package/linthost/no_unsafe_assignment_readonly_arrays_test.go +27 -0
- package/linthost/no_unsafe_assignment_reassignment_test.go +29 -0
- package/linthost/no_unsafe_assignment_recursive_generics_test.go +26 -0
- package/linthost/no_unsafe_assignment_recursive_types_test.go +30 -0
- package/linthost/no_unsafe_assignment_tuples_test.go +26 -0
- package/linthost/no_unsafe_assignment_unions_intersections_test.go +40 -0
- package/linthost/no_unsafe_call_test.go +49 -0
- package/linthost/no_unsafe_enum_comparison_test.go +51 -0
- package/linthost/no_unsafe_finally_resolves_jump_targets_inside_and_outside_the_finally_test.go +40 -0
- package/linthost/no_unsafe_member_access_test.go +50 -0
- package/linthost/no_unsafe_optional_chaining_preserves_contiguous_chain_test.go +28 -0
- package/linthost/no_unsafe_return_test.go +52 -0
- package/linthost/no_unsafe_unary_minus_test.go +47 -0
- package/linthost/no_unused_expressions_allows_jsx_by_default_test.go +38 -0
- package/linthost/no_unused_expressions_allows_productive_kinds_test.go +61 -0
- package/linthost/no_unused_expressions_composes_short_circuit_and_ternary_test.go +60 -0
- package/linthost/no_unused_expressions_directive_prologue_positions_test.go +63 -0
- package/linthost/no_unused_expressions_honors_allow_short_circuit_test.go +59 -0
- package/linthost/no_unused_expressions_honors_allow_tagged_templates_test.go +52 -0
- package/linthost/no_unused_expressions_honors_allow_ternary_test.go +58 -0
- package/linthost/no_unused_expressions_honors_enforce_for_jsx_test.go +56 -0
- package/linthost/no_unused_expressions_honors_ignore_directives_test.go +62 -0
- package/linthost/no_unused_expressions_preserves_migrated_default_controls_test.go +29 -0
- package/linthost/no_unused_expressions_ts_wrappers_inherit_classification_test.go +61 -0
- package/linthost/no_useless_catch_reports_a_rethrowing_catch_with_and_without_finally_test.go +42 -0
- package/linthost/no_useless_constructor_preserves_argument_filtering_test.go +44 -0
- package/linthost/no_useless_empty_export_allows_module_marker_test.go +36 -0
- package/linthost/no_useless_escape_flags_regex_character_class_test.go +53 -0
- package/linthost/no_useless_escape_invalid_utf8_names_replacement_character_test.go +63 -0
- package/linthost/no_useless_escape_judges_quotes_and_template_escapes_by_enclosing_delimiter_test.go +58 -0
- package/linthost/no_useless_escape_message_names_decoded_rune_test.go +74 -0
- package/linthost/no_useless_escape_multibyte_range_covers_backslash_only_test.go +71 -0
- package/linthost/no_useless_escape_nested_untagged_template_in_tagged_substitution_test.go +67 -0
- package/linthost/no_useless_escape_v_flag_class_preserves_syntax_char_escapes_test.go +60 -0
- package/linthost/no_useless_rename_declines_fix_when_comment_between_names_test.go +38 -0
- package/linthost/no_useless_rename_offers_withheld_tail_deletion_as_suggestion_test.go +37 -0
- package/linthost/no_var_preserves_loop_body_retained_values_test.go +33 -0
- package/linthost/no_var_skips_ambient_declare_var_test.go +55 -0
- package/linthost/no_var_skips_declaration_file_vars_test.go +41 -0
- package/linthost/no_var_skips_using_declarations_test.go +44 -0
- package/linthost/node_config_loader_env_prepends_nearest_node_modules_test.go +51 -0
- package/linthost/node_package_manifest_from_resolves_a_relative_anchor_test.go +56 -0
- package/linthost/node_package_manifest_from_skips_a_node_modules_directory_test.go +51 -0
- package/linthost/node_platform_pair_matches_the_npm_platform_vocabulary_test.go +62 -0
- package/linthost/node_report_bounds_before_skipping_trivia_test.go +44 -0
- package/linthost/node_spans_multiple_lines_returns_false_for_nil_node_test.go +41 -0
- package/linthost/node_suggestions_preserve_owned_edit_channels_test.go +86 -0
- package/linthost/non_nullable_type_assertion_style_test.go +49 -0
- package/linthost/object_shorthand_declines_fix_when_comment_in_value_span_test.go +38 -0
- package/linthost/object_shorthand_offers_withheld_collapse_as_suggestion_test.go +37 -0
- package/linthost/only_throw_error_test.go +44 -0
- package/linthost/override_glob_matches_a_file_named_through_a_miscased_import_test.go +49 -0
- package/linthost/override_glob_stored_case_preserves_character_class_test.go +41 -0
- package/linthost/parse_config_store_accepts_severity_tuples_test.go +49 -0
- package/linthost/parse_config_store_keeps_ignores_entry_scoped_when_files_present_test.go +56 -0
- package/linthost/parse_config_store_promotes_global_ignores_alongside_rules_test.go +56 -0
- package/linthost/parse_config_store_promotes_global_ignores_with_format_block_test.go +53 -0
- package/linthost/parse_config_store_resolves_files_and_ignores_test.go +70 -0
- package/linthost/parse_external_rule_entry_preserves_three_slot_tuple_test.go +54 -0
- package/linthost/parse_external_rule_entry_treats_null_second_slot_as_no_options_test.go +35 -0
- package/linthost/parse_plugins_blank_payload_returns_nil_test.go +29 -0
- package/linthost/parse_plugins_rejects_bad_json_test.go +31 -0
- package/linthost/parse_plugins_round_trip_test.go +51 -0
- package/linthost/parse_rules_accepts_eslint_tuples_in_standard_inline_config_test.go +64 -0
- package/linthost/parse_rules_accepts_legacy_numeric_severities_test.go +44 -0
- package/linthost/parse_rules_accepts_string_severities_test.go +60 -0
- package/linthost/parse_rules_nil_treated_as_empty_test.go +35 -0
- package/linthost/parse_rules_preserves_positional_options_test.go +75 -0
- package/linthost/parse_subcommand_flags_accepts_common_flag_combinations_test.go +57 -0
- package/linthost/playwright_no_force_option_ignores_non_playwright_options_test.go +35 -0
- package/linthost/playwright_no_networkidle_ignores_non_playwright_wait_until_test.go +35 -0
- package/linthost/prefer_as_const_preserves_migrated_all_family_contexts_test.go +20 -0
- package/linthost/prefer_as_const_property_annotation_offers_exact_suggestion_test.go +41 -0
- package/linthost/prefer_as_const_variable_annotation_offers_exact_suggestion_test.go +41 -0
- package/linthost/prefer_const_allows_reads_in_destructuring_pattern_test.go +43 -0
- package/linthost/prefer_const_counts_non_null_assignment_target_by_symbol_test.go +24 -0
- package/linthost/prefer_const_counts_parenthesized_update_target_by_symbol_test.go +26 -0
- package/linthost/prefer_const_counts_write_forms_by_symbol_test.go +57 -0
- package/linthost/prefer_const_honors_destructuring_option_test.go +77 -0
- package/linthost/prefer_const_honors_ignore_read_before_assign_for_shorthand_read_test.go +30 -0
- package/linthost/prefer_const_honors_ignore_read_before_assign_test.go +58 -0
- package/linthost/prefer_const_preserves_migrated_lexical_fixture_test.go +112 -0
- package/linthost/prefer_const_test.go +57 -0
- package/linthost/prefer_const_tracks_lexical_binding_identity_test.go +60 -0
- package/linthost/prefer_explicit_assert_test.go +36 -0
- package/linthost/prefer_find_test.go +48 -0
- package/linthost/prefer_implicit_assert_test.go +36 -0
- package/linthost/prefer_includes_test.go +49 -0
- package/linthost/prefer_presence_queries_test.go +37 -0
- package/linthost/prefer_promise_reject_errors_test.go +45 -0
- package/linthost/prefer_query_by_disappearance_test.go +35 -0
- package/linthost/prefer_query_matchers_test.go +37 -0
- package/linthost/prefer_readonly_preserves_mutated_private_fields_test.go +57 -0
- package/linthost/prefer_reduce_type_parameter_test.go +56 -0
- package/linthost/prefer_regexp_exec_test.go +48 -0
- package/linthost/prefer_return_this_type_requires_all_completion_paths_test.go +43 -0
- package/linthost/prefer_return_this_type_test.go +55 -0
- package/linthost/prefer_screen_queries_test.go +39 -0
- package/linthost/prefer_string_starts_ends_with_test.go +52 -0
- package/linthost/prefer_template_declines_fix_when_comment_in_concat_span_test.go +50 -0
- package/linthost/prefer_template_fix_embeds_numeric_subchain_as_single_slot_test.go +33 -0
- package/linthost/prefer_template_fix_escapes_backtick_in_literal_test.go +32 -0
- package/linthost/prefer_template_fix_escapes_dollar_brace_seam_test.go +33 -0
- package/linthost/prefer_template_fix_flattens_operands_after_leading_string_test.go +34 -0
- package/linthost/prefer_template_fix_ignores_string_under_other_operator_test.go +32 -0
- package/linthost/prefer_template_fix_keeps_parenthesized_subchain_single_slot_test.go +32 -0
- package/linthost/prefer_template_fix_leading_identifier_chain_test.go +30 -0
- package/linthost/prefer_template_fix_preserves_carriage_return_test.go +33 -0
- package/linthost/prefer_template_fix_preserves_newline_test.go +30 -0
- package/linthost/prefer_template_fix_preserves_template_operand_group_test.go +27 -0
- package/linthost/prefer_template_fix_renders_empty_string_operand_with_default_coercion_test.go +31 -0
- package/linthost/prefer_template_fix_sees_string_through_parens_when_flattening_test.go +34 -0
- package/linthost/prefer_template_fix_three_part_concat_test.go +31 -0
- package/linthost/prefer_template_offers_withheld_template_as_suggestion_test.go +37 -0
- package/linthost/prefer_template_preserves_default_coercion_hint_test.go +30 -0
- package/linthost/prefer_template_skips_all_literal_chain_test.go +27 -0
- package/linthost/prefer_template_skips_numeric_only_chain_test.go +28 -0
- package/linthost/prefer_user_event_setup_ignores_setup_call_test.go +35 -0
- package/linthost/print_arg_list_emits_trailing_comma_when_mode_all_test.go +38 -0
- package/linthost/print_arg_list_omits_trailing_comma_when_mode_es5_test.go +39 -0
- package/linthost/print_arg_list_omits_trailing_comma_when_mode_none_test.go +39 -0
- package/linthost/print_arg_list_returns_parens_for_nil_list_test.go +30 -0
- package/linthost/print_call_expression_falls_back_verbatim_when_args_contain_nil_test.go +43 -0
- package/linthost/print_call_expression_includes_question_dot_token_test.go +36 -0
- package/linthost/print_call_expression_includes_type_arguments_test.go +34 -0
- package/linthost/print_call_expression_returns_empty_for_nil_node_test.go +29 -0
- package/linthost/print_dispatch.go +50 -15
- package/linthost/print_doc.go +206 -41
- package/linthost/print_engine.go +78 -51
- package/linthost/print_new_expression_falls_back_verbatim_when_args_contain_nil_test.go +42 -0
- package/linthost/print_new_expression_includes_type_arguments_test.go +36 -0
- package/linthost/print_new_expression_omits_argument_list_when_absent_test.go +36 -0
- package/linthost/print_new_expression_returns_empty_for_nil_node_test.go +28 -0
- package/linthost/print_node_returns_empty_for_nil_node_test.go +31 -0
- package/linthost/print_nodes_control_flow.go +4 -4
- package/linthost/print_nodes_function.go +9 -11
- package/linthost/print_nodes_imports.go +8 -11
- package/linthost/print_nodes_object.go +3 -6
- package/linthost/printer_test_helpers_test.go +46 -0
- package/linthost/project_companion_preserves_file_scoped_rule_config_test.go +45 -0
- package/linthost/project_contributor_ast_only_marker_keeps_parallel_walk_test.go +54 -0
- package/linthost/project_contributor_generic_accepts_options_method_keeps_legacy_payload_test.go +81 -0
- package/linthost/project_contributor_optionless_marker_rejects_payload_test.go +62 -0
- package/linthost/project_contributor_without_marker_keeps_options_compatibility_test.go +70 -0
- package/linthost/project_contributor_without_marker_keeps_type_checker_test.go +53 -0
- package/linthost/project_engine.go +8 -0
- package/linthost/project_hint_collection_requires_passed_published_state_test.go +105 -0
- package/linthost/project_hint_publication_filters_malformed_and_recovers_panic_test.go +66 -0
- package/linthost/project_identity_mints_distinct_program_lifecycles_test.go +51 -0
- package/linthost/project_input_reader.go +358 -0
- package/linthost/project_input_snapshot_normalizes_windows_case_and_separators_test.go +43 -0
- package/linthost/project_input_snapshot_preserves_missing_files_zero_match_globs_and_config_provenance_test.go +130 -0
- package/linthost/project_input_snapshot_reconciles_options_and_physical_paths_test.go +108 -0
- package/linthost/project_input_snapshot_rejects_remote_urls_test.go +59 -0
- package/linthost/project_inputs.go +31 -4
- package/linthost/project_inputs_command_publishes_configured_snapshot_without_program_test.go +115 -0
- package/linthost/project_rule_config_folds_global_extends_and_options_test.go +68 -0
- package/linthost/project_rule_config_rejects_any_files_selector_test.go +46 -0
- package/linthost/project_rule_live_reports_are_concurrent_and_deterministic_test.go +89 -0
- package/linthost/project_rule_reports_per_finding_severity_test.go +74 -0
- package/linthost/project_rule_results_reach_public_file_context_test.go +172 -0
- package/linthost/project_rule_runs_for_empty_source_set_test.go +52 -0
- package/linthost/project_rule_sources_apply_only_global_ignores_test.go +62 -0
- package/linthost/project_rule_sources_include_imported_sibling_source_test.go +110 -0
- package/linthost/project_rule_state_and_live_failure_reach_file_dispatch_test.go +89 -0
- package/linthost/project_rule_state_and_reporter_are_isolated_between_cycles_test.go +87 -0
- package/linthost/project_source_files_follow_tsconfig_selection_test.go +86 -0
- package/linthost/project_source_selection_preserves_explicit_bundled_roots_test.go +73 -0
- package/linthost/promise_function_async_test.go +49 -0
- package/linthost/public_rule_context_accepts_legacy_reporter_test.go +50 -0
- package/linthost/public_rule_context_legacy_reporter_drops_fix_edits_test.go +57 -0
- package/linthost/public_rule_context_options_are_isolated_test.go +106 -0
- package/linthost/public_rule_context_report_fix_falls_back_when_no_edits_test.go +39 -0
- package/linthost/public_rule_context_report_fix_forwards_to_fixreporter_test.go +102 -0
- package/linthost/public_rule_context_report_fix_off_severity_drops_silently_test.go +41 -0
- package/linthost/public_rule_context_report_fix_skips_nil_node_test.go +34 -0
- package/linthost/public_rule_context_report_range_fix_falls_back_when_no_edits_test.go +38 -0
- package/linthost/public_rule_context_report_range_fix_forwards_to_fixreporter_test.go +49 -0
- package/linthost/public_rule_context_report_related_falls_back_test.go +58 -0
- package/linthost/public_rule_context_report_related_forwards_test.go +108 -0
- package/linthost/public_rule_context_report_suggestion_falls_back_when_unsupported_test.go +41 -0
- package/linthost/public_rule_context_report_suggestion_forwards_to_suggestionreporter_test.go +97 -0
- package/linthost/public_rule_context_report_suggestion_with_no_choices_reports_test.go +33 -0
- package/linthost/radix_accepts_every_integer_radix_from_two_through_thirty_six_test.go +33 -0
- package/linthost/range_suggestion_finding_uses_canonical_bounds_test.go +47 -0
- package/linthost/react_button_has_type_requires_explicit_type_test.go +22 -0
- package/linthost/react_compiler_subset_reports_local_purity_violations_test.go +72 -0
- package/linthost/react_display_name_reports_anonymous_memo_test.go +25 -0
- package/linthost/react_exhaustive_deps_reports_missing_identifiers_test.go +58 -0
- package/linthost/react_helpers_test.go +36 -0
- package/linthost/react_iframe_missing_sandbox_reports_iframe_test.go +21 -0
- package/linthost/react_jsx_key_reports_array_element_test.go +21 -0
- package/linthost/react_jsx_key_reports_conditional_map_element_test.go +23 -0
- package/linthost/react_jsx_key_reports_logical_map_element_test.go +23 -0
- package/linthost/react_jsx_no_duplicate_props_reports_duplicate_test.go +21 -0
- package/linthost/react_jsx_no_script_url_reports_javascript_href_test.go +20 -0
- package/linthost/react_jsx_no_target_blank_reports_missing_rel_test.go +22 -0
- package/linthost/react_jsx_no_undef_declarations_collected_once_per_file_test.go +63 -0
- package/linthost/react_jsx_no_undef_reports_undeclared_component_test.go +25 -0
- package/linthost/react_jsx_no_undef_skips_declared_components_test.go +46 -0
- package/linthost/react_jsx_no_useless_fragment_test.go +29 -0
- package/linthost/react_no_array_index_key_reports_index_key_test.go +21 -0
- package/linthost/react_no_array_index_key_reports_renamed_index_key_test.go +23 -0
- package/linthost/react_no_array_index_key_skips_nested_non_list_element_test.go +22 -0
- package/linthost/react_no_array_index_key_skips_unrelated_index_identifier_test.go +21 -0
- package/linthost/react_no_children_prop_reports_children_prop_test.go +21 -0
- package/linthost/react_no_danger_reports_dangerously_set_inner_html_test.go +21 -0
- package/linthost/react_no_danger_with_children_reports_mixed_content_test.go +22 -0
- package/linthost/react_no_danger_with_children_survives_spread_props_test.go +23 -0
- package/linthost/react_no_direct_mutation_state_reports_state_property_write_test.go +22 -0
- package/linthost/react_no_find_dom_node_reports_call_test.go +20 -0
- package/linthost/react_no_is_mounted_reports_call_test.go +20 -0
- package/linthost/react_no_string_refs_reports_string_ref_test.go +20 -0
- package/linthost/react_no_unescaped_entities_reports_quote_text_test.go +21 -0
- package/linthost/react_only_export_components_honors_allow_options_test.go +41 -0
- package/linthost/react_only_export_components_reports_non_component_export_test.go +41 -0
- package/linthost/react_perf_helpers_test.go +58 -0
- package/linthost/react_perf_jsx_no_jsx_as_prop_test.go +29 -0
- package/linthost/react_perf_jsx_no_new_array_as_prop_test.go +30 -0
- package/linthost/react_perf_jsx_no_new_function_as_prop_test.go +31 -0
- package/linthost/react_perf_jsx_no_new_object_as_prop_test.go +31 -0
- package/linthost/react_perf_native_allow_list_test.go +49 -0
- package/linthost/react_perf_rules_skip_jsx_source_test.go +29 -0
- package/linthost/react_rules_of_hooks_rejects_hook_after_conditional_return_test.go +54 -0
- package/linthost/react_rules_of_hooks_rejects_invalid_call_sites_test.go +65 -0
- package/linthost/react_source_file_rules_handle_tsx_descendants_test.go +77 -0
- package/linthost/react_state_setters_reject_render_and_effect_calls_test.go +62 -0
- package/linthost/react_style_prop_object_reports_string_style_test.go +22 -0
- package/linthost/react_void_dom_elements_no_children_reports_img_child_test.go +22 -0
- package/linthost/regex_optimizer_distinguishes_a_zero_upper_bound_from_an_open_range_test.go +44 -0
- package/linthost/regex_optimizer_preserves_ranges_crossing_meta_sets_test.go +67 -0
- package/linthost/regex_tree_optimizer.go +54 -10
- package/linthost/regexp_alias_rules_test.go +53 -0
- package/linthost/regexp_cache.go +63 -33
- package/linthost/regexp_character_class_and_group_rules_test.go +64 -0
- package/linthost/regexp_duplicate_class_uses_code_points_test.go +41 -0
- package/linthost/regexp_quantifier_and_flag_rules_test.go +52 -0
- package/linthost/regexp_useless_ignore_case_flag_test.go +111 -0
- package/linthost/regexp_useless_multiline_flag_test.go +71 -0
- package/linthost/register_rejects_duplicate_rule_name_test.go +74 -0
- package/linthost/reject_any_type_test.go +50 -0
- package/linthost/reject_function_type_test.go +48 -0
- package/linthost/related_getter_setter_pairs_test.go +56 -0
- package/linthost/render_result_dom_access_and_events_test.go +45 -0
- package/linthost/require_array_sort_compare_test.go +47 -0
- package/linthost/require_await_counts_for_await_and_promise_returns_test.go +76 -0
- package/linthost/require_description_test.go +29 -0
- package/linthost/require_param_description_allows_multiline_continuation_test.go +27 -0
- package/linthost/require_param_description_test.go +29 -0
- package/linthost/require_param_name_test.go +26 -0
- package/linthost/require_property_description_allows_multiline_continuation_test.go +27 -0
- package/linthost/require_property_description_test.go +30 -0
- package/linthost/require_property_name_test.go +26 -0
- package/linthost/require_returns_description_allows_multiline_continuation_test.go +27 -0
- package/linthost/require_returns_description_test.go +29 -0
- package/linthost/required_behavioral_witness_kinds_ignore_non_public_candidates_test.go +51 -0
- package/linthost/resident_apply_change_matches_cold_load_test.go +106 -0
- package/linthost/resident_cache_replaces_a_checker_free_program_when_a_checker_arrives_test.go +57 -0
- package/linthost/resident_cache_retains_program_for_declared_external_change_test.go +61 -0
- package/linthost/resident_cache_serves_a_checker_free_verb_from_the_checker_program_test.go +51 -0
- package/linthost/resident_heritage_update_rebuilds_checker_test.go +70 -0
- package/linthost/resident_regex_cache_retires_reloaded_configurations_test.go +123 -0
- package/linthost/resident_rules_are_reused_only_while_their_config_is_unchanged_test.go +180 -0
- package/linthost/resident_whole_corpus_matches_cold_load_test.go +167 -0
- package/linthost/resolve_config_file_path_uses_tsconfig_directory_test.go +34 -0
- package/linthost/resolve_config_tsgo_falls_back_to_the_project_root_anchor_test.go +36 -0
- package/linthost/resolve_config_tsgo_keeps_an_explicitly_pinned_compiler_test.go +41 -0
- package/linthost/resolve_config_tsgo_prefers_the_config_anchor_over_the_project_root_test.go +41 -0
- package/linthost/resolve_config_tsgo_resolves_the_project_compiler_without_the_environment_test.go +33 -0
- package/linthost/resolve_config_tsgo_resolves_through_a_linked_typescript_install_test.go +48 -0
- package/linthost/resolve_config_tsgo_returns_nothing_without_a_project_typescript_test.go +32 -0
- package/linthost/resolve_config_tsgo_returns_nothing_without_the_platform_package_test.go +40 -0
- package/linthost/resolve_ttsx_launcher_falls_back_to_the_bare_command_test.go +36 -0
- package/linthost/resolve_ttsx_launcher_keeps_an_explicitly_pinned_binary_test.go +40 -0
- package/linthost/resolve_ttsx_launcher_resolves_the_project_launcher_without_the_environment_test.go +33 -0
- package/linthost/restrict_plus_operands_test.go +47 -0
- package/linthost/restrict_template_expressions_test.go +47 -0
- package/linthost/return_await_test.go +54 -0
- package/linthost/rule_codes.go +16 -2
- package/linthost/rule_codes_are_unique_and_banded_across_live_registry_test.go +74 -0
- package/linthost/rule_docs.go +1 -1
- package/linthost/rule_documentation_urls_cover_the_builtin_corpus_test.go +86 -0
- package/linthost/rule_snapshot_engine_requires_a_valid_active_rule_test.go +59 -0
- package/linthost/rules_boundaries.go +19 -7
- package/linthost/rules_consistent_return.go +323 -16
- package/linthost/rules_core_extra.go +41 -82
- package/linthost/rules_default_case.go +1 -1
- package/linthost/rules_escape.go +18 -3
- package/linthost/rules_finally.go +49 -15
- package/linthost/rules_format_arrow_parens.go +8 -10
- package/linthost/rules_format_bracket_spacing.go +14 -19
- package/linthost/rules_format_print_width.go +28 -19
- package/linthost/rules_format_quote_props.go +5 -11
- package/linthost/rules_format_quotes.go +5 -6
- package/linthost/rules_format_sort_imports.go +27 -15
- package/linthost/rules_format_statement_split.go +3 -5
- package/linthost/rules_functional.go +21 -14
- package/linthost/rules_gap.go +9 -12
- package/linthost/rules_jsdoc.go +2 -3
- package/linthost/rules_jsx_a11y.go +2 -0
- package/linthost/rules_logic.go +88 -11
- package/linthost/rules_loops.go +16 -2
- package/linthost/rules_max_nested_callbacks.go +28 -12
- package/linthost/rules_misc.go +38 -8
- package/linthost/rules_no_extend_native.go +52 -13
- package/linthost/rules_no_fallthrough.go +1 -1
- package/linthost/rules_no_invalid_this.go +6 -3
- package/linthost/rules_no_mixed_operators.go +42 -10
- package/linthost/rules_no_param_reassign.go +1 -1
- package/linthost/rules_no_unreachable.go +61 -2
- package/linthost/rules_no_useless_constructor.go +21 -27
- package/linthost/rules_problems.go +26 -2
- package/linthost/rules_regexp.go +76 -28
- package/linthost/rules_security.go +4 -4
- package/linthost/rules_self.go +42 -6
- package/linthost/rules_solid.go +14 -26
- package/linthost/rules_sort_keys.go +12 -14
- package/linthost/rules_storybook.go +16 -26
- package/linthost/rules_strings.go +9 -19
- package/linthost/rules_suggestions.go +79 -45
- package/linthost/rules_testing_library.go +18 -0
- package/linthost/rules_ts_no_restricted_types.go +9 -1
- package/linthost/rules_ts_no_unnecessary_type_arguments.go +44 -47
- package/linthost/rules_ts_prefer_readonly.go +111 -42
- package/linthost/rules_ts_prefer_return_this_type.go +21 -14
- package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +12 -17
- package/linthost/rules_unicorn_no_unnecessary_await.go +39 -13
- package/linthost/rules_unicorn_no_unnecessary_slice_end.go +7 -10
- package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +29 -12
- package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +7 -25
- package/linthost/rules_unicorn_no_useless_length_check.go +19 -19
- package/linthost/rules_unicorn_prefer_array_some.go +1 -2
- package/linthost/rules_unicorn_prefer_bigint_literals.go +21 -18
- package/linthost/rules_unicorn_prefer_date_now.go +7 -17
- package/linthost/rules_unicorn_prefer_default_parameters.go +7 -15
- package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +7 -13
- package/linthost/rules_unicorn_prefer_negative_index.go +12 -13
- package/linthost/rules_unicorn_prefer_node_protocol.go +5 -5
- package/linthost/rules_unicorn_prefer_object_from_entries.go +7 -14
- package/linthost/rules_unicorn_prefer_regexp_test_rule.go +17 -19
- package/linthost/rules_unicorn_prefer_single_call.go +12 -6
- package/linthost/rules_unicorn_prefer_spread.go +7 -13
- package/linthost/rules_unicorn_prefer_string_replace_all.go +4 -3
- package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +22 -3
- package/linthost/rules_unicorn_prefer_top_level_await.go +4 -3
- package/linthost/rules_unicorn_relative_url_style.go +33 -14
- package/linthost/rules_var.go +73 -3
- package/linthost/runtime_rule_codes_are_collision_free_and_order_independent_test.go +101 -0
- package/linthost/security_assigned_names_unwrap_assertion_targets_test.go +54 -0
- package/linthost/security_bindings_collected_once_per_file_test.go +63 -0
- package/linthost/security_detect_bidi_characters_test.go +44 -0
- package/linthost/security_name_based_node_api_findings_stay_untagged_test.go +87 -0
- package/linthost/self_compare_and_self_assign_ignore_calls_and_empty_template_curly_is_not_a_placeholder_test.go +50 -0
- package/linthost/semantic_finding_guard_rejects_recovered_execution_failures_test.go +75 -0
- package/linthost/serve.go +42 -25
- package/linthost/set_env_replaces_or_appends_test.go +39 -0
- package/linthost/severity_string_formats_values_test.go +34 -0
- package/linthost/signature_flags_expose_construct_signature_abstractness_test.go +136 -0
- package/linthost/signature_introspection_reaches_runtime_endpoints_test.go +123 -0
- package/linthost/solid_helpers_test.go +92 -0
- package/linthost/solid_import_proxy_and_dependency_rules_test.go +48 -0
- package/linthost/solid_imports_leaves_a_type_only_destination_alone_test.go +42 -0
- package/linthost/solid_imports_relocates_a_misrouted_specifier_test.go +69 -0
- package/linthost/solid_jsx_attribute_guards_test.go +69 -0
- package/linthost/solid_no_react_deps_tags_dependency_array_unnecessary_test.go +106 -0
- package/linthost/solid_reactivity_and_component_returns_test.go +49 -0
- package/linthost/solid_rendering_style_preferences_test.go +59 -0
- package/linthost/solid_self_closing_comp_keeps_text_children_test.go +32 -0
- package/linthost/solid_source_file_rules_handle_jsx_initializers_test.go +47 -0
- package/linthost/solid_style_prop_reports_non_zero_numeric_lengths_test.go +37 -0
- package/linthost/solid_validate_jsx_nesting_test.go +53 -0
- package/linthost/sort_keys_compares_across_a_computed_key_and_resets_at_a_spread_test.go +33 -0
- package/linthost/source_extension_tables_separate_selection_from_widening_test.go +44 -0
- package/linthost/source_has_statement_terminator_detects_semicolon_test.go +28 -0
- package/linthost/source_has_statement_terminator_returns_false_for_empty_string_test.go +27 -0
- package/linthost/source_has_statement_terminator_returns_false_for_unclosed_block_comment_test.go +31 -0
- package/linthost/source_has_statement_terminator_returns_false_when_absent_test.go +29 -0
- package/linthost/source_has_statement_terminator_skips_trailing_block_comment_test.go +30 -0
- package/linthost/source_has_statement_terminator_skips_trailing_whitespace_test.go +31 -0
- package/linthost/standalone_checker_resolves_cross_file_type_after_pooled_diagnostics_test.go +85 -0
- package/linthost/storybook_deletion_findings_tag_unnecessary_test.go +127 -0
- package/linthost/storybook_legacy_api_findings_tag_deprecated_test.go +110 -0
- package/linthost/strict_boolean_expressions_test.go +49 -0
- package/linthost/switch_exhaustiveness_check_advanced_type_shapes_test.go +83 -0
- package/linthost/switch_exhaustiveness_check_finite_members_test.go +76 -0
- package/linthost/switch_exhaustiveness_check_helpers_test.go +99 -0
- package/linthost/switch_exhaustiveness_check_no_unchecked_indexed_access_test.go +56 -0
- package/linthost/switch_exhaustiveness_check_options_test.go +118 -0
- package/linthost/switch_exhaustiveness_check_parser_comment_ranges_test.go +64 -0
- package/linthost/switch_exhaustiveness_check_preserves_migrated_defaults_and_options_test.go +139 -0
- package/linthost/switch_exhaustiveness_check_test.go +73 -0
- package/linthost/tail_is_clean_terminator_returns_false_for_invalid_inputs_test.go +64 -0
- package/linthost/testing_library_helpers_test.go +71 -0
- package/linthost/tsdoc_syntax_test.go +64 -0
- package/linthost/ttsx_command_context_spawns_the_project_launcher_test.go +47 -0
- package/linthost/type_alias_reference_node_uses_borrowed_builder_context_test.go +128 -0
- package/linthost/type_args_start_and_end_guard_branches_test.go +58 -0
- package/linthost/type_instantiation_mappers_reach_runtime_endpoints_test.go +213 -0
- package/linthost/type_mapper_parallel_substitution_avoids_capture_test.go +106 -0
- package/linthost/typed_rule_semantic_helpers_test.go +34 -0
- package/linthost/unbound_method_test.go +53 -0
- package/linthost/unicorn_array_some_requires_an_existence_comparison_test.go +29 -0
- package/linthost/unicorn_await_literal_does_not_assume_an_object_has_no_then_test.go +33 -0
- package/linthost/unicorn_better_regex_constructor_fix_escapes_cooked_pattern_test.go +146 -0
- package/linthost/unicorn_better_regex_fix_is_idempotent_test.go +37 -0
- package/linthost/unicorn_better_regex_leaves_optimal_literals_test.go +36 -0
- package/linthost/unicorn_better_regex_reports_exact_range_and_message_test.go +52 -0
- package/linthost/unicorn_better_regex_reports_without_fix_on_source_member_test.go +38 -0
- package/linthost/unicorn_better_regex_rewrites_regexp_constructor_test.go +70 -0
- package/linthost/unicorn_better_regex_skips_unicode_flag_literals_test.go +34 -0
- package/linthost/unicorn_better_regex_sort_character_classes_option_test.go +39 -0
- package/linthost/unicorn_better_regex_test.go +44 -0
- package/linthost/unicorn_bigint_literal_requires_an_exact_integer_value_test.go +34 -0
- package/linthost/unicorn_consistent_destructuring_jsx_tag_names_are_exempt_test.go +53 -0
- package/linthost/unicorn_consistent_destructuring_skips_valid_forms_test.go +221 -0
- package/linthost/unicorn_consistent_destructuring_suggestion_is_opt_in_and_idempotent_test.go +54 -0
- package/linthost/unicorn_consistent_destructuring_test.go +306 -0
- package/linthost/unicorn_consistent_existence_index_check_fix_is_idempotent_test.go +45 -0
- package/linthost/unicorn_consistent_existence_index_check_fix_rewrites_magnitude_comparisons_test.go +96 -0
- package/linthost/unicorn_consistent_existence_index_check_skips_upstream_valid_forms_test.go +143 -0
- package/linthost/unicorn_consistent_existence_index_check_test.go +212 -0
- package/linthost/unicorn_consistent_function_scoping_chains_blocks_inside_loop_bodies_test.go +53 -0
- package/linthost/unicorn_consistent_function_scoping_checks_arrow_lexical_environment_test.go +48 -0
- package/linthost/unicorn_consistent_function_scoping_checks_returned_arrow_chains_test.go +29 -0
- package/linthost/unicorn_consistent_function_scoping_honors_check_arrow_functions_test.go +42 -0
- package/linthost/unicorn_consistent_function_scoping_keeps_shared_outer_references_together_test.go +28 -0
- package/linthost/unicorn_consistent_function_scoping_outer_reference_pins_recursive_function_test.go +31 -0
- package/linthost/unicorn_consistent_function_scoping_preserves_upstream_factory_exceptions_test.go +59 -0
- package/linthost/unicorn_consistent_function_scoping_protects_super_and_private_names_test.go +57 -0
- package/linthost/unicorn_consistent_function_scoping_reads_class_head_positions_as_lexical_environment_test.go +42 -0
- package/linthost/unicorn_consistent_function_scoping_reports_canonical_head_ranges_test.go +44 -0
- package/linthost/unicorn_consistent_function_scoping_resolves_jsx_component_captures_test.go +44 -0
- package/linthost/unicorn_consistent_function_scoping_test.go +45 -0
- package/linthost/unicorn_consistent_function_scoping_treats_loop_scopes_as_one_boundary_test.go +36 -0
- package/linthost/unicorn_consistent_function_scoping_uses_binding_identity_and_ignores_self_recursion_test.go +42 -0
- package/linthost/unicorn_consistent_function_scoping_validates_the_public_option_shape_test.go +58 -0
- package/linthost/unicorn_consistent_template_literal_escape_command_fix_idempotence_test.go +41 -0
- package/linthost/unicorn_consistent_template_literal_escape_fires_on_declaration_files_test.go +35 -0
- package/linthost/unicorn_consistent_template_literal_escape_fixes_template_literal_types_test.go +35 -0
- package/linthost/unicorn_consistent_template_literal_escape_fixes_upstream_invalid_corpus_test.go +80 -0
- package/linthost/unicorn_consistent_template_literal_escape_honors_backslash_parity_test.go +64 -0
- package/linthost/unicorn_consistent_template_literal_escape_preserves_continuations_crlf_and_unicode_test.go +34 -0
- package/linthost/unicorn_consistent_template_literal_escape_reports_exact_element_ranges_test.go +71 -0
- package/linthost/unicorn_consistent_template_literal_escape_reports_untagged_inside_tagged_test.go +43 -0
- package/linthost/unicorn_consistent_template_literal_escape_skips_tagged_templates_test.go +40 -0
- package/linthost/unicorn_consistent_template_literal_escape_skips_upstream_valid_corpus_test.go +49 -0
- package/linthost/unicorn_date_now_preserves_constructor_arguments_test.go +34 -0
- package/linthost/unicorn_escape_case_bounds_escape_digit_runs_test.go +97 -0
- package/linthost/unicorn_escape_case_honors_backslash_parity_test.go +67 -0
- package/linthost/unicorn_escape_case_reports_interpolated_template_segments_test.go +97 -0
- package/linthost/unicorn_escape_case_skips_tagged_templates_test.go +62 -0
- package/linthost/unicorn_escape_family_survives_crlf_and_astral_literals_test.go +67 -0
- package/linthost/unicorn_filename_case_cases_key_order_shapes_message_test.go +42 -0
- package/linthost/unicorn_filename_case_default_ignored_index_basenames_test.go +40 -0
- package/linthost/unicorn_filename_case_directory_handling_test.go +89 -0
- package/linthost/unicorn_filename_case_extension_lowercase_test.go +72 -0
- package/linthost/unicorn_filename_case_ignore_patterns_match_segments_test.go +78 -0
- package/linthost/unicorn_filename_case_multiple_file_extensions_option_test.go +77 -0
- package/linthost/unicorn_filename_case_option_validation_test.go +74 -0
- package/linthost/unicorn_filename_case_real_project_paths_test.go +50 -0
- package/linthost/unicorn_filename_case_report_anchors_and_no_fix_test.go +59 -0
- package/linthost/unicorn_filename_case_split_name_line_terminator_edge_test.go +37 -0
- package/linthost/unicorn_filename_case_test.go +131 -0
- package/linthost/unicorn_filename_case_unicode_segments_test.go +33 -0
- package/linthost/unicorn_filename_case_upstream_invalid_filenames_test.go +268 -0
- package/linthost/unicorn_filename_case_upstream_valid_filenames_test.go +173 -0
- package/linthost/unicorn_import_style_accepts_mixed_styles_when_all_allowed_test.go +29 -0
- package/linthost/unicorn_import_style_banned_module_reports_dedicated_message_test.go +70 -0
- package/linthost/unicorn_import_style_check_toggles_disable_each_syntax_family_test.go +61 -0
- package/linthost/unicorn_import_style_default_module_policy_matrix_test.go +69 -0
- package/linthost/unicorn_import_style_default_policies_at_exact_ranges_test.go +65 -0
- package/linthost/unicorn_import_style_default_policies_skip_compliant_and_unknown_modules_test.go +37 -0
- package/linthost/unicorn_import_style_disjunction_lists_allowed_styles_in_order_test.go +44 -0
- package/linthost/unicorn_import_style_dynamic_import_expression_forms_test.go +69 -0
- package/linthost/unicorn_import_style_evaluates_static_string_module_names_test.go +58 -0
- package/linthost/unicorn_import_style_extend_default_styles_false_drops_builtin_policies_test.go +46 -0
- package/linthost/unicorn_import_style_named_module_policy_matrix_test.go +81 -0
- package/linthost/unicorn_import_style_namespace_module_policy_matrix_test.go +63 -0
- package/linthost/unicorn_import_style_object_pattern_key_forms_test.go +46 -0
- package/linthost/unicorn_import_style_optional_require_calls_are_never_classified_test.go +24 -0
- package/linthost/unicorn_import_style_rejects_malformed_options_before_linting_test.go +56 -0
- package/linthost/unicorn_import_style_reports_no_automatic_fixes_test.go +31 -0
- package/linthost/unicorn_import_style_skips_non_matching_reference_shapes_test.go +47 -0
- package/linthost/unicorn_import_style_style_overrides_replace_inherited_flags_test.go +69 -0
- package/linthost/unicorn_import_style_test.go +87 -0
- package/linthost/unicorn_import_style_type_only_imports_follow_value_semantics_test.go +53 -0
- package/linthost/unicorn_import_style_unassigned_policy_accepts_unassigned_forms_test.go +31 -0
- package/linthost/unicorn_import_style_unassigned_policy_reports_every_assigned_form_test.go +66 -0
- package/linthost/unicorn_isolated_functions_arguments_test.go +48 -0
- package/linthost/unicorn_isolated_functions_browser_and_page_callees_test.go +63 -0
- package/linthost/unicorn_isolated_functions_comments_test.go +131 -0
- package/linthost/unicorn_isolated_functions_execute_script_func_property_test.go +83 -0
- package/linthost/unicorn_isolated_functions_function_name_callees_test.go +100 -0
- package/linthost/unicorn_isolated_functions_helpers_test.go +76 -0
- package/linthost/unicorn_isolated_functions_override_globals_test.go +92 -0
- package/linthost/unicorn_isolated_functions_parameter_default_capture_test.go +47 -0
- package/linthost/unicorn_isolated_functions_scope_internals_test.go +57 -0
- package/linthost/unicorn_isolated_functions_selector_test.go +43 -0
- package/linthost/unicorn_isolated_functions_test.go +75 -0
- package/linthost/unicorn_isolated_functions_this_and_super_test.go +110 -0
- package/linthost/unicorn_isolated_functions_typeof_this_test.go +45 -0
- package/linthost/unicorn_isolated_functions_typescript_types_test.go +39 -0
- package/linthost/unicorn_isolated_functions_unresolved_reference_test.go +41 -0
- package/linthost/unicorn_known_boundary_observations_test.go +113 -0
- package/linthost/unicorn_length_check_preserves_escaped_foreach_results_test.go +33 -0
- package/linthost/unicorn_negative_index_requires_its_own_receiver_and_index_argument_test.go +32 -0
- package/linthost/unicorn_no_hex_escape_honors_backslash_parity_test.go +63 -0
- package/linthost/unicorn_no_hex_escape_ignores_non_hex_escapes_test.go +75 -0
- package/linthost/unicorn_no_hex_escape_reports_interpolated_template_segments_test.go +86 -0
- package/linthost/unicorn_no_hex_escape_skips_tagged_templates_test.go +57 -0
- package/linthost/unicorn_no_typeof_undefined_check_global_variables_option_test.go +90 -0
- package/linthost/unicorn_no_typeof_undefined_declines_unsafe_fix_test.go +50 -0
- package/linthost/unicorn_no_typeof_undefined_fix_rewrites_comparisons_test.go +43 -0
- package/linthost/unicorn_no_typeof_undefined_skips_upstream_valid_forms_test.go +57 -0
- package/linthost/unicorn_no_typeof_undefined_test.go +88 -0
- package/linthost/unicorn_no_unnecessary_polyfills_checks_only_static_string_specifiers_test.go +50 -0
- package/linthost/unicorn_no_unnecessary_polyfills_config_discovery_test.go +109 -0
- package/linthost/unicorn_no_unnecessary_polyfills_core_js_compat_oracle_test.go +74 -0
- package/linthost/unicorn_no_unnecessary_polyfills_corpus_project_scenario_test.go +30 -0
- package/linthost/unicorn_no_unnecessary_polyfills_custom_stats_discovery_test.go +45 -0
- package/linthost/unicorn_no_unnecessary_polyfills_engine_oracle_test.go +101 -0
- package/linthost/unicorn_no_unnecessary_polyfills_engines_discovery_test.go +29 -0
- package/linthost/unicorn_no_unnecessary_polyfills_option_overrides_config_discovery_test.go +28 -0
- package/linthost/unicorn_no_unnecessary_polyfills_options_test.go +38 -0
- package/linthost/unicorn_no_unnecessary_polyfills_package_json_browserslist_section_test.go +25 -0
- package/linthost/unicorn_no_unnecessary_polyfills_pattern_table_oracle_test.go +47 -0
- package/linthost/unicorn_no_unnecessary_polyfills_rejects_malformed_options_test.go +48 -0
- package/linthost/unicorn_no_unnecessary_polyfills_silent_without_resolvable_targets_test.go +26 -0
- package/linthost/unicorn_no_unnecessary_polyfills_test.go +128 -0
- package/linthost/unicorn_no_unnecessary_polyfills_upstream_invalid_targets_test.go +73 -0
- package/linthost/unicorn_no_unused_properties_corpus_test.go +81 -0
- package/linthost/unicorn_no_unused_properties_key_matching_test.go +83 -0
- package/linthost/unicorn_no_unused_properties_object_literal_semantics_test.go +211 -0
- package/linthost/unicorn_no_unused_properties_reference_identity_test.go +72 -0
- package/linthost/unicorn_no_unused_properties_reporting_shape_test.go +89 -0
- package/linthost/unicorn_no_unused_properties_script_global_scope_test.go +60 -0
- package/linthost/unicorn_no_unused_properties_template_keys_test.go +35 -0
- package/linthost/unicorn_no_unused_properties_type_literal_semantics_test.go +155 -0
- package/linthost/unicorn_number_literal_case_fix_is_idempotent_test.go +54 -0
- package/linthost/unicorn_number_literal_case_fixes_bigint_and_separated_literals_test.go +43 -0
- package/linthost/unicorn_number_literal_case_fixes_every_literal_in_one_pass_test.go +37 -0
- package/linthost/unicorn_number_literal_case_fixes_literals_in_every_syntactic_position_test.go +51 -0
- package/linthost/unicorn_number_literal_case_fixes_radix_prefix_and_hex_digits_test.go +42 -0
- package/linthost/unicorn_number_literal_case_fixes_uppercase_exponent_test.go +42 -0
- package/linthost/unicorn_number_literal_case_reports_exact_range_and_message_test.go +53 -0
- package/linthost/unicorn_number_literal_case_skips_canonical_literals_test.go +38 -0
- package/linthost/unicorn_number_literal_case_uppercases_hex_exponent_digits_test.go +44 -0
- package/linthost/unicorn_prefer_number_properties_autofixes_is_na_n_with_number_argument_test.go +24 -0
- package/linthost/unicorn_prefer_number_properties_autofixes_safe_global_test.go +24 -0
- package/linthost/unicorn_prefer_number_properties_checks_infinity_when_enabled_test.go +43 -0
- package/linthost/unicorn_prefer_number_properties_checks_na_n_when_enabled_test.go +30 -0
- package/linthost/unicorn_prefer_number_properties_expands_shorthand_fix_test.go +24 -0
- package/linthost/unicorn_prefer_number_properties_fixes_negative_infinity_test.go +25 -0
- package/linthost/unicorn_prefer_number_properties_interpolates_message_test.go +33 -0
- package/linthost/unicorn_prefer_number_properties_leaves_infinity_and_na_n_under_defaults_test.go +24 -0
- package/linthost/unicorn_prefer_number_properties_reports_object_value_positions_test.go +37 -0
- package/linthost/unicorn_prefer_number_properties_skips_base10_and_missing_radix_test.go +35 -0
- package/linthost/unicorn_prefer_number_properties_skips_shadowed_bindings_test.go +40 -0
- package/linthost/unicorn_prefer_number_properties_suggests_unsafe_is_na_n_test.go +38 -0
- package/linthost/unicorn_prefer_number_properties_test.go +81 -0
- package/linthost/unicorn_prefer_number_properties_validates_options_test.go +64 -0
- package/linthost/unicorn_prefer_optional_catch_binding_test.go +53 -0
- package/linthost/unicorn_prefer_simple_condition_first_handles_or_chains_and_non_logical_type_wrappers_test.go +45 -0
- package/linthost/unicorn_prefer_simple_condition_first_parser_aware_comments_do_not_mistake_literal_text_test.go +28 -0
- package/linthost/unicorn_prefer_simple_condition_first_preserves_mixed_operators_and_parentheses_test.go +32 -0
- package/linthost/unicorn_prefer_simple_condition_first_reports_exact_safe_finding_and_stable_fix_test.go +64 -0
- package/linthost/unicorn_prefer_simple_condition_first_restricts_reports_to_boolean_contexts_test.go +68 -0
- package/linthost/unicorn_prefer_simple_condition_first_reviews_each_homogeneous_mixed_operator_chain_test.go +55 -0
- package/linthost/unicorn_prefer_simple_condition_first_uses_canonical_simple_expression_grammar_test.go +105 -0
- package/linthost/unicorn_prefer_simple_condition_first_withholds_unsafe_and_syntax_owned_fixes_test.go +57 -0
- package/linthost/unicorn_prefer_string_raw_survives_unterminated_literals_test.go +36 -0
- package/linthost/unicorn_prevent_abbreviations_allows_generated_names_to_shadow_without_capture_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_allows_reserved_words_in_property_suggestions_test.go +43 -0
- package/linthost/unicorn_prevent_abbreviations_applies_import_controls_to_static_require_bindings_test.go +29 -0
- package/linthost/unicorn_prevent_abbreviations_applies_import_mode_to_external_import_equals_test.go +29 -0
- package/linthost/unicorn_prevent_abbreviations_applies_internal_import_defaults_and_preserves_imported_names_test.go +40 -0
- package/linthost/unicorn_prevent_abbreviations_avoids_catch_parameter_body_redeclarations_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_avoids_compiler_provided_global_bindings_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_avoids_var_lexical_early_error_collisions_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_checks_physical_filename_without_offering_edits_test.go +52 -0
- package/linthost/unicorn_prevent_abbreviations_checks_shorthand_destructuring_only_when_enabled_test.go +25 -0
- package/linthost/unicorn_prevent_abbreviations_does_not_apply_require_mode_to_qualified_import_equals_test.go +24 -0
- package/linthost/unicorn_prevent_abbreviations_does_not_capture_outer_reads_with_unused_inner_bindings_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_does_not_capture_unresolved_names_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_does_not_report_destructuring_assignment_keys_as_properties_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_does_not_treat_destructuring_property_keys_as_collisions_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_expands_compound_and_cased_names_but_skips_constants_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_false_replacement_disables_compound_matches_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_false_replacement_stops_case_variant_fallback_test.go +22 -0
- package/linthost/unicorn_prevent_abbreviations_honors_negative_replacement_and_allow_list_patches_test.go +40 -0
- package/linthost/unicorn_prevent_abbreviations_honors_replacement_allow_and_ignore_options_test.go +42 -0
- package/linthost/unicorn_prevent_abbreviations_ignores_detached_js_doc_when_deciding_fix_safety_test.go +47 -0
- package/linthost/unicorn_prevent_abbreviations_ignores_non_lexical_jsx_and_tuple_names_for_collisions_test.go +24 -0
- package/linthost/unicorn_prevent_abbreviations_keeps_exported_js_doc_and_jsx_bindings_diagnostic_only_test.go +107 -0
- package/linthost/unicorn_prevent_abbreviations_keeps_independent_loop_and_switch_scopes_independent_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_keeps_mapped_and_conditional_type_scopes_independent_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_keeps_shadowed_bindings_independent_and_avoids_collisions_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_keeps_type_script_signature_scopes_independent_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_offers_whole_binding_suggestions_for_ambiguous_names_test.go +40 -0
- package/linthost/unicorn_prevent_abbreviations_preserves_astral_first_rune_casing_test.go +27 -0
- package/linthost/unicorn_prevent_abbreviations_preserves_canonical_upper_first_for_uncased_prefixes_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_preserves_explicit_imported_alias_names_test.go +22 -0
- package/linthost/unicorn_prevent_abbreviations_preserves_exported_alias_names_test.go +35 -0
- package/linthost/unicorn_prevent_abbreviations_property_checks_are_opt_in_and_suggestion_only_test.go +34 -0
- package/linthost/unicorn_prevent_abbreviations_recognizes_only_canonical_static_require_calls_test.go +43 -0
- package/linthost/unicorn_prevent_abbreviations_rejects_malformed_options_test.go +36 -0
- package/linthost/unicorn_prevent_abbreviations_renames_class_inner_and_outer_references_together_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_renames_default_export_local_names_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_renames_merged_type_and_value_references_together_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_renames_type_predicate_references_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_reports_binding_once_and_fixes_every_reference_test.go +31 -0
- package/linthost/unicorn_prevent_abbreviations_separates_generated_names_at_cross_scope_reads_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_separates_generated_names_in_one_scope_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_supports_canonical_empty_replacement_spelling_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_test.go +34 -0
- package/linthost/unicorn_prevent_abbreviations_uses_default_import_control_for_named_default_syntax_test.go +25 -0
- package/linthost/unicorn_prevent_abbreviations_uses_function_scope_for_destructured_var_collisions_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_uses_function_scope_for_var_collisions_test.go +23 -0
- package/linthost/unicorn_prevent_abbreviations_uses_java_script_full_unicode_casing_test.go +29 -0
- package/linthost/unicorn_prevent_abbreviations_uses_strict_binding_grammar_for_custom_replacements_test.go +51 -0
- package/linthost/unicorn_regexp_test_requires_a_boolean_result_consumer_test.go +33 -0
- package/linthost/unicorn_relative_url_style_preserves_leading_trimmed_characters_test.go +47 -0
- package/linthost/unicorn_report_only_advice_exposes_semantic_preconditions_test.go +48 -0
- package/linthost/unicorn_rule_finding_helpers_test.go +14 -0
- package/linthost/unicorn_rule_names_helpers_test.go +11 -0
- package/linthost/unicorn_single_call_excludes_event_listener_registration_test.go +30 -0
- package/linthost/unicorn_slice_end_preserves_other_receiver_bounds_test.go +30 -0
- package/linthost/unicorn_splice_count_preserves_bounds_and_insertions_test.go +33 -0
- package/linthost/unicorn_spread_fallback_is_load_bearing_for_arrays_test.go +31 -0
- package/linthost/unicorn_string_content_applies_first_matching_pattern_in_configured_order_test.go +55 -0
- package/linthost/unicorn_string_content_escapes_backticks_and_dollars_in_template_fix_test.go +75 -0
- package/linthost/unicorn_string_content_escapes_delimiter_quotes_in_literal_fix_test.go +60 -0
- package/linthost/unicorn_string_content_escapes_line_separators_keeps_other_whitespace_raw_test.go +79 -0
- package/linthost/unicorn_string_content_fix_false_reports_suggestion_only_test.go +73 -0
- package/linthost/unicorn_string_content_honors_custom_message_and_placeholders_test.go +41 -0
- package/linthost/unicorn_string_content_jsx_attribute_fix_uses_html_entities_test.go +103 -0
- package/linthost/unicorn_string_content_matches_case_insensitively_when_configured_test.go +68 -0
- package/linthost/unicorn_string_content_normalizes_template_line_endings_like_acorn_test.go +87 -0
- package/linthost/unicorn_string_content_preserves_control_escapes_in_literal_fix_test.go +93 -0
- package/linthost/unicorn_string_content_rejects_malformed_options_before_linting_test.go +79 -0
- package/linthost/unicorn_string_content_reports_and_fixes_plain_string_literal_test.go +54 -0
- package/linthost/unicorn_string_content_reports_each_template_quasi_at_exact_ranges_test.go +61 -0
- package/linthost/unicorn_string_content_selector_matches_keep_ignored_tag_exemption_test.go +33 -0
- package/linthost/unicorn_string_content_selectors_restrict_checked_nodes_test.go +68 -0
- package/linthost/unicorn_string_content_skips_empty_and_non_string_literals_test.go +43 -0
- package/linthost/unicorn_string_content_skips_ignored_template_tags_test.go +81 -0
- package/linthost/unicorn_string_content_stays_silent_without_pattern_options_test.go +34 -0
- package/linthost/unicorn_string_content_treats_pattern_as_regular_expression_test.go +77 -0
- package/linthost/unicorn_switch_case_break_position_declines_unsafe_or_semantic_moves_test.go +111 -0
- package/linthost/unicorn_switch_case_break_position_fix_preserves_statements_comments_and_eol_test.go +187 -0
- package/linthost/unicorn_switch_case_break_position_reports_every_supported_terminator_at_exact_range_test.go +132 -0
- package/linthost/unicorn_switch_case_break_position_requires_sole_non_empty_block_then_direct_terminator_test.go +112 -0
- package/linthost/unicorn_template_indent_accepts_parenthesized_jest_inline_snapshot_test.go +26 -0
- package/linthost/unicorn_template_indent_detects_tabs_outside_templates_test.go +31 -0
- package/linthost/unicorn_template_indent_falls_back_to_two_spaces_without_any_indent_signal_test.go +23 -0
- package/linthost/unicorn_template_indent_fix_preserves_quasis_substitutions_escapes_and_blank_lines_test.go +71 -0
- package/linthost/unicorn_template_indent_fixes_empty_boundary_quasis_with_insertions_test.go +37 -0
- package/linthost/unicorn_template_indent_fixes_nested_templates_without_touching_expressions_test.go +52 -0
- package/linthost/unicorn_template_indent_honors_configured_tags_functions_comments_and_selectors_test.go +69 -0
- package/linthost/unicorn_template_indent_honors_numeric_and_whitespace_indent_options_test.go +51 -0
- package/linthost/unicorn_template_indent_pins_every_default_matcher_test.go +46 -0
- package/linthost/unicorn_template_indent_preserves_content_trailing_spaces_test.go +31 -0
- package/linthost/unicorn_template_indent_preserves_crlf_test.go +35 -0
- package/linthost/unicorn_template_indent_preserves_every_interior_ecma_script_line_ending_test.go +39 -0
- package/linthost/unicorn_template_indent_preserves_leading_byte_order_mark_test.go +27 -0
- package/linthost/unicorn_template_indent_preserves_mixed_interior_line_endings_test.go +35 -0
- package/linthost/unicorn_template_indent_recognizes_every_ecma_script_source_line_separator_test.go +48 -0
- package/linthost/unicorn_template_indent_rejects_jest_inline_snapshot_near_misses_test.go +35 -0
- package/linthost/unicorn_template_indent_rejects_malformed_options_before_linting_test.go +52 -0
- package/linthost/unicorn_template_indent_selects_every_official_entry_point_at_exact_range_test.go +56 -0
- package/linthost/unicorn_template_indent_skips_unselected_single_line_and_already_correct_templates_test.go +37 -0
- package/linthost/unicorn_template_indent_test.go +20 -0
- package/linthost/unicorn_text_encoding_identifier_case_enforces_dash_in_jsx_charset_attributes_test.go +69 -0
- package/linthost/unicorn_text_encoding_identifier_case_enforces_dash_in_text_decoder_test.go +47 -0
- package/linthost/unicorn_text_encoding_identifier_case_fixes_fs_read_file_encoding_test.go +44 -0
- package/linthost/unicorn_text_encoding_identifier_case_handles_template_literals_test.go +46 -0
- package/linthost/unicorn_text_encoding_identifier_case_reports_suggestion_range_and_message_test.go +78 -0
- package/linthost/unicorn_text_encoding_identifier_case_skips_canonical_and_unknown_labels_test.go +35 -0
- package/linthost/unicorn_text_encoding_identifier_case_suggests_without_fixing_off_read_file_positions_test.go +36 -0
- package/linthost/unicorn_text_encoding_identifier_case_withdash_option_prefers_dash_test.go +52 -0
- package/linthost/unicorn_throw_new_error_fix_parenthesizes_a_shielded_call_chain_test.go +69 -0
- package/linthost/unicorn_throw_new_error_fix_spaces_an_abutting_throw_keyword_test.go +64 -0
- package/linthost/unicorn_throw_new_error_fixes_every_throw_in_one_pass_test.go +42 -0
- package/linthost/unicorn_throw_new_error_fixes_upstream_invalid_corpus_test.go +114 -0
- package/linthost/unicorn_throw_new_error_reports_custom_and_member_callees_test.go +62 -0
- package/linthost/unicorn_throw_new_error_skips_non_matching_callees_test.go +68 -0
- package/linthost/unregistered_rule_code_lookup_preserves_registered_assignments_test.go +102 -0
- package/linthost/use_unknown_in_catch_callback_variable_test.go +48 -0
- package/linthost/user_pattern_cache_follows_resolver_ownership_test.go +87 -0
- package/linthost/user_pattern_cache_parallel_reuses_results_test.go +67 -0
- package/linthost/user_source_files_exclude_imported_declarations_and_javascript_test.go +82 -0
- package/linthost/user_source_files_span_program_typescript_sources_test.go +72 -0
- package/linthost/valid_typeof_equality_operator_scope_test.go +173 -0
- package/linthost/verbatim_range_returns_empty_for_invalid_range_test.go +53 -0
- package/linthost/verbatim_returns_empty_for_nil_node_test.go +30 -0
- package/linthost/verbatim_returns_empty_for_out_of_range_node_test.go +52 -0
- package/linthost/vitest_expect_expect_reports_empty_test_test.go +35 -0
- package/linthost/vitest_finding_helpers_test.go +14 -0
- package/linthost/vitest_no_conditional_expect_reports_expect_inside_if_test.go +37 -0
- package/linthost/vitest_no_conditional_tests_reports_test_inside_if_test.go +35 -0
- package/linthost/vitest_no_disabled_tests_reports_skip_test.go +34 -0
- package/linthost/vitest_no_done_callback_reports_test_parameter_test.go +34 -0
- package/linthost/vitest_no_focused_tests_reports_only_test.go +34 -0
- package/linthost/vitest_no_identical_title_reports_duplicate_sibling_test.go +35 -0
- package/linthost/vitest_no_standalone_expect_reports_top_level_expect_test.go +33 -0
- package/linthost/vitest_no_test_return_statement_reports_return_test.go +35 -0
- package/linthost/vitest_prefer_to_have_length_reports_length_matcher_test.go +34 -0
- package/linthost/vitest_valid_describe_callback_reports_async_callback_test.go +34 -0
- package/linthost/vitest_valid_expect_reports_missing_matcher_test.go +35 -0
- package/linthost/vitest_valid_title_reports_empty_title_test.go +34 -0
- package/linthost/wait_for_assertion_and_side_effect_guards_test.go +55 -0
- package/linthost/windows_junction_dependency_entry_matches_node_fingerprint_test.go +55 -0
- package/linthost/windows_loader_temp_base_stays_on_config_volume_test.go +98 -0
- package/linthost/windows_project_source_selection_preserves_physical_aliases_test.go +69 -0
- package/linthost/windows_real_project_path_expands_windows_short_ancestor_test.go +47 -0
- package/linthost/windows_resolve_config_tsgo_through_linked_typescript_install_test.go +52 -0
- package/linthost/windows_short_path_other_test.go +11 -0
- package/linthost/windows_short_path_windows_test.go +39 -0
- package/linthost/workspace_link_resolves_a_sibling_package_to_its_source_test.go +86 -0
- package/package.json +5 -3
- package/rule/astutil/astutil.go +165 -59
- package/rule/context_decode_options_preserves_defaults_and_decoder_errors_test.go +87 -0
- package/rule/graph.go +82 -16
- package/rule/hint.go +95 -28
- package/rule/new_project_context_preserves_snapshot_ownership_test.go +62 -0
- package/rule/new_project_input_context_preserves_owned_options_test.go +59 -0
- package/rule/new_project_rule_result_preserves_snapshot_ownership_test.go +63 -0
- package/rule/project.go +382 -22
- package/rule/project_input_reader.go +163 -0
- package/rule/rule.go +540 -92
- package/src/createTtscPlugin.ts +3010 -0
- package/src/index.ts +1 -2974
- package/src/internal/configEvaluatorFailure.ts +17 -9
- package/src/internal/lintTrace.ts +106 -0
- package/src/internal/normalizeContributors.ts +79 -0
- package/src/structures/ITtscLintConfig.ts +27 -8
- package/src/structures/ITtscLintPlugin.ts +13 -8
- package/src/structures/ITtscLintPluginConfig.ts +18 -7
- package/src/structures/ITtscLintPluginMeta.ts +10 -7
- package/src/structures/TtscLintRuleSetting.ts +18 -13
- package/src/structures/TtscLintSeverity.ts +5 -0
- package/src/structures/format/ITtscLintFormat.ts +14 -8
- package/src/structures/format/ITtscLintFormatJsDoc.ts +8 -1
- package/src/structures/format/ITtscLintFormatSortImports.ts +14 -8
- package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +133 -25
- package/src/structures/rules/ITtscLintBoundariesRules.ts +10 -5
- package/src/structures/rules/ITtscLintContributorRules.ts +20 -13
- package/src/structures/rules/ITtscLintCoreRuleOptions.ts +226 -24
- package/src/structures/rules/ITtscLintCoreRules.ts +92 -72
- package/src/structures/rules/ITtscLintCypressRuleOptions.ts +8 -1
- package/src/structures/rules/ITtscLintCypressRules.ts +24 -21
- package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +140 -24
- package/src/structures/rules/ITtscLintFunctionalRules.ts +20 -12
- package/src/structures/rules/ITtscLintJestRules.ts +22 -16
- package/src/structures/rules/ITtscLintJsdocRules.ts +5 -0
- package/src/structures/rules/ITtscLintJsxA11yRules.ts +24 -21
- package/src/structures/rules/ITtscLintNextjsRules.ts +40 -42
- package/src/structures/rules/ITtscLintPlaywrightRules.ts +24 -14
- package/src/structures/rules/ITtscLintPromiseRules.ts +23 -14
- package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +8 -1
- package/src/structures/rules/ITtscLintReactPerfRules.ts +18 -15
- package/src/structures/rules/ITtscLintReactRuleOptions.ts +14 -4
- package/src/structures/rules/ITtscLintReactRules.ts +33 -27
- package/src/structures/rules/ITtscLintRegexpRules.ts +18 -4
- package/src/structures/rules/ITtscLintRuleOptionsMap.ts +150 -15
- package/src/structures/rules/ITtscLintRules.ts +13 -9
- package/src/structures/rules/ITtscLintSecurityRules.ts +33 -23
- package/src/structures/rules/ITtscLintSolidRules.ts +57 -47
- package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +10 -2
- package/src/structures/rules/ITtscLintStorybookRules.ts +52 -62
- package/src/structures/rules/ITtscLintTanstackQueryRules.ts +34 -30
- package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +12 -3
- package/src/structures/rules/ITtscLintTestingLibraryRules.ts +20 -15
- package/src/structures/rules/ITtscLintTypeScriptRuleOptions.ts +116 -16
- package/src/structures/rules/ITtscLintTypeScriptRules.ts +62 -51
- package/src/structures/rules/ITtscLintUnicornRuleOptions.ts +241 -48
- package/src/structures/rules/ITtscLintUnicornRules.ts +97 -44
- package/src/structures/rules/ITtscLintVitestRules.ts +19 -11
- package/src/structures/rules/TtscLintContributorOverlay.ts +40 -0
- package/src/structures/rules/index.ts +1 -0
package/linthost/config.go
CHANGED
|
@@ -16,11 +16,21 @@ import (
|
|
|
16
16
|
"sort"
|
|
17
17
|
"strings"
|
|
18
18
|
"sync"
|
|
19
|
+
"time"
|
|
19
20
|
|
|
20
21
|
"github.com/samchon/ttsc/packages/ttsc/driver/windowsjunction"
|
|
21
22
|
)
|
|
22
23
|
|
|
23
24
|
// Severity is the `error | warning | off` ladder.
|
|
25
|
+
//
|
|
26
|
+
// @evidence contracts/common.md#principled-implementation Ordered constants represent disabled, warning and error states; unknown integers remain distinguishable through String.
|
|
27
|
+
// @evidence contracts/common.md#clear-and-simple-design One scalar severity keeps reporting policy independent from each rule's option shape.
|
|
28
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts The constants define the public severity ladder rather than consumer-specific outcomes.
|
|
29
|
+
// @evidence contracts/common.md#meaningful-documentation The native comment names the three supported states, with prose separated from acknowledgment tags.
|
|
30
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation Severity is a declaration of data shape and performs no filesystem, path or process operation.
|
|
31
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms Severity is a declaration of data shape and chooses no algorithm or processing strategy.
|
|
32
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work Severity is a declaration of data shape and coordinates no computation that could be shared.
|
|
33
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources Severity is a declaration of data shape; the code that holds its values owns their lifetime.
|
|
24
34
|
type Severity int
|
|
25
35
|
|
|
26
36
|
const (
|
|
@@ -29,6 +39,16 @@ const (
|
|
|
29
39
|
SeverityError
|
|
30
40
|
)
|
|
31
41
|
|
|
42
|
+
// String returns the configuration spelling, or "unknown" for an unsupported value.
|
|
43
|
+
//
|
|
44
|
+
// @evidence contracts/common.md#principled-implementation The exhaustive supported-state switch maps each severity to its config spelling without treating unknown integers as off.
|
|
45
|
+
// @evidence contracts/common.md#clear-and-simple-design A local switch owns the display mapping and requires no rule-specific formatter.
|
|
46
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Literal spellings are the severity protocol, not replacements for evaluated rule results.
|
|
47
|
+
// @evidence contracts/common.md#meaningful-documentation The native comment states both supported conversion and the unknown-value result in a separate paragraph from tags.
|
|
48
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation Severity.String performs no filesystem or process operation of its own.
|
|
49
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms Severity.String has no loop of its own and runs a fixed number of steps.
|
|
50
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work Severity.String keeps no cache and shares no in-flight computation.
|
|
51
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources Severity.String acquires no handle or task and retains nothing beyond the receiver's own fields.
|
|
32
52
|
func (s Severity) String() string {
|
|
33
53
|
switch s {
|
|
34
54
|
case SeverityError:
|
|
@@ -45,13 +65,39 @@ func (s Severity) String() string {
|
|
|
45
65
|
//
|
|
46
66
|
// `Config` carries the original tsconfig plugin entry. `Name` and `Stage`
|
|
47
67
|
// come from the JS plugin descriptor returned to the ttsc host.
|
|
68
|
+
//
|
|
69
|
+
// @evidence contracts/common.md#principled-implementation JSON field names match the compiler's serialized descriptor envelope while Config preserves arbitrary plugin-entry values for boundary validation.
|
|
70
|
+
// @evidence contracts/common.md#clear-and-simple-design The original entry and evaluated descriptor identity remain separate fields because they have different producers.
|
|
71
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts This DTO preserves host input and adds no plugin-specific execution or foreign mutation.
|
|
72
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose identifies each field's producer, and spaced field comments explain their roles without property acknowledgments.
|
|
73
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation PluginEntry is a declaration of data shape and performs no filesystem, path or process operation.
|
|
74
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms PluginEntry is a declaration of data shape and chooses no algorithm or processing strategy.
|
|
75
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work PluginEntry is a declaration of data shape and coordinates no computation that could be shared.
|
|
76
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources PluginEntry is a declaration of data shape; the code that holds its values owns their lifetime.
|
|
48
77
|
type PluginEntry struct {
|
|
78
|
+
// Config is the original tsconfig plugin entry, including configFile.
|
|
49
79
|
Config map[string]any `json:"config"`
|
|
50
|
-
|
|
51
|
-
|
|
80
|
+
|
|
81
|
+
// Name is the identity returned by the evaluated plugin descriptor.
|
|
82
|
+
Name string `json:"name"`
|
|
83
|
+
|
|
84
|
+
// Stage is the descriptor's host execution stage.
|
|
85
|
+
Stage string `json:"stage"`
|
|
52
86
|
}
|
|
53
87
|
|
|
54
88
|
// ParsePlugins decodes the `--plugins-json` payload.
|
|
89
|
+
// Empty or whitespace-only input means no entries; malformed JSON returns a contextual error.
|
|
90
|
+
// Parsing examines the supplied payload and allocates decoded records and their
|
|
91
|
+
// configuration values. The caller owns the returned records.
|
|
92
|
+
//
|
|
93
|
+
// @evidence contracts/common.md#principled-implementation encoding/json decodes the host envelope into PluginEntry records; the explicit empty-input case represents an absent descriptor list.
|
|
94
|
+
// @evidence contracts/common.md#clear-and-simple-design Parsing and contextual error wrapping form one boundary operation, leaving lint selection to FindLintEntry.
|
|
95
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts The absence case follows the host protocol and does not fabricate entries to satisfy a consumer.
|
|
96
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose states absence and malformed-input effects, with a blank comment line before tags.
|
|
97
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ParsePlugins performs no filesystem or process operation of its own.
|
|
98
|
+
// @evidence contracts/performance.md#efficient-algorithms Trimming, byte conversion and JSON decoding scale with payload size; decoded entries and configuration values determine result storage. One complete parse is necessary to validate and decode this supplied envelope without a second custom traversal.
|
|
99
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work ParsePlugins keeps no cache and shares no in-flight computation.
|
|
100
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources ParsePlugins owns no retained state, handle or running task; decoded records are transferred to the caller and temporary results from a failed parse are not retained.
|
|
55
101
|
func ParsePlugins(text string) ([]PluginEntry, error) {
|
|
56
102
|
if strings.TrimSpace(text) == "" {
|
|
57
103
|
return nil, nil
|
|
@@ -66,6 +112,16 @@ func ParsePlugins(text string) ([]PluginEntry, error) {
|
|
|
66
112
|
// FindLintEntry returns the active lint entry. ttsc orders check plugins before
|
|
67
113
|
// transform plugins before invoking native sidecars, so lint inspects authored
|
|
68
114
|
// source even when transform plugins are also configured.
|
|
115
|
+
// The returned pointer refers to the caller's slice; absence returns nil without an error.
|
|
116
|
+
//
|
|
117
|
+
// @evidence contracts/common.md#principled-implementation A declaration-order scan selects the descriptor with the public lint package identity and returns its actual record.
|
|
118
|
+
// @evidence contracts/common.md#clear-and-simple-design Selection uses the descriptor Name and leaves host staging and config evaluation with their existing owners.
|
|
119
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts The package identity is the supported descriptor protocol; no consumer or fixture name alters selection.
|
|
120
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains host ordering, alias ownership and the absent result, separated visibly from tags.
|
|
121
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation FindLintEntry compares plugin names and touches no filesystem path or process.
|
|
122
|
+
// @evidence contracts/performance.md#efficient-algorithms A linear scan that stops at the first @ttsc/lint entry, O(entries).
|
|
123
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work FindLintEntry keeps no cache and shares no computation.
|
|
124
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources FindLintEntry returns a pointer into the caller's slice and allocates nothing.
|
|
69
125
|
func FindLintEntry(entries []PluginEntry) (*PluginEntry, error) {
|
|
70
126
|
for i := range entries {
|
|
71
127
|
if entries[i].Name == "@ttsc/lint" {
|
|
@@ -77,53 +133,122 @@ func FindLintEntry(entries []PluginEntry) (*PluginEntry, error) {
|
|
|
77
133
|
|
|
78
134
|
// RuleConfig captures the resolved per-rule severity. The map is keyed by
|
|
79
135
|
// rule name (e.g. "no-var").
|
|
136
|
+
// ResolveProjectRules validates duplicate canonical identities before the engine
|
|
137
|
+
// reads this map. Direct metadata consumers must perform that validation first.
|
|
138
|
+
//
|
|
139
|
+
// @evidence contracts/common.md#principled-implementation A name-keyed map represents one severity per rule; ResolveProjectRules rejects colliding canonical identities before engine projections can detach severity from options.
|
|
140
|
+
// @evidence contracts/common.md#clear-and-simple-design The severity-only representation also implements RuleResolver without requiring option or file-scope storage.
|
|
141
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts The map represents supplied policy rather than cached diagnostics or expected outputs.
|
|
142
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose identifies the severity-only role and the validation prerequisite for direct metadata consumers.
|
|
143
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleConfig is a declaration of data shape and performs no filesystem, path or process operation.
|
|
144
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms RuleConfig is a declaration of data shape and chooses no algorithm or processing strategy.
|
|
145
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleConfig is a declaration of data shape and coordinates no computation that could be shared.
|
|
146
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleConfig is a declaration of data shape; the code that holds its values owns their lifetime.
|
|
80
147
|
type RuleConfig map[string]Severity
|
|
81
148
|
|
|
82
149
|
// RuleOptionsMap captures the rule-specific options payload, keyed by rule
|
|
83
150
|
// name. Severity-only rules never appear here. A single option slot preserves
|
|
84
151
|
// its JSON shape; multiple positional slots are encoded as an array. Each rule
|
|
85
152
|
// decodes the payload according to its public option type on demand.
|
|
153
|
+
//
|
|
154
|
+
// @evidence contracts/common.md#principled-implementation Raw JSON preserves each rule's option representation independently from severity storage; the owning rule interprets the payload and owns any option validation it supports.
|
|
155
|
+
// @evidence contracts/common.md#clear-and-simple-design A parallel name-keyed map keeps heterogeneous option types out of the engine-facing severity representation.
|
|
156
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Option payloads remain supplied configuration, with no hardcoded result or foreign decoder patch.
|
|
157
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains absent options and single-versus-multiple-slot encoding, then separates the acknowledgments.
|
|
158
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleOptionsMap is a declaration of data shape and performs no filesystem, path or process operation.
|
|
159
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms RuleOptionsMap is a declaration of data shape and chooses no algorithm or processing strategy.
|
|
160
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleOptionsMap is a declaration of data shape and coordinates no computation that could be shared.
|
|
161
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleOptionsMap is a declaration of data shape; the code that holds its values owns their lifetime.
|
|
86
162
|
type RuleOptionsMap map[string]json.RawMessage
|
|
87
163
|
|
|
88
164
|
// ProjectRuleSetting is the global declaration resolved for one registered
|
|
89
165
|
// project rule. Declared distinguishes a missing entry from an explicit off.
|
|
166
|
+
//
|
|
167
|
+
// @evidence contracts/common.md#principled-implementation An independent presence bit preserves the distinction between an absent project rule and an explicitly disabled rule.
|
|
168
|
+
// @evidence contracts/common.md#clear-and-simple-design Presence, severity and optional raw options form one resolved project setting without retaining file-specific scope.
|
|
169
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts The presence distinction models supported config semantics rather than inferring declaration from a severity default.
|
|
170
|
+
// @evidence contracts/common.md#meaningful-documentation The type and spaced member comments explain absence and payload meaning without property tags.
|
|
171
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ProjectRuleSetting is a declaration of data shape and performs no filesystem, path or process operation.
|
|
172
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms ProjectRuleSetting is a declaration of data shape and chooses no algorithm or processing strategy.
|
|
173
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work ProjectRuleSetting is a declaration of data shape and coordinates no computation that could be shared.
|
|
174
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources ProjectRuleSetting is a declaration of data shape; the code that holds its values owns their lifetime.
|
|
90
175
|
type ProjectRuleSetting struct {
|
|
176
|
+
// Declared reports whether a matching global entry explicitly named the rule.
|
|
91
177
|
Declared bool
|
|
178
|
+
|
|
179
|
+
// Severity is meaningful as a declaration only when Declared is true.
|
|
92
180
|
Severity Severity
|
|
93
|
-
|
|
181
|
+
|
|
182
|
+
// Options is the resolved raw payload, possibly inherited from an earlier
|
|
183
|
+
// global declaration. It is nil when no payload was contributed.
|
|
184
|
+
Options json.RawMessage
|
|
94
185
|
}
|
|
95
186
|
|
|
96
187
|
// ResolvedRuleConfig is the complete rule setting that applies to one source
|
|
97
|
-
// file. Rules and Options
|
|
98
|
-
//
|
|
99
|
-
//
|
|
188
|
+
// file. Built-in config-store resolution folds Rules and Options from the
|
|
189
|
+
// same matching entries. Custom resolvers must preserve that ownership rather
|
|
190
|
+
// than borrowing an option tuple from an entry outside the file's scope.
|
|
100
191
|
//
|
|
101
192
|
// `Ignored` means an `ignores`-only config entry matched the file and the
|
|
102
193
|
// engine should skip linting it entirely. `OutOfScope` means the store has at
|
|
103
194
|
// least one rule-bearing entry but none applies to this file. Keeping the two
|
|
104
195
|
// states distinct lets wrappers preserve entry-local ignores: one entry may
|
|
105
196
|
// reject a file while another matching entry still contributes rules.
|
|
197
|
+
//
|
|
198
|
+
// @evidence contracts/common.md#principled-implementation Paired severity and option maps carry the resolver's matching-entry policy without encoding one field into the other; separate ignored and out-of-scope states distinguish exclusion from no contributing declaration.
|
|
199
|
+
// @evidence contracts/common.md#clear-and-simple-design The value carries a single file's resolution with an explicit authority bit for compatibility with older custom resolvers.
|
|
200
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts OptionsResolved distinguishes a real interface capability instead of substituting an empty map for unresolved data.
|
|
201
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains scope and compatibility states; each public field has its own spaced comment and no checklist tag.
|
|
202
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ResolvedRuleConfig is a declaration of data shape and performs no filesystem, path or process operation.
|
|
203
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms ResolvedRuleConfig is a declaration of data shape and chooses no algorithm or processing strategy.
|
|
204
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work ResolvedRuleConfig is a declaration of data shape and coordinates no computation that could be shared.
|
|
205
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources ResolvedRuleConfig is a declaration of data shape; the code that holds its values owns their lifetime.
|
|
106
206
|
type ResolvedRuleConfig struct {
|
|
107
|
-
Rules
|
|
207
|
+
// Rules contains the severities contributed by matching entries.
|
|
208
|
+
Rules RuleConfig
|
|
209
|
+
|
|
210
|
+
// Options contains payloads inherited only through the same matching entries.
|
|
108
211
|
Options RuleOptionsMap
|
|
212
|
+
|
|
109
213
|
// OptionsResolved distinguishes an authoritative empty per-file option map
|
|
110
214
|
// from a legacy custom resolver that still supplies options exclusively via
|
|
111
215
|
// RuleResolver.RuleOptions.
|
|
112
216
|
OptionsResolved bool
|
|
113
|
-
|
|
114
|
-
|
|
217
|
+
|
|
218
|
+
// Ignored requests skipping this file entirely after a global ignore match.
|
|
219
|
+
Ignored bool
|
|
220
|
+
|
|
221
|
+
// OutOfScope reports that rule-bearing entries exist but none selects this file.
|
|
222
|
+
OutOfScope bool
|
|
115
223
|
}
|
|
116
224
|
|
|
117
225
|
// RuleOptions returns the file-resolved option payload for name. Built-in
|
|
118
226
|
// aliases are normalized on lookup so the same key selects both severity and
|
|
119
227
|
// options.
|
|
228
|
+
// The returned slice is the stored payload, so callers must treat it as read-only.
|
|
229
|
+
// The supplying resolver must reject colliding canonical keys before execution.
|
|
230
|
+
//
|
|
231
|
+
// @evidence contracts/common.md#principled-implementation Exact, canonical and unique normalized-alias lookup read the file's authoritative option map without falling back to another file's declaration.
|
|
232
|
+
// @evidence contracts/common.md#clear-and-simple-design Lookup remains on the resolved value so execution need not repeat config-entry folding.
|
|
233
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Namespace normalization follows the rule naming contract and does not select a payload by consumer identity.
|
|
234
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose states normalization, absence and borrowed slice ownership with tags in a separate comment paragraph.
|
|
235
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleOptions looks up option bytes by rule name and touches no filesystem path or process.
|
|
236
|
+
// @evidence contracts/performance.md#efficient-algorithms Exact and canonical keys use an expected constant number of map probes, with hashing and normalization proportional to query-name bytes. Only a miss scans n stored names, paying their normalization/comparison byte costs; option bytes are returned without decoding or copying.
|
|
237
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleOptions keeps no cache and shares no computation.
|
|
238
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleOptions returns the stored message without copying; the resolved configuration owns it.
|
|
120
239
|
func (r ResolvedRuleConfig) RuleOptions(name string) json.RawMessage {
|
|
121
240
|
if raw := r.Options[name]; len(raw) > 0 {
|
|
122
241
|
return raw
|
|
123
242
|
}
|
|
124
|
-
|
|
243
|
+
canonical := normalizeBuiltinRuleName(name)
|
|
244
|
+
if raw := r.Options[canonical]; len(raw) > 0 {
|
|
125
245
|
return raw
|
|
126
246
|
}
|
|
247
|
+
for storedName, raw := range r.Options {
|
|
248
|
+
if normalizeBuiltinRuleName(storedName) == canonical {
|
|
249
|
+
return raw
|
|
250
|
+
}
|
|
251
|
+
}
|
|
127
252
|
return nil
|
|
128
253
|
}
|
|
129
254
|
|
|
@@ -132,36 +257,115 @@ func (r ResolvedRuleConfig) RuleOptions(name string) json.RawMessage {
|
|
|
132
257
|
// InlineRuleResolver (a severity map plus per-rule options), and *ConfigStore
|
|
133
258
|
// (a parsed lint config file, with per-file glob resolution for both severity
|
|
134
259
|
// and options).
|
|
260
|
+
//
|
|
261
|
+
// @evidence contracts/common.md#principled-implementation Separate per-file and global operations express which config decisions have a file identity and which build dispatch or project state.
|
|
262
|
+
// @evidence contracts/common.md#clear-and-simple-design The interface exposes resolution behavior rather than parsed entries, allowing flat and scoped implementations to share the engine boundary.
|
|
263
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Compatibility lookup is an explicit supported interface method, not a patch of another resolver's internals.
|
|
264
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose names implementations and method comments describe scope, absence and precedence with blank lines between members.
|
|
265
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleResolver is a declaration of data shape and performs no filesystem, path or process operation.
|
|
266
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms RuleResolver is a declaration of data shape and chooses no algorithm or processing strategy.
|
|
267
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleResolver is a declaration of data shape and coordinates no computation that could be shared.
|
|
268
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleResolver is a declaration of data shape; the code that holds its values owns their lifetime.
|
|
135
269
|
type RuleResolver interface {
|
|
136
270
|
// ResolveRules returns the effective severities and option payloads for the
|
|
137
271
|
// given source file. Implementations that support `files`/`ignores`
|
|
138
272
|
// patterns apply both halves of each rule setting here; flat RuleConfig
|
|
139
|
-
//
|
|
273
|
+
// returns all severities with canonical built-in keys and no options.
|
|
274
|
+
//
|
|
275
|
+
// @evidence contracts/common.md#principled-implementation Returning severity and options together makes one file-selection decision authoritative for both parts of a setting.
|
|
276
|
+
// @evidence contracts/common.md#clear-and-simple-design One resolution call exposes the file-bound value without requiring engine access to entry storage.
|
|
277
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts The interface delegates scope through a supported method rather than probing concrete resolver internals.
|
|
278
|
+
// @evidence contracts/common.md#meaningful-documentation The native method comment explains flat versus scoped semantics before a separate tag paragraph.
|
|
279
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleResolver.ResolveRules is a method signature without a body; each implementation owns any filesystem or process behavior.
|
|
280
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms RuleResolver.ResolveRules is a method signature without a body; each implementation chooses its own algorithm.
|
|
281
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleResolver.ResolveRules is a method signature without a body; each implementation decides what, if anything, to share.
|
|
282
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleResolver.ResolveRules is a method signature without a body; each implementation owns any retained state.
|
|
140
283
|
ResolveRules(fileName string) ResolvedRuleConfig
|
|
284
|
+
|
|
141
285
|
// ActiveRuleNames returns the sorted names of every rule that is not SeverityOff
|
|
142
286
|
// in at least one config entry. Used to build the engine's dispatch table.
|
|
287
|
+
//
|
|
288
|
+
// @evidence contracts/common.md#principled-implementation The union of potentially enabled names lets dispatch construction retain rules that apply to only some files.
|
|
289
|
+
// @evidence contracts/common.md#clear-and-simple-design The method supplies ordered identities rather than exposing a second executable config model.
|
|
290
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts The activity definition follows declarations, not whether a known fixture produced a diagnostic.
|
|
291
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose states sorting, potential activity and the dispatch consumer with separated tags.
|
|
292
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleResolver.ActiveRuleNames is a method signature without a body; each implementation owns any filesystem or process behavior.
|
|
293
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms RuleResolver.ActiveRuleNames is a method signature without a body; each implementation chooses its own algorithm.
|
|
294
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleResolver.ActiveRuleNames is a method signature without a body; each implementation decides what, if anything, to share.
|
|
295
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleResolver.ActiveRuleNames is a method signature without a body; each implementation owns any retained state.
|
|
143
296
|
ActiveRuleNames() []string
|
|
297
|
+
|
|
144
298
|
// EnabledRuleConfig returns the project-wide severity map for rules that are
|
|
145
299
|
// not SeverityOff. Where multiple entries disagree, SeverityError wins.
|
|
300
|
+
//
|
|
301
|
+
// @evidence contracts/common.md#principled-implementation The aggregate severity map represents potential project reporting, while file execution remains owned by ResolveRules.
|
|
302
|
+
// @evidence contracts/common.md#clear-and-simple-design Global metadata has a named operation distinct from per-file resolution.
|
|
303
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Severity aggregation is an explicit interface policy rather than an inferred result from test outputs.
|
|
304
|
+
// @evidence contracts/common.md#meaningful-documentation The method comment states off filtering and error precedence in native prose before tags.
|
|
305
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleResolver.EnabledRuleConfig is a method signature without a body; each implementation owns any filesystem or process behavior.
|
|
306
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms RuleResolver.EnabledRuleConfig is a method signature without a body; each implementation chooses its own algorithm.
|
|
307
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleResolver.EnabledRuleConfig is a method signature without a body; each implementation decides what, if anything, to share.
|
|
308
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleResolver.EnabledRuleConfig is a method signature without a body; each implementation owns any retained state.
|
|
146
309
|
EnabledRuleConfig() RuleConfig
|
|
310
|
+
|
|
147
311
|
// RuleOptions is the file-agnostic compatibility lookup used by flat and
|
|
148
312
|
// metadata-only consumers. Runtime file binding reads
|
|
149
313
|
// ResolveRules(fileName).RuleOptions(name), which is authoritative for
|
|
150
314
|
// scoped resolvers. Returns nil for severity-only and unknown rules.
|
|
315
|
+
//
|
|
316
|
+
// @evidence contracts/common.md#principled-implementation This file-agnostic lookup supports older flat consumers without overriding authoritative per-file option resolution.
|
|
317
|
+
// @evidence contracts/common.md#clear-and-simple-design The compatibility boundary is visible as one method instead of hidden fallback state inside the engine.
|
|
318
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Retaining this method addresses supported resolver compatibility rather than compensating for a false scope assumption.
|
|
319
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose identifies the compatibility consumer and nil result, separate from the acknowledgment paragraph.
|
|
320
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleResolver.RuleOptions is a method signature without a body; each implementation owns any filesystem or process behavior.
|
|
321
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms RuleResolver.RuleOptions is a method signature without a body; each implementation chooses its own algorithm.
|
|
322
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleResolver.RuleOptions is a method signature without a body; each implementation decides what, if anything, to share.
|
|
323
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleResolver.RuleOptions is a method signature without a body; each implementation owns any retained state.
|
|
151
324
|
RuleOptions(name string) json.RawMessage
|
|
325
|
+
|
|
152
326
|
// ResolveProjectRules folds global declarations for registered project-rule
|
|
153
327
|
// names. A mention under a files selector is rejected because project state
|
|
154
328
|
// has no file identity, except when the same built-in name also owns a file
|
|
155
329
|
// rule; that scoped declaration remains exclusively file-local.
|
|
330
|
+
//
|
|
331
|
+
// @evidence contracts/common.md#principled-implementation Project settings have no file identity, so the operation rejects file-only declarations except a shared name whose file companion owns that scope.
|
|
332
|
+
// @evidence contracts/common.md#clear-and-simple-design A single project-resolution boundary owns global policy and errors before rule-state construction.
|
|
333
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts The built-in companion exception represents an actual dual registration, not a consumer-specific whitelist.
|
|
334
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains the scope rejection and companion distinction with a separate tag paragraph.
|
|
335
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleResolver.ResolveProjectRules is a method signature without a body; each implementation owns any filesystem or process behavior.
|
|
336
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms RuleResolver.ResolveProjectRules is a method signature without a body; each implementation chooses its own algorithm.
|
|
337
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleResolver.ResolveProjectRules is a method signature without a body; each implementation decides what, if anything, to share.
|
|
338
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleResolver.ResolveProjectRules is a method signature without a body; each implementation owns any retained state.
|
|
156
339
|
ResolveProjectRules(names []string) (map[string]ProjectRuleSetting, error)
|
|
157
340
|
}
|
|
158
341
|
|
|
159
342
|
// RuleOptionsVariantsResolver is an optional extension for resolvers that can
|
|
160
|
-
//
|
|
161
|
-
//
|
|
343
|
+
// expose more than one option payload a rule may receive. Engine construction
|
|
344
|
+
// checks each distinct payload through the rule's supported option-validation
|
|
345
|
+
// capability before any file is visited. Scoped resolvers expose declarations;
|
|
346
|
+
// command adapters may substitute reachable defaults for absent payloads.
|
|
162
347
|
// Custom resolvers that omit this interface remain compatible through the
|
|
163
348
|
// single RuleResolver.RuleOptions fallback.
|
|
349
|
+
//
|
|
350
|
+
// @evidence contracts/common.md#principled-implementation Optional structural interface satisfaction exposes the option variants reachable through each resolver's policy without requiring every existing resolver to implement it.
|
|
351
|
+
// @evidence contracts/common.md#clear-and-simple-design One capability method extends validation independently from the required engine resolver interface.
|
|
352
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Go interface assertion uses a supported extension boundary, not foreign method replacement.
|
|
353
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains supported eager checks, scoped declarations, command defaults and legacy fallback before tags; the member documents returned ownership.
|
|
354
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleOptionsVariantsResolver is a declaration of data shape and performs no filesystem, path or process operation.
|
|
355
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms RuleOptionsVariantsResolver is a declaration of data shape and chooses no algorithm or processing strategy.
|
|
356
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleOptionsVariantsResolver is a declaration of data shape and coordinates no computation that could be shared.
|
|
357
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleOptionsVariantsResolver is a declaration of data shape; the code that holds its values owns their lifetime.
|
|
164
358
|
type RuleOptionsVariantsResolver interface {
|
|
359
|
+
// RuleOptionsVariants returns independently owned payloads name may receive.
|
|
360
|
+
//
|
|
361
|
+
// @evidence contracts/common.md#principled-implementation Enumerating resolver-policy variants permits eager checks of scoped tuples and reachable command defaults before any file execution.
|
|
362
|
+
// @evidence contracts/common.md#clear-and-simple-design The operation returns raw payloads for the existing rule decoder rather than adding another option schema.
|
|
363
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Variant discovery follows declarations and does not manufacture payloads to match observed diagnostics.
|
|
364
|
+
// @evidence contracts/common.md#meaningful-documentation Native member prose states population and slice ownership separately from tags.
|
|
365
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleOptionsVariantsResolver.RuleOptionsVariants is a method signature without a body; each implementation owns any filesystem or process behavior.
|
|
366
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms RuleOptionsVariantsResolver.RuleOptionsVariants is a method signature without a body; each implementation chooses its own algorithm.
|
|
367
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleOptionsVariantsResolver.RuleOptionsVariants is a method signature without a body; each implementation decides what, if anything, to share.
|
|
368
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleOptionsVariantsResolver.RuleOptionsVariants is a method signature without a body; each implementation owns any retained state.
|
|
165
369
|
RuleOptionsVariants(name string) []json.RawMessage
|
|
166
370
|
}
|
|
167
371
|
|
|
@@ -183,6 +387,7 @@ func resolvedRuleOptionsVariants(resolver RuleResolver, name string) []json.RawM
|
|
|
183
387
|
type boundProjectRuleResolver struct {
|
|
184
388
|
RuleResolver
|
|
185
389
|
settings map[string]ProjectRuleSetting
|
|
390
|
+
patterns *userPatternCache
|
|
186
391
|
}
|
|
187
392
|
|
|
188
393
|
func bindProjectRuleResolver(resolver RuleResolver) (RuleResolver, error) {
|
|
@@ -193,7 +398,11 @@ func bindProjectRuleResolver(resolver RuleResolver) (RuleResolver, error) {
|
|
|
193
398
|
if err != nil {
|
|
194
399
|
return nil, err
|
|
195
400
|
}
|
|
196
|
-
return boundProjectRuleResolver{
|
|
401
|
+
return boundProjectRuleResolver{
|
|
402
|
+
RuleResolver: resolver,
|
|
403
|
+
settings: settings,
|
|
404
|
+
patterns: patternCacheForResolver(resolver),
|
|
405
|
+
}, nil
|
|
197
406
|
}
|
|
198
407
|
|
|
199
408
|
func (r boundProjectRuleResolver) ResolveProjectRules(names []string) (map[string]ProjectRuleSetting, error) {
|
|
@@ -237,7 +446,17 @@ func (r boundProjectRuleResolver) residentRuleConfigState() residentRuleConfigSt
|
|
|
237
446
|
}
|
|
238
447
|
|
|
239
448
|
// ResolveRules implements RuleResolver. A flat RuleConfig has no glob scoping,
|
|
240
|
-
// so every file receives the full map
|
|
449
|
+
// so every file receives the full map with canonical built-in names.
|
|
450
|
+
// Call ResolveProjectRules first to reject colliding canonical identities.
|
|
451
|
+
//
|
|
452
|
+
// @evidence contracts/common.md#principled-implementation After project-boundary identity validation, canonicalizing the severity map gives every file the same global policy and marks the absence of options as authoritative.
|
|
453
|
+
// @evidence contracts/common.md#clear-and-simple-design A flat adapter constructs one resolved value and delegates key policy to the shared normalization helper.
|
|
454
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts No file name or diagnostic result changes the global map; normalization only implements supported rule aliases.
|
|
455
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains flat scope, normalization and prerequisite identity validation before separate tags.
|
|
456
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleConfig.ResolveRules performs no filesystem or process operation of its own.
|
|
457
|
+
// @evidence contracts/performance.md#efficient-algorithms Canonicalization scans n severity entries into a new map, requiring O(n) map operations plus name normalization/hashing bytes and O(n) result entries. Empty maps are returned without rebuilding.
|
|
458
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This stateless projection reads a caller-owned map for one call; it owns no cross-call identity or invalidation protocol for sharing projections after caller mutations.
|
|
459
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources No handle, task or historical state is retained. The caller owns the nonempty canonical map returned by this projection; an empty receiver may be reused.
|
|
241
460
|
func (c RuleConfig) ResolveRules(string) ResolvedRuleConfig {
|
|
242
461
|
return ResolvedRuleConfig{
|
|
243
462
|
Rules: normalizeRuleConfigKeys(c),
|
|
@@ -247,12 +466,30 @@ func (c RuleConfig) ResolveRules(string) ResolvedRuleConfig {
|
|
|
247
466
|
|
|
248
467
|
// ActiveRuleNames implements RuleResolver. Returns rule names whose severity
|
|
249
468
|
// is not SeverityOff, sorted for deterministic engine dispatch-table construction.
|
|
469
|
+
//
|
|
470
|
+
// @evidence contracts/common.md#principled-implementation Normalization followed by non-off filtering and sorting produces the potential dispatch identities under the no-duplicate-alias premise.
|
|
471
|
+
// @evidence contracts/common.md#clear-and-simple-design Shared key normalization and name sorting keep identity policy outside the dispatch consumer.
|
|
472
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Enabled names come from declared severities, without fixture-specific activation.
|
|
473
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains off filtering and deterministic order, with a separate acknowledgment paragraph.
|
|
474
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleConfig.ActiveRuleNames performs no filesystem or process operation of its own.
|
|
475
|
+
// @evidence contracts/performance.md#efficient-algorithms Normalization and filtering scan n entries, then sort k active names: O(n+k log k) name operations plus normalization, hashing and comparison bytes. The temporary normalized map and returned slice reserve O(n) entries.
|
|
476
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This stateless projection reads current caller-owned severities and owns no cross-call identity or invalidation protocol for sharing results after caller mutations.
|
|
477
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources No handle, task or historical state is retained; the normalized temporary map is local and the caller owns the returned name slice.
|
|
250
478
|
func (c RuleConfig) ActiveRuleNames() []string {
|
|
251
479
|
return sortedRuleNames(normalizeRuleConfigKeys(c), func(sev Severity) bool { return sev != SeverityOff })
|
|
252
480
|
}
|
|
253
481
|
|
|
254
482
|
// EnabledRuleConfig implements RuleResolver. Returns a copy containing only the
|
|
255
483
|
// non-off entries; used to populate engine state and diagnostic reporting.
|
|
484
|
+
//
|
|
485
|
+
// @evidence contracts/common.md#principled-implementation A fresh canonical-key map retains each non-off global severity; direct maps must avoid colliding aliases.
|
|
486
|
+
// @evidence contracts/common.md#clear-and-simple-design One map projection supplies metadata without mutating the caller's severity map.
|
|
487
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Filtering follows the explicit disabled state rather than recorded diagnostics or consumer identities.
|
|
488
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose states copy ownership, filtering and the metadata consumer before separated tags.
|
|
489
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation EnabledRuleConfig filters rule severities and touches no filesystem path or process.
|
|
490
|
+
// @evidence contracts/performance.md#efficient-algorithms One pass over n severity entries writes k non-off canonical keys, O(n) entry operations plus name normalization/hashing bytes and O(k) returned entries.
|
|
491
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This call projects current caller-owned severities and owns no cross-call mutation identity for sharing results after caller changes.
|
|
492
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The returned map is new and owned by the caller; no handle or task is acquired.
|
|
256
493
|
func (c RuleConfig) EnabledRuleConfig() RuleConfig {
|
|
257
494
|
out := RuleConfig{}
|
|
258
495
|
for name, sev := range c {
|
|
@@ -263,13 +500,34 @@ func (c RuleConfig) EnabledRuleConfig() RuleConfig {
|
|
|
263
500
|
return out
|
|
264
501
|
}
|
|
265
502
|
|
|
266
|
-
// RuleOptions on a bare RuleConfig is always nil
|
|
267
|
-
//
|
|
268
|
-
//
|
|
503
|
+
// RuleOptions on a bare RuleConfig is always nil because this representation
|
|
504
|
+
// contains severities only. Use InlineRuleResolver for supplied option payloads.
|
|
505
|
+
//
|
|
506
|
+
// @evidence contracts/common.md#principled-implementation Returning nil expresses the absence of option storage in a severity-only map.
|
|
507
|
+
// @evidence contracts/common.md#clear-and-simple-design The method adapts the existing flat representation without allocating unused option maps.
|
|
508
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts The empty result follows the representation's production contract rather than a test-only execution path.
|
|
509
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains absence and the option-bearing alternative with a blank line before tags.
|
|
510
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleConfig.RuleOptions performs no filesystem or process operation of its own.
|
|
511
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms RuleConfig.RuleOptions has no loop of its own and runs a fixed number of steps.
|
|
512
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleConfig.RuleOptions keeps no cache and shares no in-flight computation.
|
|
513
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleConfig.RuleOptions acquires no handle or task and retains nothing beyond the receiver's own fields.
|
|
269
514
|
func (RuleConfig) RuleOptions(string) json.RawMessage { return nil }
|
|
270
515
|
|
|
271
516
|
// ResolveProjectRules treats a flat RuleConfig as one global declaration.
|
|
517
|
+
// It rejects distinct keys for the same canonical rule even when their values agree.
|
|
518
|
+
//
|
|
519
|
+
// @evidence contracts/common.md#principled-implementation Whole-map identity validation rejects alias collisions before canonical lookup; membership remains independent from severity, so explicit off stays declared.
|
|
520
|
+
// @evidence contracts/common.md#clear-and-simple-design Requested project names are projected from one normalized flat map without introducing file scope.
|
|
521
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Alias collisions return an error rather than arbitrary iteration-order precedence; missing names remain absent rather than fabricated defaults.
|
|
522
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose states global interpretation; ProjectRuleSetting documents absence and option meaning used by the return value.
|
|
523
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ResolveProjectRules reads rule names and severities and touches no filesystem path or process.
|
|
524
|
+
// @evidence contracts/performance.md#efficient-algorithms Validation sorts n stored names, then normalization and p requested lookups require O(n log n+p) name operations plus normalization, hashing and comparison bytes. Temporary maps/name lists scale with n and the result map with p.
|
|
525
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This call validates and projects current caller-owned severities; it owns no cross-call mutation identity. The native loadRules boundary separately binds one project resolution for reuse during engine construction.
|
|
526
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The returned map is new and owned by the caller; no handle or task is acquired.
|
|
272
527
|
func (c RuleConfig) ResolveProjectRules(names []string) (map[string]ProjectRuleSetting, error) {
|
|
528
|
+
if err := validateCanonicalRuleNames(c); err != nil {
|
|
529
|
+
return nil, err
|
|
530
|
+
}
|
|
273
531
|
normalized := normalizeRuleConfigKeys(c)
|
|
274
532
|
out := make(map[string]ProjectRuleSetting, len(names))
|
|
275
533
|
for _, name := range names {
|
|
@@ -290,16 +548,61 @@ func normalizeRuleConfigKeys(c RuleConfig) RuleConfig {
|
|
|
290
548
|
return out
|
|
291
549
|
}
|
|
292
550
|
|
|
293
|
-
//
|
|
294
|
-
//
|
|
295
|
-
//
|
|
551
|
+
// validateCanonicalRuleNames rejects distinct spellings of the same rule in
|
|
552
|
+
// one map before canonicalization can detach a severity from its option tuple.
|
|
553
|
+
// Sorting only the keys makes the reported conflicting pair deterministic.
|
|
554
|
+
func validateCanonicalRuleNames[V any](entries map[string]V) error {
|
|
555
|
+
names := make([]string, 0, len(entries))
|
|
556
|
+
for name := range entries {
|
|
557
|
+
names = append(names, name)
|
|
558
|
+
}
|
|
559
|
+
sort.Strings(names)
|
|
560
|
+
seen := make(map[string]string, len(names))
|
|
561
|
+
for _, name := range names {
|
|
562
|
+
canonical := normalizeBuiltinRuleName(name)
|
|
563
|
+
if previous, duplicate := seen[canonical]; duplicate {
|
|
564
|
+
return fmt.Errorf(
|
|
565
|
+
"@ttsc/lint: rule keys %q and %q both resolve to %q; declare each rule once",
|
|
566
|
+
previous, name, canonical,
|
|
567
|
+
)
|
|
568
|
+
}
|
|
569
|
+
seen[canonical] = name
|
|
570
|
+
}
|
|
571
|
+
return nil
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// InlineRuleResolver pairs global severities with raw option payloads.
|
|
575
|
+
// Callers may construct it directly for an already-resolved flat configuration;
|
|
576
|
+
// ResolveProjectRules validates both maps before engine use or direct metadata
|
|
577
|
+
// projection; alias duplicates are rejected even when their payloads agree.
|
|
578
|
+
//
|
|
579
|
+
// @evidence contracts/common.md#principled-implementation Parallel maps represent global identities with distinct severity and payload types; project-boundary validation rejects duplicate canonical identities in either map before engine projection.
|
|
580
|
+
// @evidence contracts/common.md#clear-and-simple-design The flat resolver adds options to RuleConfig without carrying unused file-pattern or extends state.
|
|
581
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Public construction supports engine integrations and is not a special path for tests.
|
|
582
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains direct construction, required validation and ownership with spaced member comments and no property tags.
|
|
583
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation InlineRuleResolver is a declaration of data shape and performs no filesystem, path or process operation.
|
|
584
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms InlineRuleResolver is a declaration of data shape and chooses no algorithm or processing strategy.
|
|
585
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work InlineRuleResolver is a declaration of data shape and coordinates no computation that could be shared.
|
|
586
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources InlineRuleResolver is a declaration of data shape; the code that holds its values owns their lifetime.
|
|
296
587
|
type InlineRuleResolver struct {
|
|
297
|
-
Rules
|
|
588
|
+
// Rules supplies global severities and remains owned by the caller.
|
|
589
|
+
Rules RuleConfig
|
|
590
|
+
|
|
591
|
+
// Options supplies global raw JSON payloads; callers must not mutate them during use.
|
|
298
592
|
Options RuleOptionsMap
|
|
299
593
|
}
|
|
300
594
|
|
|
301
595
|
// ResolveRules implements RuleResolver. Inline rules have no glob scoping;
|
|
302
596
|
// the full map applies to every file.
|
|
597
|
+
//
|
|
598
|
+
// @evidence contracts/common.md#principled-implementation Shared canonicalization projects both maps into an authoritative global resolution, copying raw option bytes and requiring nonconflicting aliases.
|
|
599
|
+
// @evidence contracts/common.md#clear-and-simple-design The adapter delegates map policy to existing helpers and avoids recreating file-scoping logic.
|
|
600
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Every file uses supplied global policy, with no source-name special cases or diagnostic-driven defaults.
|
|
601
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose states global scope; the owning type documents input ownership and alias assumptions before its tags.
|
|
602
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation InlineRuleResolver.ResolveRules performs no filesystem or process operation of its own.
|
|
603
|
+
// @evidence contracts/performance.md#efficient-algorithms Both maps are normalized in one pass each over n severity and m option entries, plus name normalization/hashing and b copied payload bytes. Result storage scales with n+m+b; empty option storage stays nil and an empty severity map may be reused.
|
|
604
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This call projects current caller-owned maps and owns no cross-call identity or invalidation protocol for sharing results after caller mutations.
|
|
605
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources No handle, task or historical state is retained. Nonempty normalized maps and copied option bytes are transferred to the caller; an empty severity receiver may remain shared.
|
|
303
606
|
func (r InlineRuleResolver) ResolveRules(string) ResolvedRuleConfig {
|
|
304
607
|
return ResolvedRuleConfig{
|
|
305
608
|
Rules: normalizeRuleConfigKeys(r.Rules),
|
|
@@ -320,11 +623,29 @@ func normalizeRuleOptionsKeys(options RuleOptionsMap) RuleOptionsMap {
|
|
|
320
623
|
}
|
|
321
624
|
|
|
322
625
|
// ActiveRuleNames implements RuleResolver by delegating to the inner RuleConfig.
|
|
626
|
+
//
|
|
627
|
+
// @evidence contracts/common.md#principled-implementation Delegation preserves the severity map's non-off, canonical and sorted dispatch-name policy.
|
|
628
|
+
// @evidence contracts/common.md#clear-and-simple-design The wrapper reuses the severity owner instead of duplicating activity selection beside the options map.
|
|
629
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Option presence does not fabricate activity for a rule disabled by supplied severity.
|
|
630
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose identifies the policy owner; RuleConfig documents filtering and sorting, and tags remain separate.
|
|
631
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation InlineRuleResolver.ActiveRuleNames performs no filesystem or process operation of its own.
|
|
632
|
+
// @evidence contracts/performance.md#efficient-algorithms Delegation normalizes and filters n severity entries, then sorts k active names, O(n+k log k) name operations plus name bytes. The normalized temporary map and returned slice reserve O(n) entries; options are not traversed.
|
|
633
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work Activity is a projection of the caller's current severity map, not a shared producer with a cross-call mutation identity.
|
|
634
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources Delegation returns a caller-owned name slice and retains no historical state, handle or task in this wrapper.
|
|
323
635
|
func (r InlineRuleResolver) ActiveRuleNames() []string {
|
|
324
636
|
return r.Rules.ActiveRuleNames()
|
|
325
637
|
}
|
|
326
638
|
|
|
327
639
|
// EnabledRuleConfig implements RuleResolver by delegating to the inner RuleConfig.
|
|
640
|
+
//
|
|
641
|
+
// @evidence contracts/common.md#principled-implementation Delegating to Rules preserves the non-off global severity projection regardless of optional payload presence.
|
|
642
|
+
// @evidence contracts/common.md#clear-and-simple-design Severity aggregation has one implementation and the wrapper adds no redundant map state.
|
|
643
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Options cannot activate a disabled rule through a compatibility exception.
|
|
644
|
+
// @evidence contracts/common.md#meaningful-documentation The native delegation comment makes the behavior owner apparent, with a blank comment line before tags.
|
|
645
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation InlineRuleResolver.EnabledRuleConfig performs no filesystem or process operation of its own.
|
|
646
|
+
// @evidence contracts/performance.md#efficient-algorithms Delegation scans n severity entries and writes k non-off canonical keys, O(n) entry operations plus normalization/hashing bytes and O(k) returned entries. The options map is not inspected.
|
|
647
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This call projects current caller-owned severities; the wrapper does not coordinate a shared result or cross-call mutation identity.
|
|
648
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources Delegation returns a new caller-owned severity map and retains no historical state, handle or task in this wrapper.
|
|
328
649
|
func (r InlineRuleResolver) EnabledRuleConfig() RuleConfig {
|
|
329
650
|
return r.Rules.EnabledRuleConfig()
|
|
330
651
|
}
|
|
@@ -332,6 +653,16 @@ func (r InlineRuleResolver) EnabledRuleConfig() RuleConfig {
|
|
|
332
653
|
// RuleOptions implements RuleResolver. Returns the raw JSON options blob for
|
|
333
654
|
// `name`, or nil when the rule was configured without options or the name is
|
|
334
655
|
// unknown.
|
|
656
|
+
// The returned slice is borrowed from Options and must remain read-only.
|
|
657
|
+
//
|
|
658
|
+
// @evidence contracts/common.md#principled-implementation Exact, canonical and unique normalized-alias lookup return only the supplied global payload and preserve nil for missing option storage after identity validation.
|
|
659
|
+
// @evidence contracts/common.md#clear-and-simple-design One lookup method adapts the options map without merging or decoding rule-specific payloads.
|
|
660
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Alias normalization is supported naming policy and does not select options from expected diagnostics.
|
|
661
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains nil results and borrowed byte ownership before separated tags.
|
|
662
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleOptions looks up option bytes by rule name and touches no filesystem path or process.
|
|
663
|
+
// @evidence contracts/performance.md#efficient-algorithms Exact and canonical keys use an expected constant number of map probes, with hashing and normalization proportional to query-name bytes. Only a miss scans n stored names, paying their normalization/comparison byte costs; option bytes are borrowed without decoding or copying.
|
|
664
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleOptions keeps no cache and shares no computation.
|
|
665
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources RuleOptions returns the stored message without copying; the resolver owns it.
|
|
335
666
|
func (r InlineRuleResolver) RuleOptions(name string) json.RawMessage {
|
|
336
667
|
if r.Options == nil {
|
|
337
668
|
return nil
|
|
@@ -343,13 +674,34 @@ func (r InlineRuleResolver) RuleOptions(name string) json.RawMessage {
|
|
|
343
674
|
if raw := r.Options[canonical]; len(raw) > 0 {
|
|
344
675
|
return raw
|
|
345
676
|
}
|
|
677
|
+
for storedName, raw := range r.Options {
|
|
678
|
+
if normalizeBuiltinRuleName(storedName) == canonical {
|
|
679
|
+
return raw
|
|
680
|
+
}
|
|
681
|
+
}
|
|
346
682
|
return nil
|
|
347
683
|
}
|
|
348
684
|
|
|
349
685
|
// ResolveProjectRules treats inline rules as global and preserves their
|
|
350
686
|
// explicit options tuple.
|
|
687
|
+
// Both maps are validated for duplicate canonical identities before any setting folds.
|
|
688
|
+
//
|
|
689
|
+
// @evidence contracts/common.md#principled-implementation Both maps reject canonical identity collisions before severity declaration bits and defensive payload copies are folded into requested global settings.
|
|
690
|
+
// @evidence contracts/common.md#clear-and-simple-design Severity resolution is reused and only the option-bearing part is added by this wrapper.
|
|
691
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts The global adapter introduces no file-dependent project state or special consumer branch.
|
|
692
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose states global interpretation and tuple preservation, with acknowledgments in a separate paragraph.
|
|
693
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ResolveProjectRules reads rule names, severities and option bytes and touches no filesystem path or process.
|
|
694
|
+
// @evidence contracts/performance.md#efficient-algorithms Validation sorts n severity names and m option names before p requested lookups. Exact/canonical option keys need one lookup and fallback can scan m names per request, giving O(n log n+m log m+p(1+m)) name operations in the worst case plus name bytes and copied payload bytes. Temporary/result containers scale with n+m+p and returned payload size.
|
|
695
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This call validates and projects current caller-owned maps; it owns no cross-call mutation identity. The native loadRules boundary separately binds one project resolution for reuse during engine construction.
|
|
696
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources Each option message is copied into the returned settings so they do not alias resolver memory; no handle or task is acquired.
|
|
351
697
|
func (r InlineRuleResolver) ResolveProjectRules(names []string) (map[string]ProjectRuleSetting, error) {
|
|
352
|
-
|
|
698
|
+
if err := validateCanonicalRuleNames(r.Options); err != nil {
|
|
699
|
+
return nil, err
|
|
700
|
+
}
|
|
701
|
+
settings, err := r.Rules.ResolveProjectRules(names)
|
|
702
|
+
if err != nil {
|
|
703
|
+
return nil, err
|
|
704
|
+
}
|
|
353
705
|
for _, name := range names {
|
|
354
706
|
setting := settings[name]
|
|
355
707
|
setting.Options = append(json.RawMessage(nil), r.RuleOptions(name)...)
|
|
@@ -367,10 +719,24 @@ func (r InlineRuleResolver) ResolveProjectRules(names []string) (map[string]Proj
|
|
|
367
719
|
// https://eslint.org/docs/latest/use/configure/rules#using-configuration-files
|
|
368
720
|
//
|
|
369
721
|
// A config file is a single `ITtscLintConfig` object. Its `extends` field
|
|
370
|
-
// names another config file to fold in first
|
|
371
|
-
//
|
|
372
|
-
// extending file's
|
|
722
|
+
// names another config file to fold in first. A file may contribute a
|
|
723
|
+
// global-ignore entry and a scoped rule entry, or no entry when it has neither.
|
|
724
|
+
// Extends-target entries precede the extending file's entries so local rules
|
|
725
|
+
// win on collision; format settings join the same scoped rule entry.
|
|
726
|
+
// Duplicate aliases within one rules object are rejected before entries are stored.
|
|
727
|
+
// Parsed stores share an option-regex cache through a pointer, so read-only
|
|
728
|
+
// value copies preserve reuse without copying synchronization state.
|
|
729
|
+
//
|
|
730
|
+
// @evidence contracts/common.md#principled-implementation Ordered entries preserve extends precedence and matching-file ownership of severities and options; global-ignore entries distinguish whole-file exclusion from local selection.
|
|
731
|
+
// @evidence contracts/common.md#clear-and-simple-design Parsed entries are the policy source of truth, while paths and fingerprints separately carry watch and resident-cache provenance.
|
|
732
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Compatibility option lookup derives from entries rather than a second flattened state; the parser rejects duplicate canonical identities instead of choosing map-order precedence.
|
|
733
|
+
// @evidence contracts/common.md#meaningful-documentation Native paragraphs explain matching, inheritance, ignores and alias limits; public methods document copy ownership and metadata-only semantics.
|
|
734
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ConfigStore is a declaration of data shape and performs no filesystem, path or process operation.
|
|
735
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms ConfigStore is a declaration of data shape and chooses no algorithm or processing strategy.
|
|
736
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work ConfigStore is a declaration of data shape and coordinates no computation that could be shared.
|
|
737
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources ConfigStore is a declaration of data shape; the code that holds its values owns their lifetime.
|
|
373
738
|
type ConfigStore struct {
|
|
739
|
+
patterns *userPatternCache
|
|
374
740
|
cacheDependencies []configDependencyFingerprint
|
|
375
741
|
cacheFiles []string
|
|
376
742
|
directories []string
|
|
@@ -379,9 +745,20 @@ type ConfigStore struct {
|
|
|
379
745
|
resolutionRoot string
|
|
380
746
|
}
|
|
381
747
|
|
|
382
|
-
// ConfigPaths returns the config
|
|
748
|
+
// ConfigPaths returns the config, extends and evaluated public dependency files
|
|
749
|
+
// that produced this store. Private resident-cache fingerprints remain separate.
|
|
383
750
|
// The paths are retained as exact dependencies even when no rule declares
|
|
384
751
|
// additional project inputs.
|
|
752
|
+
// The returned slice is a copy, so callers can change its membership.
|
|
753
|
+
//
|
|
754
|
+
// @evidence contracts/common.md#principled-implementation Copying the stored path slice preserves config provenance while preventing callers from changing store membership.
|
|
755
|
+
// @evidence contracts/common.md#clear-and-simple-design Watch-input exposure is separate from entry resolution and private executable-cache fingerprints.
|
|
756
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Paths come from actual config evaluation and inheritance, not a fixture-specific watch list.
|
|
757
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains retained provenance and defensive slice ownership with separated tags.
|
|
758
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ConfigPaths returns config path strings the store already holds; it opens no file and compares no path.
|
|
759
|
+
// @evidence contracts/performance.md#efficient-algorithms One slice copy, O(paths).
|
|
760
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work ConfigPaths keeps no cache and shares no computation.
|
|
761
|
+
// @evidence contracts/performance.md#bound-retention-and-release-resources The store retains its path list for its own lifetime and ConfigPaths returns a copy, so a caller cannot mutate or extend the retained slice.
|
|
385
762
|
func (s *ConfigStore) ConfigPaths() []string {
|
|
386
763
|
if s == nil {
|
|
387
764
|
return nil
|
|
@@ -392,6 +769,16 @@ func (s *ConfigStore) ConfigPaths() []string {
|
|
|
392
769
|
// ConfigDirectories returns resolution-topology directories whose immediate
|
|
393
770
|
// entries can change which executable-config module Node selects. Consumers
|
|
394
771
|
// watch these as cold configuration inputs rather than ordinary rule data.
|
|
772
|
+
// The returned slice is a copy; a nil store has no directory inputs.
|
|
773
|
+
//
|
|
774
|
+
// @evidence contracts/common.md#principled-implementation Exposing copied topology directories permits consumers to observe resolution changes without mutating store state.
|
|
775
|
+
// @evidence contracts/common.md#clear-and-simple-design Module-selection inputs have a distinct accessor because they are not source files or rule data.
|
|
776
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Directories are tracked resolver inputs rather than assumed fixed Node search locations.
|
|
777
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains topology relevance, nil behavior and copy ownership before tags.
|
|
778
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ConfigDirectories returns directory strings the store already holds; it opens no file and compares no path.
|
|
779
|
+
// @evidence contracts/performance.md#efficient-algorithms One slice copy, O(directories).
|
|
780
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work ConfigDirectories keeps no cache and shares no computation.
|
|
781
|
+
// @evidence contracts/performance.md#bound-retention-and-release-resources The store retains its directory list for its own lifetime and ConfigDirectories returns a copy, so a caller cannot mutate or extend the retained slice.
|
|
395
782
|
func (s *ConfigStore) ConfigDirectories() []string {
|
|
396
783
|
if s == nil {
|
|
397
784
|
return nil
|
|
@@ -403,7 +790,8 @@ func (s *ConfigStore) ConfigDirectories() []string {
|
|
|
403
790
|
// that produced this store. Executable configs retain their complete dependency
|
|
404
791
|
// fingerprints, including package implementation files that must invalidate a
|
|
405
792
|
// resident answer without becoming public project-watch inputs. JSON configs
|
|
406
|
-
// retain
|
|
793
|
+
// retain the actual raw-byte fingerprint captured by their decoding read; no
|
|
794
|
+
// later hash substitutes for the consumed input.
|
|
407
795
|
func (s *ConfigStore) residentRuleConfigState() residentRuleConfigState {
|
|
408
796
|
if s == nil {
|
|
409
797
|
return residentRuleConfigState{}
|
|
@@ -424,6 +812,16 @@ func (s *ConfigStore) residentRuleConfigState() residentRuleConfigState {
|
|
|
424
812
|
// carries the matching file's options. Callers that only understand the older
|
|
425
813
|
// interface observe the final declared tuple, preserving the former flat
|
|
426
814
|
// resolver behavior without storing a second source of truth.
|
|
815
|
+
// The returned bytes are copied and remain independent of the stored payload.
|
|
816
|
+
//
|
|
817
|
+
// @evidence contracts/common.md#principled-implementation Declaration-order traversal selects the final explicit tuple for metadata compatibility without claiming that it applies to a particular file.
|
|
818
|
+
// @evidence contracts/common.md#clear-and-simple-design The representative payload is derived from entries instead of maintained in a duplicate flattened option map.
|
|
819
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts The fallback exists for supported file-agnostic consumers and cannot override ResolveRules execution scope.
|
|
820
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose distinguishes metadata compatibility from file execution and documents copied ownership with separated tags.
|
|
821
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleOptions selects option bytes by rule name and touches no filesystem path or process.
|
|
822
|
+
// @evidence contracts/performance.md#efficient-algorithms Normalize the input name, then scan entries for its last nonempty payload and copy the winner; work includes name normalization and hashing plus O(entries + winning payload bytes), with output storage proportional to the copied payload.
|
|
823
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work RuleOptions keeps no cache; every call reads the store's entries.
|
|
824
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The winning message is copied so the caller cannot mutate store memory; no handle or task is acquired.
|
|
427
825
|
func (s *ConfigStore) RuleOptions(name string) json.RawMessage {
|
|
428
826
|
if s == nil {
|
|
429
827
|
return nil
|
|
@@ -455,10 +853,20 @@ func (s *ConfigStore) flattenOptions() RuleOptionsMap {
|
|
|
455
853
|
return options
|
|
456
854
|
}
|
|
457
855
|
|
|
458
|
-
// RuleOptionsVariants exposes
|
|
459
|
-
// severity-only declaration
|
|
460
|
-
// files/extends
|
|
461
|
-
// last.
|
|
856
|
+
// RuleOptionsVariants exposes each non-ignore entry's declared payload,
|
|
857
|
+
// including nil for a severity-only declaration. Engine construction can check
|
|
858
|
+
// all files/extends variants through the rule's supported validation capability
|
|
859
|
+
// rather than selecting only the last parsed tuple.
|
|
860
|
+
// Returned payloads are independent byte copies; nil marks a severity-only declaration.
|
|
861
|
+
//
|
|
862
|
+
// @evidence contracts/common.md#principled-implementation Every non-ignore entry declaring the canonical name contributes its own payload, including nil, so eager validation does not skip scoped variants.
|
|
863
|
+
// @evidence contracts/common.md#clear-and-simple-design The optional capability projects existing entries and reuses the rule decoder rather than introducing another configuration model.
|
|
864
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Variant enumeration uses declared settings, not which examples happened to execute a rule.
|
|
865
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose states full declaration population, severity-only nil and independent byte ownership before tags.
|
|
866
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation RuleOptionsVariants selects option bytes by rule name and touches no filesystem path or process.
|
|
867
|
+
// @evidence contracts/performance.md#efficient-algorithms One pass over e entries probes the canonical name and copies b bytes across v declared variants, O(e) map probes plus name hashing and b copy work, with O(v+b) result storage. The declaration list is the source of truth, so eager discovery must inspect entries even when their file selectors differ.
|
|
868
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This projection owns no shared producer or invalidation identity. Engine construction separately deduplicates identical payload bytes before invoking supported validation.
|
|
869
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The returned slice and nonempty payload copies belong to the caller; nil payloads carry no bytes. This call retains no historical result, handle or task in the store.
|
|
462
870
|
func (s *ConfigStore) RuleOptionsVariants(name string) []json.RawMessage {
|
|
463
871
|
if s == nil {
|
|
464
872
|
return nil
|
|
@@ -477,25 +885,57 @@ func (s *ConfigStore) RuleOptionsVariants(name string) []json.RawMessage {
|
|
|
477
885
|
return variants
|
|
478
886
|
}
|
|
479
887
|
|
|
480
|
-
// ConfigEntry is
|
|
888
|
+
// ConfigEntry is one parsed selection or global-ignore entry from a config file.
|
|
481
889
|
// BaseDir anchors glob resolution; Files and Ignores are the pattern lists.
|
|
482
|
-
// IgnoreOnly
|
|
483
|
-
//
|
|
484
|
-
// matched.
|
|
890
|
+
// IgnoreOnly represents a global-ignore entry derived from an ignores list
|
|
891
|
+
// without a nonempty files restriction. These entries are evaluated first in
|
|
892
|
+
// ResolveRules and short-circuit the walk when matched.
|
|
893
|
+
//
|
|
894
|
+
// @evidence contracts/common.md#principled-implementation One entry binds relative patterns and paired rule maps to the config file that owns them, while selector presence remains distinct from an empty pattern list.
|
|
895
|
+
// @evidence contracts/common.md#clear-and-simple-design Entry-local scope and global-ignore state are explicit fields, avoiding parallel flattened policy.
|
|
896
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Presence bits model actual config syntax instead of guessing scope from a nonempty collection.
|
|
897
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose and spaced field comments explain pattern anchoring, presence and ignore meaning without property tags.
|
|
898
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ConfigEntry is a declaration of data shape and performs no filesystem, path or process operation.
|
|
899
|
+
// @evidenceExclude contracts/performance.md#efficient-algorithms ConfigEntry is a declaration of data shape and chooses no algorithm or processing strategy.
|
|
900
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work ConfigEntry is a declaration of data shape and coordinates no computation that could be shared.
|
|
901
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources ConfigEntry is a declaration of data shape; the code that holds its values owns their lifetime.
|
|
485
902
|
type ConfigEntry struct {
|
|
486
|
-
BaseDir
|
|
487
|
-
|
|
903
|
+
// BaseDir anchors this config file's relative selectors.
|
|
904
|
+
BaseDir string
|
|
905
|
+
|
|
906
|
+
// Files lists positive patterns; an empty list imposes no file restriction.
|
|
907
|
+
Files []string
|
|
908
|
+
|
|
909
|
+
// HasFilesSelector preserves explicit selector syntax for project-rule validation.
|
|
488
910
|
HasFilesSelector bool
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
911
|
+
|
|
912
|
+
// Ignores subtracts files from this entry, or globally when IgnoreOnly is true.
|
|
913
|
+
Ignores []string
|
|
914
|
+
|
|
915
|
+
// Rules contains this entry's declarations, including explicit off states.
|
|
916
|
+
Rules RuleConfig
|
|
917
|
+
|
|
918
|
+
// Options contains this entry's option tuples, folded with its matching severities.
|
|
919
|
+
Options RuleOptionsMap
|
|
920
|
+
|
|
921
|
+
// IgnoreOnly makes a matching ignore skip the file before ordinary entries fold.
|
|
922
|
+
IgnoreOnly bool
|
|
493
923
|
}
|
|
494
924
|
|
|
495
925
|
// ResolveRules implements RuleResolver. Ignore-only entries are checked first;
|
|
496
926
|
// if one matches, the file is marked Ignored and linting is skipped entirely.
|
|
497
927
|
// Otherwise the entries are walked in declaration order and the last matching
|
|
498
928
|
// entry wins (later entries shadow earlier ones for the same rule name).
|
|
929
|
+
// A later severity-only declaration retains the most recent options from a matching entry.
|
|
930
|
+
//
|
|
931
|
+
// @evidence contracts/common.md#principled-implementation Global ignores precede ordered entry matching; paired maps are folded only from matching entries, retaining inherited tuples when a later matching declaration has no options.
|
|
932
|
+
// @evidence contracts/common.md#clear-and-simple-design A global-ignore phase precedes the ordered file-scope fold; ConfigEntry owns pattern predicates and the result distinguishes ignored from out-of-scope.
|
|
933
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts No options are borrowed from nonmatching entries and no consumer name bypasses selection.
|
|
934
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose documents global-ignore ordering, precedence and severity-only inheritance before a separate tag paragraph.
|
|
935
|
+
// @evidence contracts/portability.md#os-neutral-implementation Selector helpers use native filepath identities and symlink/junction ancestor resolution, then slash-normalized glob spelling. Stored-case fallback requires the actual path to exist and a unique on-disk case-fold match; it does not infer case policy from the OS name. Relative paths escaping the resolved base are rejected; resolution failures preserve lexical spelling, and a failed relative-path calculation disables stored-case fallback.
|
|
936
|
+
// @evidence contracts/performance.md#efficient-algorithms Up to two passes inspect e entries and merge q matching rule declarations, with name hashing/normalization and b copied payload bytes. Selector work includes pattern matching, native ancestor resolution and eligible stored-case directory scans; output holds u distinct rules and their final payload bytes. Global ignores return early.
|
|
937
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This call projects current entries and filesystem identities; it has no cross-call invalidation proof for memoizing matching after native topology changes.
|
|
938
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The returned maps are new and owned by the caller and option bytes are copied; no handle or task is acquired.
|
|
499
939
|
func (s *ConfigStore) ResolveRules(fileName string) ResolvedRuleConfig {
|
|
500
940
|
if s == nil {
|
|
501
941
|
return ResolvedRuleConfig{Rules: RuleConfig{}, OptionsResolved: true}
|
|
@@ -538,6 +978,15 @@ func (s *ConfigStore) ResolveRules(fileName string) ResolvedRuleConfig {
|
|
|
538
978
|
// names that are not SeverityOff across every non-ignore-only config entry,
|
|
539
979
|
// regardless of which files they apply to. The engine uses this to build the
|
|
540
980
|
// per-rule dispatch table before file iteration begins.
|
|
981
|
+
//
|
|
982
|
+
// @evidence contracts/common.md#principled-implementation Unioning non-off declarations from every ordinary entry retains potentially active rules regardless of current file scope, then sorts their canonical identities.
|
|
983
|
+
// @evidence contracts/common.md#clear-and-simple-design Dispatch metadata is derived from entries without executing file matching or caching a duplicate activity list.
|
|
984
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Activity follows supported config declarations instead of sampled source diagnostics.
|
|
985
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains ignore-only exclusion, potential activity and the pre-file dispatch consumer before tags.
|
|
986
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ActiveRuleNames collects rule names and touches no filesystem path or process.
|
|
987
|
+
// @evidence contracts/performance.md#efficient-algorithms Scanning e entries and q ordinary rule declarations builds u distinct active names, then sorts them: O(e+q+u log u) entry/name operations plus normalization, hashing and comparison bytes. The temporary union and returned slice hold O(u) entries; no file selectors or option payloads are evaluated.
|
|
988
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This metadata projection owns no shared producer or cross-call invalidation identity; engine construction separately uses its result to build dispatch once.
|
|
989
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The temporary union is local and the caller owns the returned name slice. No historical metadata, handle or task is retained by this call.
|
|
541
990
|
func (s *ConfigStore) ActiveRuleNames() []string {
|
|
542
991
|
if s == nil {
|
|
543
992
|
return nil
|
|
@@ -559,6 +1008,15 @@ func (s *ConfigStore) ActiveRuleNames() []string {
|
|
|
559
1008
|
// EnabledRuleConfig implements RuleResolver. Returns the project-wide severity
|
|
560
1009
|
// map for non-off rules. Where multiple entries configure the same rule,
|
|
561
1010
|
// SeverityError is sticky — it cannot be downgraded by a later warning entry.
|
|
1011
|
+
//
|
|
1012
|
+
// @evidence contracts/common.md#principled-implementation Aggregating non-off entries with sticky error severity conservatively represents potential project reporting without replacing file-specific resolution.
|
|
1013
|
+
// @evidence contracts/common.md#clear-and-simple-design The metadata projection is computed from the same entries rather than stored as independent execution policy.
|
|
1014
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Error precedence is the documented aggregate policy, not a special case for a diagnostic fixture.
|
|
1015
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose states global aggregation and sticky error semantics with a separate acknowledgment paragraph.
|
|
1016
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation EnabledRuleConfig merges rule severities and touches no filesystem path or process.
|
|
1017
|
+
// @evidence contracts/performance.md#efficient-algorithms Scanning e entries and q ordinary rule declarations writes u distinct non-off canonical names, O(e+q) entry/name operations plus normalization/hashing bytes and O(u) returned entries. No file selectors or payload bytes are evaluated.
|
|
1018
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This metadata projection owns no shared producer or cross-call invalidation identity; engine construction separately retains the aggregate reporting state it needs.
|
|
1019
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The caller owns the new severity map, including the empty nil-store result. This call retains no historical metadata, handle or task.
|
|
562
1020
|
func (s *ConfigStore) EnabledRuleConfig() RuleConfig {
|
|
563
1021
|
out := RuleConfig{}
|
|
564
1022
|
if s == nil {
|
|
@@ -586,6 +1044,15 @@ func (s *ConfigStore) EnabledRuleConfig() RuleConfig {
|
|
|
586
1044
|
// invalid configuration, including off declarations and option tuples. A
|
|
587
1045
|
// built-in companion sharing a file-rule name ignores that scoped declaration
|
|
588
1046
|
// so the file rule can retain its existing per-file configuration.
|
|
1047
|
+
//
|
|
1048
|
+
// @evidence contracts/common.md#principled-implementation Base-first global folding preserves declaration presence and inherited options; file-only project declarations are rejected unless a registered file companion owns that scoped mention.
|
|
1049
|
+
// @evidence contracts/common.md#clear-and-simple-design Requested identities form a lookup set and project validation stays with the store that knows entry scope.
|
|
1050
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts The companion exception checks actual LookupRule registration rather than a hand-maintained consumer whitelist.
|
|
1051
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose states project-scope rejection and the registered-companion distinction before separated tags.
|
|
1052
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ResolveProjectRules resolves rule names and option bytes and touches no filesystem path or process.
|
|
1053
|
+
// @evidence contracts/performance.md#efficient-algorithms A wanted-name index is built for p requests, e entries are visited and q configured rules in participating entries are scanned once. This costs O(p+e+q) entry/name operations plus normalization/hashing bytes and the total option bytes copied by matching inherited updates; lookup/result maps reserve O(p) entries and results retain the final resolved payloads.
|
|
1054
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This method owns one fold of the current store. The native loadRules boundary binds its project resolution into boundProjectRuleResolver so engine construction can reuse the settings instead of folding the store again.
|
|
1055
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The returned map is new and owned by the caller and option bytes are copied; no handle or task is acquired.
|
|
589
1056
|
func (s *ConfigStore) ResolveProjectRules(names []string) (map[string]ProjectRuleSetting, error) {
|
|
590
1057
|
out := make(map[string]ProjectRuleSetting, len(names))
|
|
591
1058
|
wanted := make(map[string]string, len(names))
|
|
@@ -631,9 +1098,18 @@ func (s *ConfigStore) ResolveProjectRules(names []string) (map[string]ProjectRul
|
|
|
631
1098
|
return out, nil
|
|
632
1099
|
}
|
|
633
1100
|
|
|
634
|
-
// Flatten returns
|
|
1101
|
+
// Flatten returns a new severity map for all non-ignore-only entries,
|
|
635
1102
|
// including SeverityOff rules. Used by LoadRuleConfig (callers that expect a
|
|
636
1103
|
// plain RuleConfig). Later entries shadow earlier ones for the same rule name.
|
|
1104
|
+
//
|
|
1105
|
+
// @evidence contracts/common.md#principled-implementation Declaration-order folding retains explicit off states and intentionally discards file scope to represent the documented unconstrained union.
|
|
1106
|
+
// @evidence contracts/common.md#clear-and-simple-design A derived map adapts legacy severity consumers without becoming another source of execution truth.
|
|
1107
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Flattening is an explicit metadata API and is not substituted for scoped engine execution.
|
|
1108
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains the loss of scope, inclusion of off and precedence before a separate tag paragraph.
|
|
1109
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation Flatten merges rule severities and touches no filesystem path or process.
|
|
1110
|
+
// @evidence contracts/performance.md#efficient-algorithms One fold visits e entries and q rules in participating entries, with O(e+q) entry/map operations plus rule-name trimming, normalization and hashing bytes. A full fold is needed for the unconstrained union and later-entry precedence. The returned map holds u distinct canonical names and severities in O(u) map entries; normalized names can share their source string backing storage.
|
|
1111
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work Flatten owns one severity projection of the store, not a cross-request computation coordinator. Its fresh writable result gives each caller independent map membership; callers establish equivalence and ownership before reusing a projection.
|
|
1112
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The returned map is new and owned by the caller; no handle or task is acquired.
|
|
637
1113
|
func (s *ConfigStore) Flatten() RuleConfig {
|
|
638
1114
|
out := RuleConfig{}
|
|
639
1115
|
if s == nil {
|
|
@@ -664,15 +1140,24 @@ func (e ConfigEntry) matchesIgnores(fileName string) bool {
|
|
|
664
1140
|
return len(e.Ignores) > 0 && matchAnyPattern(e.BaseDir, e.Ignores, fileName)
|
|
665
1141
|
}
|
|
666
1142
|
|
|
667
|
-
// ParseRules
|
|
1143
|
+
// ParseRules projects a decoded rule object to a severity map, preserving
|
|
1144
|
+
// supplied key spelling and rejecting duplicate canonical aliases.
|
|
1145
|
+
//
|
|
1146
|
+
// Nil means no rules. Entries accept "off", "warn"/"warning", "error" or
|
|
1147
|
+
// JSON-decoded float64 values 0, 1, 2, either bare or in a severity/options tuple.
|
|
1148
|
+
// Unsupported severities, empty tuples and unencodable options return an error.
|
|
668
1149
|
//
|
|
669
|
-
//
|
|
670
|
-
//
|
|
671
|
-
// - `"warning"` → SeverityWarn
|
|
672
|
-
// - `"error"` → SeverityError
|
|
1150
|
+
// Tuples are checked and option payloads encoded by the shared parser, then
|
|
1151
|
+
// discarded from this severity-only result; use ParseRulesWithOptions to retain them.
|
|
673
1152
|
//
|
|
674
|
-
//
|
|
675
|
-
//
|
|
1153
|
+
// @evidence contracts/common.md#principled-implementation Delegating to the tuple-aware parser preserves severity validation while intentionally discarding option storage for this severity-only API.
|
|
1154
|
+
// @evidence contracts/common.md#clear-and-simple-design One parser owns entry decoding; this wrapper only projects the severity result.
|
|
1155
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Invalid severity is returned as an error rather than silently disabled to satisfy a consumer.
|
|
1156
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose describes decoded input, nil, complete severity vocabulary, tuple errors, key spelling and the option-bearing alternative before separate tags.
|
|
1157
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ParseRules performs no filesystem or process operation of its own.
|
|
1158
|
+
// @evidence contracts/performance.md#efficient-algorithms The shared parser sorts n stored names, scans entries and encodes supplied option bytes, O(n log n) name comparisons plus name and payload bytes. Delegation preserves the same strict tuple/error semantics; only the severity map is transferred, while temporary option maps and bytes become reclaimable after return.
|
|
1159
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work This decoded-value projection owns no shared producer or cross-call identity for mutable caller inputs.
|
|
1160
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The caller owns the new severity map; temporary discarded option storage is not retained by this wrapper. No handle or task is acquired.
|
|
676
1161
|
func ParseRules(raw any) (RuleConfig, error) {
|
|
677
1162
|
cfg, _, err := ParseRulesWithOptions(raw)
|
|
678
1163
|
return cfg, err
|
|
@@ -682,6 +1167,19 @@ func ParseRules(raw any) (RuleConfig, error) {
|
|
|
682
1167
|
// `[severity, ...options]` tuple per rule and returns the severity map
|
|
683
1168
|
// alongside an options map keyed by rule name. The options map only
|
|
684
1169
|
// contains entries for rules whose configuration carries option slots.
|
|
1170
|
+
// Keys retain their supplied spelling. Distinct keys for one canonical rule are
|
|
1171
|
+
// rejected, including duplicate aliases with equal severities or payloads.
|
|
1172
|
+
// JSON-loaded option slots retain nested object-entry order; an ordinary Go map
|
|
1173
|
+
// has no authored member order for this boundary to recover.
|
|
1174
|
+
//
|
|
1175
|
+
// @evidence contracts/common.md#principled-implementation Canonical identity validation rejects ambiguous maps before entry decoding separates severity and JSON option slots, preserving each tuple and one-slot shape.
|
|
1176
|
+
// @evidence contracts/common.md#clear-and-simple-design The boundary validates a raw object once and returns paired maps for existing severity and option consumers.
|
|
1177
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Ambiguous aliases are errors regardless of equal values, rather than iteration-order precedence; invalid entries do not receive fabricated defaults.
|
|
1178
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains tuple shape, option-map population and preserved key spelling with a blank line before tags.
|
|
1179
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation ParseRulesWithOptions decodes an already-loaded rules value and touches no filesystem path or process.
|
|
1180
|
+
// @evidence contracts/performance.md#efficient-algorithms Canonical-name validation sorts n rule names before a linear entry pass, requiring O(n log n) name comparisons plus hashing/name-byte work. Option encoding examines the supplied payload bytes and allocates the returned JSON; result maps scale with rule and option counts.
|
|
1181
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work ParseRulesWithOptions keeps no cache; every call decodes its argument.
|
|
1182
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The returned maps are new and owned by the caller; no handle or task is acquired.
|
|
685
1183
|
func ParseRulesWithOptions(raw any) (RuleConfig, RuleOptionsMap, error) {
|
|
686
1184
|
if raw == nil {
|
|
687
1185
|
return RuleConfig{}, RuleOptionsMap{}, nil
|
|
@@ -690,6 +1188,9 @@ func ParseRulesWithOptions(raw any) (RuleConfig, RuleOptionsMap, error) {
|
|
|
690
1188
|
if !ok {
|
|
691
1189
|
return nil, nil, fmt.Errorf("@ttsc/lint: \"rules\" must be an object, got %T", raw)
|
|
692
1190
|
}
|
|
1191
|
+
if err := validateCanonicalRuleNames(dict); err != nil {
|
|
1192
|
+
return nil, nil, err
|
|
1193
|
+
}
|
|
693
1194
|
cfg := make(RuleConfig, len(dict))
|
|
694
1195
|
opts := make(RuleOptionsMap)
|
|
695
1196
|
for name, value := range dict {
|
|
@@ -771,7 +1272,10 @@ func collectConfigStoreWithin(
|
|
|
771
1272
|
rootPath string,
|
|
772
1273
|
resolutionRoot string,
|
|
773
1274
|
) (*ConfigStore, error) {
|
|
774
|
-
store := &ConfigStore{
|
|
1275
|
+
store := &ConfigStore{
|
|
1276
|
+
patterns: &userPatternCache{},
|
|
1277
|
+
resolutionRoot: filepath.Clean(resolutionRoot),
|
|
1278
|
+
}
|
|
775
1279
|
var chain []string
|
|
776
1280
|
if rootPath != "" {
|
|
777
1281
|
rootPath = filepath.Clean(rootPath)
|
|
@@ -932,16 +1436,21 @@ func collectConfigObject(store *ConfigStore, raw any, baseDir, path string, chai
|
|
|
932
1436
|
if !ok {
|
|
933
1437
|
return fmt.Errorf("@ttsc/lint: %s.rules must be a rule severity map, got %T", path, rulesValue)
|
|
934
1438
|
}
|
|
1439
|
+
if err := validateCanonicalRuleNames(typedMap); err != nil {
|
|
1440
|
+
return fmt.Errorf("%s.rules: %w", path, err)
|
|
1441
|
+
}
|
|
935
1442
|
// `format/*` rules are configured exclusively through the `format`
|
|
936
1443
|
// block; they are never valid keys in `rules`. Silently drop any that
|
|
937
1444
|
// appear, the same way an unknown rule name is ignored (see
|
|
938
1445
|
// parseExternalRuleMapInto): a config must not carry a formatter
|
|
939
1446
|
// setting in two places, and a stray `format/*` here is simply not the
|
|
940
1447
|
// formatting surface, so it has no effect rather than erroring.
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
1448
|
+
// Evaluated objects can be shared by concurrent cache readers. Filter
|
|
1449
|
+
// into owned storage instead of deleting from the cached source map.
|
|
1450
|
+
rulesMap = make(map[string]any, len(typedMap))
|
|
1451
|
+
for key, value := range typedMap {
|
|
1452
|
+
if !isFormatRuleName(normalizeBuiltinRuleName(key)) {
|
|
1453
|
+
rulesMap[key] = value
|
|
945
1454
|
}
|
|
946
1455
|
}
|
|
947
1456
|
}
|
|
@@ -984,6 +1493,9 @@ func collectExternalRuleMapWithOptions(out RuleConfig, opts RuleOptionsMap, raw
|
|
|
984
1493
|
if !ok {
|
|
985
1494
|
return fmt.Errorf("@ttsc/lint: %s must be a rules object, got %T", path, raw)
|
|
986
1495
|
}
|
|
1496
|
+
if err := validateCanonicalRuleNames(dict); err != nil {
|
|
1497
|
+
return fmt.Errorf("%s: %w", path, err)
|
|
1498
|
+
}
|
|
987
1499
|
for name, value := range dict {
|
|
988
1500
|
sev, ruleOpts, err := parseExternalRuleEntry(value)
|
|
989
1501
|
if err != nil {
|
|
@@ -1050,8 +1562,17 @@ func parsePatternList(raw any, path string) ([]string, error) {
|
|
|
1050
1562
|
}
|
|
1051
1563
|
|
|
1052
1564
|
// LoadRuleConfig resolves the lint config for one plugin entry and flattens it
|
|
1053
|
-
// to a plain RuleConfig (no glob scoping).
|
|
1054
|
-
//
|
|
1565
|
+
// to a plain RuleConfig (no glob scoping). Metadata consumers can use the
|
|
1566
|
+
// unconstrained severity union; file execution should use LoadConfigResolver.
|
|
1567
|
+
//
|
|
1568
|
+
// @evidence contracts/common.md#principled-implementation The loader delegates config evaluation and projects the resolver's supported severity view, preserving store off declarations through Flatten.
|
|
1569
|
+
// @evidence contracts/common.md#clear-and-simple-design One adapter owns the legacy severity-only return shape while the scoped loader owns discovery and parsing.
|
|
1570
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Resolver type handling corresponds to real supported representations and does not bypass per-file execution policy.
|
|
1571
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose identifies metadata use and directs file execution to the scoped resolver, with separated tags.
|
|
1572
|
+
// @evidence contracts/portability.md#os-neutral-implementation LoadRuleConfig carries native cwd/tsconfig/config paths through LoadConfigResolver. That boundary uses filepath-based project anchoring and native discovery/evaluation helpers, while file URLs and executable argument forms belong to their loader owners; this projection introduces no case-folding or shell command text.
|
|
1573
|
+
// @evidence contracts/performance.md#efficient-algorithms LoadRuleConfig includes the delegated discovery, config-byte parsing/evaluation, dependency validation and store construction costs of LoadConfigResolver. Store projection adds Flatten entry/rule/name work and a fresh severity map; alternate resolver representations supply their own severity view. A fixed type switch does not make the owning load constant-cost.
|
|
1574
|
+
// @evidence contracts/performance.md#reuse-equivalent-work Executable config evaluation reuses the dependency-validated memory/disk producer reached through LoadConfigResolver; this adapter adds no projection cache. The ConfigStore branch returns fresh writable severity membership, so evaluation reuse does not imply sharing caller-mutable projection maps.
|
|
1575
|
+
// @evidence contracts/performance.md#bound-retention-and-release-resources The delegated loader owns temporary files and synchronous evaluator children; its shared evaluation cache outlives this adapter. The returned severity map belongs to the caller: ConfigStore produces new membership while a RuleConfig resolver is returned directly. Temporary parsed store metadata becomes reclaimable when otherwise unreferenced; this function imposes no cache eviction or result-size bound.
|
|
1055
1576
|
func LoadRuleConfig(entry *PluginEntry, cwd, tsconfigPath string) (RuleConfig, error) {
|
|
1056
1577
|
resolver, err := LoadConfigResolver(entry, cwd, tsconfigPath)
|
|
1057
1578
|
if err != nil {
|
|
@@ -1074,10 +1595,25 @@ func LoadRuleConfig(entry *PluginEntry, cwd, tsconfigPath string) (RuleConfig, e
|
|
|
1074
1595
|
// `configFile`, a path (relative to the tsconfig directory, or absolute) to
|
|
1075
1596
|
// the lint config file. When `configFile` is set, that file is loaded; when it
|
|
1076
1597
|
// is absent, a `lint.config.*` / `ttsc-lint.config.*` file is discovered by
|
|
1077
|
-
// walking upward from the tsconfig directory
|
|
1598
|
+
// walking upward from the tsconfig directory and then from the working
|
|
1599
|
+
// directory (see discoveryConfigBaseDirs for the embedder-declared origin).
|
|
1078
1600
|
//
|
|
1079
1601
|
// All rules, format options, and contributor plugins live in the config file
|
|
1080
|
-
// itself
|
|
1602
|
+
// itself; the tsconfig entry has no inline rule/format/plugin surface.
|
|
1603
|
+
//
|
|
1604
|
+
// Executable configs are cached against their recorded module dependencies,
|
|
1605
|
+
// not arbitrary environment, network or user-performed filesystem reads.
|
|
1606
|
+
// Set TTSC_LINT_DISABLE_CONFIG_CACHE for configs that depend on such inputs.
|
|
1607
|
+
// Extends chains are bounded to 32 files; dependency tracking is not a sandbox.
|
|
1608
|
+
//
|
|
1609
|
+
// @evidence contracts/common.md#principled-implementation Explicit or discovered config paths use the project-root channel and extension-specific evaluator; base-first entry collection preserves inheritance and file scope under the documented dependency and depth limits.
|
|
1610
|
+
// @evidence contracts/common.md#clear-and-simple-design The public boundary validates configFile and delegates discovery, evaluation and entry folding to their owners rather than supporting parallel inline policy.
|
|
1611
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Node's supported hooks track module resolution without replacing foreign fs methods; the bounded extends guard is a documented limit, while cache use for untracked external inputs must be disabled.
|
|
1612
|
+
// @evidence contracts/common.md#meaningful-documentation Native paragraphs explain project anchoring, config ownership, cache premises and limits, with a blank comment line before tags.
|
|
1613
|
+
// @evidence contracts/portability.md#os-neutral-implementation LoadConfigResolver owns native config discovery/loading through its helpers. The launcher project-root channel wins over wrapper tsconfig origins; filepath preserves native path spelling and discovery probes actual candidates without assuming case policy from OS names. JSON uses native reads, JS uses explicit Node arguments/stdin, and TS uses loader-owned file URLs, argument vectors and platform temp/module-link boundaries rather than shell interpolation.
|
|
1614
|
+
// @evidence contracts/performance.md#efficient-algorithms Discovery probes fourteen names per visited ancestor directory across the selected origins. Loading includes config bytes, executable evaluator work when needed, dependency digest validation, recursive extends and parsed entries/rules/options; each extends lineage is capped at thirty-two files, not total branch population. Provenance helpers perform membership scans and sorting of stored paths/directories, so additional work can be quadratic in their population plus comparison/path bytes. Returned store and temporary evaluation space scale with these inputs; no fixed total time or unmeasured speedup is claimed.
|
|
1615
|
+
// @evidence contracts/performance.md#reuse-equivalent-work Executable evaluation delegates to a memory/disk cache keyed by version, absolute entry path/content and resolution-root namespace, with recorded dependency fingerprints revalidated on hits. Failed evaluations are not stored; dependency changes cause new work. JSON is read directly, and entry folding is performed for each load. Environment, network and arbitrary user filesystem effects are outside tracked equivalence and require the documented cache opt-out; no single-flight coordination is claimed.
|
|
1616
|
+
// @evidence contracts/performance.md#bound-retention-and-release-resources The returned parsed store owns entries/options and public/resident dependency provenance until its consumer releases it. Loader helpers wait for each evaluator child and defer temporary-directory cleanup on success/error; their background contexts provide no caller deadline or external cancellation, and cleanup errors are not surfaced. Memory evaluation entries live for the process and disk entries have no eviction policy here, growing with distinct versioned content/dependency payloads. This loader imposes no total config-byte, branch-population or evaluator-runtime bound.
|
|
1081
1617
|
func LoadConfigResolver(entry *PluginEntry, cwd, tsconfigPath string) (RuleResolver, error) {
|
|
1082
1618
|
if entry == nil {
|
|
1083
1619
|
return RuleConfig{}, nil
|
|
@@ -1150,7 +1686,12 @@ func appendResidentConfigEvaluation(
|
|
|
1150
1686
|
cloned.Realpath = cloneConfigDependencyRealpath(dependency.Realpath)
|
|
1151
1687
|
store.cacheDependencies = append(store.cacheDependencies, cloned)
|
|
1152
1688
|
}
|
|
1153
|
-
|
|
1689
|
+
// JSON retains its existing timestamp-window resident guard as well as
|
|
1690
|
+
// the new consumed-byte proof. Executable evaluations keep their own
|
|
1691
|
+
// dependency population and never acquire this JSON-only path guard.
|
|
1692
|
+
if !strings.EqualFold(filepath.Ext(location), ".json") {
|
|
1693
|
+
return
|
|
1694
|
+
}
|
|
1154
1695
|
}
|
|
1155
1696
|
location = filepath.Clean(location)
|
|
1156
1697
|
if !containsPath(store.cacheFiles, location) {
|
|
@@ -1300,18 +1841,15 @@ func discoveryConfigBaseDirs(cwd, tsconfigPath string) []string {
|
|
|
1300
1841
|
return origins
|
|
1301
1842
|
}
|
|
1302
1843
|
|
|
1303
|
-
// containsPath reports whether
|
|
1304
|
-
//
|
|
1305
|
-
//
|
|
1844
|
+
// containsPath reports whether paths already holds candidate's cleaned spelling.
|
|
1845
|
+
// Preserve distinct spellings even on Windows: directory case sensitivity and
|
|
1846
|
+
// alias topology cannot be inferred from the operating system alone.
|
|
1306
1847
|
func containsPath(paths []string, candidate string) bool {
|
|
1307
1848
|
cleaned := filepath.Clean(candidate)
|
|
1308
1849
|
for _, existing := range paths {
|
|
1309
1850
|
if existing == cleaned {
|
|
1310
1851
|
return true
|
|
1311
1852
|
}
|
|
1312
|
-
if runtime.GOOS == "windows" && strings.EqualFold(existing, cleaned) {
|
|
1313
|
-
return true
|
|
1314
|
-
}
|
|
1315
1853
|
}
|
|
1316
1854
|
return false
|
|
1317
1855
|
}
|
|
@@ -1371,6 +1909,8 @@ type evaluatedConfigFile struct {
|
|
|
1371
1909
|
dependencyDirectories []string
|
|
1372
1910
|
dependencyDigests []configDependencyFingerprint
|
|
1373
1911
|
dependenciesTracked bool
|
|
1912
|
+
// Private correlation only; cachedConfigEvaluation serializes none of it.
|
|
1913
|
+
traceInvocation *lintTraceInvocation
|
|
1374
1914
|
}
|
|
1375
1915
|
|
|
1376
1916
|
type cachedConfigEvaluation struct {
|
|
@@ -1397,8 +1937,7 @@ func loadConfigFileEvaluationWithin(
|
|
|
1397
1937
|
ext := strings.ToLower(filepath.Ext(location))
|
|
1398
1938
|
switch ext {
|
|
1399
1939
|
case ".json":
|
|
1400
|
-
|
|
1401
|
-
return evaluatedConfigFile{value: value}, err
|
|
1940
|
+
return loadJSONConfigEvaluation(location)
|
|
1402
1941
|
case ".js", ".cjs", ".mjs":
|
|
1403
1942
|
return loadCachedConfigEvaluationForRoot(
|
|
1404
1943
|
location,
|
|
@@ -1421,12 +1960,16 @@ func loadConfigFileEvaluationWithin(
|
|
|
1421
1960
|
}
|
|
1422
1961
|
|
|
1423
1962
|
// configCacheVersion namespaces the on-disk config cache. Bump it whenever
|
|
1424
|
-
// the shape
|
|
1425
|
-
// older @ttsc/lint binary are
|
|
1426
|
-
// v8
|
|
1427
|
-
//
|
|
1428
|
-
//
|
|
1429
|
-
|
|
1963
|
+
// the cached shape or dependency interpretation changes, so entries written
|
|
1964
|
+
// by an older @ttsc/lint binary are misses rather than silently reused.
|
|
1965
|
+
// v8 rechecks recorded dependencies after evaluation. A recorded transient
|
|
1966
|
+
// digest or path that differs from the final observation prevents caching;
|
|
1967
|
+
// equal observations do not prove absence of intervening replacements.
|
|
1968
|
+
// v9 invalidates module graphs whose identity and package-boundary decisions
|
|
1969
|
+
// used lexical case folding instead of actual filesystem identity.
|
|
1970
|
+
// v11 preserves rule option object-entry order through evaluation and disk reuse.
|
|
1971
|
+
// v12 makes the JS contributor evaluator preserve typed-base project ownership.
|
|
1972
|
+
const configCacheVersion = "v12"
|
|
1430
1973
|
|
|
1431
1974
|
// configEvalCache memoizes evaluated .ts/.js lint config objects for the
|
|
1432
1975
|
// lifetime of one process; the on-disk cache (configCacheDir) extends the
|
|
@@ -1516,7 +2059,12 @@ func loadCachedConfigEvaluationWithPolicy(
|
|
|
1516
2059
|
cacheNamespace string,
|
|
1517
2060
|
) (evaluatedConfigFile, error) {
|
|
1518
2061
|
if configCacheDisabled() {
|
|
1519
|
-
|
|
2062
|
+
evaluated, err := eval(location)
|
|
2063
|
+
evaluated.traceInvocation.record("config-cache-outcome", map[string]any{
|
|
2064
|
+
"location": location, "outcome": "disabled", "success": err == nil,
|
|
2065
|
+
"dependencies": evaluated.dependencyDigests,
|
|
2066
|
+
})
|
|
2067
|
+
return evaluated, err
|
|
1520
2068
|
}
|
|
1521
2069
|
content, err := os.ReadFile(location)
|
|
1522
2070
|
if err != nil {
|
|
@@ -1541,6 +2089,10 @@ func loadCachedConfigEvaluationWithPolicy(
|
|
|
1541
2089
|
if ok &&
|
|
1542
2090
|
cached.DependenciesTracked == dependenciesRequired &&
|
|
1543
2091
|
cachedConfigEvaluationIsCurrent(cached) {
|
|
2092
|
+
newLintTraceInvocation().record("config-cache-outcome", map[string]any{
|
|
2093
|
+
"location": location, "key": key, "outcome": "memory-hit",
|
|
2094
|
+
"dependencies": cached.Dependencies, "dependenciesTracked": cached.DependenciesTracked,
|
|
2095
|
+
})
|
|
1544
2096
|
return evaluatedConfigFileFromCache(cached), nil
|
|
1545
2097
|
}
|
|
1546
2098
|
if disk, hit := readConfigDiskCache(key); hit &&
|
|
@@ -1549,6 +2101,10 @@ func loadCachedConfigEvaluationWithPolicy(
|
|
|
1549
2101
|
configEvalCacheMu.Lock()
|
|
1550
2102
|
configEvalCache[key] = disk
|
|
1551
2103
|
configEvalCacheMu.Unlock()
|
|
2104
|
+
newLintTraceInvocation().record("config-cache-outcome", map[string]any{
|
|
2105
|
+
"location": location, "key": key, "outcome": "disk-hit",
|
|
2106
|
+
"dependencies": disk.Dependencies, "dependenciesTracked": disk.DependenciesTracked,
|
|
2107
|
+
})
|
|
1552
2108
|
return evaluatedConfigFileFromCache(disk), nil
|
|
1553
2109
|
}
|
|
1554
2110
|
|
|
@@ -1556,9 +2112,18 @@ func loadCachedConfigEvaluationWithPolicy(
|
|
|
1556
2112
|
for attempt := 0; attempt < 3; attempt++ {
|
|
1557
2113
|
evaluated, err = eval(location)
|
|
1558
2114
|
if err != nil {
|
|
2115
|
+
evaluated.traceInvocation.record("config-cache-outcome", map[string]any{
|
|
2116
|
+
"location": location, "key": key, "attempt": attempt + 1,
|
|
2117
|
+
"outcome": "evaluation-error", "error": err.Error(),
|
|
2118
|
+
})
|
|
1559
2119
|
return evaluatedConfigFile{}, err
|
|
1560
2120
|
}
|
|
1561
2121
|
if evaluated.dependenciesTracked != dependenciesRequired {
|
|
2122
|
+
evaluated.traceInvocation.record("config-cache-outcome", map[string]any{
|
|
2123
|
+
"location": location, "key": key, "attempt": attempt + 1,
|
|
2124
|
+
"outcome": "tracking-policy-mismatch", "dependenciesTracked": evaluated.dependenciesTracked,
|
|
2125
|
+
"dependenciesRequired": dependenciesRequired,
|
|
2126
|
+
})
|
|
1562
2127
|
return evaluatedConfigFile{}, fmt.Errorf(
|
|
1563
2128
|
"@ttsc/lint: config evaluator for %s returned dependenciesTracked=%t, want %t",
|
|
1564
2129
|
location,
|
|
@@ -1578,8 +2143,18 @@ func loadCachedConfigEvaluationWithPolicy(
|
|
|
1578
2143
|
configEvalCache[key] = cached
|
|
1579
2144
|
configEvalCacheMu.Unlock()
|
|
1580
2145
|
writeConfigDiskCache(key, cached)
|
|
2146
|
+
evaluated.traceInvocation.record("config-cache-outcome", map[string]any{
|
|
2147
|
+
"location": location, "key": key, "attempt": attempt + 1,
|
|
2148
|
+
"outcome": "memory-published", "diskWriteAttempted": true,
|
|
2149
|
+
"dependencies": cached.Dependencies, "dependenciesTracked": cached.DependenciesTracked,
|
|
2150
|
+
})
|
|
1581
2151
|
return evaluated, nil
|
|
1582
2152
|
}
|
|
2153
|
+
evaluated.traceInvocation.record("config-cache-outcome", map[string]any{
|
|
2154
|
+
"location": location, "key": key, "attempt": attempt + 1,
|
|
2155
|
+
"outcome": "not-current", "returnedUncached": attempt == 2,
|
|
2156
|
+
"dependencies": evaluated.dependencyDigests, "dependenciesTracked": evaluated.dependenciesTracked,
|
|
2157
|
+
})
|
|
1583
2158
|
}
|
|
1584
2159
|
return evaluated, nil
|
|
1585
2160
|
}
|
|
@@ -1768,10 +2343,23 @@ func readConfigDiskCache(key string) (cachedConfigEvaluation, bool) {
|
|
|
1768
2343
|
if err != nil {
|
|
1769
2344
|
return cachedConfigEvaluation{}, false
|
|
1770
2345
|
}
|
|
1771
|
-
var
|
|
1772
|
-
|
|
2346
|
+
var envelope struct {
|
|
2347
|
+
Value json.RawMessage `json:"value"`
|
|
2348
|
+
Dependencies []configDependencyFingerprint `json:"dependencies"`
|
|
2349
|
+
DependenciesTracked bool `json:"dependenciesTracked"`
|
|
2350
|
+
}
|
|
2351
|
+
if err := json.Unmarshal(body, &envelope); err != nil {
|
|
1773
2352
|
return cachedConfigEvaluation{}, false
|
|
1774
2353
|
}
|
|
2354
|
+
value, err := decodeConfigJSON(envelope.Value)
|
|
2355
|
+
if err != nil {
|
|
2356
|
+
return cachedConfigEvaluation{}, false
|
|
2357
|
+
}
|
|
2358
|
+
cached := cachedConfigEvaluation{
|
|
2359
|
+
Value: value,
|
|
2360
|
+
Dependencies: envelope.Dependencies,
|
|
2361
|
+
DependenciesTracked: envelope.DependenciesTracked,
|
|
2362
|
+
}
|
|
1775
2363
|
if !isConfigObject(cached.Value) {
|
|
1776
2364
|
return cachedConfigEvaluation{}, false
|
|
1777
2365
|
}
|
|
@@ -1823,23 +2411,45 @@ func writeConfigDiskCache(key string, cached cachedConfigEvaluation) {
|
|
|
1823
2411
|
// loadJSONConfigFile reads and JSON-parses a lint config file. A leading UTF-8
|
|
1824
2412
|
// BOM is stripped before parsing so files saved by Windows editors are accepted.
|
|
1825
2413
|
func loadJSONConfigFile(location string) (any, error) {
|
|
1826
|
-
|
|
2414
|
+
evaluated, err := loadJSONConfigEvaluation(location)
|
|
2415
|
+
return evaluated.value, err
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2418
|
+
// loadJSONConfigEvaluation retains the raw bytes actually decoded by this call
|
|
2419
|
+
// beside its native identity. The BOM affects the byte witness even though JSON
|
|
2420
|
+
// decoding strips it. Read failures never produce a complete config proof.
|
|
2421
|
+
func loadJSONConfigEvaluation(location string) (evaluatedConfigFile, error) {
|
|
2422
|
+
beforePhysical := configDependencyRealpath(location)
|
|
2423
|
+
file, err := os.Open(location)
|
|
1827
2424
|
if err != nil {
|
|
1828
|
-
return
|
|
2425
|
+
return evaluatedConfigFile{}, fmt.Errorf("@ttsc/lint: read config file %s: %w", location, err)
|
|
1829
2426
|
}
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
2427
|
+
before, beforeErr := file.Stat()
|
|
2428
|
+
body, readErr := io.ReadAll(file)
|
|
2429
|
+
after, afterErr := file.Stat()
|
|
2430
|
+
closeErr := file.Close()
|
|
2431
|
+
if readErr != nil {
|
|
2432
|
+
return evaluatedConfigFile{}, fmt.Errorf("@ttsc/lint: read config file %s: %w", location, readErr)
|
|
2433
|
+
}
|
|
2434
|
+
if closeErr != nil {
|
|
2435
|
+
return evaluatedConfigFile{}, fmt.Errorf("@ttsc/lint: close config file %s: %w", location, closeErr)
|
|
2436
|
+
}
|
|
2437
|
+
digest := sha256.Sum256(body)
|
|
2438
|
+
selected, selectedErr := os.Stat(location)
|
|
2439
|
+
physical := configDependencyRealpath(location)
|
|
2440
|
+
stable := beforeErr == nil && afterErr == nil && selectedErr == nil && os.SameFile(before, after) && os.SameFile(after, selected) &&
|
|
2441
|
+
before.Mode() == after.Mode() && before.Size() == after.Size() && before.ModTime().Equal(after.ModTime()) &&
|
|
2442
|
+
sameConfigDependencyRealpath(beforePhysical, physical)
|
|
1834
2443
|
body = bytes.TrimPrefix(body, []byte{0xEF, 0xBB, 0xBF})
|
|
1835
|
-
|
|
1836
|
-
if err
|
|
1837
|
-
return
|
|
2444
|
+
out, err := decodeConfigJSON(body)
|
|
2445
|
+
if err != nil {
|
|
2446
|
+
return evaluatedConfigFile{}, fmt.Errorf("@ttsc/lint: parse config file %s: %w", location, err)
|
|
1838
2447
|
}
|
|
1839
2448
|
if !isConfigObject(out) {
|
|
1840
|
-
return
|
|
2449
|
+
return evaluatedConfigFile{}, fmt.Errorf("@ttsc/lint: config file %s must export an ITtscLintConfig object", location)
|
|
1841
2450
|
}
|
|
1842
|
-
return out,
|
|
2451
|
+
return evaluatedConfigFile{value: out, dependencies: []string{location}, dependenciesTracked: true,
|
|
2452
|
+
dependencyDigests: []configDependencyFingerprint{{Path: filepath.Clean(location), Digest: hex.EncodeToString(digest[:]), IdentityStable: stable, Kind: configDependencyFile, Realpath: physical, Scope: configDependencyWatch}}}, nil
|
|
1843
2453
|
}
|
|
1844
2454
|
|
|
1845
2455
|
// serializableConfigKeys is the single source of truth for the ITtscLintConfig
|
|
@@ -1869,43 +2479,125 @@ func serializableConfigKeysLiteral() string {
|
|
|
1869
2479
|
// path for error messages; `label` is the human-readable subject (e.g. "config
|
|
1870
2480
|
// file" or "TypeScript config file") spliced into the load/parse error
|
|
1871
2481
|
// prefixes so each loader keeps its own wording.
|
|
2482
|
+
// Opt-in observation retains the exact bytes read and the actual normalized
|
|
2483
|
+
// dependencies under one invocation. It never supplies a replacement result.
|
|
1872
2484
|
func runConfigLoaderCommand(
|
|
1873
2485
|
cmd *exec.Cmd,
|
|
1874
2486
|
location string,
|
|
1875
2487
|
label string,
|
|
1876
2488
|
outputPath string,
|
|
1877
|
-
) (evaluatedConfigFile, error) {
|
|
2489
|
+
) (evaluated evaluatedConfigFile, resultErr error) {
|
|
1878
2490
|
// The child's stderr is human output and goes straight to this process's
|
|
1879
2491
|
// stderr as it is written. Collecting it only to replay it afterwards is what
|
|
1880
2492
|
// made a long evaluation print nothing at all, and what would make a loud one
|
|
1881
2493
|
// grow this process's memory without bound.
|
|
1882
2494
|
cmd.Stdout = io.Discard
|
|
1883
2495
|
cmd.Stderr = os.Stderr
|
|
2496
|
+
observation := newLintTraceInvocation()
|
|
2497
|
+
var rawCapture map[string]any
|
|
2498
|
+
readOutcome := "not-read"
|
|
2499
|
+
normalizationAttempted := false
|
|
2500
|
+
normalizationAccepted := false
|
|
2501
|
+
if observation != nil {
|
|
2502
|
+
defer func() {
|
|
2503
|
+
data := map[string]any{
|
|
2504
|
+
"location": location,
|
|
2505
|
+
"label": label,
|
|
2506
|
+
"raw": rawCapture,
|
|
2507
|
+
"readOutcome": readOutcome,
|
|
2508
|
+
"normalizationAttempted": normalizationAttempted,
|
|
2509
|
+
"normalizationAccepted": normalizationAccepted,
|
|
2510
|
+
"dependencies": evaluated.dependencyDigests,
|
|
2511
|
+
"dependenciesTracked": evaluated.dependenciesTracked,
|
|
2512
|
+
"success": resultErr == nil,
|
|
2513
|
+
}
|
|
2514
|
+
if resultErr != nil {
|
|
2515
|
+
data["error"] = resultErr.Error()
|
|
2516
|
+
}
|
|
2517
|
+
evaluated.traceInvocation = observation
|
|
2518
|
+
observation.record("config-loader-result", data)
|
|
2519
|
+
}()
|
|
2520
|
+
}
|
|
2521
|
+
var lower time.Time
|
|
2522
|
+
if observation != nil {
|
|
2523
|
+
lower = time.Now().UTC()
|
|
2524
|
+
observation.record("process-attempt", map[string]any{
|
|
2525
|
+
"pid": 0, "argv": cmd.Args, "cwd": cmd.Dir, "cwdInherited": cmd.Dir == "",
|
|
2526
|
+
"startLowerBound": lower.Format(time.RFC3339Nano), "owner": "lint-config-loader",
|
|
2527
|
+
})
|
|
2528
|
+
}
|
|
1884
2529
|
err := cmd.Run()
|
|
2530
|
+
if observation != nil {
|
|
2531
|
+
upper := time.Now().UTC()
|
|
2532
|
+
pid := 0
|
|
2533
|
+
if cmd.Process != nil {
|
|
2534
|
+
pid = cmd.Process.Pid
|
|
2535
|
+
}
|
|
2536
|
+
data := map[string]any{
|
|
2537
|
+
"pid": pid, "started": pid > 0, "exitObserved": cmd.ProcessState != nil,
|
|
2538
|
+
"argv": cmd.Args, "cwd": cmd.Dir, "cwdInherited": cmd.Dir == "",
|
|
2539
|
+
"startLowerBound": lower.Format(time.RFC3339Nano),
|
|
2540
|
+
"startUpperBound": upper.Format(time.RFC3339Nano), "owner": "lint-config-loader",
|
|
2541
|
+
"method": "Run", "success": err == nil,
|
|
2542
|
+
}
|
|
2543
|
+
if cmd.ProcessState != nil {
|
|
2544
|
+
data["exitCode"] = cmd.ProcessState.ExitCode()
|
|
2545
|
+
data["stateSuccess"] = cmd.ProcessState.Success()
|
|
2546
|
+
data["state"] = cmd.ProcessState.String()
|
|
2547
|
+
}
|
|
2548
|
+
if err != nil {
|
|
2549
|
+
data["error"] = err.Error()
|
|
2550
|
+
}
|
|
2551
|
+
observation.record("process-result", data)
|
|
2552
|
+
}
|
|
1885
2553
|
if err != nil {
|
|
1886
2554
|
// The loader's stack already reached the user's stderr as it was written.
|
|
1887
2555
|
// What it could not put there is a reason a caller can act on, so that
|
|
1888
2556
|
// arrives through the result file instead.
|
|
1889
|
-
if reason := loaderFailureReason(outputPath
|
|
2557
|
+
if reason := loaderFailureReason(outputPath, func(raw []byte, readErr error) {
|
|
2558
|
+
if observation != nil {
|
|
2559
|
+
readOutcome = "complete"
|
|
2560
|
+
if readErr != nil {
|
|
2561
|
+
readOutcome = "IO-failed"
|
|
2562
|
+
}
|
|
2563
|
+
rawCapture = observation.capture("loader-raw", raw)
|
|
2564
|
+
}
|
|
2565
|
+
}); reason != "" {
|
|
1890
2566
|
return evaluatedConfigFile{}, fmt.Errorf("@ttsc/lint: load %s %s: %s", label, location, reason)
|
|
1891
2567
|
}
|
|
1892
2568
|
return evaluatedConfigFile{}, fmt.Errorf("@ttsc/lint: load %s %s: %w", label, location, err)
|
|
1893
2569
|
}
|
|
1894
2570
|
output, err := os.ReadFile(outputPath)
|
|
2571
|
+
if observation != nil {
|
|
2572
|
+
readOutcome = "complete"
|
|
2573
|
+
if err != nil {
|
|
2574
|
+
readOutcome = "IO-failed"
|
|
2575
|
+
}
|
|
2576
|
+
rawCapture = observation.capture("loader-raw", output)
|
|
2577
|
+
}
|
|
1895
2578
|
if err != nil {
|
|
1896
2579
|
return evaluatedConfigFile{}, fmt.Errorf("@ttsc/lint: read %s %s result: %w", label, location, err)
|
|
1897
2580
|
}
|
|
1898
2581
|
var envelope struct {
|
|
1899
2582
|
Dependencies []configDependencyFingerprint `json:"dependencies"`
|
|
1900
|
-
Value
|
|
2583
|
+
Value json.RawMessage `json:"value"`
|
|
1901
2584
|
}
|
|
1902
2585
|
if err := json.Unmarshal(output, &envelope); err != nil {
|
|
1903
2586
|
return evaluatedConfigFile{}, fmt.Errorf("@ttsc/lint: parse %s %s output: %w", label, location, err)
|
|
1904
2587
|
}
|
|
1905
|
-
|
|
2588
|
+
var value any
|
|
2589
|
+
if len(envelope.Value) != 0 {
|
|
2590
|
+
value, err = decodeConfigJSON(envelope.Value)
|
|
2591
|
+
if err != nil {
|
|
2592
|
+
return evaluatedConfigFile{}, fmt.Errorf("@ttsc/lint: parse %s %s output: %w", label, location, err)
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
if !isConfigObject(value) {
|
|
1906
2596
|
return evaluatedConfigFile{}, fmt.Errorf("@ttsc/lint: config file %s must export an ITtscLintConfig object", location)
|
|
1907
2597
|
}
|
|
1908
2598
|
normalized, ok := normalizeConfigDependencyFingerprints(envelope.Dependencies)
|
|
2599
|
+
normalizationAttempted = true
|
|
2600
|
+
normalizationAccepted = ok
|
|
1909
2601
|
if !ok {
|
|
1910
2602
|
return evaluatedConfigFile{}, fmt.Errorf("@ttsc/lint: %s %s returned malformed dependency fingerprints", label, location)
|
|
1911
2603
|
}
|
|
@@ -1921,7 +2613,7 @@ func runConfigLoaderCommand(
|
|
|
1921
2613
|
}
|
|
1922
2614
|
}
|
|
1923
2615
|
return evaluatedConfigFile{
|
|
1924
|
-
value:
|
|
2616
|
+
value: value,
|
|
1925
2617
|
dependencies: dependencies,
|
|
1926
2618
|
dependencyDirectories: directories,
|
|
1927
2619
|
dependencyDigests: normalized,
|
|
@@ -2997,35 +3689,43 @@ function modulePackageName(specifier) {
|
|
|
2997
3689
|
function resolvedPackageContains(modules, packageName, childLocation) {
|
|
2998
3690
|
try {
|
|
2999
3691
|
const packageRoot = fs.realpathSync(path.join(modules, packageName));
|
|
3000
|
-
const
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
relative
|
|
3006
|
-
(relative
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
);
|
|
3692
|
+
const child = fs.realpathSync(childLocation);
|
|
3693
|
+
const relative = path.relative(packageRoot, child);
|
|
3694
|
+
if (relative === "") return sameResolutionPath(packageRoot, child);
|
|
3695
|
+
if (
|
|
3696
|
+
relative === ".." ||
|
|
3697
|
+
relative.startsWith(".." + path.sep) ||
|
|
3698
|
+
path.isAbsolute(relative)
|
|
3699
|
+
) return false;
|
|
3700
|
+
let ancestor = child;
|
|
3701
|
+
for (let remaining = relative.split(path.sep).length; remaining !== 0; --remaining)
|
|
3702
|
+
ancestor = path.dirname(ancestor);
|
|
3703
|
+
return sameResolutionPath(packageRoot, ancestor);
|
|
3010
3704
|
} catch {
|
|
3011
3705
|
return false;
|
|
3012
3706
|
}
|
|
3013
3707
|
}
|
|
3014
3708
|
|
|
3015
3709
|
function sameResolutionPath(left, right) {
|
|
3016
|
-
|
|
3710
|
+
const resolvedLeft = path.resolve(left);
|
|
3711
|
+
const resolvedRight = path.resolve(right);
|
|
3712
|
+
if (resolvedLeft === resolvedRight) return true;
|
|
3713
|
+
if (path.relative(resolvedLeft, resolvedRight) !== "") return false;
|
|
3714
|
+
try {
|
|
3715
|
+
const leftIdentity = fs.statSync(resolvedLeft, { bigint: true });
|
|
3716
|
+
const rightIdentity = fs.statSync(resolvedRight, { bigint: true });
|
|
3717
|
+
return leftIdentity.ino !== 0n &&
|
|
3718
|
+
leftIdentity.dev === rightIdentity.dev &&
|
|
3719
|
+
leftIdentity.ino === rightIdentity.ino;
|
|
3720
|
+
} catch {
|
|
3721
|
+
return false;
|
|
3722
|
+
}
|
|
3017
3723
|
}
|
|
3018
3724
|
|
|
3019
3725
|
function samePhysicalPath(left, right) {
|
|
3020
3726
|
try {
|
|
3021
3727
|
return sameResolutionPath(realPath(left), realPath(right));
|
|
3022
3728
|
} catch {
|
|
3023
|
-
// Fall back to the spellings themselves, folding case the way the platform
|
|
3024
|
-
// does. On the entry gate a false negative is catastrophic — the config
|
|
3025
|
-
// stops being recognized and its whole graph collapses — while a false
|
|
3026
|
-
// positive only over-includes, so the degradation has to lean toward "same
|
|
3027
|
-
// file". A drive-letter or component case difference is the ordinary
|
|
3028
|
-
// Windows situation; a per-directory case-sensitive tree is the rare one.
|
|
3029
3729
|
return sameResolutionPath(left, right);
|
|
3030
3730
|
}
|
|
3031
3731
|
}
|
|
@@ -4321,35 +5021,43 @@ function resolvedPackageContains(
|
|
|
4321
5021
|
): boolean {
|
|
4322
5022
|
try {
|
|
4323
5023
|
const packageRoot = fs.realpathSync(path.join(modules, packageName));
|
|
4324
|
-
const
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
relative
|
|
4330
|
-
(relative
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
);
|
|
5024
|
+
const child = fs.realpathSync(childLocation);
|
|
5025
|
+
const relative = path.relative(packageRoot, child);
|
|
5026
|
+
if (relative === "") return sameResolutionPath(packageRoot, child);
|
|
5027
|
+
if (
|
|
5028
|
+
relative === ".." ||
|
|
5029
|
+
relative.startsWith(".." + path.sep) ||
|
|
5030
|
+
path.isAbsolute(relative)
|
|
5031
|
+
) return false;
|
|
5032
|
+
let ancestor = child;
|
|
5033
|
+
for (let remaining = relative.split(path.sep).length; remaining !== 0; --remaining)
|
|
5034
|
+
ancestor = path.dirname(ancestor);
|
|
5035
|
+
return sameResolutionPath(packageRoot, ancestor);
|
|
4334
5036
|
} catch {
|
|
4335
5037
|
return false;
|
|
4336
5038
|
}
|
|
4337
5039
|
}
|
|
4338
5040
|
|
|
4339
5041
|
function sameResolutionPath(left: string, right: string): boolean {
|
|
4340
|
-
|
|
5042
|
+
const resolvedLeft = path.resolve(left);
|
|
5043
|
+
const resolvedRight = path.resolve(right);
|
|
5044
|
+
if (resolvedLeft === resolvedRight) return true;
|
|
5045
|
+
if (path.relative(resolvedLeft, resolvedRight) !== "") return false;
|
|
5046
|
+
try {
|
|
5047
|
+
const leftIdentity = fs.statSync(resolvedLeft, { bigint: true });
|
|
5048
|
+
const rightIdentity = fs.statSync(resolvedRight, { bigint: true });
|
|
5049
|
+
return leftIdentity.ino !== 0n &&
|
|
5050
|
+
leftIdentity.dev === rightIdentity.dev &&
|
|
5051
|
+
leftIdentity.ino === rightIdentity.ino;
|
|
5052
|
+
} catch {
|
|
5053
|
+
return false;
|
|
5054
|
+
}
|
|
4341
5055
|
}
|
|
4342
5056
|
|
|
4343
5057
|
function samePhysicalPath(left: string, right: string): boolean {
|
|
4344
5058
|
try {
|
|
4345
5059
|
return sameResolutionPath(realPath(left), realPath(right));
|
|
4346
5060
|
} catch {
|
|
4347
|
-
// Fall back to the spellings themselves, folding case the way the platform
|
|
4348
|
-
// does. On the entry gate a false negative is catastrophic — the config
|
|
4349
|
-
// stops being recognized and its whole graph collapses — while a false
|
|
4350
|
-
// positive only over-includes, so the degradation has to lean toward "same
|
|
4351
|
-
// file". A drive-letter or component case difference is the ordinary
|
|
4352
|
-
// Windows situation; a per-directory case-sensitive tree is the rare one.
|
|
4353
5061
|
return sameResolutionPath(left, right);
|
|
4354
5062
|
}
|
|
4355
5063
|
}
|
|
@@ -4562,11 +5270,8 @@ func typeScriptConfigLoaderTsconfig(loader, location, outDir string) string {
|
|
|
4562
5270
|
// packages/banner/driver/banner.go and packages/strip/driver/config.go. #1169
|
|
4563
5271
|
// decided against extracting it — the only home the three modules could share
|
|
4564
5272
|
// is the public `packages/ttsc/driver` seam, and packages/lint's go.mod
|
|
4565
|
-
// deliberately requires no in-tree ttsc module —
|
|
4566
|
-
//
|
|
4567
|
-
// between these markers across all three copies on every pull request, so
|
|
4568
|
-
// editing one and not the others fails by name. That file's header carries the
|
|
4569
|
-
// full decision and the rules for changing this block.
|
|
5273
|
+
// deliberately requires no in-tree ttsc module — so a change to one copy must
|
|
5274
|
+
// be made to all three.
|
|
4570
5275
|
//
|
|
4571
5276
|
// The code between the markers must stay identical. Comments may differ, the
|
|
4572
5277
|
// `@ttsc/<pkg>:` error prefix may differ, and @ttsc/strip spells each name with
|
|
@@ -4707,12 +5412,13 @@ func resolveDirLink(dir string) string {
|
|
|
4707
5412
|
// project being linted, with an explicit environment variable winning and a
|
|
4708
5413
|
// last resort that invents no path.
|
|
4709
5414
|
//
|
|
4710
|
-
//
|
|
4711
|
-
//
|
|
4712
|
-
//
|
|
4713
|
-
//
|
|
4714
|
-
//
|
|
4715
|
-
// outside a `ttsx`-launched
|
|
5415
|
+
// No automated check holds the three Go copies identical: a change lands in
|
|
5416
|
+
// all three by hand, and each package's own config-loader tests exercise it.
|
|
5417
|
+
// The JS original — `resolveConfigTsgo` / `resolveTtsxLauncher` in
|
|
5418
|
+
// packages/lint/src/index.ts — is a fourth copy in another language; the two
|
|
5419
|
+
// evaluators must keep one policy, because it was a divergence between them
|
|
5420
|
+
// that made a TypeScript lint config unevaluable outside a `ttsx`-launched
|
|
5421
|
+
// host.
|
|
4716
5422
|
//
|
|
4717
5423
|
// The environment alone is the wrong place to ask. `ttsx` exports
|
|
4718
5424
|
// TTSC_TSGO_BINARY and TTSC_TTSX_BINARY to its own descendants, so a host
|
|
@@ -5101,8 +5807,9 @@ func sortedRuleNames(config RuleConfig, include func(Severity) bool) []string {
|
|
|
5101
5807
|
// with "..").
|
|
5102
5808
|
func matchAnyPattern(baseDir string, patterns []string, fileName string) bool {
|
|
5103
5809
|
rel := filepath.ToSlash(fileName)
|
|
5810
|
+
base := ""
|
|
5104
5811
|
if baseDir != "" {
|
|
5105
|
-
base
|
|
5812
|
+
base = baseDir
|
|
5106
5813
|
if abs, err := filepath.Abs(base); err == nil {
|
|
5107
5814
|
base = abs
|
|
5108
5815
|
}
|
|
@@ -5117,9 +5824,29 @@ func matchAnyPattern(baseDir string, patterns []string, fileName string) bool {
|
|
|
5117
5824
|
return false
|
|
5118
5825
|
}
|
|
5119
5826
|
rel = filepath.ToSlash(candidate)
|
|
5827
|
+
} else {
|
|
5828
|
+
base = ""
|
|
5120
5829
|
}
|
|
5121
5830
|
}
|
|
5122
5831
|
rel = strings.TrimPrefix(rel, "./")
|
|
5832
|
+
if matchAnyGlob(patterns, rel) {
|
|
5833
|
+
return true
|
|
5834
|
+
}
|
|
5835
|
+
if base == "" {
|
|
5836
|
+
return false
|
|
5837
|
+
}
|
|
5838
|
+
// Most glob misses cannot become matches by changing only case. Rule
|
|
5839
|
+
// overrides test every file, so avoid a directory walk for those misses.
|
|
5840
|
+
// Character classes, escapes, and Unicode use the full on-disk decision:
|
|
5841
|
+
// lowercasing a class range can change which punctuation it admits.
|
|
5842
|
+
if !mayMatchStoredCase(patterns, rel) {
|
|
5843
|
+
return false
|
|
5844
|
+
}
|
|
5845
|
+
stored := storedRelativeSpelling(base, rel)
|
|
5846
|
+
return stored != rel && matchAnyGlob(patterns, stored)
|
|
5847
|
+
}
|
|
5848
|
+
|
|
5849
|
+
func matchAnyGlob(patterns []string, rel string) bool {
|
|
5123
5850
|
for _, pattern := range patterns {
|
|
5124
5851
|
if matchGlob(normalizeGlobPattern(pattern), rel) {
|
|
5125
5852
|
return true
|
|
@@ -5128,161 +5855,111 @@ func matchAnyPattern(baseDir string, patterns []string, fileName string) bool {
|
|
|
5128
5855
|
return false
|
|
5129
5856
|
}
|
|
5130
5857
|
|
|
5131
|
-
//
|
|
5132
|
-
//
|
|
5133
|
-
//
|
|
5134
|
-
//
|
|
5135
|
-
func
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
if !strings.Contains(pattern, "/") {
|
|
5139
|
-
return "**/" + pattern
|
|
5858
|
+
// mayMatchStoredCase is only a negative filter. A simple ASCII glob that
|
|
5859
|
+
// cannot match rel even without case has no stored-case match to discover.
|
|
5860
|
+
// Anything whose case folding or glob grammar needs more than ASCII is read
|
|
5861
|
+
// from the tree instead of risking a false negative.
|
|
5862
|
+
func mayMatchStoredCase(patterns []string, rel string) bool {
|
|
5863
|
+
if !isASCII(rel) {
|
|
5864
|
+
return true
|
|
5140
5865
|
}
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
// not appear in the part slices. Brace alternatives (`{a,b,c}`) are expanded
|
|
5148
|
-
// before matching so patterns like `src/foo/{a.ts,b.ts}` reach every branch —
|
|
5149
|
-
// Go's `filepath.Match` does not honor brace expansion natively.
|
|
5150
|
-
func matchGlob(pattern, name string) bool {
|
|
5151
|
-
pattern = strings.Trim(pattern, "/")
|
|
5152
|
-
name = strings.Trim(name, "/")
|
|
5153
|
-
if pattern == "" {
|
|
5154
|
-
return name == ""
|
|
5155
|
-
}
|
|
5156
|
-
nameParts := []string{}
|
|
5157
|
-
if name != "" {
|
|
5158
|
-
nameParts = strings.Split(name, "/")
|
|
5159
|
-
}
|
|
5160
|
-
for _, expanded := range expandBraces(pattern) {
|
|
5161
|
-
if matchGlobParts(strings.Split(expanded, "/"), nameParts) {
|
|
5866
|
+
folded := strings.ToLower(rel)
|
|
5867
|
+
for _, pattern := range patterns {
|
|
5868
|
+
if !isASCII(pattern) || strings.ContainsAny(pattern, "[]\\") {
|
|
5869
|
+
return true
|
|
5870
|
+
}
|
|
5871
|
+
if matchGlob(strings.ToLower(normalizeGlobPattern(pattern)), folded) {
|
|
5162
5872
|
return true
|
|
5163
5873
|
}
|
|
5164
5874
|
}
|
|
5165
5875
|
return false
|
|
5166
5876
|
}
|
|
5167
5877
|
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
// returned unchanged so that callers can treat the result as an authoritative
|
|
5173
|
-
// list of every concrete alternative the user wrote.
|
|
5174
|
-
//
|
|
5175
|
-
// Only top-level braces are recognized; nested braces inside another brace
|
|
5176
|
-
// group's alternative are honored by the recursion in alternative expansion,
|
|
5177
|
-
// but escaped braces (`\{`, `\}`) are not currently supported because lint
|
|
5178
|
-
// config patterns have no reason to embed literal braces. If a user ever needs
|
|
5179
|
-
// one, the simplest workaround is to author the glob without the brace group.
|
|
5180
|
-
func expandBraces(pattern string) []string {
|
|
5181
|
-
open := strings.IndexByte(pattern, '{')
|
|
5182
|
-
if open < 0 {
|
|
5183
|
-
return []string{pattern}
|
|
5184
|
-
}
|
|
5185
|
-
// Find the matching close brace, accounting for nested groups so the
|
|
5186
|
-
// outermost group is split first. A pattern with no matching close brace
|
|
5187
|
-
// is treated as a literal — return it unchanged. `closeIdx` shadows no
|
|
5188
|
-
// builtin (unlike the natural `close` name), which keeps `go vet` quiet.
|
|
5189
|
-
depth := 0
|
|
5190
|
-
closeIdx := -1
|
|
5191
|
-
for i := open; i < len(pattern); i++ {
|
|
5192
|
-
switch pattern[i] {
|
|
5193
|
-
case '{':
|
|
5194
|
-
depth++
|
|
5195
|
-
case '}':
|
|
5196
|
-
depth--
|
|
5197
|
-
if depth == 0 {
|
|
5198
|
-
closeIdx = i
|
|
5199
|
-
}
|
|
5200
|
-
}
|
|
5201
|
-
if closeIdx >= 0 {
|
|
5202
|
-
break
|
|
5203
|
-
}
|
|
5204
|
-
}
|
|
5205
|
-
if closeIdx < 0 {
|
|
5206
|
-
return []string{pattern}
|
|
5207
|
-
}
|
|
5208
|
-
prefix := pattern[:open]
|
|
5209
|
-
suffix := pattern[closeIdx+1:]
|
|
5210
|
-
// Split the brace body on top-level commas so nested groups remain
|
|
5211
|
-
// intact for the recursive expansion below.
|
|
5212
|
-
body := pattern[open+1 : closeIdx]
|
|
5213
|
-
alternatives := splitBraceAlternatives(body)
|
|
5214
|
-
// Expand each alternative against the suffix; the suffix may itself
|
|
5215
|
-
// contain further brace groups, which the recursive call handles.
|
|
5216
|
-
suffixExpansions := expandBraces(suffix)
|
|
5217
|
-
out := make([]string, 0, len(alternatives)*len(suffixExpansions))
|
|
5218
|
-
for _, alt := range alternatives {
|
|
5219
|
-
for _, altExpanded := range expandBraces(alt) {
|
|
5220
|
-
for _, suf := range suffixExpansions {
|
|
5221
|
-
out = append(out, prefix+altExpanded+suf)
|
|
5222
|
-
}
|
|
5878
|
+
func isASCII(value string) bool {
|
|
5879
|
+
for index := 0; index < len(value); index++ {
|
|
5880
|
+
if value[index] >= 0x80 {
|
|
5881
|
+
return false
|
|
5223
5882
|
}
|
|
5224
5883
|
}
|
|
5225
|
-
return
|
|
5884
|
+
return true
|
|
5226
5885
|
}
|
|
5227
5886
|
|
|
5228
|
-
//
|
|
5229
|
-
//
|
|
5230
|
-
//
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
start = i + 1
|
|
5247
|
-
}
|
|
5887
|
+
// storedRelativeSpelling returns `rel`, a slash-separated path below `base`,
|
|
5888
|
+
// spelled the way each directory stores its names. A Program can name a file
|
|
5889
|
+
// the way an import spelled it, and on a volume that ignores case (macOS's
|
|
5890
|
+
// default) `SRC/DIRECTORY/index.ts` reaches `src/directory/index.ts` while
|
|
5891
|
+
// `filepath.EvalSymlinks` keeps the import's spelling, so a glob written
|
|
5892
|
+
// against the tree missed it (samchon/ttsc#1589). Each component its parent
|
|
5893
|
+
// does not list exactly is replaced by the one entry equal to it ignoring
|
|
5894
|
+
// case; a path that does not exist, or a component with no single such entry,
|
|
5895
|
+
// keeps the given spelling.
|
|
5896
|
+
func storedRelativeSpelling(base, rel string) string {
|
|
5897
|
+
if _, err := os.Stat(filepath.Join(base, filepath.FromSlash(rel))); err != nil {
|
|
5898
|
+
return rel
|
|
5899
|
+
}
|
|
5900
|
+
current := base
|
|
5901
|
+
components := strings.Split(rel, "/")
|
|
5902
|
+
for index, component := range components {
|
|
5903
|
+
if component == "" || component == "." {
|
|
5904
|
+
continue
|
|
5248
5905
|
}
|
|
5906
|
+
components[index] = storedEntryName(current, component)
|
|
5907
|
+
current = filepath.Join(current, components[index])
|
|
5249
5908
|
}
|
|
5250
|
-
|
|
5251
|
-
return out
|
|
5909
|
+
return strings.Join(components, "/")
|
|
5252
5910
|
}
|
|
5253
5911
|
|
|
5254
|
-
//
|
|
5255
|
-
//
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
return len(nameParts) == 0
|
|
5912
|
+
// storedEntryName is the name `directory` stores for `name`: `name` itself when
|
|
5913
|
+
// the directory lists it, else its single entry equal to it ignoring case.
|
|
5914
|
+
func storedEntryName(directory, name string) string {
|
|
5915
|
+
entries, err := os.ReadDir(directory)
|
|
5916
|
+
if err != nil {
|
|
5917
|
+
return name
|
|
5261
5918
|
}
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
if
|
|
5265
|
-
return
|
|
5919
|
+
match := ""
|
|
5920
|
+
for _, entry := range entries {
|
|
5921
|
+
if entry.Name() == name {
|
|
5922
|
+
return name
|
|
5266
5923
|
}
|
|
5267
|
-
|
|
5268
|
-
if
|
|
5269
|
-
return
|
|
5924
|
+
if strings.EqualFold(entry.Name(), name) {
|
|
5925
|
+
if match != "" {
|
|
5926
|
+
return name
|
|
5270
5927
|
}
|
|
5928
|
+
match = entry.Name()
|
|
5271
5929
|
}
|
|
5272
|
-
return false
|
|
5273
5930
|
}
|
|
5274
|
-
if
|
|
5275
|
-
return
|
|
5931
|
+
if match == "" {
|
|
5932
|
+
return name
|
|
5276
5933
|
}
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5934
|
+
return match
|
|
5935
|
+
}
|
|
5936
|
+
|
|
5937
|
+
// normalizeGlobPattern normalizes a user-supplied glob pattern to forward
|
|
5938
|
+
// slashes and strips a leading "./". Patterns that contain no slash are treated
|
|
5939
|
+
// as basename-only globs by prepending "**/" so that `*.ts` matches any
|
|
5940
|
+
// TypeScript file regardless of directory depth, matching ESLint's behavior.
|
|
5941
|
+
func normalizeGlobPattern(pattern string) string {
|
|
5942
|
+
pattern = filepath.ToSlash(pattern)
|
|
5943
|
+
pattern = strings.TrimPrefix(pattern, "./")
|
|
5944
|
+
if !strings.Contains(pattern, "/") {
|
|
5945
|
+
return "**/" + pattern
|
|
5280
5946
|
}
|
|
5281
|
-
return
|
|
5947
|
+
return pattern
|
|
5282
5948
|
}
|
|
5283
5949
|
|
|
5284
5950
|
// Severity returns the configured level for a rule, defaulting to
|
|
5285
5951
|
// `SeverityOff`. Rules opt in explicitly — silent on missing entries.
|
|
5952
|
+
// Lookup accepts either canonical or eslint-prefixed stored keys after map
|
|
5953
|
+
// identity validation through ResolveProjectRules.
|
|
5954
|
+
//
|
|
5955
|
+
// @evidence contracts/common.md#principled-implementation Exact, canonical and unique normalized-alias lookup preserve explicit off values and default only absent names to off after identity validation.
|
|
5956
|
+
// @evidence contracts/common.md#clear-and-simple-design One scalar lookup owns absence behavior without constructing a normalized map for each rule query.
|
|
5957
|
+
// @evidence contracts/common.md#prohibited-implementation-shortcuts Missing declarations remain disabled by documented policy rather than a fixture-specific activation fallback.
|
|
5958
|
+
// @evidence contracts/common.md#meaningful-documentation Native prose explains opt-in absence and the direction of alias lookup, separated from the acknowledgment tags.
|
|
5959
|
+
// @evidenceExclude contracts/portability.md#os-neutral-implementation Severity looks up a rule severity by name and touches no filesystem path or process.
|
|
5960
|
+
// @evidence contracts/performance.md#efficient-algorithms Exact and canonical keys use an expected constant number of map probes, with hashing and normalization proportional to query-name bytes. Only a miss scans n stored names, paying their normalization/comparison byte costs; no normalized map or cached snapshot is built.
|
|
5961
|
+
// @evidenceExclude contracts/performance.md#reuse-equivalent-work Severity keeps no cache and shares no computation.
|
|
5962
|
+
// @evidenceExclude contracts/performance.md#bound-retention-and-release-resources Severity acquires no handle or task and retains nothing.
|
|
5286
5963
|
func (c RuleConfig) Severity(name string) Severity {
|
|
5287
5964
|
if c == nil {
|
|
5288
5965
|
return SeverityOff
|
|
@@ -5294,6 +5971,11 @@ func (c RuleConfig) Severity(name string) Severity {
|
|
|
5294
5971
|
if sev, ok := c[canonical]; ok {
|
|
5295
5972
|
return sev
|
|
5296
5973
|
}
|
|
5974
|
+
for storedName, sev := range c {
|
|
5975
|
+
if normalizeBuiltinRuleName(storedName) == canonical {
|
|
5976
|
+
return sev
|
|
5977
|
+
}
|
|
5978
|
+
}
|
|
5297
5979
|
return SeverityOff
|
|
5298
5980
|
}
|
|
5299
5981
|
|
|
@@ -5310,8 +5992,11 @@ func (c RuleConfig) Severity(name string) Severity {
|
|
|
5310
5992
|
// writes, and namespaced so it cannot collide with a payload field. This file
|
|
5311
5993
|
// spends "error" on rule severity, which is exactly the confusion a shared,
|
|
5312
5994
|
// prefixed key avoids.
|
|
5313
|
-
|
|
5995
|
+
// observe receives this same read's bytes and error before envelope decoding;
|
|
5996
|
+
// it cannot substitute bytes or alter the returned failure reason.
|
|
5997
|
+
func loaderFailureReason(outputPath string, observe func([]byte, error)) string {
|
|
5314
5998
|
raw, err := os.ReadFile(outputPath)
|
|
5999
|
+
observe(raw, err)
|
|
5315
6000
|
if err != nil {
|
|
5316
6001
|
return ""
|
|
5317
6002
|
}
|