@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,39 @@
|
|
|
1
|
+
// defaultCase: a `switch` statement that omits the `default` clause
|
|
2
|
+
// silently drops every discriminant value not matched by an explicit
|
|
3
|
+
// `case` label. The rule wants the catch-all path written out so an
|
|
4
|
+
// unhandled discriminant becomes an intentional branch — even if that
|
|
5
|
+
// branch is a `// no default` comment marker.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: each visited `SwitchStatement` checks its `CaseBlock`
|
|
8
|
+
// clauses for any node of kind `DefaultClause`. The rule reports on the
|
|
9
|
+
// switch keyword itself rather than the case block so the diagnostic
|
|
10
|
+
// lands at the head of the statement.
|
|
11
|
+
// https://eslint.org/docs/latest/rules/default-case
|
|
12
|
+
package linthost
|
|
13
|
+
|
|
14
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
15
|
+
|
|
16
|
+
type defaultCase struct{}
|
|
17
|
+
|
|
18
|
+
func (defaultCase) Name() string { return "default-case" }
|
|
19
|
+
func (defaultCase) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSwitchStatement} }
|
|
20
|
+
func (defaultCase) Check(ctx *Context, node *shimast.Node) {
|
|
21
|
+
sw := node.AsSwitchStatement()
|
|
22
|
+
if sw == nil || sw.CaseBlock == nil {
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
block := sw.CaseBlock.AsCaseBlock()
|
|
26
|
+
if block == nil || block.Clauses == nil {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
for _, clause := range block.Clauses.Nodes {
|
|
30
|
+
if clause != nil && clause.Kind == shimast.KindDefaultClause {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
ctx.Report(node, "Expected a default case.")
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
func init() {
|
|
38
|
+
Register(defaultCase{})
|
|
39
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// defaultCaseLast: a `switch` statement whose `default` clause is not
|
|
2
|
+
// the final clause changes fall-through semantics in a way that almost
|
|
3
|
+
// never matches the author's intent — running `default` then falling
|
|
4
|
+
// into `case "b"` is rarely what a misordered switch wants. The rule
|
|
5
|
+
// requires `default` to appear after every `case` label.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: each visited `SwitchStatement` walks its `CaseBlock`
|
|
8
|
+
// clauses, and any `DefaultClause` that is not the last element is
|
|
9
|
+
// reported on the clause itself.
|
|
10
|
+
// https://eslint.org/docs/latest/rules/default-case-last
|
|
11
|
+
package linthost
|
|
12
|
+
|
|
13
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
14
|
+
|
|
15
|
+
type defaultCaseLast struct{}
|
|
16
|
+
|
|
17
|
+
func (defaultCaseLast) Name() string { return "default-case-last" }
|
|
18
|
+
func (defaultCaseLast) Visits() []shimast.Kind {
|
|
19
|
+
return []shimast.Kind{shimast.KindSwitchStatement}
|
|
20
|
+
}
|
|
21
|
+
func (defaultCaseLast) Check(ctx *Context, node *shimast.Node) {
|
|
22
|
+
sw := node.AsSwitchStatement()
|
|
23
|
+
if sw == nil || sw.CaseBlock == nil {
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
block := sw.CaseBlock.AsCaseBlock()
|
|
27
|
+
if block == nil || block.Clauses == nil {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
clauses := block.Clauses.Nodes
|
|
31
|
+
if len(clauses) == 0 {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
last := clauses[len(clauses)-1]
|
|
35
|
+
for i := 0; i < len(clauses)-1; i++ {
|
|
36
|
+
clause := clauses[i]
|
|
37
|
+
if clause != nil && clause.Kind == shimast.KindDefaultClause {
|
|
38
|
+
_ = last
|
|
39
|
+
ctx.Report(clause, "Default clause should be the last clause.")
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
func init() {
|
|
45
|
+
Register(defaultCaseLast{})
|
|
46
|
+
}
|
package/linthost/rules_dupes.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
|
+
// noDuplicateCase: duplicated `case` labels in a single switch.
|
|
6
6
|
// https://eslint.org/docs/latest/rules/no-duplicate-case
|
|
7
7
|
type noDuplicateCase struct{}
|
|
8
8
|
|
|
@@ -38,7 +38,7 @@ func (noDuplicateCase) Check(ctx *Context, node *shimast.Node) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
//
|
|
41
|
+
// noDupeKeys: duplicated property names in a single object literal.
|
|
42
42
|
// https://eslint.org/docs/latest/rules/no-dupe-keys
|
|
43
43
|
type noDupeKeys struct{}
|
|
44
44
|
|
|
@@ -63,7 +63,7 @@ func (noDupeKeys) Check(ctx *Context, node *shimast.Node) {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
//
|
|
66
|
+
// noDupeArgs: duplicated parameter names in a single function head.
|
|
67
67
|
// https://eslint.org/docs/latest/rules/no-dupe-args
|
|
68
68
|
type noDupeArgs struct{}
|
|
69
69
|
|
package/linthost/rules_empty.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
|
+
// noEmpty: empty block statements (`{}`), but allow empty catch
|
|
6
6
|
// clauses since they're idiomatic for "ignore the error".
|
|
7
7
|
// https://eslint.org/docs/latest/rules/no-empty
|
|
8
8
|
type noEmpty struct{}
|
|
@@ -27,7 +27,7 @@ func (noEmpty) Check(ctx *Context, node *shimast.Node) {
|
|
|
27
27
|
ctx.Report(node, "Empty block statement.")
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
//
|
|
30
|
+
// noEmptyFunction: empty function / method / arrow / accessor bodies.
|
|
31
31
|
// https://eslint.org/docs/latest/rules/no-empty-function
|
|
32
32
|
type noEmptyFunction struct{}
|
|
33
33
|
|
|
@@ -60,7 +60,7 @@ func (noEmptyFunction) Check(ctx *Context, node *shimast.Node) {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
//
|
|
63
|
+
// noEmptyPattern: `({}) => x` or `function ({}) {}` — destructuring
|
|
64
64
|
// patterns with no bindings are usually a bug.
|
|
65
65
|
// https://eslint.org/docs/latest/rules/no-empty-pattern
|
|
66
66
|
type noEmptyPattern struct{}
|
package/linthost/rules_escape.go
CHANGED
|
@@ -6,7 +6,7 @@ import (
|
|
|
6
6
|
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
7
7
|
)
|
|
8
8
|
|
|
9
|
-
//
|
|
9
|
+
// noUselessEscape: flag backslashes that escape characters which do not
|
|
10
10
|
// require escaping. Inside string/template literals the meaningful
|
|
11
11
|
// escapes are limited to a fixed set; everywhere else the backslash is
|
|
12
12
|
// noise from a copy/paste accident or a confused author. ESLint
|
|
@@ -41,13 +41,16 @@ func (noUselessEscape) Check(ctx *Context, node *shimast.Node) {
|
|
|
41
41
|
if isInsideTaggedTemplate(node) {
|
|
42
42
|
return
|
|
43
43
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
// tsgo's `node.Pos()` points at the start of leading trivia; the regex
|
|
45
|
+
// scanner relies on `raw[0] == '/'`, so we have to anchor on the
|
|
46
|
+
// post-trivia token start. String/template scans tolerate leading
|
|
47
|
+
// trivia bytes by accident, but using `tokenRange` for every branch
|
|
48
|
+
// keeps reported offsets aligned with the actual literal.
|
|
49
|
+
pos, end := tokenRange(ctx.File, node)
|
|
50
|
+
if pos < 0 || pos >= end {
|
|
48
51
|
return
|
|
49
52
|
}
|
|
50
|
-
raw :=
|
|
53
|
+
raw := ctx.File.Text()[pos:end]
|
|
51
54
|
// Determine quote/scan delimiters based on node kind so the
|
|
52
55
|
// single-char escape whitelist matches ESLint per-context.
|
|
53
56
|
switch node.Kind {
|
|
@@ -66,12 +69,18 @@ func (noUselessEscape) Check(ctx *Context, node *shimast.Node) {
|
|
|
66
69
|
const stringValidEscapes = "'\"\\bfnrtv0xuU\n\r"
|
|
67
70
|
const templateValidEscapes = "`'\"\\bfnrtv0xuU$\n\r"
|
|
68
71
|
|
|
69
|
-
//
|
|
70
|
-
// preceded by `\`
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
|
|
72
|
+
// regexNonClassValidEscapes covers characters that are meaningful when
|
|
73
|
+
// preceded by `\` outside a character class — every regex meta-char plus
|
|
74
|
+
// the line terminators. Inside a `[...]` most of these characters lose
|
|
75
|
+
// their special meaning (`.`, `*`, `+`, `?`, `(`, `)`, `{`, `}`, `|`, `$`,
|
|
76
|
+
// `/` are all literal in a class), so the in-class allowlist is narrower:
|
|
77
|
+
// backslash, the class-delimiting `]`, the range operator `-`, and `^`
|
|
78
|
+
// (which would otherwise turn the class into a negation if the escape
|
|
79
|
+
// were stripped). Standard shorthand escapes (`\d`, `\w`, …) and the
|
|
80
|
+
// Unicode/hex/control escapes are handled separately in
|
|
81
|
+
// `isUselessRegexEscape` and apply in both contexts.
|
|
82
|
+
const regexNonClassValidEscapes = "^$\\.*+?()[]{}|/-\n\r"
|
|
83
|
+
const regexClassValidEscapes = "\\]-^\n\r"
|
|
75
84
|
|
|
76
85
|
// reportStringEscapes walks the raw source bytes of a string or template
|
|
77
86
|
// literal and reports each backslash whose following character is not in
|
|
@@ -212,29 +221,40 @@ func isUselessStringEscape(ch byte, whitelist string) bool {
|
|
|
212
221
|
|
|
213
222
|
// isUselessRegexEscape reports whether a backslash before `ch` is redundant
|
|
214
223
|
// in a regex pattern. `inClass` is true when the escape occurs inside a `[…]`
|
|
215
|
-
// character class, which
|
|
224
|
+
// character class, which narrows the set of meaningful meta-char escapes:
|
|
225
|
+
// most regex meta-chars (`.`, `*`, `+`, `?`, `(`, `)`, `{`, `}`, `|`, `^`,
|
|
226
|
+
// `$`, `/`) are literal inside a class, so escaping them there is noise.
|
|
216
227
|
func isUselessRegexEscape(ch byte, inClass bool) bool {
|
|
217
228
|
if ch < 0x20 {
|
|
218
229
|
return false
|
|
219
230
|
}
|
|
220
|
-
// Regex meta-chars and their friends.
|
|
221
|
-
if strings.IndexByte(regexValidEscapes, ch) >= 0 {
|
|
222
|
-
return false
|
|
223
|
-
}
|
|
224
|
-
// Inside a character class `]`, `\`, and `-` are still meaningful
|
|
225
|
-
// beyond the always-list; everything else stays useless.
|
|
226
231
|
if inClass {
|
|
227
|
-
|
|
228
|
-
case ']', '\\', '-', 'b':
|
|
232
|
+
if strings.IndexByte(regexClassValidEscapes, ch) >= 0 {
|
|
229
233
|
return false
|
|
230
234
|
}
|
|
235
|
+
} else if strings.IndexByte(regexNonClassValidEscapes, ch) >= 0 {
|
|
236
|
+
return false
|
|
231
237
|
}
|
|
232
|
-
// Common regex shorthand: \d \D \w \W \s \S \b \
|
|
238
|
+
// Common regex shorthand: \d \D \w \W \s \S \b \f \n \r \t \v \0 \x \u \c \p \P,
|
|
239
|
+
// plus decimal back-references \1..\9. `\B` (non-word-boundary) and `\k<name>`
|
|
240
|
+
// (named backref) are only meaningful outside a character class; `\q{...}` is
|
|
241
|
+
// a v-flag string-disjunction escape that is also class-only-meaningful.
|
|
233
242
|
switch ch {
|
|
234
|
-
case 'd', 'D', 'w', 'W', 's', 'S', 'b', '
|
|
235
|
-
'x', 'u', 'c', 'p', 'P',
|
|
243
|
+
case 'd', 'D', 'w', 'W', 's', 'S', 'b', 'f', 'n', 'r', 't', 'v', '0',
|
|
244
|
+
'x', 'u', 'c', 'p', 'P',
|
|
245
|
+
'1', '2', '3', '4', '5', '6', '7', '8', '9':
|
|
236
246
|
return false
|
|
237
247
|
}
|
|
248
|
+
if !inClass {
|
|
249
|
+
switch ch {
|
|
250
|
+
case 'B', 'k':
|
|
251
|
+
return false
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
if ch == 'q' {
|
|
255
|
+
return false
|
|
256
|
+
}
|
|
257
|
+
}
|
|
238
258
|
return true
|
|
239
259
|
}
|
|
240
260
|
|
package/linthost/rules_eval.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
|
+
// noEval: forbid `eval(...)` calls. Members of nested namespaces (e.g.
|
|
6
6
|
// `globalThis.eval(...)`) are not flagged here — that's
|
|
7
7
|
// `no-implied-eval`, which we don't ship in v0.
|
|
8
8
|
// https://eslint.org/docs/latest/rules/no-eval
|
|
@@ -20,7 +20,7 @@ func (noEval) Check(ctx *Context, node *shimast.Node) {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
//
|
|
23
|
+
// noScriptUrl: forbid `"javascript:..."` literals. Often used to inject
|
|
24
24
|
// inline JS via DOM `href`/`src`; legacy and dangerous.
|
|
25
25
|
// https://eslint.org/docs/latest/rules/no-script-url
|
|
26
26
|
type noScriptURL struct{}
|
|
@@ -2,7 +2,7 @@ package linthost
|
|
|
2
2
|
|
|
3
3
|
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
4
4
|
|
|
5
|
-
//
|
|
5
|
+
// noUnsafeFinally: `return` / `break` / `continue` / `throw` inside a
|
|
6
6
|
// `finally` clause silently overrides the in-flight exception or value.
|
|
7
7
|
// https://eslint.org/docs/latest/rules/no-unsafe-finally
|
|
8
8
|
type noUnsafeFinally struct{}
|
|
@@ -83,7 +83,7 @@ func keywordOfControl(node *shimast.Node) string {
|
|
|
83
83
|
return "control flow"
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
//
|
|
86
|
+
// noUselessCatch: `catch (err) { throw err; }` adds no behavior.
|
|
87
87
|
// https://eslint.org/docs/latest/rules/no-useless-catch
|
|
88
88
|
type noUselessCatch struct{}
|
|
89
89
|
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
package linthost
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
5
|
+
shimscanner "github.com/microsoft/typescript-go/shim/scanner"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
// formatArrowParens normalizes the parentheses around a single-parameter
|
|
9
|
+
// arrow function, mirroring Prettier's `arrowParens`:
|
|
10
|
+
//
|
|
11
|
+
// - prefer "always" (Prettier default): a bare `x => x` gains parens,
|
|
12
|
+
// becoming `(x) => x`.
|
|
13
|
+
// - prefer "avoid": `(x) => x` drops them, becoming `x => x`.
|
|
14
|
+
//
|
|
15
|
+
// Only a single parameter that is a plain identifier with no type
|
|
16
|
+
// annotation, default, rest, optional `?`, or modifier is affected, every
|
|
17
|
+
// other shape (`(x: T)`, `({ x })`, `(...x)`, `(x = 1)`, `(x?)`, `(x, y)`,
|
|
18
|
+
// `()`) keeps its parentheses in both modes, exactly as Prettier does.
|
|
19
|
+
// `async x => x` is handled too: the modifier sits before the parameter, so
|
|
20
|
+
// the parameter-name span is unaffected.
|
|
21
|
+
//
|
|
22
|
+
// The rule rewrites only the parameter span (`x` <-> `(x)`), never the body
|
|
23
|
+
// or the `=>`, so a chained arrow `a => b => …` has each eligible arm
|
|
24
|
+
// normalized independently. Idempotent: a parameter already in the
|
|
25
|
+
// preferred shape compares equal and emits nothing.
|
|
26
|
+
type formatArrowParens struct{}
|
|
27
|
+
|
|
28
|
+
type formatArrowParensOptions struct {
|
|
29
|
+
Prefer string `json:"prefer"`
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
func (formatArrowParens) Name() string { return "format/arrow-parens" }
|
|
33
|
+
func (formatArrowParens) IsFormat() bool { return true }
|
|
34
|
+
|
|
35
|
+
func (formatArrowParens) Visits() []shimast.Kind {
|
|
36
|
+
return []shimast.Kind{shimast.KindArrowFunction}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
func (formatArrowParens) Check(ctx *Context, node *shimast.Node) {
|
|
40
|
+
if ctx == nil || ctx.File == nil || node == nil {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
arrow := node.AsArrowFunction()
|
|
44
|
+
if arrow == nil || arrow.Parameters == nil {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
params := arrow.Parameters.Nodes
|
|
48
|
+
if len(params) != 1 || params[0] == nil {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
param := params[0]
|
|
52
|
+
if !isBareIdentifierParam(param) {
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
// A type-parameter list (`<T>(x) => …`) forces the parameter parens in
|
|
56
|
+
// both modes (a bare `<T>x =>` is not valid), so leave such an arrow
|
|
57
|
+
// alone, its parens are mandatory, not stylistic.
|
|
58
|
+
if arrow.TypeParameters != nil && len(arrow.TypeParameters.Nodes) > 0 {
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
// A return-type annotation (`(x): T => …`) also requires the parens.
|
|
62
|
+
if arrow.Type != nil {
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
var opts formatArrowParensOptions
|
|
67
|
+
_ = ctx.DecodeOptions(&opts)
|
|
68
|
+
prefer := opts.Prefer
|
|
69
|
+
if prefer != "avoid" {
|
|
70
|
+
prefer = "always"
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
src := ctx.File.Text()
|
|
74
|
+
nameStart := shimscanner.SkipTrivia(src, param.Pos())
|
|
75
|
+
nameEnd := param.End()
|
|
76
|
+
if nameStart < 0 || nameEnd <= nameStart || nameEnd > len(src) {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Is the parameter already wrapped in `(` … `)`? Scan over whitespace on
|
|
81
|
+
// each side; the sole parameter of an arrow is delimited by the
|
|
82
|
+
// parameter-list parens when present.
|
|
83
|
+
openParen := scanBackForByte(src, nameStart, '(')
|
|
84
|
+
closeParen := scanForwardForByte(src, nameEnd, ')')
|
|
85
|
+
wrapped := openParen >= 0 && closeParen >= 0
|
|
86
|
+
|
|
87
|
+
switch prefer {
|
|
88
|
+
case "avoid":
|
|
89
|
+
if !wrapped {
|
|
90
|
+
return // already bare
|
|
91
|
+
}
|
|
92
|
+
// Replace `( … name … )` with just the name.
|
|
93
|
+
ctx.ReportRangeFix(
|
|
94
|
+
openParen,
|
|
95
|
+
closeParen+1,
|
|
96
|
+
"Single-parameter arrow should omit parentheses.",
|
|
97
|
+
TextEdit{Pos: openParen, End: closeParen + 1, Text: src[nameStart:nameEnd]},
|
|
98
|
+
)
|
|
99
|
+
default: // always
|
|
100
|
+
if wrapped {
|
|
101
|
+
return // already parenthesized
|
|
102
|
+
}
|
|
103
|
+
ctx.ReportRangeFix(
|
|
104
|
+
nameStart,
|
|
105
|
+
nameEnd,
|
|
106
|
+
"Single-parameter arrow should keep parentheses.",
|
|
107
|
+
TextEdit{Pos: nameStart, End: nameEnd, Text: "(" + src[nameStart:nameEnd] + ")"},
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// isBareIdentifierParam reports whether `param` is a plain identifier
|
|
113
|
+
// parameter: no rest `...`, no optional `?`, no type annotation, no default,
|
|
114
|
+
// no modifier (a parameter property), and an identifier name. Only such a
|
|
115
|
+
// parameter is eligible for arrow-paren normalization; every richer shape
|
|
116
|
+
// keeps its parentheses in both Prettier modes.
|
|
117
|
+
func isBareIdentifierParam(param *shimast.Node) bool {
|
|
118
|
+
decl := param.AsParameterDeclaration()
|
|
119
|
+
if decl == nil {
|
|
120
|
+
return false
|
|
121
|
+
}
|
|
122
|
+
if decl.DotDotDotToken != nil || decl.QuestionToken != nil ||
|
|
123
|
+
decl.Type != nil || decl.Initializer != nil {
|
|
124
|
+
return false
|
|
125
|
+
}
|
|
126
|
+
if mods := param.Modifiers(); mods != nil && len(mods.Nodes) > 0 {
|
|
127
|
+
return false
|
|
128
|
+
}
|
|
129
|
+
name := param.Name()
|
|
130
|
+
return name != nil && name.Kind == shimast.KindIdentifier
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// scanBackForByte returns the offset of the nearest `target` byte at or
|
|
134
|
+
// before `from`-1, scanning over whitespace only; -1 if a non-whitespace,
|
|
135
|
+
// non-target byte is reached first.
|
|
136
|
+
func scanBackForByte(src string, from int, target byte) int {
|
|
137
|
+
for i := from - 1; i >= 0; i-- {
|
|
138
|
+
c := src[i]
|
|
139
|
+
if c == target {
|
|
140
|
+
return i
|
|
141
|
+
}
|
|
142
|
+
if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
|
|
143
|
+
return -1
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return -1
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// scanForwardForByte returns the offset of the nearest `target` byte at or
|
|
150
|
+
// after `from`, scanning over whitespace only; -1 if a non-whitespace,
|
|
151
|
+
// non-target byte is reached first.
|
|
152
|
+
func scanForwardForByte(src string, from int, target byte) int {
|
|
153
|
+
for i := from; i < len(src); i++ {
|
|
154
|
+
c := src[i]
|
|
155
|
+
if c == target {
|
|
156
|
+
return i
|
|
157
|
+
}
|
|
158
|
+
if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
|
|
159
|
+
return -1
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return -1
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
func init() {
|
|
166
|
+
Register(formatArrowParens{})
|
|
167
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
package linthost
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
5
|
+
shimscanner "github.com/microsoft/typescript-go/shim/scanner"
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
// formatBracketSpacing normalizes the inner padding of single-line brace
|
|
9
|
+
// pairs, mirroring Prettier's `bracketSpacing`:
|
|
10
|
+
//
|
|
11
|
+
// - prefer true (Prettier default): one space just inside the braces,
|
|
12
|
+
// `{ x: 1 }`, `{ a, b }`, `import { foo } from "m"`.
|
|
13
|
+
// - prefer false: no inner space, `{x: 1}`, `{a, b}`, `import {foo}`.
|
|
14
|
+
//
|
|
15
|
+
// It applies to object literals, object binding patterns (destructuring),
|
|
16
|
+
// named imports/exports, and type literals, the brace kinds Prettier's
|
|
17
|
+
// bracketSpacing governs. Block, class, interface, enum, and module braces
|
|
18
|
+
// are NOT affected (their layout is owned by the indentation rules).
|
|
19
|
+
//
|
|
20
|
+
// The rule touches only a brace pair that opens and closes on the SAME
|
|
21
|
+
// line: a multi-line container's interior is the indentation rules' surface,
|
|
22
|
+
// and an empty `{}` has no interior to pad. It rewrites just the whitespace
|
|
23
|
+
// run immediately inside each brace, so it never disturbs the contents.
|
|
24
|
+
// Idempotent: a pair already in the preferred shape compares equal.
|
|
25
|
+
type formatBracketSpacing struct{}
|
|
26
|
+
|
|
27
|
+
type formatBracketSpacingOptions struct {
|
|
28
|
+
Spacing *bool `json:"spacing"`
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
func (formatBracketSpacing) Name() string { return "format/bracket-spacing" }
|
|
32
|
+
func (formatBracketSpacing) IsFormat() bool { return true }
|
|
33
|
+
|
|
34
|
+
func (formatBracketSpacing) Visits() []shimast.Kind {
|
|
35
|
+
return []shimast.Kind{
|
|
36
|
+
shimast.KindObjectLiteralExpression,
|
|
37
|
+
shimast.KindObjectBindingPattern,
|
|
38
|
+
shimast.KindNamedImports,
|
|
39
|
+
shimast.KindNamedExports,
|
|
40
|
+
shimast.KindTypeLiteral,
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
func (formatBracketSpacing) Check(ctx *Context, node *shimast.Node) {
|
|
45
|
+
if ctx == nil || ctx.File == nil || node == nil {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
var opts formatBracketSpacingOptions
|
|
49
|
+
_ = ctx.DecodeOptions(&opts)
|
|
50
|
+
spacing := true
|
|
51
|
+
if opts.Spacing != nil {
|
|
52
|
+
spacing = *opts.Spacing
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
src := ctx.File.Text()
|
|
56
|
+
start := shimscanner.SkipTrivia(src, node.Pos())
|
|
57
|
+
end := node.End()
|
|
58
|
+
if start < 0 || end <= start || end > len(src) {
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
// The node's first byte should be `{` and last `}`; a parenthesized or
|
|
62
|
+
// otherwise-wrapped form is out of scope.
|
|
63
|
+
if src[start] != '{' || src[end-1] != '}' {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
inner := src[start+1 : end-1]
|
|
67
|
+
if len(inner) == 0 {
|
|
68
|
+
return // empty `{}`, nothing to pad
|
|
69
|
+
}
|
|
70
|
+
// Multi-line: the interior belongs to the indentation rules.
|
|
71
|
+
for i := 0; i < len(inner); i++ {
|
|
72
|
+
if inner[i] == '\n' || inner[i] == '\r' {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Only-whitespace interior (`{ }`) is treated as empty: collapse to the
|
|
77
|
+
// canonical empty form rather than padding nothing.
|
|
78
|
+
trimmed := trimASCIISpace(inner)
|
|
79
|
+
if len(trimmed) == 0 {
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Compute the desired interior: exactly one leading+trailing space when
|
|
84
|
+
// spacing is on, none when off.
|
|
85
|
+
var want string
|
|
86
|
+
if spacing {
|
|
87
|
+
want = " " + trimmed + " "
|
|
88
|
+
} else {
|
|
89
|
+
want = trimmed
|
|
90
|
+
}
|
|
91
|
+
if inner == want {
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
ctx.ReportRangeFix(
|
|
95
|
+
start+1,
|
|
96
|
+
end-1,
|
|
97
|
+
"Normalize brace spacing to match bracketSpacing.",
|
|
98
|
+
TextEdit{Pos: start + 1, End: end - 1, Text: want},
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// trimASCIISpace strips leading and trailing spaces and tabs from s.
|
|
103
|
+
func trimASCIISpace(s string) string {
|
|
104
|
+
i := 0
|
|
105
|
+
for i < len(s) && (s[i] == ' ' || s[i] == '\t') {
|
|
106
|
+
i++
|
|
107
|
+
}
|
|
108
|
+
j := len(s)
|
|
109
|
+
for j > i && (s[j-1] == ' ' || s[j-1] == '\t') {
|
|
110
|
+
j--
|
|
111
|
+
}
|
|
112
|
+
return s[i:j]
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
func init() {
|
|
116
|
+
Register(formatBracketSpacing{})
|
|
117
|
+
}
|