@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,114 @@
|
|
|
1
|
+
// unicorn/prefer-native-coercion-functions: an arrow that does nothing
|
|
2
|
+
// but pass its parameter to `String` / `Number` / `Boolean` / `BigInt`
|
|
3
|
+
// / `Symbol` is a wrapper around a function that already has the same
|
|
4
|
+
// signature. Passing the built-in reference directly drops a closure
|
|
5
|
+
// allocation, a stack frame, and a layer of indirection at every call
|
|
6
|
+
// site while reading as the operation it actually performs.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit `KindArrowFunction` and `KindFunctionExpression`. Fire
|
|
9
|
+
// when the function takes exactly one bare-identifier parameter AND its
|
|
10
|
+
// body is either an arrow expression body that calls one of the named
|
|
11
|
+
// constructors with the parameter as the sole argument, or a block body
|
|
12
|
+
// with a single `return <Name>(<param>);` statement.
|
|
13
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-native-coercion-functions.md
|
|
14
|
+
package linthost
|
|
15
|
+
|
|
16
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
17
|
+
|
|
18
|
+
type unicornPreferNativeCoercionFunctions struct{}
|
|
19
|
+
|
|
20
|
+
func (unicornPreferNativeCoercionFunctions) Name() string {
|
|
21
|
+
return "unicorn/prefer-native-coercion-functions"
|
|
22
|
+
}
|
|
23
|
+
func (unicornPreferNativeCoercionFunctions) Visits() []shimast.Kind {
|
|
24
|
+
return []shimast.Kind{shimast.KindArrowFunction, shimast.KindFunctionExpression}
|
|
25
|
+
}
|
|
26
|
+
func (unicornPreferNativeCoercionFunctions) Check(ctx *Context, node *shimast.Node) {
|
|
27
|
+
params := node.Parameters()
|
|
28
|
+
if len(params) != 1 {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
paramName := parameterIdentifierName(params[0])
|
|
32
|
+
if paramName == "" {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
var body *shimast.Node
|
|
36
|
+
switch node.Kind {
|
|
37
|
+
case shimast.KindArrowFunction:
|
|
38
|
+
if arrow := node.AsArrowFunction(); arrow != nil {
|
|
39
|
+
body = arrow.Body
|
|
40
|
+
}
|
|
41
|
+
case shimast.KindFunctionExpression:
|
|
42
|
+
if fn := node.AsFunctionExpression(); fn != nil {
|
|
43
|
+
body = fn.Body
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if body == nil {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
call := unicornPreferNativeCoercionBodyCall(body)
|
|
50
|
+
if call == nil {
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
if !unicornPreferNativeCoercionIsCoercion(call, paramName) {
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
ctx.Report(node, "Use the bare `String` / `Number` / `Boolean` / `BigInt` function reference instead of an arrow wrapper.")
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// unicornPreferNativeCoercionBodyCall normalizes a function body to the
|
|
60
|
+
// inner `CallExpression`. A concise arrow body returns its expression
|
|
61
|
+
// directly; a block body must contain exactly one `return <expr>;` and
|
|
62
|
+
// the returned expression must itself be a call.
|
|
63
|
+
func unicornPreferNativeCoercionBodyCall(body *shimast.Node) *shimast.Node {
|
|
64
|
+
if body == nil {
|
|
65
|
+
return nil
|
|
66
|
+
}
|
|
67
|
+
if body.Kind != shimast.KindBlock {
|
|
68
|
+
expr := stripParens(body)
|
|
69
|
+
if expr == nil || expr.Kind != shimast.KindCallExpression {
|
|
70
|
+
return nil
|
|
71
|
+
}
|
|
72
|
+
return expr
|
|
73
|
+
}
|
|
74
|
+
block := body.AsBlock()
|
|
75
|
+
if block == nil || block.Statements == nil || len(block.Statements.Nodes) != 1 {
|
|
76
|
+
return nil
|
|
77
|
+
}
|
|
78
|
+
stmt := block.Statements.Nodes[0]
|
|
79
|
+
if stmt == nil || stmt.Kind != shimast.KindReturnStatement {
|
|
80
|
+
return nil
|
|
81
|
+
}
|
|
82
|
+
ret := stmt.AsReturnStatement()
|
|
83
|
+
if ret == nil || ret.Expression == nil {
|
|
84
|
+
return nil
|
|
85
|
+
}
|
|
86
|
+
expr := stripParens(ret.Expression)
|
|
87
|
+
if expr == nil || expr.Kind != shimast.KindCallExpression {
|
|
88
|
+
return nil
|
|
89
|
+
}
|
|
90
|
+
return expr
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// unicornPreferNativeCoercionIsCoercion reports whether `call` is a
|
|
94
|
+
// `String|Number|Boolean|BigInt|Symbol(<param>)` invocation where the
|
|
95
|
+
// single argument is the parameter identifier.
|
|
96
|
+
func unicornPreferNativeCoercionIsCoercion(call *shimast.Node, paramName string) bool {
|
|
97
|
+
c := call.AsCallExpression()
|
|
98
|
+
if c == nil || c.Expression == nil {
|
|
99
|
+
return false
|
|
100
|
+
}
|
|
101
|
+
switch identifierText(c.Expression) {
|
|
102
|
+
case "String", "Number", "Boolean", "BigInt", "Symbol":
|
|
103
|
+
default:
|
|
104
|
+
return false
|
|
105
|
+
}
|
|
106
|
+
if c.Arguments == nil || len(c.Arguments.Nodes) != 1 {
|
|
107
|
+
return false
|
|
108
|
+
}
|
|
109
|
+
return identifierText(stripParens(c.Arguments.Nodes[0])) == paramName
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
func init() {
|
|
113
|
+
Register(unicornPreferNativeCoercionFunctions{})
|
|
114
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// unicorn/prefer-negative-index: `arr.slice(arr.length - N)` is the
|
|
2
|
+
// long-hand spelling of `arr.slice(-N)`. The subtraction repeats the
|
|
3
|
+
// receiver, allocates an extra read, and obscures the intent. The same
|
|
4
|
+
// idiom shows up across `slice`, `splice`, `toSpliced`, `at`, and
|
|
5
|
+
// `lastIndexOf`; all five accept a negative index that means the same
|
|
6
|
+
// thing the subtraction expresses, so the rule pushes authors there.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit `KindCallExpression`. Fire when the callee is
|
|
9
|
+
// `PropertyAccess(_, name)` for one of those five method names AND the
|
|
10
|
+
// first argument is a `KindBinaryExpression` with operator `-`, LHS a
|
|
11
|
+
// `PropertyAccess(_, length)`, and RHS a positive numeric literal.
|
|
12
|
+
// Reports on the offending argument so the diagnostic anchors to the
|
|
13
|
+
// expression the author would rewrite.
|
|
14
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-negative-index.md
|
|
15
|
+
package linthost
|
|
16
|
+
|
|
17
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
18
|
+
|
|
19
|
+
type unicornPreferNegativeIndex struct{}
|
|
20
|
+
|
|
21
|
+
func (unicornPreferNegativeIndex) Name() string { return "unicorn/prefer-negative-index" }
|
|
22
|
+
func (unicornPreferNegativeIndex) Visits() []shimast.Kind {
|
|
23
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
24
|
+
}
|
|
25
|
+
func (unicornPreferNegativeIndex) Check(ctx *Context, node *shimast.Node) {
|
|
26
|
+
call := node.AsCallExpression()
|
|
27
|
+
if call == nil || call.Expression == nil {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
if call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
34
|
+
if access == nil {
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
switch identifierText(access.Name()) {
|
|
38
|
+
case "slice", "splice", "toSpliced", "at", "lastIndexOf":
|
|
39
|
+
default:
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) == 0 {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
first := stripParens(call.Arguments.Nodes[0])
|
|
46
|
+
if first == nil || first.Kind != shimast.KindBinaryExpression {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
bin := first.AsBinaryExpression()
|
|
50
|
+
if bin == nil || bin.OperatorToken == nil ||
|
|
51
|
+
bin.OperatorToken.Kind != shimast.KindMinusToken {
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
left := stripParens(bin.Left)
|
|
55
|
+
if left == nil || left.Kind != shimast.KindPropertyAccessExpression {
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
prop := left.AsPropertyAccessExpression()
|
|
59
|
+
if prop == nil || identifierText(prop.Name()) != "length" {
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
right := stripParens(bin.Right)
|
|
63
|
+
if right == nil || right.Kind != shimast.KindNumericLiteral {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
if !unicornPreferAtIsPositiveInteger(numericLiteralText(right)) {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
ctx.Report(first, "Use a negative index (`-N`) instead of `arr.length - N`.")
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
func init() {
|
|
73
|
+
Register(unicornPreferNegativeIndex{})
|
|
74
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// unicorn/prefer-node-protocol: the bare Node built-in specifier
|
|
2
|
+
// (`import "fs"` / `require("fs")`) is ambiguous — a userland package
|
|
3
|
+
// named `fs` on the module path resolves first, silently hijacking
|
|
4
|
+
// what readers assume is the Node built-in. The `node:` prefix removes
|
|
5
|
+
// the ambiguity and is supported by every modern Node release.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: visit `ImportDeclaration` for the static-import case and
|
|
8
|
+
// `CallExpression` for the `require(...)` case. Both reduce to a
|
|
9
|
+
// single string-literal specifier compared against the allowlist of
|
|
10
|
+
// Node built-in module names; matching specifiers (without the
|
|
11
|
+
// `node:` prefix) fire on the literal node itself so the diagnostic
|
|
12
|
+
// underlines the specifier text the reader needs to change.
|
|
13
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-node-protocol.md
|
|
14
|
+
package linthost
|
|
15
|
+
|
|
16
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
17
|
+
|
|
18
|
+
// unicornPreferNodeProtocolBuiltins enumerates the bare Node built-in
|
|
19
|
+
// module specifiers that must be rewritten to use the `node:` prefix.
|
|
20
|
+
var unicornPreferNodeProtocolBuiltins = map[string]struct{}{
|
|
21
|
+
"assert": {},
|
|
22
|
+
"assert/strict": {},
|
|
23
|
+
"async_hooks": {},
|
|
24
|
+
"buffer": {},
|
|
25
|
+
"child_process": {},
|
|
26
|
+
"cluster": {},
|
|
27
|
+
"console": {},
|
|
28
|
+
"constants": {},
|
|
29
|
+
"crypto": {},
|
|
30
|
+
"dgram": {},
|
|
31
|
+
"diagnostics_channel": {},
|
|
32
|
+
"dns": {},
|
|
33
|
+
"dns/promises": {},
|
|
34
|
+
"domain": {},
|
|
35
|
+
"events": {},
|
|
36
|
+
"fs": {},
|
|
37
|
+
"fs/promises": {},
|
|
38
|
+
"http": {},
|
|
39
|
+
"http2": {},
|
|
40
|
+
"https": {},
|
|
41
|
+
"inspector": {},
|
|
42
|
+
"module": {},
|
|
43
|
+
"net": {},
|
|
44
|
+
"os": {},
|
|
45
|
+
"path": {},
|
|
46
|
+
"path/posix": {},
|
|
47
|
+
"path/win32": {},
|
|
48
|
+
"perf_hooks": {},
|
|
49
|
+
"process": {},
|
|
50
|
+
"punycode": {},
|
|
51
|
+
"querystring": {},
|
|
52
|
+
"readline": {},
|
|
53
|
+
"readline/promises": {},
|
|
54
|
+
"repl": {},
|
|
55
|
+
"stream": {},
|
|
56
|
+
"stream/consumers": {},
|
|
57
|
+
"stream/promises": {},
|
|
58
|
+
"stream/web": {},
|
|
59
|
+
"string_decoder": {},
|
|
60
|
+
"sys": {},
|
|
61
|
+
"timers": {},
|
|
62
|
+
"timers/promises": {},
|
|
63
|
+
"tls": {},
|
|
64
|
+
"trace_events": {},
|
|
65
|
+
"tty": {},
|
|
66
|
+
"url": {},
|
|
67
|
+
"util": {},
|
|
68
|
+
"util/types": {},
|
|
69
|
+
"v8": {},
|
|
70
|
+
"vm": {},
|
|
71
|
+
"wasi": {},
|
|
72
|
+
"worker_threads": {},
|
|
73
|
+
"zlib": {},
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
type unicornPreferNodeProtocol struct{}
|
|
77
|
+
|
|
78
|
+
func (unicornPreferNodeProtocol) Name() string { return "unicorn/prefer-node-protocol" }
|
|
79
|
+
func (unicornPreferNodeProtocol) Visits() []shimast.Kind {
|
|
80
|
+
return []shimast.Kind{shimast.KindImportDeclaration, shimast.KindCallExpression}
|
|
81
|
+
}
|
|
82
|
+
func (unicornPreferNodeProtocol) Check(ctx *Context, node *shimast.Node) {
|
|
83
|
+
switch node.Kind {
|
|
84
|
+
case shimast.KindImportDeclaration:
|
|
85
|
+
imp := node.AsImportDeclaration()
|
|
86
|
+
if imp == nil || imp.ModuleSpecifier == nil {
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
if imp.ModuleSpecifier.Kind != shimast.KindStringLiteral {
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
specifier := stringLiteralText(imp.ModuleSpecifier)
|
|
93
|
+
if _, ok := unicornPreferNodeProtocolBuiltins[specifier]; !ok {
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
ctx.Report(imp.ModuleSpecifier, "Prefer `node:` protocol when importing Node built-ins.")
|
|
97
|
+
case shimast.KindCallExpression:
|
|
98
|
+
call := node.AsCallExpression()
|
|
99
|
+
if call == nil || call.Expression == nil {
|
|
100
|
+
return
|
|
101
|
+
}
|
|
102
|
+
if identifierText(call.Expression) != "require" {
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) != 1 {
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
arg := call.Arguments.Nodes[0]
|
|
109
|
+
if arg == nil || arg.Kind != shimast.KindStringLiteral {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
specifier := stringLiteralText(arg)
|
|
113
|
+
if _, ok := unicornPreferNodeProtocolBuiltins[specifier]; !ok {
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
ctx.Report(arg, "Prefer `node:` protocol when importing Node built-ins.")
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
func init() {
|
|
121
|
+
Register(unicornPreferNodeProtocol{})
|
|
122
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// unicorn/prefer-number-properties: the global functions `isNaN`,
|
|
2
|
+
// `isFinite`, `parseFloat`, `parseInt`, and the global constants `NaN`,
|
|
3
|
+
// `Infinity` were aliased onto the `Number` namespace in ES2015. The
|
|
4
|
+
// `Number.*` forms coerce more predictably (`Number.isNaN("abc")` is
|
|
5
|
+
// `false`, while the global `isNaN("abc")` is `true`) and are more
|
|
6
|
+
// discoverable. The rule pushes authors to the namespaced spellings.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit each `Identifier`. The text must be one of the six
|
|
9
|
+
// shadowable names. The identifier must be in a value-expression
|
|
10
|
+
// position — not the name part of a property access (`obj.isNaN`),
|
|
11
|
+
// not the key of a property assignment, and not a binding name. Reports
|
|
12
|
+
// on the identifier.
|
|
13
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-number-properties.md
|
|
14
|
+
package linthost
|
|
15
|
+
|
|
16
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
17
|
+
|
|
18
|
+
var unicornPreferNumberPropertiesNames = map[string]struct{}{
|
|
19
|
+
"isNaN": {},
|
|
20
|
+
"isFinite": {},
|
|
21
|
+
"parseFloat": {},
|
|
22
|
+
"parseInt": {},
|
|
23
|
+
"NaN": {},
|
|
24
|
+
"Infinity": {},
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type unicornPreferNumberProperties struct{}
|
|
28
|
+
|
|
29
|
+
func (unicornPreferNumberProperties) Name() string {
|
|
30
|
+
return "unicorn/prefer-number-properties"
|
|
31
|
+
}
|
|
32
|
+
func (unicornPreferNumberProperties) Visits() []shimast.Kind {
|
|
33
|
+
return []shimast.Kind{shimast.KindIdentifier}
|
|
34
|
+
}
|
|
35
|
+
func (unicornPreferNumberProperties) Check(ctx *Context, node *shimast.Node) {
|
|
36
|
+
name := identifierText(node)
|
|
37
|
+
if _, ok := unicornPreferNumberPropertiesNames[name]; !ok {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
parent := node.Parent
|
|
41
|
+
if parent == nil {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
switch parent.Kind {
|
|
45
|
+
case shimast.KindPropertyAccessExpression:
|
|
46
|
+
// `obj.isNaN` — the identifier is the property name, not a
|
|
47
|
+
// reference to the global. `Number.isNaN(...)` itself also
|
|
48
|
+
// reaches here and must not be flagged.
|
|
49
|
+
access := parent.AsPropertyAccessExpression()
|
|
50
|
+
if access != nil && access.Name() == node {
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
case shimast.KindQualifiedName:
|
|
54
|
+
// Type-position `A.B` — same rationale as PropertyAccess.
|
|
55
|
+
return
|
|
56
|
+
case shimast.KindPropertyAssignment,
|
|
57
|
+
shimast.KindShorthandPropertyAssignment,
|
|
58
|
+
shimast.KindMethodDeclaration,
|
|
59
|
+
shimast.KindPropertyDeclaration,
|
|
60
|
+
shimast.KindEnumMember,
|
|
61
|
+
shimast.KindPropertySignature,
|
|
62
|
+
shimast.KindMethodSignature,
|
|
63
|
+
shimast.KindGetAccessor,
|
|
64
|
+
shimast.KindSetAccessor:
|
|
65
|
+
// Member name slots on object/class shapes.
|
|
66
|
+
return
|
|
67
|
+
case shimast.KindParameter,
|
|
68
|
+
shimast.KindVariableDeclaration,
|
|
69
|
+
shimast.KindBindingElement,
|
|
70
|
+
shimast.KindFunctionDeclaration,
|
|
71
|
+
shimast.KindFunctionExpression,
|
|
72
|
+
shimast.KindClassDeclaration,
|
|
73
|
+
shimast.KindClassExpression,
|
|
74
|
+
shimast.KindImportSpecifier,
|
|
75
|
+
shimast.KindImportClause,
|
|
76
|
+
shimast.KindNamespaceImport,
|
|
77
|
+
shimast.KindExportSpecifier,
|
|
78
|
+
shimast.KindTypeParameter,
|
|
79
|
+
shimast.KindLabeledStatement:
|
|
80
|
+
// Binding / declaration names, not references to the global.
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
ctx.Report(node, "Prefer `Number.<X>` over the global `<X>` (e.g. `Number.isNaN`, `Number.parseInt`).")
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
func init() {
|
|
87
|
+
Register(unicornPreferNumberProperties{})
|
|
88
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// unicorn/prefer-object-from-entries: `entries.reduce((acc, [k, v]) =>
|
|
2
|
+
// ({ ...acc, [k]: v }), {})` is the long-hand spelling of
|
|
3
|
+
// `Object.fromEntries(entries)`. The reduce shape allocates a fresh
|
|
4
|
+
// object at every step (O(n^2) total), reads as the operation rather
|
|
5
|
+
// than the intent, and quietly drops to `Object` from whatever type the
|
|
6
|
+
// entry shape implied. `Object.fromEntries` does the same thing in one
|
|
7
|
+
// pass with one allocation and one well-known name.
|
|
8
|
+
//
|
|
9
|
+
// AST-only: visit `KindCallExpression`. Fire when the callee is
|
|
10
|
+
// `PropertyAccess(_, reduce)` AND the call has exactly two arguments AND
|
|
11
|
+
// the second argument is an empty `KindObjectLiteralExpression`. The
|
|
12
|
+
// shape of the reducer is intentionally not inspected: an empty-object
|
|
13
|
+
// seed in a `.reduce` chain is, in practice, the from-entries shape.
|
|
14
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-object-from-entries.md
|
|
15
|
+
package linthost
|
|
16
|
+
|
|
17
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
18
|
+
|
|
19
|
+
type unicornPreferObjectFromEntries struct{}
|
|
20
|
+
|
|
21
|
+
func (unicornPreferObjectFromEntries) Name() string {
|
|
22
|
+
return "unicorn/prefer-object-from-entries"
|
|
23
|
+
}
|
|
24
|
+
func (unicornPreferObjectFromEntries) Visits() []shimast.Kind {
|
|
25
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
26
|
+
}
|
|
27
|
+
func (unicornPreferObjectFromEntries) Check(ctx *Context, node *shimast.Node) {
|
|
28
|
+
call := node.AsCallExpression()
|
|
29
|
+
if call == nil || call.Expression == nil {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
if call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
36
|
+
if access == nil || identifierText(access.Name()) != "reduce" {
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) != 2 {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
seed := stripParens(call.Arguments.Nodes[1])
|
|
43
|
+
if seed == nil || seed.Kind != shimast.KindObjectLiteralExpression {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
obj := seed.AsObjectLiteralExpression()
|
|
47
|
+
if obj == nil || obj.Properties == nil || len(obj.Properties.Nodes) != 0 {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
ctx.Report(node, "Prefer `Object.fromEntries(...)` over `.reduce((acc, ...) => ..., {})` patterns.")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func init() {
|
|
54
|
+
Register(unicornPreferObjectFromEntries{})
|
|
55
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// unicorn/prefer-optional-catch-binding: ES2019 introduced optional
|
|
2
|
+
// catch bindings (`catch { ... }`) so that catch clauses that never
|
|
3
|
+
// reference the thrown error don't need to declare a binding at all.
|
|
4
|
+
// Holding onto the binding name keeps a dead local variable in source
|
|
5
|
+
// and signals that the catch body still cares about the error when in
|
|
6
|
+
// fact it doesn't.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit each `CatchClause`, restrict to the common-case
|
|
9
|
+
// binding names `e` and `error` (true scope analysis would require a
|
|
10
|
+
// resolver), and confirm the body's source text does not contain the
|
|
11
|
+
// binding name as a word-bounded identifier. The previous substring
|
|
12
|
+
// scan was load-bearing-wrong: `strings.Contains(body, "e")` matches
|
|
13
|
+
// nearly any English identifier, hiding the rule entirely; word
|
|
14
|
+
// boundaries (`\bname\b`) correctly distinguish `e` from `error`,
|
|
15
|
+
// `error` from `errorMessage`, etc. False positives on `name` inside
|
|
16
|
+
// string literals or comments are acceptable because the rule is
|
|
17
|
+
// conservative by design.
|
|
18
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-optional-catch-binding.md
|
|
19
|
+
package linthost
|
|
20
|
+
|
|
21
|
+
import (
|
|
22
|
+
"regexp"
|
|
23
|
+
|
|
24
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
var unicornPreferOptionalCatchBindingNamePattern = map[string]*regexp.Regexp{
|
|
28
|
+
"e": regexp.MustCompile(`\be\b`),
|
|
29
|
+
"error": regexp.MustCompile(`\berror\b`),
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type unicornPreferOptionalCatchBinding struct{}
|
|
33
|
+
|
|
34
|
+
func (unicornPreferOptionalCatchBinding) Name() string {
|
|
35
|
+
return "unicorn/prefer-optional-catch-binding"
|
|
36
|
+
}
|
|
37
|
+
func (unicornPreferOptionalCatchBinding) Visits() []shimast.Kind {
|
|
38
|
+
return []shimast.Kind{shimast.KindCatchClause}
|
|
39
|
+
}
|
|
40
|
+
func (unicornPreferOptionalCatchBinding) Check(ctx *Context, node *shimast.Node) {
|
|
41
|
+
catch := node.AsCatchClause()
|
|
42
|
+
if catch == nil || catch.VariableDeclaration == nil || catch.Block == nil {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
binding := catch.VariableDeclaration.Name()
|
|
46
|
+
if binding == nil || binding.Kind != shimast.KindIdentifier {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
name := identifierText(binding)
|
|
50
|
+
pattern, ok := unicornPreferOptionalCatchBindingNamePattern[name]
|
|
51
|
+
if !ok {
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
if pattern.MatchString(nodeText(ctx.File, catch.Block)) {
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
ctx.Report(binding, "Prefer optional catch binding `catch { ... }` when the error is unused.")
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
func init() {
|
|
61
|
+
Register(unicornPreferOptionalCatchBinding{})
|
|
62
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// unicorn/prefer-prototype-methods: `[].slice`, `[].push`,
|
|
2
|
+
// `{}.hasOwnProperty` and similar empty-literal property accesses are
|
|
3
|
+
// shorthand for grabbing a prototype method without typing
|
|
4
|
+
// `Array.prototype.slice` / `Object.prototype.hasOwnProperty`. The
|
|
5
|
+
// shorthand allocates a throwaway literal at every call, hides the
|
|
6
|
+
// intent of borrowing a prototype method, and is slower than the
|
|
7
|
+
// direct prototype lookup.
|
|
8
|
+
//
|
|
9
|
+
// AST-only: visit each `PropertyAccessExpression`, then match the
|
|
10
|
+
// receiver against either an empty `ArrayLiteralExpression` (no
|
|
11
|
+
// elements) or an empty `ObjectLiteralExpression` (no properties).
|
|
12
|
+
// The property name is intentionally not restricted — any borrowed
|
|
13
|
+
// method should switch to the explicit `<Constructor>.prototype.<m>`
|
|
14
|
+
// form.
|
|
15
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-prototype-methods.md
|
|
16
|
+
package linthost
|
|
17
|
+
|
|
18
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
19
|
+
|
|
20
|
+
type unicornPreferPrototypeMethods struct{}
|
|
21
|
+
|
|
22
|
+
func (unicornPreferPrototypeMethods) Name() string { return "unicorn/prefer-prototype-methods" }
|
|
23
|
+
func (unicornPreferPrototypeMethods) Visits() []shimast.Kind {
|
|
24
|
+
return []shimast.Kind{shimast.KindPropertyAccessExpression}
|
|
25
|
+
}
|
|
26
|
+
func (unicornPreferPrototypeMethods) Check(ctx *Context, node *shimast.Node) {
|
|
27
|
+
access := node.AsPropertyAccessExpression()
|
|
28
|
+
if access == nil || access.Expression == nil {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
receiver := stripParens(access.Expression)
|
|
32
|
+
if receiver == nil {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
switch receiver.Kind {
|
|
36
|
+
case shimast.KindArrayLiteralExpression:
|
|
37
|
+
arr := receiver.AsArrayLiteralExpression()
|
|
38
|
+
if arr == nil || arr.Elements == nil || len(arr.Elements.Nodes) != 0 {
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
case shimast.KindObjectLiteralExpression:
|
|
42
|
+
obj := receiver.AsObjectLiteralExpression()
|
|
43
|
+
if obj == nil || obj.Properties == nil || len(obj.Properties.Nodes) != 0 {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
default:
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
ctx.Report(node, "Use `Array.prototype.<method>` / `Object.prototype.<method>` instead of borrowing via an empty literal.")
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
func init() {
|
|
53
|
+
Register(unicornPreferPrototypeMethods{})
|
|
54
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// unicorn/prefer-query-selector: `getElementById`,
|
|
2
|
+
// `getElementsByClassName`, and `getElementsByTagName` predate the CSS
|
|
3
|
+
// selector family on `Document` and `Element`. Unifying every lookup on
|
|
4
|
+
// `querySelector` / `querySelectorAll` lets callers compose selectors
|
|
5
|
+
// without juggling three different method signatures and live-collection
|
|
6
|
+
// semantics.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit each `CallExpression`, match a property-access callee
|
|
9
|
+
// whose method identifier is one of the legacy lookup names, and fire
|
|
10
|
+
// when the call has exactly one string-literal argument. The
|
|
11
|
+
// string-literal gate isolates the canonical id/class/tag shape from
|
|
12
|
+
// runtime-built argument expressions that the rule would mis-suggest a
|
|
13
|
+
// selector for.
|
|
14
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-query-selector.md
|
|
15
|
+
package linthost
|
|
16
|
+
|
|
17
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
18
|
+
|
|
19
|
+
var unicornPreferQuerySelectorMethods = map[string]struct{}{
|
|
20
|
+
"getElementById": {},
|
|
21
|
+
"getElementsByClassName": {},
|
|
22
|
+
"getElementsByTagName": {},
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type unicornPreferQuerySelector struct{}
|
|
26
|
+
|
|
27
|
+
func (unicornPreferQuerySelector) Name() string { return "unicorn/prefer-query-selector" }
|
|
28
|
+
func (unicornPreferQuerySelector) Visits() []shimast.Kind {
|
|
29
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
30
|
+
}
|
|
31
|
+
func (unicornPreferQuerySelector) Check(ctx *Context, node *shimast.Node) {
|
|
32
|
+
call := node.AsCallExpression()
|
|
33
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
37
|
+
if access == nil {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
method := identifierText(access.Name())
|
|
41
|
+
if _, ok := unicornPreferQuerySelectorMethods[method]; !ok {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) != 1 {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
arg := call.Arguments.Nodes[0]
|
|
48
|
+
if arg == nil || arg.Kind != shimast.KindStringLiteral {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
ctx.Report(node, "Prefer `querySelector` / `querySelectorAll` over `"+method+"`.")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
func init() {
|
|
55
|
+
Register(unicornPreferQuerySelector{})
|
|
56
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// unicorn/prefer-reflect-apply: `Function.prototype.apply.call(fn, thisArg, args)`
|
|
2
|
+
// is the long-hand pre-`Reflect.apply` workaround for invoking `apply`
|
|
3
|
+
// when the receiver may have shadowed it. `Reflect.apply(fn, thisArg, args)`
|
|
4
|
+
// expresses the same intent in a single named operation and survives
|
|
5
|
+
// `apply` being deleted from the prototype chain.
|
|
6
|
+
//
|
|
7
|
+
// AST-only and text-driven: visit each `CallExpression` and match the
|
|
8
|
+
// callee against the exact textual chain `Function.prototype.apply.call`.
|
|
9
|
+
// Comparing against the source text is the cleanest conservative
|
|
10
|
+
// recognition; alternate spellings (computed access, intermediate
|
|
11
|
+
// aliases) are intentionally out of scope.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-reflect-apply.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
16
|
+
|
|
17
|
+
type unicornPreferReflectApply struct{}
|
|
18
|
+
|
|
19
|
+
func (unicornPreferReflectApply) Name() string { return "unicorn/prefer-reflect-apply" }
|
|
20
|
+
func (unicornPreferReflectApply) Visits() []shimast.Kind {
|
|
21
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
22
|
+
}
|
|
23
|
+
func (unicornPreferReflectApply) Check(ctx *Context, node *shimast.Node) {
|
|
24
|
+
call := node.AsCallExpression()
|
|
25
|
+
if call == nil || call.Expression == nil {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
if nodeText(ctx.File, call.Expression) != "Function.prototype.apply.call" {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
ctx.Report(node, "Prefer `Reflect.apply` over `Function.prototype.apply.call`.")
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
func init() {
|
|
35
|
+
Register(unicornPreferReflectApply{})
|
|
36
|
+
}
|