@ttsc/lint 0.13.0 → 0.14.0-dev.20250530.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +955 -85
- package/lib/defaultFormat.d.ts +15 -8
- package/lib/defaultFormat.js +15 -8
- package/lib/defaultFormat.js.map +1 -1
- package/lib/index.d.ts +46 -0
- package/lib/index.js +60 -37
- package/lib/index.js.map +1 -1
- package/lib/structures/ITtscLintConfig.d.ts +12 -6
- package/lib/structures/TtscLintRuleSetting.d.ts +49 -0
- package/lib/structures/{TtscLintRuleOptions.js → TtscLintRuleSetting.js} +1 -1
- package/lib/structures/TtscLintRuleSetting.js.map +1 -0
- package/lib/structures/format/ITtscLintFormat.d.ts +128 -0
- package/lib/structures/{TtscLintRuleMap.js → format/ITtscLintFormat.js} +1 -1
- package/lib/structures/format/ITtscLintFormat.js.map +1 -0
- package/lib/structures/format/ITtscLintFormatJsDoc.d.ts +17 -0
- package/lib/structures/{ITtscLintFormatConfig.js → format/ITtscLintFormatJsDoc.js} +1 -1
- package/lib/structures/format/ITtscLintFormatJsDoc.js.map +1 -0
- package/lib/structures/format/ITtscLintFormatSortImports.d.ts +54 -0
- package/lib/structures/format/ITtscLintFormatSortImports.js +3 -0
- package/lib/structures/format/ITtscLintFormatSortImports.js.map +1 -0
- package/lib/structures/format/index.d.ts +3 -0
- package/lib/structures/format/index.js +20 -0
- package/lib/structures/format/index.js.map +1 -0
- package/lib/structures/index.d.ts +3 -4
- package/lib/structures/index.js +3 -4
- package/lib/structures/index.js.map +1 -1
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +95 -0
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +13 -0
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +75 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.js +3 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintContributorRules.d.ts +16 -0
- package/lib/structures/rules/ITtscLintContributorRules.js +3 -0
- package/lib/structures/rules/ITtscLintContributorRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintCoreRules.d.ts +1229 -0
- package/lib/structures/rules/ITtscLintCoreRules.js +3 -0
- package/lib/structures/rules/ITtscLintCoreRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +17 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js +10 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintCypressRules.d.ts +125 -0
- package/lib/structures/rules/ITtscLintCypressRules.js +3 -0
- package/lib/structures/rules/ITtscLintCypressRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +154 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +13 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +162 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.js +3 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJestRules.d.ts +190 -0
- package/lib/structures/rules/ITtscLintJestRules.js +3 -0
- package/lib/structures/rules/ITtscLintJestRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJsdocRules.d.ts +133 -0
- package/lib/structures/rules/ITtscLintJsdocRules.js +3 -0
- package/lib/structures/rules/ITtscLintJsdocRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +294 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.js +3 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintNextjsRules.d.ts +180 -0
- package/lib/structures/rules/ITtscLintNextjsRules.js +3 -0
- package/lib/structures/rules/ITtscLintNextjsRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +312 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.js +3 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintPromiseRules.d.ts +179 -0
- package/lib/structures/rules/ITtscLintPromiseRules.js +3 -0
- package/lib/structures/rules/ITtscLintPromiseRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +18 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js +8 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +49 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.js +3 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +37 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.js +11 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactRules.d.ts +276 -0
- package/lib/structures/rules/ITtscLintReactRules.js +3 -0
- package/lib/structures/rules/ITtscLintReactRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintRegexpRules.d.ts +182 -0
- package/lib/structures/rules/ITtscLintRegexpRules.js +3 -0
- package/lib/structures/rules/ITtscLintRegexpRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +65 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.js +3 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.js.map +1 -0
- package/lib/structures/rules/ITtscLintRules.d.ts +55 -0
- package/lib/structures/{TtscLintRule.js → rules/ITtscLintRules.js} +1 -1
- package/lib/structures/rules/ITtscLintRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintSecurityRules.d.ts +141 -0
- package/lib/structures/rules/ITtscLintSecurityRules.js +3 -0
- package/lib/structures/rules/ITtscLintSecurityRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintSolidRules.d.ts +178 -0
- package/lib/structures/rules/ITtscLintSolidRules.js +3 -0
- package/lib/structures/rules/ITtscLintSolidRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +20 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.js +9 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintStorybookRules.d.ts +165 -0
- package/lib/structures/rules/ITtscLintStorybookRules.js +3 -0
- package/lib/structures/rules/ITtscLintStorybookRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +88 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.js +3 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +21 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js +10 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +293 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.js +3 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +1074 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.js +3 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintUnicornRules.d.ts +997 -0
- package/lib/structures/rules/ITtscLintUnicornRules.js +3 -0
- package/lib/structures/rules/ITtscLintUnicornRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintVitestRules.d.ts +133 -0
- package/lib/structures/rules/ITtscLintVitestRules.js +3 -0
- package/lib/structures/rules/ITtscLintVitestRules.js.map +1 -0
- package/lib/structures/rules/index.d.ts +31 -0
- package/lib/structures/rules/index.js +48 -0
- package/lib/structures/rules/index.js.map +1 -0
- package/linthost/ast_helpers.go +30 -5
- package/linthost/compile.go +33 -2
- package/linthost/config.go +118 -71
- package/linthost/config_format.go +270 -104
- package/linthost/directives.go +67 -25
- package/linthost/dispatch.go +14 -3
- package/linthost/engine.go +160 -40
- package/linthost/fix.go +10 -3
- package/linthost/flags_gen.go +17 -15
- package/linthost/format.go +222 -25
- package/linthost/format_editor_settings.go +262 -0
- package/linthost/host.go +40 -3
- package/linthost/lsp.go +898 -0
- package/linthost/print_dispatch.go +5 -2
- package/linthost/print_engine.go +5 -5
- package/linthost/print_nodes_call.go +149 -67
- package/linthost/print_nodes_function.go +27 -2
- package/linthost/print_nodes_list.go +40 -5
- package/linthost/print_nodes_object.go +1 -1
- package/linthost/print_nodes_ternary.go +86 -0
- package/linthost/rule_names.go +14 -0
- package/linthost/rules_arrays.go +2 -2
- package/linthost/rules_boundaries.go +532 -0
- package/linthost/rules_camelcase.go +133 -0
- package/linthost/rules_complexity.go +95 -0
- package/linthost/rules_consistent_return.go +130 -0
- package/linthost/rules_console.go +1 -1
- package/linthost/rules_core_extra.go +739 -0
- package/linthost/rules_curly.go +70 -0
- package/linthost/rules_cypress.go +608 -0
- package/linthost/rules_debugger.go +2 -2
- package/linthost/rules_default_case.go +39 -0
- package/linthost/rules_default_case_last.go +46 -0
- package/linthost/rules_dupes.go +3 -3
- package/linthost/rules_empty.go +3 -3
- package/linthost/rules_escape.go +44 -24
- package/linthost/rules_eval.go +2 -2
- package/linthost/rules_finally.go +2 -2
- package/linthost/rules_format_arrow_parens.go +167 -0
- package/linthost/rules_format_bracket_spacing.go +117 -0
- package/linthost/rules_format_clause_join.go +172 -0
- package/linthost/rules_format_declaration_header.go +595 -0
- package/linthost/rules_format_indent.go +372 -0
- package/linthost/rules_format_jsdoc.go +5 -5
- package/linthost/rules_format_orphan_semi.go +106 -0
- package/linthost/rules_format_parameter_properties.go +175 -0
- package/linthost/rules_format_print_width.go +66 -55
- package/linthost/rules_format_quote_props.go +169 -0
- package/linthost/rules_format_quotes.go +76 -30
- package/linthost/rules_format_semi.go +186 -11
- package/linthost/rules_format_sort_imports.go +437 -118
- package/linthost/rules_format_statement_split.go +343 -0
- package/linthost/rules_format_ternary_nullish_parens.go +77 -0
- package/linthost/rules_format_trailing_comma.go +22 -3
- package/linthost/rules_format_whitespace.go +336 -0
- package/linthost/rules_functional.go +967 -0
- package/linthost/rules_gap.go +24 -45
- package/linthost/rules_grouped_accessor_pairs.go +87 -0
- package/linthost/rules_guard_for_in.go +198 -0
- package/linthost/rules_id_length.go +77 -0
- package/linthost/rules_imports.go +70 -2
- package/linthost/rules_init_declarations.go +53 -0
- package/linthost/rules_jest.go +618 -0
- package/linthost/rules_jsdoc.go +502 -0
- package/linthost/rules_jsx_a11y.go +1264 -0
- package/linthost/rules_logic.go +12 -12
- package/linthost/rules_loops.go +1 -1
- package/linthost/rules_max_classes_per_file.go +58 -0
- package/linthost/rules_max_depth.go +83 -0
- package/linthost/rules_max_lines.go +101 -0
- package/linthost/rules_max_lines_per_function.go +57 -0
- package/linthost/rules_max_nested_callbacks.go +61 -0
- package/linthost/rules_max_params.go +49 -0
- package/linthost/rules_max_statements.go +59 -0
- package/linthost/rules_misc.go +1 -1
- package/linthost/rules_nextjs.go +697 -0
- package/linthost/rules_no_else_return.go +75 -0
- package/linthost/rules_no_empty_named_blocks.go +91 -0
- package/linthost/rules_no_extend_native.go +51 -0
- package/linthost/rules_no_import_assign.go +140 -0
- package/linthost/rules_no_invalid_this.go +52 -0
- package/linthost/rules_no_loop_func.go +85 -0
- package/linthost/rules_no_magic_numbers.go +123 -0
- package/linthost/rules_no_mixed_operators.go +80 -0
- package/linthost/rules_no_param_reassign.go +98 -0
- package/linthost/rules_no_redeclare.go +270 -0
- package/linthost/rules_no_restricted_imports.go +105 -0
- package/linthost/rules_no_restricted_syntax.go +49 -0
- package/linthost/rules_no_shadow.go +147 -0
- package/linthost/rules_no_unreachable.go +77 -0
- package/linthost/rules_no_useless_assignment.go +120 -0
- package/linthost/rules_no_useless_constructor.go +245 -0
- package/linthost/rules_no_useless_return.go +51 -0
- package/linthost/rules_params.go +1 -1
- package/linthost/rules_playwright.go +788 -0
- package/linthost/rules_prefer_arrow_callback.go +124 -0
- package/linthost/rules_prefer_destructuring.go +98 -0
- package/linthost/rules_prefer_named_capture_group.go +129 -0
- package/linthost/rules_prefer_rest_params.go +94 -0
- package/linthost/rules_problems.go +41 -30
- package/linthost/rules_promise.go +1057 -2
- package/linthost/rules_protos.go +2 -2
- package/linthost/rules_react.go +773 -0
- package/linthost/rules_react_extras.go +227 -0
- package/linthost/rules_react_hooks.go +848 -0
- package/linthost/rules_react_perf.go +293 -0
- package/linthost/rules_react_refresh.go +583 -0
- package/linthost/rules_regexp.go +410 -0
- package/linthost/rules_security.go +830 -0
- package/linthost/rules_self.go +2 -2
- package/linthost/rules_solid.go +1073 -0
- package/linthost/rules_sort_imports.go +69 -0
- package/linthost/rules_sort_keys.go +134 -0
- package/linthost/rules_storybook.go +1176 -0
- package/linthost/rules_strings.go +4 -4
- package/linthost/rules_suggestions.go +38 -38
- package/linthost/rules_tanstack_query.go +844 -0
- package/linthost/rules_testing_library.go +1204 -0
- package/linthost/rules_throw.go +1 -1
- package/linthost/rules_ts.go +19 -19
- package/linthost/rules_ts_async.go +399 -0
- package/linthost/rules_ts_class_literal_property_style.go +115 -0
- package/linthost/rules_ts_consistent_type_exports.go +256 -0
- package/linthost/rules_ts_explicit_function_return_type.go +67 -0
- package/linthost/rules_ts_extra.go +159 -36
- package/linthost/rules_ts_no_base_to_string.go +218 -0
- package/linthost/rules_ts_no_confusing_void.go +72 -0
- package/linthost/rules_ts_no_deprecated.go +195 -0
- package/linthost/rules_ts_no_for_in_array.go +84 -0
- package/linthost/rules_ts_no_magic_numbers.go +124 -0
- package/linthost/rules_ts_no_meaningless_void_operator.go +84 -0
- package/linthost/rules_ts_no_misused_spread.go +104 -0
- package/linthost/rules_ts_no_redundant_type_constituents.go +113 -0
- package/linthost/rules_ts_no_restricted_types.go +62 -0
- package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +129 -0
- package/linthost/rules_ts_no_unnecessary_condition.go +250 -0
- package/linthost/rules_ts_no_unnecessary_qualifier.go +118 -0
- package/linthost/rules_ts_no_unnecessary_template_expression.go +178 -0
- package/linthost/rules_ts_no_unnecessary_type_arguments.go +234 -0
- package/linthost/rules_ts_no_unnecessary_type_assertion.go +157 -0
- package/linthost/rules_ts_no_unsafe_argument.go +82 -0
- package/linthost/rules_ts_no_unsafe_assignment.go +102 -0
- package/linthost/rules_ts_no_unsafe_call.go +82 -0
- package/linthost/rules_ts_no_unsafe_enum_comparison.go +235 -0
- package/linthost/rules_ts_no_unsafe_member_access.go +58 -0
- package/linthost/rules_ts_no_unsafe_return.go +126 -0
- package/linthost/rules_ts_no_unsafe_unary_minus.go +81 -0
- package/linthost/rules_ts_no_useless_constructor.go +52 -0
- package/linthost/rules_ts_non_nullable_type_assertion_style.go +108 -0
- package/linthost/rules_ts_parameter_properties.go +38 -0
- package/linthost/rules_ts_prefer_find.go +178 -0
- package/linthost/rules_ts_prefer_includes.go +255 -0
- package/linthost/rules_ts_prefer_nullish_coalescing.go +104 -0
- package/linthost/rules_ts_prefer_optional_chain.go +228 -0
- package/linthost/rules_ts_prefer_promise_reject_errors.go +176 -0
- package/linthost/rules_ts_prefer_readonly.go +73 -0
- package/linthost/rules_ts_prefer_reduce_type_parameter.go +116 -0
- package/linthost/rules_ts_prefer_regexp_exec.go +122 -0
- package/linthost/rules_ts_prefer_return_this_type.go +135 -0
- package/linthost/rules_ts_prefer_string_starts_ends_with.go +360 -0
- package/linthost/rules_ts_promise_function_async.go +77 -0
- package/linthost/rules_ts_related_getter_setter_pairs.go +113 -0
- package/linthost/rules_ts_require_array_sort_compare.go +96 -0
- package/linthost/rules_ts_restrict_plus_operands.go +127 -0
- package/linthost/rules_ts_restrict_template_expressions.go +95 -0
- package/linthost/rules_ts_simple.go +387 -0
- package/linthost/rules_ts_sort_type_constituents.go +144 -0
- package/linthost/rules_ts_strict_boolean_expressions.go +157 -0
- package/linthost/rules_ts_switch_exhaustiveness_check.go +147 -0
- package/linthost/rules_ts_unbound_method.go +126 -0
- package/linthost/rules_tsdoc.go +136 -0
- package/linthost/rules_unicorn_better_regex.go +27 -0
- package/linthost/rules_unicorn_catch_error_name.go +46 -0
- package/linthost/rules_unicorn_consistent_assert.go +47 -0
- package/linthost/rules_unicorn_consistent_date_clone.go +54 -0
- package/linthost/rules_unicorn_consistent_destructuring.go +25 -0
- package/linthost/rules_unicorn_consistent_empty_array_spread.go +62 -0
- package/linthost/rules_unicorn_consistent_existence_index_check.go +80 -0
- package/linthost/rules_unicorn_consistent_function_scoping.go +25 -0
- package/linthost/rules_unicorn_consistent_template_literal_escape.go +25 -0
- package/linthost/rules_unicorn_custom_error_definition.go +138 -0
- package/linthost/rules_unicorn_empty_brace_spaces.go +73 -0
- package/linthost/rules_unicorn_error_message.go +64 -0
- package/linthost/rules_unicorn_escape_case.go +51 -0
- package/linthost/rules_unicorn_expiring_todo_comments.go +78 -0
- package/linthost/rules_unicorn_explicit_length_check.go +88 -0
- package/linthost/rules_unicorn_filename_case.go +29 -0
- package/linthost/rules_unicorn_import_style.go +28 -0
- package/linthost/rules_unicorn_isolated_functions.go +29 -0
- package/linthost/rules_unicorn_new_for_builtins.go +87 -0
- package/linthost/rules_unicorn_no_abusive_eslint_disable.go +63 -0
- package/linthost/rules_unicorn_no_accessor_recursion.go +115 -0
- package/linthost/rules_unicorn_no_anonymous_default_export.go +74 -0
- package/linthost/rules_unicorn_no_array_callback_reference.go +65 -0
- package/linthost/rules_unicorn_no_array_for_each.go +40 -0
- package/linthost/rules_unicorn_no_array_method_this_argument.go +61 -0
- package/linthost/rules_unicorn_no_array_reduce.go +41 -0
- package/linthost/rules_unicorn_no_array_reverse.go +44 -0
- package/linthost/rules_unicorn_no_array_sort.go +43 -0
- package/linthost/rules_unicorn_no_await_expression_member.go +40 -0
- package/linthost/rules_unicorn_no_await_in_promise_methods.go +69 -0
- package/linthost/rules_unicorn_no_console_spaces.go +61 -0
- package/linthost/rules_unicorn_no_document_cookie.go +41 -0
- package/linthost/rules_unicorn_no_empty_file.go +44 -0
- package/linthost/rules_unicorn_no_for_loop.go +102 -0
- package/linthost/rules_unicorn_no_hex_escape.go +42 -0
- package/linthost/rules_unicorn_no_immediate_mutation.go +90 -0
- package/linthost/rules_unicorn_no_instanceof_builtins.go +66 -0
- package/linthost/rules_unicorn_no_invalid_fetch_options.go +79 -0
- package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +51 -0
- package/linthost/rules_unicorn_no_keyword_prefix.go +101 -0
- package/linthost/rules_unicorn_no_lonely_if.go +44 -0
- package/linthost/rules_unicorn_no_magic_array_flat_depth.go +51 -0
- package/linthost/rules_unicorn_no_named_default.go +54 -0
- package/linthost/rules_unicorn_no_negated_condition.go +85 -0
- package/linthost/rules_unicorn_no_negation_in_equality_check.go +50 -0
- package/linthost/rules_unicorn_no_nested_ternary.go +43 -0
- package/linthost/rules_unicorn_no_new_array.go +30 -0
- package/linthost/rules_unicorn_no_new_buffer.go +31 -0
- package/linthost/rules_unicorn_no_null.go +24 -0
- package/linthost/rules_unicorn_no_object_as_default_parameter.go +48 -0
- package/linthost/rules_unicorn_no_process_exit.go +43 -0
- package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +59 -0
- package/linthost/rules_unicorn_no_static_only_class.go +56 -0
- package/linthost/rules_unicorn_no_thenable.go +74 -0
- package/linthost/rules_unicorn_no_this_assignment.go +35 -0
- package/linthost/rules_unicorn_no_typeof_undefined.go +58 -0
- package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +49 -0
- package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +70 -0
- package/linthost/rules_unicorn_no_unnecessary_await.go +51 -0
- package/linthost/rules_unicorn_no_unnecessary_polyfills.go +32 -0
- package/linthost/rules_unicorn_no_unnecessary_slice_end.go +48 -0
- package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +115 -0
- package/linthost/rules_unicorn_no_unreadable_iife.go +50 -0
- package/linthost/rules_unicorn_no_unused_properties.go +30 -0
- package/linthost/rules_unicorn_no_useless_collection_argument.go +63 -0
- package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +46 -0
- package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +81 -0
- package/linthost/rules_unicorn_no_useless_iterator_to_array.go +72 -0
- package/linthost/rules_unicorn_no_useless_length_check.go +144 -0
- package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +81 -0
- package/linthost/rules_unicorn_no_useless_spread.go +67 -0
- package/linthost/rules_unicorn_no_useless_switch_case.go +55 -0
- package/linthost/rules_unicorn_no_useless_undefined.go +55 -0
- package/linthost/rules_unicorn_no_zero_fractions.go +52 -0
- package/linthost/rules_unicorn_number_literal_case.go +69 -0
- package/linthost/rules_unicorn_numeric_separators_style.go +75 -0
- package/linthost/rules_unicorn_prefer_add_event_listener.go +66 -0
- package/linthost/rules_unicorn_prefer_array_find.go +51 -0
- package/linthost/rules_unicorn_prefer_array_flat.go +52 -0
- package/linthost/rules_unicorn_prefer_array_flat_map.go +63 -0
- package/linthost/rules_unicorn_prefer_array_index_of.go +147 -0
- package/linthost/rules_unicorn_prefer_array_some.go +67 -0
- package/linthost/rules_unicorn_prefer_at.go +77 -0
- package/linthost/rules_unicorn_prefer_bigint_literals.go +77 -0
- package/linthost/rules_unicorn_prefer_blob_reading_methods.go +44 -0
- package/linthost/rules_unicorn_prefer_class_fields.go +93 -0
- package/linthost/rules_unicorn_prefer_classlist_toggle.go +120 -0
- package/linthost/rules_unicorn_prefer_code_point.go +49 -0
- package/linthost/rules_unicorn_prefer_date_now.go +78 -0
- package/linthost/rules_unicorn_prefer_default_parameters.go +144 -0
- package/linthost/rules_unicorn_prefer_dom_node_append.go +40 -0
- package/linthost/rules_unicorn_prefer_dom_node_dataset.go +55 -0
- package/linthost/rules_unicorn_prefer_dom_node_remove.go +41 -0
- package/linthost/rules_unicorn_prefer_dom_node_text_content.go +37 -0
- package/linthost/rules_unicorn_prefer_event_target.go +36 -0
- package/linthost/rules_unicorn_prefer_export_from.go +129 -0
- package/linthost/rules_unicorn_prefer_global_this.go +127 -0
- package/linthost/rules_unicorn_prefer_import_meta_properties.go +66 -0
- package/linthost/rules_unicorn_prefer_includes.go +149 -0
- package/linthost/rules_unicorn_prefer_json_parse_buffer.go +65 -0
- package/linthost/rules_unicorn_prefer_keyboard_event_key.go +38 -0
- package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +48 -0
- package/linthost/rules_unicorn_prefer_math_min_max.go +60 -0
- package/linthost/rules_unicorn_prefer_math_trunc.go +62 -0
- package/linthost/rules_unicorn_prefer_modern_dom_apis.go +47 -0
- package/linthost/rules_unicorn_prefer_modern_math_apis.go +70 -0
- package/linthost/rules_unicorn_prefer_module.go +50 -0
- package/linthost/rules_unicorn_prefer_native_coercion_functions.go +114 -0
- package/linthost/rules_unicorn_prefer_negative_index.go +74 -0
- package/linthost/rules_unicorn_prefer_node_protocol.go +122 -0
- package/linthost/rules_unicorn_prefer_number_properties.go +88 -0
- package/linthost/rules_unicorn_prefer_object_from_entries.go +55 -0
- package/linthost/rules_unicorn_prefer_optional_catch_binding.go +62 -0
- package/linthost/rules_unicorn_prefer_prototype_methods.go +54 -0
- package/linthost/rules_unicorn_prefer_query_selector.go +56 -0
- package/linthost/rules_unicorn_prefer_reflect_apply.go +36 -0
- package/linthost/rules_unicorn_prefer_regexp_test_rule.go +80 -0
- package/linthost/rules_unicorn_prefer_response_static_json.go +53 -0
- package/linthost/rules_unicorn_prefer_set_has.go +42 -0
- package/linthost/rules_unicorn_prefer_set_size.go +48 -0
- package/linthost/rules_unicorn_prefer_simple_condition_first.go +34 -0
- package/linthost/rules_unicorn_prefer_single_call.go +96 -0
- package/linthost/rules_unicorn_prefer_spread.go +51 -0
- package/linthost/rules_unicorn_prefer_string_raw.go +43 -0
- package/linthost/rules_unicorn_prefer_string_replace_all.go +95 -0
- package/linthost/rules_unicorn_prefer_string_slice.go +43 -0
- package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +148 -0
- package/linthost/rules_unicorn_prefer_string_trim_start_end.go +48 -0
- package/linthost/rules_unicorn_prefer_structured_clone.go +71 -0
- package/linthost/rules_unicorn_prefer_switch.go +103 -0
- package/linthost/rules_unicorn_prefer_ternary.go +71 -0
- package/linthost/rules_unicorn_prefer_top_level_await.go +72 -0
- package/linthost/rules_unicorn_prefer_type_error.go +127 -0
- package/linthost/rules_unicorn_prevent_abbreviations.go +127 -0
- package/linthost/rules_unicorn_relative_url_style.go +49 -0
- package/linthost/rules_unicorn_require_array_join_separator.go +45 -0
- package/linthost/rules_unicorn_require_module_attributes.go +54 -0
- package/linthost/rules_unicorn_require_module_specifiers.go +55 -0
- package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +43 -0
- package/linthost/rules_unicorn_require_post_message_target_origin.go +44 -0
- package/linthost/rules_unicorn_string_content.go +27 -0
- package/linthost/rules_unicorn_switch_case_braces.go +42 -0
- package/linthost/rules_unicorn_switch_case_break_position.go +31 -0
- package/linthost/rules_unicorn_template_indent.go +28 -0
- package/linthost/rules_unicorn_text_encoding_identifier_case.go +72 -0
- package/linthost/rules_unicorn_throw_new_error.go +61 -0
- package/linthost/rules_var.go +10 -4
- package/linthost/rules_vitest.go +568 -0
- package/package.json +3 -3
- package/plugin/main.go +49 -3
- package/rule/astutil/astutil.go +10 -3
- package/rule/rule.go +12 -10
- package/src/defaultFormat.ts +17 -10
- package/src/index.ts +65 -43
- package/src/structures/ITtscLintConfig.ts +14 -8
- package/src/structures/TtscLintRuleSetting.ts +55 -0
- package/src/structures/format/ITtscLintFormat.ts +141 -0
- package/src/structures/format/ITtscLintFormatJsDoc.ts +18 -0
- package/src/structures/format/ITtscLintFormatSortImports.ts +62 -0
- package/src/structures/format/index.ts +3 -0
- package/src/structures/index.ts +3 -4
- package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +117 -0
- package/src/structures/rules/ITtscLintBoundariesRules.ts +91 -0
- package/src/structures/rules/ITtscLintContributorRules.ts +20 -0
- package/src/structures/rules/ITtscLintCoreRules.ts +1378 -0
- package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
- package/src/structures/rules/ITtscLintCypressRules.ts +141 -0
- package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +200 -0
- package/src/structures/rules/ITtscLintFunctionalRules.ts +197 -0
- package/src/structures/rules/ITtscLintJestRules.ts +209 -0
- package/src/structures/rules/ITtscLintJsdocRules.ts +146 -0
- package/src/structures/rules/ITtscLintJsxA11yRules.ts +331 -0
- package/src/structures/rules/ITtscLintNextjsRules.ts +201 -0
- package/src/structures/rules/ITtscLintPlaywrightRules.ts +343 -0
- package/src/structures/rules/ITtscLintPromiseRules.ts +196 -0
- package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
- package/src/structures/rules/ITtscLintReactPerfRules.ts +53 -0
- package/src/structures/rules/ITtscLintReactRuleOptions.ts +41 -0
- package/src/structures/rules/ITtscLintReactRules.ts +308 -0
- package/src/structures/rules/ITtscLintRegexpRules.ts +204 -0
- package/src/structures/rules/ITtscLintRuleOptionsMap.ts +88 -0
- package/src/structures/rules/ITtscLintRules.ts +77 -0
- package/src/structures/rules/ITtscLintSecurityRules.ts +155 -0
- package/src/structures/rules/ITtscLintSolidRules.ts +199 -0
- package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +22 -0
- package/src/structures/rules/ITtscLintStorybookRules.ts +184 -0
- package/src/structures/rules/ITtscLintTanstackQueryRules.ts +96 -0
- package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +23 -0
- package/src/structures/rules/ITtscLintTestingLibraryRules.ts +325 -0
- package/src/structures/rules/ITtscLintTypeScriptRules.ts +1172 -0
- package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
- package/src/structures/rules/ITtscLintVitestRules.ts +146 -0
- package/src/structures/rules/index.ts +31 -0
- package/lib/structures/ITtscLintFormatConfig.d.ts +0 -153
- package/lib/structures/ITtscLintFormatConfig.js.map +0 -1
- package/lib/structures/TtscLintRule.d.ts +0 -17
- package/lib/structures/TtscLintRule.js.map +0 -1
- package/lib/structures/TtscLintRuleMap.d.ts +0 -46
- package/lib/structures/TtscLintRuleMap.js.map +0 -1
- package/lib/structures/TtscLintRuleOptions.d.ts +0 -137
- package/lib/structures/TtscLintRuleOptions.js.map +0 -1
- package/src/structures/ITtscLintFormatConfig.ts +0 -168
- package/src/structures/TtscLintRule.ts +0 -160
- package/src/structures/TtscLintRuleMap.ts +0 -55
- package/src/structures/TtscLintRuleOptions.ts +0 -151
|
@@ -28,7 +28,7 @@ import (
|
|
|
28
28
|
// indented, corrupt output. To prevent that, every printer reports a
|
|
29
29
|
// `covered` boolean alongside its Doc: `true` means the whole printed
|
|
30
30
|
// subtree is reflow-safe (no multi-line verbatim node), `false` means a
|
|
31
|
-
// multi-line verbatim node is buried inside. The
|
|
31
|
+
// multi-line verbatim node is buried inside. The formatPrintWidth
|
|
32
32
|
// rule abstains entirely when `covered` is false, so `ttsc format`
|
|
33
33
|
// either reflows correctly or leaves the bytes untouched — it never
|
|
34
34
|
// emits the half-reflowed shape. Single-line verbatim is always safe:
|
|
@@ -59,7 +59,7 @@ func NewPrintContext(file *shimast.SourceFile, opts PrintOptions) *PrintContext
|
|
|
59
59
|
// boolean: `true` when the whole printed subtree is reflow-safe,
|
|
60
60
|
// `false` when a multi-line verbatim node is buried inside it.
|
|
61
61
|
//
|
|
62
|
-
// The
|
|
62
|
+
// The formatPrintWidth rule consults `covered` to decide whether to
|
|
63
63
|
// emit an edit at all — see the coverage-signal note at the top of this
|
|
64
64
|
// file. A `false` reading is a hard abstain, not a soft hint.
|
|
65
65
|
func PrintNode(ctx *PrintContext, node *shimast.Node) (Doc, bool) {
|
|
@@ -118,6 +118,9 @@ func dispatchNode(ctx *PrintContext, node *shimast.Node) (Doc, bool, bool) {
|
|
|
118
118
|
case shimast.KindReturnStatement:
|
|
119
119
|
doc, covered := printReturnStatement(ctx, node)
|
|
120
120
|
return doc, covered, true
|
|
121
|
+
case shimast.KindConditionalExpression:
|
|
122
|
+
doc, covered := printConditionalExpression(ctx, node)
|
|
123
|
+
return doc, covered, true
|
|
121
124
|
}
|
|
122
125
|
return Doc{}, false, false
|
|
123
126
|
}
|
package/linthost/print_engine.go
CHANGED
|
@@ -68,11 +68,11 @@ import "strings"
|
|
|
68
68
|
//
|
|
69
69
|
// - "all" (default) every multi-line list gets one.
|
|
70
70
|
// - "es5" arrays, objects, named imports / exports get one;
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
71
|
+
// call arguments, parameter lists, and type-level
|
|
72
|
+
// lists do not — those positions accepted trailing
|
|
73
|
+
// commas only in ES2017+, so es5 mode skips them
|
|
74
|
+
// to match Prettier and avoid oscillating against
|
|
75
|
+
// the formatter on every cascade pass.
|
|
76
76
|
// - "none" no list gets one.
|
|
77
77
|
//
|
|
78
78
|
// An empty string is treated as "all", which keeps `DefaultPrintOptions()`
|
|
@@ -46,12 +46,16 @@ func printCallExpression(ctx *PrintContext, node *shimast.Node) (Doc, bool) {
|
|
|
46
46
|
}
|
|
47
47
|
if call.TypeArguments != nil {
|
|
48
48
|
// Verbatim range covering `<A, B>` punctuation and members.
|
|
49
|
-
parts = append(parts, verbatimRange(ctx.Source,
|
|
49
|
+
parts = append(parts, verbatimRange(ctx.Source, typeArgsStart(ctx.Source, call.TypeArguments), typeArgsEnd(ctx.Source, call.TypeArguments)))
|
|
50
50
|
}
|
|
51
51
|
if hasNilEntry(call.Arguments) {
|
|
52
52
|
return verbatim(ctx, node), !nodeSpansMultipleLines(ctx, node)
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
// Prettier never appends a trailing comma inside a dynamic
|
|
55
|
+
// `import(...)`, so the printer's reflow must agree with
|
|
56
|
+
// format/trailing-comma's same exception (see isDynamicImportCall).
|
|
57
|
+
addComma := ctx.allowsCallArgumentTrailingComma() && !isDynamicImportCall(call)
|
|
58
|
+
argDoc, argCovered := printArgList(ctx, call.Arguments, addComma)
|
|
55
59
|
parts = append(parts, argDoc)
|
|
56
60
|
return Concat(parts...), covered && argCovered
|
|
57
61
|
}
|
|
@@ -77,13 +81,13 @@ func printNewExpression(ctx *PrintContext, node *shimast.Node) (Doc, bool) {
|
|
|
77
81
|
covered = covered && !nodeSpansMultipleLines(ctx, ne.Expression)
|
|
78
82
|
}
|
|
79
83
|
if ne.TypeArguments != nil {
|
|
80
|
-
parts = append(parts, verbatimRange(ctx.Source,
|
|
84
|
+
parts = append(parts, verbatimRange(ctx.Source, typeArgsStart(ctx.Source, ne.TypeArguments), typeArgsEnd(ctx.Source, ne.TypeArguments)))
|
|
81
85
|
}
|
|
82
86
|
if ne.Arguments != nil {
|
|
83
87
|
if hasNilEntry(ne.Arguments) {
|
|
84
88
|
return verbatim(ctx, node), !nodeSpansMultipleLines(ctx, node)
|
|
85
89
|
}
|
|
86
|
-
argDoc, argCovered := printArgList(ctx, ne.Arguments)
|
|
90
|
+
argDoc, argCovered := printArgList(ctx, ne.Arguments, ctx.allowsCallArgumentTrailingComma())
|
|
87
91
|
parts = append(parts, argDoc)
|
|
88
92
|
covered = covered && argCovered
|
|
89
93
|
}
|
|
@@ -116,7 +120,14 @@ func hasNilEntry(list *shimast.NodeList) bool {
|
|
|
116
120
|
// layout, so the parens stay attached and the preceding arguments are
|
|
117
121
|
// not exploded onto their own lines. This is the Prettier behavior for
|
|
118
122
|
// `foo(x, () => { … })`.
|
|
119
|
-
|
|
123
|
+
// `addComma` is supplied by the caller (which honors `format.trailingComma`
|
|
124
|
+
// and the dynamic-import exception) rather than read here, so call and new
|
|
125
|
+
// expressions can diverge on the comma without printArgList knowing the
|
|
126
|
+
// callee. Call / new argument lists accepted trailing commas only in
|
|
127
|
+
// ES2017+, so Prettier's "es5" and "none" modes pass false; otherwise the
|
|
128
|
+
// printer would oscillate against format/trailing-comma on every cascade
|
|
129
|
+
// pass (rxjs hit this on ajax.ts and several operators / testing helpers).
|
|
130
|
+
func printArgList(ctx *PrintContext, list *shimast.NodeList, addComma bool) (Doc, bool) {
|
|
120
131
|
if list == nil {
|
|
121
132
|
return Text("()"), true
|
|
122
133
|
}
|
|
@@ -127,24 +138,65 @@ func printArgList(ctx *PrintContext, list *shimast.NodeList) (Doc, bool) {
|
|
|
127
138
|
covered = covered && childCovered
|
|
128
139
|
items = append(items, doc)
|
|
129
140
|
}
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
//
|
|
141
|
+
// Last-argument hugging wins when both predicates match; first-arg
|
|
142
|
+
// hugging only applies to the two-argument `callback, simpleArg` shape.
|
|
143
|
+
// Decline last-arg hugging when a leading argument forces the call
|
|
144
|
+
// multi-line on its own, so Prettier explodes the whole call rather than
|
|
145
|
+
// hugging the last argument. Two leading shapes trigger that: a function
|
|
146
|
+
// or arrow expression (`useMemo(() => x, [deps])`, even with an inline
|
|
147
|
+
// expression body Prettier never hugs after it), and any argument whose
|
|
148
|
+
// doc carries hard breaks (a block-bodied callback). A leading object or
|
|
149
|
+
// array that merely fits flat does NOT decline — Prettier still hugs the
|
|
150
|
+
// last argument there (`doConfigure({ … }, () => { … })`).
|
|
151
|
+
hugLast := shouldHugLastArgument(list.Nodes) &&
|
|
152
|
+
!anyLeadingArgIsFunctionLike(list.Nodes) &&
|
|
153
|
+
!anyLeadingItemBreaks(items)
|
|
137
154
|
shape := listShape{
|
|
138
155
|
OpenTok: "(",
|
|
139
156
|
CloseTok: ")",
|
|
140
157
|
Items: items,
|
|
141
158
|
Space: false,
|
|
142
|
-
AddComma:
|
|
143
|
-
HugLast:
|
|
159
|
+
AddComma: addComma,
|
|
160
|
+
HugLast: hugLast,
|
|
161
|
+
HugFirst: !hugLast && shouldHugFirstArgument(list.Nodes),
|
|
144
162
|
}
|
|
145
163
|
return printList(ctx, shape), covered
|
|
146
164
|
}
|
|
147
165
|
|
|
166
|
+
// anyLeadingArgIsFunctionLike reports whether any argument before the last
|
|
167
|
+
// is a function or arrow expression. Prettier declines last-argument
|
|
168
|
+
// hugging when a non-last argument is itself a function/arrow, regardless
|
|
169
|
+
// of its body, so `useMemo(() => compute(), [deps])` explodes rather than
|
|
170
|
+
// hugging the trailing array. This complements anyLeadingItemBreaks, which
|
|
171
|
+
// only catches leads with hard line breaks (a block body) and so misses an
|
|
172
|
+
// expression-bodied arrow.
|
|
173
|
+
func anyLeadingArgIsFunctionLike(args []*shimast.Node) bool {
|
|
174
|
+
for i := 0; i+1 < len(args); i++ {
|
|
175
|
+
if args[i] == nil {
|
|
176
|
+
continue
|
|
177
|
+
}
|
|
178
|
+
switch args[i].Kind {
|
|
179
|
+
case shimast.KindArrowFunction, shimast.KindFunctionExpression:
|
|
180
|
+
return true
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return false
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// anyLeadingItemBreaks reports whether any item before the last carries a
|
|
187
|
+
// hard line break — it cannot render flat. Such an item (a block-bodied
|
|
188
|
+
// callback) forces the call multi-line on its own, so last-argument
|
|
189
|
+
// hugging must decline and let the whole list explode, matching Prettier's
|
|
190
|
+
// willBreak gate on the non-last arguments.
|
|
191
|
+
func anyLeadingItemBreaks(items []Doc) bool {
|
|
192
|
+
for i := 0; i+1 < len(items); i++ {
|
|
193
|
+
if _, ok := flatten(items[i]); !ok {
|
|
194
|
+
return true
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return false
|
|
198
|
+
}
|
|
199
|
+
|
|
148
200
|
// shouldHugLastArgument reports whether the final entry of `args` is a
|
|
149
201
|
// shape Prettier keeps hugging the closing paren: an object or array
|
|
150
202
|
// literal, a function expression, or an arrow function whose body is a
|
|
@@ -195,6 +247,74 @@ func shouldHugLastArgument(args []*shimast.Node) bool {
|
|
|
195
247
|
return false
|
|
196
248
|
}
|
|
197
249
|
|
|
250
|
+
// shouldHugFirstArgument reports whether a call's argument list takes
|
|
251
|
+
// Prettier's "first-argument hugging" shape: exactly two arguments where
|
|
252
|
+
// the first is a block-bodied callback and the second is a short, simple
|
|
253
|
+
// value. `foo(() => { … }, target)` keeps the callback attached to the
|
|
254
|
+
// open paren and flows `, target)` after its closing brace, instead of
|
|
255
|
+
// exploding both arguments onto their own lines.
|
|
256
|
+
//
|
|
257
|
+
// Mirrors Prettier's shouldGroupFirstArg: it declines when the second
|
|
258
|
+
// argument is itself a function, arrow, conditional, or any expandable
|
|
259
|
+
// shape, so `both(() => {}, () => {})` falls through to the exploded
|
|
260
|
+
// list rather than hugging.
|
|
261
|
+
func shouldHugFirstArgument(args []*shimast.Node) bool {
|
|
262
|
+
if len(args) != 2 {
|
|
263
|
+
return false
|
|
264
|
+
}
|
|
265
|
+
first, second := args[0], args[1]
|
|
266
|
+
if first == nil || second == nil {
|
|
267
|
+
return false
|
|
268
|
+
}
|
|
269
|
+
return isFirstArgHuggableCallback(first) && isSimpleTrailingArg(second)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// isFirstArgHuggableCallback reports whether `node` is the callback shape
|
|
273
|
+
// Prettier hugs in the first-argument position: a function expression or
|
|
274
|
+
// an arrow with a block body. An expression-bodied arrow is excluded
|
|
275
|
+
// because it carries no internal break point.
|
|
276
|
+
func isFirstArgHuggableCallback(node *shimast.Node) bool {
|
|
277
|
+
switch node.Kind {
|
|
278
|
+
case shimast.KindFunctionExpression:
|
|
279
|
+
return true
|
|
280
|
+
case shimast.KindArrowFunction:
|
|
281
|
+
arrow := node.AsArrowFunction()
|
|
282
|
+
return arrow != nil && arrow.Body != nil && arrow.Body.Kind == shimast.KindBlock
|
|
283
|
+
}
|
|
284
|
+
return false
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// isSimpleTrailingArg reports whether `node` is a value that may trail a
|
|
288
|
+
// hugged first-argument callback. Prettier hugs the leading callback when
|
|
289
|
+
// the trailing argument is an identifier, member access, literal, `this`,
|
|
290
|
+
// or an array literal — most notably the `useEffect(() => { … }, [deps])`
|
|
291
|
+
// idiom. An object literal, function, arrow, or conditional is excluded so
|
|
292
|
+
// first-argument hugging declines and the whole list explodes.
|
|
293
|
+
//
|
|
294
|
+
// A call expression is deliberately NOT included: the conditional-group
|
|
295
|
+
// fit check only measures an option's first line, so a hugged-first option
|
|
296
|
+
// whose trailing call overflows the closing line (`}, deeplyNested(…))`)
|
|
297
|
+
// would still be selected, where Prettier explodes. The array case shares
|
|
298
|
+
// that limitation in principle, but dependency arrays are short in
|
|
299
|
+
// practice, the same way the identifier/member cases already are.
|
|
300
|
+
func isSimpleTrailingArg(node *shimast.Node) bool {
|
|
301
|
+
switch node.Kind {
|
|
302
|
+
case shimast.KindIdentifier,
|
|
303
|
+
shimast.KindStringLiteral,
|
|
304
|
+
shimast.KindNumericLiteral,
|
|
305
|
+
shimast.KindBigIntLiteral,
|
|
306
|
+
shimast.KindTrueKeyword,
|
|
307
|
+
shimast.KindFalseKeyword,
|
|
308
|
+
shimast.KindNullKeyword,
|
|
309
|
+
shimast.KindThisKeyword,
|
|
310
|
+
shimast.KindPropertyAccessExpression,
|
|
311
|
+
shimast.KindElementAccessExpression,
|
|
312
|
+
shimast.KindArrayLiteralExpression:
|
|
313
|
+
return true
|
|
314
|
+
}
|
|
315
|
+
return false
|
|
316
|
+
}
|
|
317
|
+
|
|
198
318
|
// forceBreakFirstGroup returns `doc` with the first Group found in a
|
|
199
319
|
// left-to-right walk of its subtree forced broken, and reports whether
|
|
200
320
|
// one was found. printListHuggingLast uses it to commit a hugged
|
|
@@ -225,72 +345,34 @@ func forceBreakFirstGroup(doc Doc) (Doc, bool) {
|
|
|
225
345
|
|
|
226
346
|
// Type-argument byte-range helpers. The shim's NodeList.End() points
|
|
227
347
|
// past the last argument; the surrounding `<` and `>` are not part of
|
|
228
|
-
// the list's range, so we have to scan around it.
|
|
348
|
+
// the list's range, so we have to scan around it. Call and new
|
|
349
|
+
// expressions share these — only the field holding the list differs.
|
|
229
350
|
|
|
230
|
-
//
|
|
231
|
-
// type-argument list
|
|
232
|
-
func
|
|
233
|
-
if
|
|
234
|
-
return -1
|
|
235
|
-
}
|
|
236
|
-
first := call.TypeArguments.Nodes[0]
|
|
237
|
-
if first == nil {
|
|
351
|
+
// typeArgsStart returns the byte offset of the `<` that opens a
|
|
352
|
+
// type-argument list. Returns -1 when absent.
|
|
353
|
+
func typeArgsStart(src string, list *shimast.NodeList) int {
|
|
354
|
+
if list == nil || len(list.Nodes) == 0 || list.Nodes[0] == nil {
|
|
238
355
|
return -1
|
|
239
356
|
}
|
|
240
357
|
// `<` is the byte immediately before the first type argument
|
|
241
358
|
// (modulo whitespace).
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if ctx.Source[i] == '<' {
|
|
359
|
+
for i := list.Nodes[0].Pos() - 1; i >= 0; i-- {
|
|
360
|
+
if src[i] == '<' {
|
|
245
361
|
return i
|
|
246
362
|
}
|
|
247
363
|
}
|
|
248
364
|
return -1
|
|
249
365
|
}
|
|
250
366
|
|
|
251
|
-
//
|
|
252
|
-
//
|
|
253
|
-
func
|
|
254
|
-
if
|
|
255
|
-
return -1
|
|
256
|
-
}
|
|
257
|
-
end := call.TypeArguments.End()
|
|
258
|
-
for i := end; i < len(ctx.Source); i++ {
|
|
259
|
-
if ctx.Source[i] == '>' {
|
|
260
|
-
return i + 1
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
return end
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// newTypeArgsStart returns the byte offset of the `<` that opens the
|
|
267
|
-
// type-argument list of a NewExpression. Returns -1 when absent.
|
|
268
|
-
func newTypeArgsStart(ctx *PrintContext, ne *shimast.NewExpression) int {
|
|
269
|
-
if ne.TypeArguments == nil || len(ne.TypeArguments.Nodes) == 0 {
|
|
270
|
-
return -1
|
|
271
|
-
}
|
|
272
|
-
first := ne.TypeArguments.Nodes[0]
|
|
273
|
-
if first == nil {
|
|
274
|
-
return -1
|
|
275
|
-
}
|
|
276
|
-
pos := first.Pos()
|
|
277
|
-
for i := pos - 1; i >= 0; i-- {
|
|
278
|
-
if ctx.Source[i] == '<' {
|
|
279
|
-
return i
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
return -1
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// newTypeArgsEnd returns the byte offset one past the closing `>` of a
|
|
286
|
-
// NewExpression's type-argument list. Returns -1 when absent.
|
|
287
|
-
func newTypeArgsEnd(ctx *PrintContext, ne *shimast.NewExpression) int {
|
|
288
|
-
if ne.TypeArguments == nil {
|
|
367
|
+
// typeArgsEnd returns the byte offset one past the closing `>` of a
|
|
368
|
+
// type-argument list. Returns -1 when the list is absent.
|
|
369
|
+
func typeArgsEnd(src string, list *shimast.NodeList) int {
|
|
370
|
+
if list == nil {
|
|
289
371
|
return -1
|
|
290
372
|
}
|
|
291
|
-
end :=
|
|
292
|
-
for i := end; i < len(
|
|
293
|
-
if
|
|
373
|
+
end := list.End()
|
|
374
|
+
for i := end; i < len(src); i++ {
|
|
375
|
+
if src[i] == '>' {
|
|
294
376
|
return i + 1
|
|
295
377
|
}
|
|
296
378
|
}
|
|
@@ -25,7 +25,7 @@ import (
|
|
|
25
25
|
// the newlines live, so the body is dispatched through PrintNode and
|
|
26
26
|
// re-indented by the Doc engine. Each printer ANDs the body's `covered`
|
|
27
27
|
// flag into its own result: a body the dispatcher cannot fully control
|
|
28
|
-
// taints the whole subtree and the
|
|
28
|
+
// taints the whole subtree and the formatPrintWidth rule abstains.
|
|
29
29
|
//
|
|
30
30
|
// The expression- and return-statement printers carry the same
|
|
31
31
|
// discipline one level deeper: a callback body whose statements are
|
|
@@ -180,6 +180,16 @@ func printBlock(ctx *PrintContext, node *shimast.Node) (Doc, bool) {
|
|
|
180
180
|
bodyParts := make([]Doc, 0, len(items)*2)
|
|
181
181
|
for i, item := range items {
|
|
182
182
|
if i > 0 {
|
|
183
|
+
// A lone leading-semicolon ASI guard stays glued to the statement
|
|
184
|
+
// it protects (`;(expr)`): when the previous statement is an empty
|
|
185
|
+
// `;` sitting directly against this one in the source, emit no line
|
|
186
|
+
// break, so the reflow agrees with format/orphan-semi instead of
|
|
187
|
+
// ping-ponging it back onto two lines every cascade pass.
|
|
188
|
+
if stmts[i-1].Kind == shimast.KindEmptyStatement &&
|
|
189
|
+
!rangeHasNewline(ctx.Source, stmts[i-1].End(), shimscanner.SkipTrivia(ctx.Source, stmts[i].Pos())) {
|
|
190
|
+
bodyParts = append(bodyParts, item)
|
|
191
|
+
continue
|
|
192
|
+
}
|
|
183
193
|
if blankLineBetweenStatements(ctx.Source, stmts[i-1].End(), stmts[i].Pos()) {
|
|
184
194
|
bodyParts = append(bodyParts, Literalline())
|
|
185
195
|
}
|
|
@@ -196,6 +206,21 @@ func printBlock(ctx *PrintContext, node *shimast.Node) (Doc, bool) {
|
|
|
196
206
|
return doc, covered
|
|
197
207
|
}
|
|
198
208
|
|
|
209
|
+
// rangeHasNewline reports whether src[start:end) contains a newline. Used
|
|
210
|
+
// to detect whether a leading-semicolon guard sits on the same line as
|
|
211
|
+
// the statement it protects.
|
|
212
|
+
func rangeHasNewline(src string, start, end int) bool {
|
|
213
|
+
if start < 0 || end > len(src) || end <= start {
|
|
214
|
+
return false
|
|
215
|
+
}
|
|
216
|
+
for i := start; i < end; i++ {
|
|
217
|
+
if src[i] == '\n' {
|
|
218
|
+
return true
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return false
|
|
222
|
+
}
|
|
223
|
+
|
|
199
224
|
// blankLineBetweenStatements reports whether the source gap between the
|
|
200
225
|
// end of one block statement and the start of the next contains a blank
|
|
201
226
|
// line — two or more newlines. printBlock uses it to keep a single
|
|
@@ -224,7 +249,7 @@ func blankLineBetweenStatements(src string, prevEnd, nextPos int) bool {
|
|
|
224
249
|
// printer joins statements with bare Hardlines that have no slot for
|
|
225
250
|
// inter-statement trivia, so a stray comment would be dropped by a
|
|
226
251
|
// reflow. Detecting it lets printBlock report the block uncovered and
|
|
227
|
-
// the
|
|
252
|
+
// the formatPrintWidth rule abstain.
|
|
228
253
|
//
|
|
229
254
|
// The scan mirrors rules_format_print_width.go::hasNonChildComments:
|
|
230
255
|
// comment-shaped bytes inside a complete statement token range (string
|
|
@@ -35,6 +35,12 @@ type listShape struct {
|
|
|
35
35
|
// multi-line callback body does not force every preceding argument
|
|
36
36
|
// onto its own line.
|
|
37
37
|
HugLast bool
|
|
38
|
+
// HugFirst keeps the FIRST item attached to the open paren and flows
|
|
39
|
+
// the remaining simple items after it, the mirror of HugLast. The
|
|
40
|
+
// call-argument printer sets it for the two-argument
|
|
41
|
+
// `callback, simpleArg` shape Prettier hugs (`foo(() => { … }, x)`).
|
|
42
|
+
// HugLast and HugFirst are mutually exclusive.
|
|
43
|
+
HugFirst bool
|
|
38
44
|
// ForceBreak commits the list to its broken, one-item-per-line shape
|
|
39
45
|
// even when it would fit flat. The object-literal printer sets it to
|
|
40
46
|
// mirror Prettier's objectWrap:"preserve" — an object the source
|
|
@@ -50,19 +56,22 @@ func printList(ctx *PrintContext, shape listShape) Doc {
|
|
|
50
56
|
return Text(shape.OpenTok + shape.CloseTok)
|
|
51
57
|
}
|
|
52
58
|
plain := printListPlain(ctx, shape)
|
|
53
|
-
if !shape.HugLast {
|
|
59
|
+
if !shape.HugLast && !shape.HugFirst {
|
|
54
60
|
return plain
|
|
55
61
|
}
|
|
56
|
-
// A
|
|
62
|
+
// A hugging list offers the engine up to three shapes, in preference
|
|
57
63
|
// order:
|
|
58
64
|
// 1. allFlat — every item on one line, chosen when it fits;
|
|
59
|
-
// 2. hugged —
|
|
60
|
-
// committed to its multi-line shape
|
|
61
|
-
// line fits but the all-flat form does not;
|
|
65
|
+
// 2. hugged — the callback (last for HugLast, first for HugFirst)
|
|
66
|
+
// committed to its multi-line shape with the other items inline,
|
|
67
|
+
// chosen when its opening line fits but the all-flat form does not;
|
|
62
68
|
// 3. plain — every item exploded onto its own indented line.
|
|
63
69
|
// The all-flat option is dropped when the list cannot render flat
|
|
64
70
|
// (a block-bodied callback argument carries hard line breaks).
|
|
65
71
|
hugged := printListHuggingLast(ctx, shape)
|
|
72
|
+
if shape.HugFirst {
|
|
73
|
+
hugged = printListHuggingFirst(ctx, shape)
|
|
74
|
+
}
|
|
66
75
|
if allFlat, ok := flatten(plain); ok {
|
|
67
76
|
return ConditionalGroup(allFlat, hugged, plain)
|
|
68
77
|
}
|
|
@@ -143,3 +152,29 @@ func printListHuggingLast(ctx *PrintContext, shape listShape) Doc {
|
|
|
143
152
|
parts = append(parts, last, Text(shape.CloseTok))
|
|
144
153
|
return Concat(parts...)
|
|
145
154
|
}
|
|
155
|
+
|
|
156
|
+
// printListHuggingFirst renders the "first-argument hugging" shape
|
|
157
|
+
// Prettier uses for `foo(() => { … }, target)`: the first item stays
|
|
158
|
+
// attached to the open paren and the remaining simple items flow inline
|
|
159
|
+
// after it, so a multi-line callback body does not explode the trailing
|
|
160
|
+
// arguments onto their own lines.
|
|
161
|
+
//
|
|
162
|
+
// hugged: OPEN OPEN-of-first … CLOSE-of-first, b, c CLOSE
|
|
163
|
+
//
|
|
164
|
+
// Like printListHuggingLast it returns a plain Concat (the callback's own
|
|
165
|
+
// printer owns its body's break) and forces the hugged item's first Group
|
|
166
|
+
// broken when the item has no hard line breaks of its own, so the hugged
|
|
167
|
+
// option stays distinct from the all-flat option.
|
|
168
|
+
func printListHuggingFirst(ctx *PrintContext, shape listShape) Doc {
|
|
169
|
+
first := shape.Items[0]
|
|
170
|
+
rest := shape.Items[1:]
|
|
171
|
+
if _, flat := flatten(first); flat {
|
|
172
|
+
first, _ = forceBreakFirstGroup(first)
|
|
173
|
+
}
|
|
174
|
+
parts := []Doc{Text(shape.OpenTok), first}
|
|
175
|
+
for _, item := range rest {
|
|
176
|
+
parts = append(parts, Text(", "), item)
|
|
177
|
+
}
|
|
178
|
+
parts = append(parts, Text(shape.CloseTok))
|
|
179
|
+
return Concat(parts...)
|
|
180
|
+
}
|
|
@@ -74,7 +74,7 @@ func printObjectLiteral(ctx *PrintContext, node *shimast.Node) (Doc, bool) {
|
|
|
74
74
|
//
|
|
75
75
|
// Prettier's objectWrap:"preserve" default keeps such an object
|
|
76
76
|
// expanded even when it would fit flat, treating the author's line
|
|
77
|
-
// break as intentional structure.
|
|
77
|
+
// break as intentional structure. formatPrintWidth mirrors that:
|
|
78
78
|
// without it a deliberately multi-line object that happens to fit
|
|
79
79
|
// would be silently collapsed onto one line, which Prettier never
|
|
80
80
|
// does.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
package linthost
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
// printConditionalExpression renders a (possibly chained) ternary with
|
|
8
|
+
// Prettier 3's "indent nested ternaries" staircase. A conditional whose
|
|
9
|
+
// consequent or alternate is itself a conditional is printed inline
|
|
10
|
+
// under the same break group, but its arms indent one extra level:
|
|
11
|
+
//
|
|
12
|
+
// aaaaaaaaaa
|
|
13
|
+
// ? bbbbbbbbbb
|
|
14
|
+
// : cccccccccc
|
|
15
|
+
// ? dddddddddd
|
|
16
|
+
// : eeeeeeeeee
|
|
17
|
+
//
|
|
18
|
+
// The whole chain shares one fit-or-break decision (a single outer
|
|
19
|
+
// Group), matching Prettier: either the entire chain fits flat
|
|
20
|
+
// (`a ? b : c ? d : e`) or every rung breaks onto its own line. Nesting
|
|
21
|
+
// is expressed by recursing the chain builder without wrapping the
|
|
22
|
+
// nested conditional in its own Group, so the Doc engine's Indent stack
|
|
23
|
+
// accumulates `tabWidth` columns per level.
|
|
24
|
+
//
|
|
25
|
+
// The second return value is the coverage flag (see PrintNode): the AND
|
|
26
|
+
// of the test and both branches, so a multi-line verbatim node anywhere
|
|
27
|
+
// in the chain makes formatPrintWidth abstain rather than emit a
|
|
28
|
+
// half-reflowed shape.
|
|
29
|
+
func printConditionalExpression(ctx *PrintContext, node *shimast.Node) (Doc, bool) {
|
|
30
|
+
body, covered := buildConditionalChain(ctx, node)
|
|
31
|
+
if body.IsNil() {
|
|
32
|
+
return verbatim(ctx, node), !nodeSpansMultipleLines(ctx, node)
|
|
33
|
+
}
|
|
34
|
+
return Group(body), covered
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// buildConditionalChain returns the chain body for `node` WITHOUT a
|
|
38
|
+
// surrounding Group, so a nested conditional recursed from here shares
|
|
39
|
+
// the caller's group and its arms indent one level deeper. The top-level
|
|
40
|
+
// printConditionalExpression wraps the outermost body in the single
|
|
41
|
+
// Group that owns the break decision.
|
|
42
|
+
func buildConditionalChain(ctx *PrintContext, node *shimast.Node) (Doc, bool) {
|
|
43
|
+
cond := node.AsConditionalExpression()
|
|
44
|
+
if cond == nil || cond.Condition == nil || cond.WhenTrue == nil || cond.WhenFalse == nil {
|
|
45
|
+
return Doc{}, true
|
|
46
|
+
}
|
|
47
|
+
testDoc, c1 := PrintNode(ctx, cond.Condition)
|
|
48
|
+
consDoc, c2 := ternaryArm(ctx, cond.WhenTrue)
|
|
49
|
+
altDoc, c3 := ternaryArm(ctx, cond.WhenFalse)
|
|
50
|
+
doc := Concat(
|
|
51
|
+
testDoc,
|
|
52
|
+
Indent(ctx.indentUnit(),
|
|
53
|
+
Line(), Text("? "), consDoc,
|
|
54
|
+
Line(), Text(": "), altDoc,
|
|
55
|
+
),
|
|
56
|
+
)
|
|
57
|
+
return doc, c1 && c2 && c3
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ternaryArm prints a ternary consequent/alternate. A nested conditional
|
|
61
|
+
// continues the chain inline (no new Group) so the staircase
|
|
62
|
+
// accumulates; every other arm prints through the normal dispatcher (an
|
|
63
|
+
// arm that is a `??` expression is already parenthesized in valid
|
|
64
|
+
// source, so it round-trips its parens via the ParenthesizedExpression
|
|
65
|
+
// printer).
|
|
66
|
+
//
|
|
67
|
+
// A non-conditional arm is wrapped in Align so that, when it breaks
|
|
68
|
+
// internally, its continuation hangs under the arm expression's own
|
|
69
|
+
// column (one level past the `? `/`: ` marker) rather than under the
|
|
70
|
+
// chain's rung indent. Prettier hangs a broken call/object arm there:
|
|
71
|
+
//
|
|
72
|
+
// cond
|
|
73
|
+
// ? foo(
|
|
74
|
+
// arg, // arm-column + one level, not rung + one level
|
|
75
|
+
// )
|
|
76
|
+
// : bar
|
|
77
|
+
//
|
|
78
|
+
// Align is a no-op for an arm that stays flat, and a nested conditional
|
|
79
|
+
// is deliberately NOT aligned — it keeps the Indent-based staircase.
|
|
80
|
+
func ternaryArm(ctx *PrintContext, node *shimast.Node) (Doc, bool) {
|
|
81
|
+
if node != nil && node.Kind == shimast.KindConditionalExpression {
|
|
82
|
+
return buildConditionalChain(ctx, node)
|
|
83
|
+
}
|
|
84
|
+
doc, covered := PrintNode(ctx, node)
|
|
85
|
+
return Align(doc), covered
|
|
86
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
package linthost
|
|
2
|
+
|
|
3
|
+
import "strings"
|
|
4
|
+
|
|
5
|
+
// normalizeBuiltinRuleName strips the optional `eslint/` namespace prefix
|
|
6
|
+
// so users may write either the bare rule id or the explicit `eslint/<id>`
|
|
7
|
+
// form. `@ttsc/lint` deliberately rejects the legacy `@typescript-eslint/`
|
|
8
|
+
// and `typescript-eslint/` prefixes — TypeScript-only rules live under
|
|
9
|
+
// the canonical `typescript/<id>` namespace.
|
|
10
|
+
func normalizeBuiltinRuleName(name string) string {
|
|
11
|
+
name = strings.TrimSpace(name)
|
|
12
|
+
name = strings.TrimPrefix(name, "eslint/")
|
|
13
|
+
return name
|
|
14
|
+
}
|
package/linthost/rules_arrays.go
CHANGED
|
@@ -2,7 +2,7 @@ package linthost
|
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
5
|
-
//
|
|
5
|
+
// noSparseArrays: `[1, , 2]` — the implied undefined slot is almost
|
|
6
6
|
// always a typo.
|
|
7
7
|
// https://eslint.org/docs/latest/rules/no-sparse-arrays
|
|
8
8
|
type noSparseArrays struct{}
|
|
@@ -24,7 +24,7 @@ func (noSparseArrays) Check(ctx *Context, node *shimast.Node) {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
//
|
|
27
|
+
// noArrayConstructor: forbid `new Array(0)` / `Array(1, 2, 3)` (use
|
|
28
28
|
// array literals). The single-argument form is intentionally excluded from
|
|
29
29
|
// the ban: `Array(n)` is commonly used to pre-allocate a sparse array by
|
|
30
30
|
// length, and banning it would generate noise on existing idiomatic code.
|