@ttsc/lint 0.13.1 → 0.14.0-dev.20260528.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 +948 -69
- package/lib/defaultFormat.d.ts +9 -6
- package/lib/defaultFormat.js +9 -6
- package/lib/defaultFormat.js.map +1 -1
- package/lib/index.d.ts +46 -0
- package/lib/index.js +35 -10
- package/lib/index.js.map +1 -1
- package/lib/structures/ITtscLintConfig.d.ts +12 -6
- package/lib/structures/{ITtscLintFormatConfig.d.ts → ITtscLintFormat.d.ts} +2 -2
- package/lib/structures/{TtscLintRuleMap.js → ITtscLintFormat.js} +1 -1
- package/lib/structures/ITtscLintFormat.js.map +1 -0
- 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/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 +104 -0
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +14 -0
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +79 -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 +17 -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 +1257 -0
- package/lib/structures/{ITtscLintFormatConfig.js → rules/ITtscLintCoreRules.js} +1 -1
- 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 +129 -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 +157 -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 +167 -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 +201 -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 +140 -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 +302 -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 +185 -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 +330 -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 +188 -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 +51 -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 +39 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.js +12 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactRules.d.ts +289 -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 +190 -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 +66 -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 +148 -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 +181 -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 +21 -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 +174 -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 +94 -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 +22 -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 +310 -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 +1132 -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 +141 -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/config.go +48 -17
- package/linthost/config_format.go +9 -9
- package/linthost/directives.go +67 -25
- package/linthost/dispatch.go +14 -3
- package/linthost/engine.go +152 -31
- package/linthost/fix.go +2 -2
- package/linthost/lsp.go +747 -0
- package/linthost/print_dispatch.go +2 -2
- package/linthost/print_nodes_function.go +2 -2
- package/linthost/print_nodes_object.go +1 -1
- 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 +94 -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_jsdoc.go +1 -1
- package/linthost/rules_format_print_width.go +9 -9
- package/linthost/rules_format_quotes.go +1 -1
- package/linthost/rules_format_semi.go +1 -1
- package/linthost/rules_format_sort_imports.go +1 -1
- package/linthost/rules_format_trailing_comma.go +1 -1
- 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 +1128 -73
- 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 +155 -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 +4 -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 +11 -8
- package/src/index.ts +40 -16
- package/src/structures/ITtscLintConfig.ts +12 -6
- package/src/structures/{ITtscLintFormatConfig.ts → ITtscLintFormat.ts} +2 -2
- package/src/structures/TtscLintRuleSetting.ts +55 -0
- package/src/structures/index.ts +3 -4
- package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +128 -0
- package/src/structures/rules/ITtscLintBoundariesRules.ts +95 -0
- package/src/structures/rules/ITtscLintContributorRules.ts +21 -0
- package/src/structures/rules/ITtscLintCoreRules.ts +1406 -0
- package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
- package/src/structures/rules/ITtscLintCypressRules.ts +145 -0
- package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +213 -0
- package/src/structures/rules/ITtscLintFunctionalRules.ts +202 -0
- package/src/structures/rules/ITtscLintJestRules.ts +220 -0
- package/src/structures/rules/ITtscLintJsdocRules.ts +153 -0
- package/src/structures/rules/ITtscLintJsxA11yRules.ts +339 -0
- package/src/structures/rules/ITtscLintNextjsRules.ts +206 -0
- package/src/structures/rules/ITtscLintPlaywrightRules.ts +361 -0
- package/src/structures/rules/ITtscLintPromiseRules.ts +205 -0
- package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
- package/src/structures/rules/ITtscLintReactPerfRules.ts +55 -0
- package/src/structures/rules/ITtscLintReactRuleOptions.ts +43 -0
- package/src/structures/rules/ITtscLintReactRules.ts +321 -0
- package/src/structures/rules/ITtscLintRegexpRules.ts +212 -0
- package/src/structures/rules/ITtscLintRuleOptionsMap.ts +89 -0
- package/src/structures/rules/ITtscLintRules.ts +77 -0
- package/src/structures/rules/ITtscLintSecurityRules.ts +162 -0
- package/src/structures/rules/ITtscLintSolidRules.ts +202 -0
- package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +23 -0
- package/src/structures/rules/ITtscLintStorybookRules.ts +193 -0
- package/src/structures/rules/ITtscLintTanstackQueryRules.ts +102 -0
- package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +24 -0
- package/src/structures/rules/ITtscLintTestingLibraryRules.ts +342 -0
- package/src/structures/rules/ITtscLintTypeScriptRules.ts +1230 -0
- package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
- package/src/structures/rules/ITtscLintVitestRules.ts +154 -0
- package/src/structures/rules/index.ts +31 -0
- 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/TtscLintRule.ts +0 -160
- package/src/structures/TtscLintRuleMap.ts +0 -55
- package/src/structures/TtscLintRuleOptions.ts +0 -151
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// unicorn/import-style: forbids named or default imports from configured
|
|
2
|
+
// modules so that, for example, `path` is always imported as the
|
|
3
|
+
// namespace `path` and never destructured. The rule's behavior is
|
|
4
|
+
// entirely driven by a per-module configuration map
|
|
5
|
+
// (`styles: { foo: { default: false, namespace: true } }`). Without that
|
|
6
|
+
// configuration plumbing landing in the host's rule-options pipeline,
|
|
7
|
+
// the rule has no defaults to enforce, so it is registered as a no-op
|
|
8
|
+
// stub to keep `TestTypedKeysMatchRegisteredRules` aligned with the
|
|
9
|
+
// typed `ITtscLintUnicornRules` surface.
|
|
10
|
+
//
|
|
11
|
+
// The matching fixture under
|
|
12
|
+
// `tests/test-lint/src/cases/unicorn-import-style.ts` keeps its
|
|
13
|
+
// `@ttsc-corpus-skip` directive until the configuration plumbing lands.
|
|
14
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/import-style.md
|
|
15
|
+
package linthost
|
|
16
|
+
|
|
17
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
18
|
+
|
|
19
|
+
type unicornImportStyle struct{}
|
|
20
|
+
|
|
21
|
+
func (unicornImportStyle) Name() string { return "unicorn/import-style" }
|
|
22
|
+
func (unicornImportStyle) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
|
|
23
|
+
func (unicornImportStyle) Check(_ *Context, _ *shimast.Node) {
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
func init() {
|
|
27
|
+
Register(unicornImportStyle{})
|
|
28
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// unicorn/isolated-functions: flags function expressions that "escape"
|
|
2
|
+
// their lexical closure unintentionally — e.g. an inner function that
|
|
3
|
+
// references no outer binding but is still placed at the inner scope.
|
|
4
|
+
// Correctly identifying "isolated function" context requires scope
|
|
5
|
+
// analysis tracking what each nested function captures, which is not
|
|
6
|
+
// available in the AST-only slice of this port.
|
|
7
|
+
//
|
|
8
|
+
// Registered as a no-op stub to keep
|
|
9
|
+
// `TestTypedKeysMatchRegisteredRules` aligned with the typed
|
|
10
|
+
// `ITtscLintUnicornRules` surface. The matching fixture under
|
|
11
|
+
// `tests/test-lint/src/cases/unicorn-isolated-functions.ts` keeps its
|
|
12
|
+
// `@ttsc-corpus-skip` directive.
|
|
13
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/isolated-functions.md
|
|
14
|
+
package linthost
|
|
15
|
+
|
|
16
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
17
|
+
|
|
18
|
+
type unicornIsolatedFunctions struct{}
|
|
19
|
+
|
|
20
|
+
func (unicornIsolatedFunctions) Name() string { return "unicorn/isolated-functions" }
|
|
21
|
+
func (unicornIsolatedFunctions) Visits() []shimast.Kind {
|
|
22
|
+
return []shimast.Kind{shimast.KindSourceFile}
|
|
23
|
+
}
|
|
24
|
+
func (unicornIsolatedFunctions) Check(_ *Context, _ *shimast.Node) {
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
func init() {
|
|
28
|
+
Register(unicornIsolatedFunctions{})
|
|
29
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// unicorn/new-for-builtins: built-in globals split into two groups for
|
|
2
|
+
// constructor etiquette. Primitive wrappers (`String`, `Number`, …) must
|
|
3
|
+
// be called WITHOUT `new` because the wrapper-object form is a footgun
|
|
4
|
+
// — `new String("x") instanceof Object` is true but `"x" instanceof
|
|
5
|
+
// Object` is false, and the wrapper form does not unify with the
|
|
6
|
+
// primitive in equality comparisons. Container constructors (`Array`,
|
|
7
|
+
// `Error`, `Map`, …) must be called WITH `new` because the call form
|
|
8
|
+
// either misbehaves (`Array(3)` allocates a sparse 3-slot array) or is
|
|
9
|
+
// outright invalid (`Error()` still works but is style-inconsistent).
|
|
10
|
+
//
|
|
11
|
+
// AST-only: visit both `NewExpression` and `CallExpression`. The
|
|
12
|
+
// callee-identifier text is matched against the corresponding allowlist
|
|
13
|
+
// and reported with the inverted construction message.
|
|
14
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/new-for-builtins.md
|
|
15
|
+
package linthost
|
|
16
|
+
|
|
17
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
18
|
+
|
|
19
|
+
// Primitive wrappers — `new` is wrong, call form is required.
|
|
20
|
+
var unicornNewForBuiltinsPrimitiveWrappers = map[string]struct{}{
|
|
21
|
+
"String": {},
|
|
22
|
+
"Number": {},
|
|
23
|
+
"Boolean": {},
|
|
24
|
+
"Symbol": {},
|
|
25
|
+
"BigInt": {},
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Container constructors — `new` is required, call form is wrong. Note
|
|
29
|
+
// that `Symbol` is intentionally NOT in this list: `Symbol(...)` is the
|
|
30
|
+
// correct primitive-wrapper call and must not be flagged.
|
|
31
|
+
var unicornNewForBuiltinsContainers = map[string]struct{}{
|
|
32
|
+
"Array": {},
|
|
33
|
+
"Error": {},
|
|
34
|
+
"EvalError": {},
|
|
35
|
+
"RangeError": {},
|
|
36
|
+
"ReferenceError": {},
|
|
37
|
+
"SyntaxError": {},
|
|
38
|
+
"TypeError": {},
|
|
39
|
+
"URIError": {},
|
|
40
|
+
"AggregateError": {},
|
|
41
|
+
"Object": {},
|
|
42
|
+
"Map": {},
|
|
43
|
+
"Set": {},
|
|
44
|
+
"WeakMap": {},
|
|
45
|
+
"WeakSet": {},
|
|
46
|
+
"Date": {},
|
|
47
|
+
"RegExp": {},
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type unicornNewForBuiltins struct{}
|
|
51
|
+
|
|
52
|
+
func (unicornNewForBuiltins) Name() string { return "unicorn/new-for-builtins" }
|
|
53
|
+
func (unicornNewForBuiltins) Visits() []shimast.Kind {
|
|
54
|
+
return []shimast.Kind{shimast.KindNewExpression, shimast.KindCallExpression}
|
|
55
|
+
}
|
|
56
|
+
func (unicornNewForBuiltins) Check(ctx *Context, node *shimast.Node) {
|
|
57
|
+
switch node.Kind {
|
|
58
|
+
case shimast.KindNewExpression:
|
|
59
|
+
ne := node.AsNewExpression()
|
|
60
|
+
if ne == nil {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
name := identifierText(ne.Expression)
|
|
64
|
+
if name == "" {
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
if _, ok := unicornNewForBuiltinsPrimitiveWrappers[name]; ok {
|
|
68
|
+
ctx.Report(node, "Don't use `new "+name+"(...)` with a primitive wrapper like `"+name+"`.")
|
|
69
|
+
}
|
|
70
|
+
case shimast.KindCallExpression:
|
|
71
|
+
call := node.AsCallExpression()
|
|
72
|
+
if call == nil {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
name := identifierText(call.Expression)
|
|
76
|
+
if name == "" {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
if _, ok := unicornNewForBuiltinsContainers[name]; ok {
|
|
80
|
+
ctx.Report(node, "Use `new "+name+"(...)` instead of `"+name+"(...)`.")
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
func init() {
|
|
86
|
+
Register(unicornNewForBuiltins{})
|
|
87
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// unicorn/no-abusive-eslint-disable: a bare `// eslint-disable*` directive
|
|
2
|
+
// with no rule list suppresses every lint rule for the affected scope.
|
|
3
|
+
// That blanket-disable hides unrelated diagnostics the next reviewer would
|
|
4
|
+
// have caught, so the rule requires every `eslint-disable*` directive to
|
|
5
|
+
// name the rules it silences.
|
|
6
|
+
//
|
|
7
|
+
// File-level dispatch: visit `KindSourceFile` once per file, scan the
|
|
8
|
+
// raw source with the tsgo scanner so embedded `/* */` and `//` tokens
|
|
9
|
+
// inside template substitutions and string literals are not mistaken for
|
|
10
|
+
// real comments, and match each comment's stripped body — already trimmed
|
|
11
|
+
// by the shared `stripCommentDelimiters` helper — against
|
|
12
|
+
// `^eslint-disable(?:-next-line|-line)?$`. A match means the directive
|
|
13
|
+
// carries no rule list and is reported on the comment range.
|
|
14
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-abusive-eslint-disable.md
|
|
15
|
+
package linthost
|
|
16
|
+
|
|
17
|
+
import (
|
|
18
|
+
"regexp"
|
|
19
|
+
|
|
20
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
21
|
+
shimscanner "github.com/microsoft/typescript-go/shim/scanner"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
var unicornNoAbusiveEslintDisablePattern = regexp.MustCompile(`^eslint-disable(?:-next-line|-line)?$`)
|
|
25
|
+
|
|
26
|
+
type unicornNoAbusiveEslintDisable struct{}
|
|
27
|
+
|
|
28
|
+
func (unicornNoAbusiveEslintDisable) Name() string { return "unicorn/no-abusive-eslint-disable" }
|
|
29
|
+
func (unicornNoAbusiveEslintDisable) Visits() []shimast.Kind {
|
|
30
|
+
return []shimast.Kind{shimast.KindSourceFile}
|
|
31
|
+
}
|
|
32
|
+
func (unicornNoAbusiveEslintDisable) Check(ctx *Context, node *shimast.Node) {
|
|
33
|
+
if ctx.File == nil {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
src := ctx.File.Text()
|
|
37
|
+
scanner := shimscanner.NewScanner()
|
|
38
|
+
scanner.SetText(src)
|
|
39
|
+
scanner.SetSkipTrivia(false)
|
|
40
|
+
for {
|
|
41
|
+
kind := scanner.Scan()
|
|
42
|
+
if kind == shimast.KindEndOfFile {
|
|
43
|
+
break
|
|
44
|
+
}
|
|
45
|
+
if kind != shimast.KindSingleLineCommentTrivia && kind != shimast.KindMultiLineCommentTrivia {
|
|
46
|
+
continue
|
|
47
|
+
}
|
|
48
|
+
start := scanner.TokenStart()
|
|
49
|
+
end := scanner.TokenEnd()
|
|
50
|
+
if start < 0 || end > len(src) || end <= start {
|
|
51
|
+
continue
|
|
52
|
+
}
|
|
53
|
+
body := stripCommentDelimiters(src[start:end])
|
|
54
|
+
if !unicornNoAbusiveEslintDisablePattern.MatchString(body) {
|
|
55
|
+
continue
|
|
56
|
+
}
|
|
57
|
+
ctx.ReportRange(start, end, "Specify the rules to disable in each `eslint-disable*` directive.")
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
func init() {
|
|
62
|
+
Register(unicornNoAbusiveEslintDisable{})
|
|
63
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// unicorn/no-accessor-recursion: a `get value()` that reads
|
|
2
|
+
// `this.value` triggers itself — the getter is the only thing that
|
|
3
|
+
// resolves `this.value`, so the call recurses until the stack runs
|
|
4
|
+
// out. The same holds for setters, computed and string-keyed names,
|
|
5
|
+
// and class / object-literal accessors. The rule pins every read of
|
|
6
|
+
// `this.<X>` inside the `<X>` accessor as a recursion bug.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit both `KindGetAccessor` and `KindSetAccessor`. Take
|
|
9
|
+
// the accessor's own name and walk its body, reporting every
|
|
10
|
+
// `KindPropertyAccessExpression(KindThisKeyword, <name>)` that
|
|
11
|
+
// matches. The walk does NOT descend into nested non-arrow function
|
|
12
|
+
// bodies (`FunctionDeclaration`, `FunctionExpression`,
|
|
13
|
+
// `MethodDeclaration`, `GetAccessor`, `SetAccessor`,
|
|
14
|
+
// `Constructor`), because those rebind `this`. Arrow functions
|
|
15
|
+
// preserve the outer `this` and are walked through.
|
|
16
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-accessor-recursion.md
|
|
17
|
+
package linthost
|
|
18
|
+
|
|
19
|
+
import (
|
|
20
|
+
"fmt"
|
|
21
|
+
|
|
22
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
type unicornNoAccessorRecursion struct{}
|
|
26
|
+
|
|
27
|
+
func (unicornNoAccessorRecursion) Name() string { return "unicorn/no-accessor-recursion" }
|
|
28
|
+
func (unicornNoAccessorRecursion) Visits() []shimast.Kind {
|
|
29
|
+
return []shimast.Kind{shimast.KindGetAccessor, shimast.KindSetAccessor}
|
|
30
|
+
}
|
|
31
|
+
func (unicornNoAccessorRecursion) Check(ctx *Context, node *shimast.Node) {
|
|
32
|
+
name := unicornAccessorRecursionName(node)
|
|
33
|
+
if name == "" {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
body := node.Body()
|
|
37
|
+
if body == nil {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
unicornAccessorRecursionWalkRespectingThisBoundary(body, func(child *shimast.Node) {
|
|
41
|
+
if child == nil || child.Kind != shimast.KindPropertyAccessExpression {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
access := child.AsPropertyAccessExpression()
|
|
45
|
+
if access == nil || access.Expression == nil {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
if access.Expression.Kind != shimast.KindThisKeyword {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
if identifierText(access.Name()) != name {
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
ctx.Report(child, fmt.Sprintf("Reading `this.%s` inside the `%s` accessor recurses forever.", name, name))
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// unicornAccessorRecursionWalkRespectingThisBoundary walks `node` and
|
|
59
|
+
// its descendants depth-first, but does not descend into bodies that
|
|
60
|
+
// rebind `this`. Arrow functions are walked through because they
|
|
61
|
+
// capture the outer `this`.
|
|
62
|
+
func unicornAccessorRecursionWalkRespectingThisBoundary(node *shimast.Node, visit func(*shimast.Node)) {
|
|
63
|
+
if node == nil {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
visit(node)
|
|
67
|
+
node.ForEachChild(func(child *shimast.Node) bool {
|
|
68
|
+
if child == nil {
|
|
69
|
+
return false
|
|
70
|
+
}
|
|
71
|
+
switch child.Kind {
|
|
72
|
+
case shimast.KindFunctionDeclaration,
|
|
73
|
+
shimast.KindFunctionExpression,
|
|
74
|
+
shimast.KindMethodDeclaration,
|
|
75
|
+
shimast.KindGetAccessor,
|
|
76
|
+
shimast.KindSetAccessor,
|
|
77
|
+
shimast.KindConstructor:
|
|
78
|
+
return false
|
|
79
|
+
}
|
|
80
|
+
unicornAccessorRecursionWalkRespectingThisBoundary(child, visit)
|
|
81
|
+
return false
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// unicornAccessorRecursionName returns the property name of a
|
|
86
|
+
// get/set accessor declaration. Only bare Identifier and StringLiteral
|
|
87
|
+
// names are supported because computed names cannot be matched against
|
|
88
|
+
// the `this.<X>` shape statically.
|
|
89
|
+
func unicornAccessorRecursionName(node *shimast.Node) string {
|
|
90
|
+
var name *shimast.Node
|
|
91
|
+
switch node.Kind {
|
|
92
|
+
case shimast.KindGetAccessor:
|
|
93
|
+
if g := node.AsGetAccessorDeclaration(); g != nil {
|
|
94
|
+
name = g.Name()
|
|
95
|
+
}
|
|
96
|
+
case shimast.KindSetAccessor:
|
|
97
|
+
if s := node.AsSetAccessorDeclaration(); s != nil {
|
|
98
|
+
name = s.Name()
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if name == nil {
|
|
102
|
+
return ""
|
|
103
|
+
}
|
|
104
|
+
switch name.Kind {
|
|
105
|
+
case shimast.KindIdentifier:
|
|
106
|
+
return identifierText(name)
|
|
107
|
+
case shimast.KindStringLiteral:
|
|
108
|
+
return stringLiteralText(name)
|
|
109
|
+
}
|
|
110
|
+
return ""
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
func init() {
|
|
114
|
+
Register(unicornNoAccessorRecursion{})
|
|
115
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// unicorn/no-anonymous-default-export: `export default function () {}`
|
|
2
|
+
// and `export default class {}` (and the arrow-function equivalent)
|
|
3
|
+
// leave the exported value without a local binding name. Stack traces,
|
|
4
|
+
// dev-tools labels, and downstream `import X from …` all rebind to the
|
|
5
|
+
// importer's chosen name, so the export site contributes nothing to
|
|
6
|
+
// readability. Giving the function/class a name keeps the original
|
|
7
|
+
// identifier visible everywhere.
|
|
8
|
+
//
|
|
9
|
+
// AST-only: TypeScript-Go's parser splits the two surface forms of
|
|
10
|
+
// `export default`. `export default <expression>` parses as
|
|
11
|
+
// `KindExportAssignment`; `export default function …` / `export default
|
|
12
|
+
// class …` parse as `KindFunctionDeclaration` / `KindClassDeclaration`
|
|
13
|
+
// with `export` + `default` modifiers and an optional `Name()`. The
|
|
14
|
+
// rule covers both paths: it reports an `ExportAssignment` whose
|
|
15
|
+
// expression is a `KindFunctionExpression`/`KindArrowFunction`/
|
|
16
|
+
// `KindClassExpression` with no name, and reports an export-default
|
|
17
|
+
// `Function`/`ClassDeclaration` whose `Name()` is nil.
|
|
18
|
+
//
|
|
19
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-anonymous-default-export.md
|
|
20
|
+
package linthost
|
|
21
|
+
|
|
22
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
23
|
+
|
|
24
|
+
type unicornNoAnonymousDefaultExport struct{}
|
|
25
|
+
|
|
26
|
+
func (unicornNoAnonymousDefaultExport) Name() string {
|
|
27
|
+
return "unicorn/no-anonymous-default-export"
|
|
28
|
+
}
|
|
29
|
+
func (unicornNoAnonymousDefaultExport) Visits() []shimast.Kind {
|
|
30
|
+
return []shimast.Kind{
|
|
31
|
+
shimast.KindExportAssignment,
|
|
32
|
+
shimast.KindFunctionDeclaration,
|
|
33
|
+
shimast.KindClassDeclaration,
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
func (unicornNoAnonymousDefaultExport) Check(ctx *Context, node *shimast.Node) {
|
|
37
|
+
switch node.Kind {
|
|
38
|
+
case shimast.KindExportAssignment:
|
|
39
|
+
assign := node.AsExportAssignment()
|
|
40
|
+
if assign == nil || assign.IsExportEquals || assign.Expression == nil {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
expr := stripParens(assign.Expression)
|
|
44
|
+
if expr == nil {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
switch expr.Kind {
|
|
48
|
+
case shimast.KindFunctionExpression:
|
|
49
|
+
if fn := expr.AsFunctionExpression(); fn != nil && fn.Name() == nil {
|
|
50
|
+
ctx.Report(node, "Give a name to the default export.")
|
|
51
|
+
}
|
|
52
|
+
case shimast.KindArrowFunction:
|
|
53
|
+
// Arrow functions never bind a name; an `export default` of
|
|
54
|
+
// one is always anonymous.
|
|
55
|
+
ctx.Report(node, "Give a name to the default export.")
|
|
56
|
+
case shimast.KindClassExpression:
|
|
57
|
+
if cls := expr.AsClassExpression(); cls != nil && cls.Name() == nil {
|
|
58
|
+
ctx.Report(node, "Give a name to the default export.")
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
case shimast.KindFunctionDeclaration, shimast.KindClassDeclaration:
|
|
62
|
+
if !hasModifier(node, shimast.KindExportKeyword) ||
|
|
63
|
+
!hasModifier(node, shimast.KindDefaultKeyword) {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
if node.Name() == nil {
|
|
67
|
+
ctx.Report(node, "Give a name to the default export.")
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
func init() {
|
|
73
|
+
Register(unicornNoAnonymousDefaultExport{})
|
|
74
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// unicorn/no-array-callback-reference: passing a function reference
|
|
2
|
+
// directly to an `Array#…` iteration method silently exposes it to
|
|
3
|
+
// extra positional arguments. `[1,2,3].filter(isEven)` passes `isEven`
|
|
4
|
+
// the index and the source array as well as the element, which is fine
|
|
5
|
+
// for `isEven` but breaks the moment the predicate's signature grows
|
|
6
|
+
// optional parameters. Wrapping in an arrow that takes just the value
|
|
7
|
+
// pins the call shape locally.
|
|
8
|
+
//
|
|
9
|
+
// AST-only: each visited `CallExpression` is matched against a
|
|
10
|
+
// property-access callee whose method name is one of the iteration
|
|
11
|
+
// methods, and the first argument is checked for the bare-identifier
|
|
12
|
+
// shape. Anything more elaborate (member access, arrow, call result)
|
|
13
|
+
// has already named the call shape explicitly and is out of scope.
|
|
14
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-callback-reference.md
|
|
15
|
+
package linthost
|
|
16
|
+
|
|
17
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
18
|
+
|
|
19
|
+
var unicornNoArrayCallbackReferenceMethods = map[string]struct{}{
|
|
20
|
+
"every": {},
|
|
21
|
+
"filter": {},
|
|
22
|
+
"find": {},
|
|
23
|
+
"findIndex": {},
|
|
24
|
+
"findLast": {},
|
|
25
|
+
"findLastIndex": {},
|
|
26
|
+
"flatMap": {},
|
|
27
|
+
"forEach": {},
|
|
28
|
+
"map": {},
|
|
29
|
+
"some": {},
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type unicornNoArrayCallbackReference struct{}
|
|
33
|
+
|
|
34
|
+
func (unicornNoArrayCallbackReference) Name() string {
|
|
35
|
+
return "unicorn/no-array-callback-reference"
|
|
36
|
+
}
|
|
37
|
+
func (unicornNoArrayCallbackReference) Visits() []shimast.Kind {
|
|
38
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
39
|
+
}
|
|
40
|
+
func (unicornNoArrayCallbackReference) Check(ctx *Context, node *shimast.Node) {
|
|
41
|
+
call := node.AsCallExpression()
|
|
42
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
46
|
+
if access == nil {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
method := identifierText(access.Name())
|
|
50
|
+
if _, ok := unicornNoArrayCallbackReferenceMethods[method]; !ok {
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) == 0 {
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
first := call.Arguments.Nodes[0]
|
|
57
|
+
if first == nil || first.Kind != shimast.KindIdentifier {
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
ctx.Report(first, "Don't pass a function reference directly to `Array#"+method+"` — wrap it in an arrow that takes only the value.")
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
func init() {
|
|
64
|
+
Register(unicornNoArrayCallbackReference{})
|
|
65
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// unicorn/no-array-for-each: `Array#forEach` is harder to short-circuit and
|
|
2
|
+
// to reason about than a `for…of` loop — `break`/`continue`/`return` from
|
|
3
|
+
// the loop body all become per-iteration callback returns with different
|
|
4
|
+
// semantics, and async/await inside the callback silently no-ops because
|
|
5
|
+
// the iteration callback is not awaited.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: dispatch on each `CallExpression`, look for a property-access
|
|
8
|
+
// callee whose method identifier is `forEach`, and fire on the call. The
|
|
9
|
+
// receiver expression is not type-checked — the syntactic shape is the
|
|
10
|
+
// signal the rule wants to discourage, regardless of whether the value is
|
|
11
|
+
// known to be an array at the type level.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-for-each.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
16
|
+
|
|
17
|
+
type unicornNoArrayForEach struct{}
|
|
18
|
+
|
|
19
|
+
func (unicornNoArrayForEach) Name() string { return "unicorn/no-array-for-each" }
|
|
20
|
+
func (unicornNoArrayForEach) Visits() []shimast.Kind {
|
|
21
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
22
|
+
}
|
|
23
|
+
func (unicornNoArrayForEach) Check(ctx *Context, node *shimast.Node) {
|
|
24
|
+
call := node.AsCallExpression()
|
|
25
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
29
|
+
if access == nil {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
if identifierText(access.Name()) != "forEach" {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
ctx.Report(node, "Use `for…of` instead of `.forEach(…)`.")
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
func init() {
|
|
39
|
+
Register(unicornNoArrayForEach{})
|
|
40
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// unicorn/no-array-method-this-argument: the iteration methods on
|
|
2
|
+
// `Array.prototype` accept an optional `thisArg` after the callback. The
|
|
3
|
+
// runtime binds that `thisArg` only for non-arrow callbacks — arrow
|
|
4
|
+
// callbacks ignore it entirely — so the second argument's behavior
|
|
5
|
+
// depends on the callable shape of the first. Replacing it with a closure
|
|
6
|
+
// that captures the intended value makes the binding unambiguous and
|
|
7
|
+
// arrow-safe.
|
|
8
|
+
//
|
|
9
|
+
// AST-only: visit each `CallExpression`, match a property-access callee
|
|
10
|
+
// whose method identifier is one of the Array.prototype iteration methods
|
|
11
|
+
// that accept a thisArg, and fire when the call has exactly two
|
|
12
|
+
// arguments. One argument is the canonical no-thisArg shape; three or
|
|
13
|
+
// more means a different callsite signature and is out of scope.
|
|
14
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-method-this-argument.md
|
|
15
|
+
package linthost
|
|
16
|
+
|
|
17
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
18
|
+
|
|
19
|
+
var unicornNoArrayMethodThisArgumentMethods = map[string]struct{}{
|
|
20
|
+
"every": {},
|
|
21
|
+
"filter": {},
|
|
22
|
+
"find": {},
|
|
23
|
+
"findIndex": {},
|
|
24
|
+
"findLast": {},
|
|
25
|
+
"findLastIndex": {},
|
|
26
|
+
"flatMap": {},
|
|
27
|
+
"forEach": {},
|
|
28
|
+
"map": {},
|
|
29
|
+
"some": {},
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type unicornNoArrayMethodThisArgument struct{}
|
|
33
|
+
|
|
34
|
+
func (unicornNoArrayMethodThisArgument) Name() string {
|
|
35
|
+
return "unicorn/no-array-method-this-argument"
|
|
36
|
+
}
|
|
37
|
+
func (unicornNoArrayMethodThisArgument) Visits() []shimast.Kind {
|
|
38
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
39
|
+
}
|
|
40
|
+
func (unicornNoArrayMethodThisArgument) Check(ctx *Context, node *shimast.Node) {
|
|
41
|
+
call := node.AsCallExpression()
|
|
42
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
46
|
+
if access == nil {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
method := identifierText(access.Name())
|
|
50
|
+
if _, ok := unicornNoArrayMethodThisArgumentMethods[method]; !ok {
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) != 2 {
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
ctx.Report(node, "Don't use `thisArg` on `Array#"+method+"` — use an explicit closure that captures the value instead.")
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
func init() {
|
|
60
|
+
Register(unicornNoArrayMethodThisArgument{})
|
|
61
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// unicorn/no-array-reduce: `Array#reduce` and `Array#reduceRight` collapse
|
|
2
|
+
// an iteration into a single callback that has to encode both the
|
|
3
|
+
// accumulator state and the per-element step, which routinely produces
|
|
4
|
+
// less-readable code than an explicit loop. The rule pushes authors
|
|
5
|
+
// toward `for…of` (or a typed accumulator initialized outside the loop)
|
|
6
|
+
// so the state and the step live on separate lines.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit each `CallExpression`, check that the callee is a
|
|
9
|
+
// property access whose method identifier is `reduce` or `reduceRight`,
|
|
10
|
+
// and fire on the call. The receiver expression is not type-checked —
|
|
11
|
+
// the syntactic shape is the signal the rule wants to discourage.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-reduce.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
16
|
+
|
|
17
|
+
type unicornNoArrayReduce struct{}
|
|
18
|
+
|
|
19
|
+
func (unicornNoArrayReduce) Name() string { return "unicorn/no-array-reduce" }
|
|
20
|
+
func (unicornNoArrayReduce) Visits() []shimast.Kind {
|
|
21
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
22
|
+
}
|
|
23
|
+
func (unicornNoArrayReduce) Check(ctx *Context, node *shimast.Node) {
|
|
24
|
+
call := node.AsCallExpression()
|
|
25
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
29
|
+
if access == nil {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
method := identifierText(access.Name())
|
|
33
|
+
if method != "reduce" && method != "reduceRight" {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
ctx.Report(node, "Avoid `Array#"+method+"()` — use an explicit loop or `for…of` instead.")
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
func init() {
|
|
40
|
+
Register(unicornNoArrayReduce{})
|
|
41
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// unicorn/no-array-reverse: `Array#reverse()` mutates the array in place
|
|
2
|
+
// and also returns the same reference, which lets aliasing bugs slip into
|
|
3
|
+
// otherwise-pure pipelines (`const out = input.reverse()` rewrites
|
|
4
|
+
// `input` too). ES2023 ships `Array#toReversed()`, which produces a new
|
|
5
|
+
// array and leaves the source untouched, so the rule pushes authors
|
|
6
|
+
// toward the non-mutating form.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit each `CallExpression`, check that the callee is a
|
|
9
|
+
// property access whose method identifier is `reverse`, and require zero
|
|
10
|
+
// arguments — `reverse` accepts none, so a non-empty argument list is
|
|
11
|
+
// almost certainly a different `reverse` on a user-defined type and is
|
|
12
|
+
// excluded by design.
|
|
13
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-reverse.md
|
|
14
|
+
package linthost
|
|
15
|
+
|
|
16
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
17
|
+
|
|
18
|
+
type unicornNoArrayReverse struct{}
|
|
19
|
+
|
|
20
|
+
func (unicornNoArrayReverse) Name() string { return "unicorn/no-array-reverse" }
|
|
21
|
+
func (unicornNoArrayReverse) Visits() []shimast.Kind {
|
|
22
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
23
|
+
}
|
|
24
|
+
func (unicornNoArrayReverse) Check(ctx *Context, node *shimast.Node) {
|
|
25
|
+
call := node.AsCallExpression()
|
|
26
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
30
|
+
if access == nil {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
if identifierText(access.Name()) != "reverse" {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
if call.Arguments != nil && len(call.Arguments.Nodes) != 0 {
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
ctx.Report(node, "Prefer `Array#toReversed()` over the mutating `Array#reverse()`.")
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func init() {
|
|
43
|
+
Register(unicornNoArrayReverse{})
|
|
44
|
+
}
|