@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
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// typescript/prefer-reduce-type-parameter: when `arr.reduce(cb, init)`
|
|
2
|
+
// is called with an `as`-asserted initial value, fix the accumulator
|
|
3
|
+
// type at the call site via `arr.reduce<T>(cb, init)` instead. The
|
|
4
|
+
// type-parameter form binds the accumulator before the callback infers
|
|
5
|
+
// its parameter types from the seed, so the callback sees the intended
|
|
6
|
+
// type instead of the seed's widened literal shape. typescript-eslint:
|
|
7
|
+
// https://typescript-eslint.io/rules/prefer-reduce-type-parameter/
|
|
8
|
+
//
|
|
9
|
+
// Type-aware. Without a Checker the rule cannot prove the receiver of
|
|
10
|
+
// `.reduce` is an array or tuple — user types named `reduce` are
|
|
11
|
+
// common (`Map#reduce`, custom accumulators, etc.) and assertion-on-
|
|
12
|
+
// initial-value is occasionally idiomatic there. The receiver must be
|
|
13
|
+
// a provable array or tuple; generics, `any`, `unknown`, and `never`
|
|
14
|
+
// pass through to keep generic helpers quiet.
|
|
15
|
+
package linthost
|
|
16
|
+
|
|
17
|
+
import (
|
|
18
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
19
|
+
shimchecker "github.com/microsoft/typescript-go/shim/checker"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
type preferReduceTypeParameter struct{}
|
|
23
|
+
|
|
24
|
+
func (preferReduceTypeParameter) Name() string {
|
|
25
|
+
return "typescript/prefer-reduce-type-parameter"
|
|
26
|
+
}
|
|
27
|
+
func (preferReduceTypeParameter) NeedsTypeChecker() bool {
|
|
28
|
+
return true
|
|
29
|
+
}
|
|
30
|
+
func (preferReduceTypeParameter) Visits() []shimast.Kind {
|
|
31
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
32
|
+
}
|
|
33
|
+
func (preferReduceTypeParameter) Check(ctx *Context, node *shimast.Node) {
|
|
34
|
+
if ctx.Checker == nil {
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
call := node.AsCallExpression()
|
|
38
|
+
if call == nil || call.Expression == nil {
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
// `arr.reduce<T>(...)` already pins the accumulator at the call
|
|
42
|
+
// site — the rule has nothing left to suggest.
|
|
43
|
+
if call.TypeArguments != nil && len(call.TypeArguments.Nodes) > 0 {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
// The call must be `<receiver>.reduce(callback, initial)` — the
|
|
47
|
+
// two-argument form whose seed is the accumulator. The single-
|
|
48
|
+
// argument `arr.reduce(cb)` shape has no seed to assert against.
|
|
49
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) != 2 {
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
receiver, method, ok := promisePropertyAccessParts(call.Expression)
|
|
53
|
+
if !ok || method != "reduce" {
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
initial := stripParens(call.Arguments.Nodes[1])
|
|
57
|
+
if initial == nil {
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
// The initial value must carry an explicit type assertion that the
|
|
61
|
+
// rule can hoist into the call's type parameter list. Both the
|
|
62
|
+
// canonical `init as T` form and the legacy `<T>init` form qualify.
|
|
63
|
+
if initial.Kind != shimast.KindAsExpression && initial.Kind != shimast.KindTypeAssertionExpression {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
if receiver == nil {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
t := ctx.Checker.GetTypeAtLocation(receiver)
|
|
70
|
+
if t == nil {
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
if !preferReduceIsArrayOrTuple(ctx.Checker, t) {
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
ctx.Report(initial, preferReduceMessage)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const preferReduceMessage = "Pass the accumulator type to `reduce` as a type parameter — `arr.reduce<T>(cb, init)` — instead of asserting on the initial value."
|
|
80
|
+
|
|
81
|
+
// preferReduceIsArrayOrTuple reports whether t is provably an array or
|
|
82
|
+
// tuple. Mirrors `preferIncludesIsArrayOrString` but excludes strings
|
|
83
|
+
// (which have no `.reduce`). Generics, `any`, `unknown`, and `never`
|
|
84
|
+
// intentionally fail closed so the rule does not blow up on generic
|
|
85
|
+
// helpers whose receiver type leaks downward.
|
|
86
|
+
func preferReduceIsArrayOrTuple(checker *shimchecker.Checker, t *shimchecker.Type) bool {
|
|
87
|
+
if checker == nil || t == nil {
|
|
88
|
+
return false
|
|
89
|
+
}
|
|
90
|
+
flags := t.Flags()
|
|
91
|
+
if flags&(shimchecker.TypeFlagsAny|shimchecker.TypeFlagsUnknown|shimchecker.TypeFlagsNever) != 0 {
|
|
92
|
+
return false
|
|
93
|
+
}
|
|
94
|
+
if flags&(shimchecker.TypeFlagsUnion|shimchecker.TypeFlagsIntersection) != 0 {
|
|
95
|
+
for _, part := range t.Types() {
|
|
96
|
+
if part == nil {
|
|
97
|
+
continue
|
|
98
|
+
}
|
|
99
|
+
if !preferReduceIsArrayOrTuple(checker, part) {
|
|
100
|
+
return false
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return true
|
|
104
|
+
}
|
|
105
|
+
if shimchecker.Checker_isArrayType(checker, t) {
|
|
106
|
+
return true
|
|
107
|
+
}
|
|
108
|
+
if shimchecker.IsTupleType(t) {
|
|
109
|
+
return true
|
|
110
|
+
}
|
|
111
|
+
return false
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
func init() {
|
|
115
|
+
Register(preferReduceTypeParameter{})
|
|
116
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// typescript/prefer-regexp-exec: prefer `re.exec(str)` over
|
|
2
|
+
// `str.match(re)` when the regex has no `g` flag. Both shapes return
|
|
3
|
+
// the same `RegExpExecArray | null` for first-match queries, but
|
|
4
|
+
// `String#match` silently switches to "every match" the moment the
|
|
5
|
+
// regex gains the `g` flag — a typo at the regex literal can change
|
|
6
|
+
// the call's return shape from `[fullMatch, ...captures]` to a flat
|
|
7
|
+
// `string[]` of matches. `RegExp#exec` is the stable form.
|
|
8
|
+
// typescript-eslint:
|
|
9
|
+
// https://typescript-eslint.io/rules/prefer-regexp-exec/
|
|
10
|
+
//
|
|
11
|
+
// Type-aware. Without a Checker the rule cannot prove the receiver of
|
|
12
|
+
// `match` is string-like, so Context.Checker == nil short-circuits each
|
|
13
|
+
// Check to a no-op the way `prefer-includes` and
|
|
14
|
+
// `prefer-string-starts-ends-with` do. The argument must be a regex
|
|
15
|
+
// literal — the AST-only baseline reads the flag suffix directly off
|
|
16
|
+
// the token text; non-literal regex arguments (a `new RegExp(...)`,
|
|
17
|
+
// a `const re = /.../` aliased through a variable) are conservatively
|
|
18
|
+
// skipped because static flag tracking would explode in scope.
|
|
19
|
+
package linthost
|
|
20
|
+
|
|
21
|
+
import (
|
|
22
|
+
"strings"
|
|
23
|
+
|
|
24
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
25
|
+
shimchecker "github.com/microsoft/typescript-go/shim/checker"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
type preferRegexpExec struct{}
|
|
29
|
+
|
|
30
|
+
func (preferRegexpExec) Name() string { return "typescript/prefer-regexp-exec" }
|
|
31
|
+
func (preferRegexpExec) NeedsTypeChecker() bool {
|
|
32
|
+
return true
|
|
33
|
+
}
|
|
34
|
+
func (preferRegexpExec) Visits() []shimast.Kind {
|
|
35
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
36
|
+
}
|
|
37
|
+
func (preferRegexpExec) Check(ctx *Context, node *shimast.Node) {
|
|
38
|
+
if ctx.Checker == nil {
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
call := node.AsCallExpression()
|
|
42
|
+
if call == nil || call.Expression == nil {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
receiver, method, ok := promisePropertyAccessParts(call.Expression)
|
|
46
|
+
if !ok || method != "match" {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
if receiver == nil {
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) != 1 {
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
arg := stripParens(call.Arguments.Nodes[0])
|
|
56
|
+
if arg == nil || arg.Kind != shimast.KindRegularExpressionLiteral {
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
// Skip when the regex literal carries the `g` flag — `String#match`
|
|
60
|
+
// returns every match in that mode, which `RegExp#exec` cannot
|
|
61
|
+
// replicate in a single call.
|
|
62
|
+
if preferRegexpExecHasGlobalFlag(ctx.File, arg) {
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
if !preferRegexpExecIsString(ctx.Checker.GetTypeAtLocation(receiver)) {
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
ctx.Report(node, preferRegexpExecMessage)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const preferRegexpExecMessage = "Prefer `RegExp#exec(str)` over `String#match(re)` when the regex has no `g` flag — `exec` returns the same first-match shape and avoids the `g`-flag fallthrough that silently changes the return type of `match`."
|
|
72
|
+
|
|
73
|
+
// preferRegexpExecHasGlobalFlag reports whether the regex literal at
|
|
74
|
+
// `node` carries the `g` flag. The flag string follows the closing `/`
|
|
75
|
+
// of the literal (e.g. `/foo/gi` has flags `"gi"`); the scanner has
|
|
76
|
+
// already validated the token, so a textual scan of the trailing
|
|
77
|
+
// suffix is sufficient.
|
|
78
|
+
func preferRegexpExecHasGlobalFlag(file *shimast.SourceFile, node *shimast.Node) bool {
|
|
79
|
+
raw := nodeText(file, node)
|
|
80
|
+
if len(raw) < 2 || raw[0] != '/' {
|
|
81
|
+
return false
|
|
82
|
+
}
|
|
83
|
+
closing := strings.LastIndexByte(raw, '/')
|
|
84
|
+
if closing <= 0 {
|
|
85
|
+
return false
|
|
86
|
+
}
|
|
87
|
+
flags := raw[closing+1:]
|
|
88
|
+
return strings.Contains(flags, "g")
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// preferRegexpExecIsString reports whether t is provably string-like.
|
|
92
|
+
// Mirrors `preferStringStartsEndsWithIsString`: `any` / `unknown` /
|
|
93
|
+
// `never` are rejected so generic helpers don't fire. Union and
|
|
94
|
+
// intersection types must have every constituent string-like.
|
|
95
|
+
func preferRegexpExecIsString(t *shimchecker.Type) bool {
|
|
96
|
+
if t == nil {
|
|
97
|
+
return false
|
|
98
|
+
}
|
|
99
|
+
flags := t.Flags()
|
|
100
|
+
if flags&(shimchecker.TypeFlagsAny|shimchecker.TypeFlagsUnknown|shimchecker.TypeFlagsNever) != 0 {
|
|
101
|
+
return false
|
|
102
|
+
}
|
|
103
|
+
if flags&shimchecker.TypeFlagsStringLike != 0 {
|
|
104
|
+
return true
|
|
105
|
+
}
|
|
106
|
+
if flags&(shimchecker.TypeFlagsUnion|shimchecker.TypeFlagsIntersection) != 0 {
|
|
107
|
+
for _, part := range t.Types() {
|
|
108
|
+
if part == nil {
|
|
109
|
+
continue
|
|
110
|
+
}
|
|
111
|
+
if !preferRegexpExecIsString(part) {
|
|
112
|
+
return false
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return true
|
|
116
|
+
}
|
|
117
|
+
return false
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
func init() {
|
|
121
|
+
Register(preferRegexpExec{})
|
|
122
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// typescript/prefer-return-this-type: when an instance method always
|
|
2
|
+
// `return this`, declare its return type as `this` instead of the
|
|
3
|
+
// enclosing class name. The `this` polymorphic-receiver type keeps the
|
|
4
|
+
// narrower subclass type at the call site so chained calls stay
|
|
5
|
+
// polymorphic: `subclass.fluent().subclassOnly()` only type-checks if
|
|
6
|
+
// `fluent()` is declared `: this` rather than `: Base`.
|
|
7
|
+
// typescript-eslint:
|
|
8
|
+
// https://typescript-eslint.io/rules/prefer-return-this-type/
|
|
9
|
+
//
|
|
10
|
+
// Type-aware. Without a Checker the rule cannot read the method's
|
|
11
|
+
// declared return type or distinguish the class symbol, so
|
|
12
|
+
// Context.Checker == nil short-circuits each Check to a no-op the way
|
|
13
|
+
// other type-aware rules do.
|
|
14
|
+
//
|
|
15
|
+
// Skipped:
|
|
16
|
+
// - methods whose return type is already `this`;
|
|
17
|
+
// - methods without an explicit declared return type (the upstream
|
|
18
|
+
// rule only proposes a narrower annotation when one is already
|
|
19
|
+
// present — adding a brand-new annotation is the job of
|
|
20
|
+
// `explicit-function-return-type`);
|
|
21
|
+
// - constructors, accessors, generators, and `async` methods (each
|
|
22
|
+
// has return-shape semantics the `this` rewrite does not preserve);
|
|
23
|
+
// - methods with no body (overload signatures, abstract members);
|
|
24
|
+
// - methods that have at least one `return X;` where `X` is not the
|
|
25
|
+
// `this` keyword.
|
|
26
|
+
package linthost
|
|
27
|
+
|
|
28
|
+
import (
|
|
29
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
type preferReturnThisType struct{}
|
|
33
|
+
|
|
34
|
+
func (preferReturnThisType) Name() string { return "typescript/prefer-return-this-type" }
|
|
35
|
+
func (preferReturnThisType) NeedsTypeChecker() bool {
|
|
36
|
+
return true
|
|
37
|
+
}
|
|
38
|
+
func (preferReturnThisType) Visits() []shimast.Kind {
|
|
39
|
+
return []shimast.Kind{shimast.KindMethodDeclaration}
|
|
40
|
+
}
|
|
41
|
+
func (preferReturnThisType) Check(ctx *Context, node *shimast.Node) {
|
|
42
|
+
if ctx.Checker == nil {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
decl := node.AsMethodDeclaration()
|
|
46
|
+
if decl == nil || decl.Body == nil {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
// Skip async / generator methods — their return shape is wrapped
|
|
50
|
+
// (`Promise<...>` / `Generator<...>`) and not directly `this`.
|
|
51
|
+
if hasAsyncModifier(node) {
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
if decl.AsteriskToken != nil {
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
// Skip static methods — the upstream rule targets instance-method
|
|
58
|
+
// chains where the receiver type is the subclass; static dispatch
|
|
59
|
+
// uses the class itself and `this` rewriting changes nothing.
|
|
60
|
+
if hasModifier(node, shimast.KindStaticKeyword) {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
// The method must have an explicit return-type annotation that is
|
|
64
|
+
// NOT already `this`. The rewrite-target is the existing annotation;
|
|
65
|
+
// without one, adding `this` would force a new annotation that the
|
|
66
|
+
// upstream rule does not propose.
|
|
67
|
+
if decl.Type == nil {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
if decl.Type.Kind == shimast.KindThisType {
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
// The enclosing class must exist — the rule applies to instance
|
|
74
|
+
// methods of class declarations / expressions only.
|
|
75
|
+
parent := node.Parent
|
|
76
|
+
if parent == nil {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
if parent.Kind != shimast.KindClassDeclaration &&
|
|
80
|
+
parent.Kind != shimast.KindClassExpression {
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
// Walk the method body. Every value-returning `return` must
|
|
84
|
+
// return exactly `this`; we also require at least one return
|
|
85
|
+
// statement so we don't fire on methods that fall off the end.
|
|
86
|
+
hasValueReturn, allAreThis := preferReturnThisTypeAnalyzeBody(decl.Body)
|
|
87
|
+
if !hasValueReturn || !allAreThis {
|
|
88
|
+
return
|
|
89
|
+
}
|
|
90
|
+
ctx.Report(decl.Type, preferReturnThisTypeMessage)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const preferReturnThisTypeMessage = "Method always returns `this` — declare the return type as `this` so subclass call sites keep the narrower receiver type."
|
|
94
|
+
|
|
95
|
+
// preferReturnThisTypeAnalyzeBody walks the method body (without
|
|
96
|
+
// descending into nested function-like scopes) and reports:
|
|
97
|
+
// - hasValueReturn: at least one `return <expression>;` exists.
|
|
98
|
+
// - allAreThis: every value-returning `return` returns the bare
|
|
99
|
+
// `this` keyword (after stripping parens).
|
|
100
|
+
//
|
|
101
|
+
// A bare `return;` is ignored — it returns `undefined`, which the rule
|
|
102
|
+
// cannot rewrite to `this` regardless. The conservative interpretation
|
|
103
|
+
// matches the upstream rule's behavior.
|
|
104
|
+
func preferReturnThisTypeAnalyzeBody(body *shimast.Node) (hasValueReturn, allAreThis bool) {
|
|
105
|
+
allAreThis = true
|
|
106
|
+
var walk func(*shimast.Node)
|
|
107
|
+
walk = func(n *shimast.Node) {
|
|
108
|
+
if n == nil {
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
if n != body && isFunctionLikeKind(n) {
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
if n.Kind == shimast.KindReturnStatement {
|
|
115
|
+
ret := n.AsReturnStatement()
|
|
116
|
+
if ret != nil && ret.Expression != nil {
|
|
117
|
+
hasValueReturn = true
|
|
118
|
+
inner := stripParens(ret.Expression)
|
|
119
|
+
if inner == nil || inner.Kind != shimast.KindThisKeyword {
|
|
120
|
+
allAreThis = false
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
n.ForEachChild(func(child *shimast.Node) bool {
|
|
125
|
+
walk(child)
|
|
126
|
+
return false
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
walk(body)
|
|
130
|
+
return hasValueReturn, allAreThis
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
func init() {
|
|
134
|
+
Register(preferReturnThisType{})
|
|
135
|
+
}
|