@ttsc/lint 0.13.0 → 0.14.0-dev.20250530.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +955 -85
- package/lib/defaultFormat.d.ts +15 -8
- package/lib/defaultFormat.js +15 -8
- package/lib/defaultFormat.js.map +1 -1
- package/lib/index.d.ts +46 -0
- package/lib/index.js +60 -37
- package/lib/index.js.map +1 -1
- package/lib/structures/ITtscLintConfig.d.ts +12 -6
- package/lib/structures/TtscLintRuleSetting.d.ts +49 -0
- package/lib/structures/{TtscLintRuleOptions.js → TtscLintRuleSetting.js} +1 -1
- package/lib/structures/TtscLintRuleSetting.js.map +1 -0
- package/lib/structures/format/ITtscLintFormat.d.ts +128 -0
- package/lib/structures/{TtscLintRuleMap.js → format/ITtscLintFormat.js} +1 -1
- package/lib/structures/format/ITtscLintFormat.js.map +1 -0
- package/lib/structures/format/ITtscLintFormatJsDoc.d.ts +17 -0
- package/lib/structures/{ITtscLintFormatConfig.js → format/ITtscLintFormatJsDoc.js} +1 -1
- package/lib/structures/format/ITtscLintFormatJsDoc.js.map +1 -0
- package/lib/structures/format/ITtscLintFormatSortImports.d.ts +54 -0
- package/lib/structures/format/ITtscLintFormatSortImports.js +3 -0
- package/lib/structures/format/ITtscLintFormatSortImports.js.map +1 -0
- package/lib/structures/format/index.d.ts +3 -0
- package/lib/structures/format/index.js +20 -0
- package/lib/structures/format/index.js.map +1 -0
- package/lib/structures/index.d.ts +3 -4
- package/lib/structures/index.js +3 -4
- package/lib/structures/index.js.map +1 -1
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +95 -0
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +13 -0
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +75 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.js +3 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintContributorRules.d.ts +16 -0
- package/lib/structures/rules/ITtscLintContributorRules.js +3 -0
- package/lib/structures/rules/ITtscLintContributorRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintCoreRules.d.ts +1229 -0
- package/lib/structures/rules/ITtscLintCoreRules.js +3 -0
- package/lib/structures/rules/ITtscLintCoreRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +17 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js +10 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintCypressRules.d.ts +125 -0
- package/lib/structures/rules/ITtscLintCypressRules.js +3 -0
- package/lib/structures/rules/ITtscLintCypressRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +154 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +13 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +162 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.js +3 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJestRules.d.ts +190 -0
- package/lib/structures/rules/ITtscLintJestRules.js +3 -0
- package/lib/structures/rules/ITtscLintJestRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJsdocRules.d.ts +133 -0
- package/lib/structures/rules/ITtscLintJsdocRules.js +3 -0
- package/lib/structures/rules/ITtscLintJsdocRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +294 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.js +3 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintNextjsRules.d.ts +180 -0
- package/lib/structures/rules/ITtscLintNextjsRules.js +3 -0
- package/lib/structures/rules/ITtscLintNextjsRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +312 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.js +3 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintPromiseRules.d.ts +179 -0
- package/lib/structures/rules/ITtscLintPromiseRules.js +3 -0
- package/lib/structures/rules/ITtscLintPromiseRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +18 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js +8 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +49 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.js +3 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +37 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.js +11 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactRules.d.ts +276 -0
- package/lib/structures/rules/ITtscLintReactRules.js +3 -0
- package/lib/structures/rules/ITtscLintReactRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintRegexpRules.d.ts +182 -0
- package/lib/structures/rules/ITtscLintRegexpRules.js +3 -0
- package/lib/structures/rules/ITtscLintRegexpRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +65 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.js +3 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.js.map +1 -0
- package/lib/structures/rules/ITtscLintRules.d.ts +55 -0
- package/lib/structures/{TtscLintRule.js → rules/ITtscLintRules.js} +1 -1
- package/lib/structures/rules/ITtscLintRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintSecurityRules.d.ts +141 -0
- package/lib/structures/rules/ITtscLintSecurityRules.js +3 -0
- package/lib/structures/rules/ITtscLintSecurityRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintSolidRules.d.ts +178 -0
- package/lib/structures/rules/ITtscLintSolidRules.js +3 -0
- package/lib/structures/rules/ITtscLintSolidRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +20 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.js +9 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintStorybookRules.d.ts +165 -0
- package/lib/structures/rules/ITtscLintStorybookRules.js +3 -0
- package/lib/structures/rules/ITtscLintStorybookRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +88 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.js +3 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +21 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js +10 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +293 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.js +3 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +1074 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.js +3 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintUnicornRules.d.ts +997 -0
- package/lib/structures/rules/ITtscLintUnicornRules.js +3 -0
- package/lib/structures/rules/ITtscLintUnicornRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintVitestRules.d.ts +133 -0
- package/lib/structures/rules/ITtscLintVitestRules.js +3 -0
- package/lib/structures/rules/ITtscLintVitestRules.js.map +1 -0
- package/lib/structures/rules/index.d.ts +31 -0
- package/lib/structures/rules/index.js +48 -0
- package/lib/structures/rules/index.js.map +1 -0
- package/linthost/ast_helpers.go +30 -5
- package/linthost/compile.go +33 -2
- package/linthost/config.go +118 -71
- package/linthost/config_format.go +270 -104
- package/linthost/directives.go +67 -25
- package/linthost/dispatch.go +14 -3
- package/linthost/engine.go +160 -40
- package/linthost/fix.go +10 -3
- package/linthost/flags_gen.go +17 -15
- package/linthost/format.go +222 -25
- package/linthost/format_editor_settings.go +262 -0
- package/linthost/host.go +40 -3
- package/linthost/lsp.go +898 -0
- package/linthost/print_dispatch.go +5 -2
- package/linthost/print_engine.go +5 -5
- package/linthost/print_nodes_call.go +149 -67
- package/linthost/print_nodes_function.go +27 -2
- package/linthost/print_nodes_list.go +40 -5
- package/linthost/print_nodes_object.go +1 -1
- package/linthost/print_nodes_ternary.go +86 -0
- package/linthost/rule_names.go +14 -0
- package/linthost/rules_arrays.go +2 -2
- package/linthost/rules_boundaries.go +532 -0
- package/linthost/rules_camelcase.go +133 -0
- package/linthost/rules_complexity.go +95 -0
- package/linthost/rules_consistent_return.go +130 -0
- package/linthost/rules_console.go +1 -1
- package/linthost/rules_core_extra.go +739 -0
- package/linthost/rules_curly.go +70 -0
- package/linthost/rules_cypress.go +608 -0
- package/linthost/rules_debugger.go +2 -2
- package/linthost/rules_default_case.go +39 -0
- package/linthost/rules_default_case_last.go +46 -0
- package/linthost/rules_dupes.go +3 -3
- package/linthost/rules_empty.go +3 -3
- package/linthost/rules_escape.go +44 -24
- package/linthost/rules_eval.go +2 -2
- package/linthost/rules_finally.go +2 -2
- package/linthost/rules_format_arrow_parens.go +167 -0
- package/linthost/rules_format_bracket_spacing.go +117 -0
- package/linthost/rules_format_clause_join.go +172 -0
- package/linthost/rules_format_declaration_header.go +595 -0
- package/linthost/rules_format_indent.go +372 -0
- package/linthost/rules_format_jsdoc.go +5 -5
- package/linthost/rules_format_orphan_semi.go +106 -0
- package/linthost/rules_format_parameter_properties.go +175 -0
- package/linthost/rules_format_print_width.go +66 -55
- package/linthost/rules_format_quote_props.go +169 -0
- package/linthost/rules_format_quotes.go +76 -30
- package/linthost/rules_format_semi.go +186 -11
- package/linthost/rules_format_sort_imports.go +437 -118
- package/linthost/rules_format_statement_split.go +343 -0
- package/linthost/rules_format_ternary_nullish_parens.go +77 -0
- package/linthost/rules_format_trailing_comma.go +22 -3
- package/linthost/rules_format_whitespace.go +336 -0
- package/linthost/rules_functional.go +967 -0
- package/linthost/rules_gap.go +24 -45
- package/linthost/rules_grouped_accessor_pairs.go +87 -0
- package/linthost/rules_guard_for_in.go +198 -0
- package/linthost/rules_id_length.go +77 -0
- package/linthost/rules_imports.go +70 -2
- package/linthost/rules_init_declarations.go +53 -0
- package/linthost/rules_jest.go +618 -0
- package/linthost/rules_jsdoc.go +502 -0
- package/linthost/rules_jsx_a11y.go +1264 -0
- package/linthost/rules_logic.go +12 -12
- package/linthost/rules_loops.go +1 -1
- package/linthost/rules_max_classes_per_file.go +58 -0
- package/linthost/rules_max_depth.go +83 -0
- package/linthost/rules_max_lines.go +101 -0
- package/linthost/rules_max_lines_per_function.go +57 -0
- package/linthost/rules_max_nested_callbacks.go +61 -0
- package/linthost/rules_max_params.go +49 -0
- package/linthost/rules_max_statements.go +59 -0
- package/linthost/rules_misc.go +1 -1
- package/linthost/rules_nextjs.go +697 -0
- package/linthost/rules_no_else_return.go +75 -0
- package/linthost/rules_no_empty_named_blocks.go +91 -0
- package/linthost/rules_no_extend_native.go +51 -0
- package/linthost/rules_no_import_assign.go +140 -0
- package/linthost/rules_no_invalid_this.go +52 -0
- package/linthost/rules_no_loop_func.go +85 -0
- package/linthost/rules_no_magic_numbers.go +123 -0
- package/linthost/rules_no_mixed_operators.go +80 -0
- package/linthost/rules_no_param_reassign.go +98 -0
- package/linthost/rules_no_redeclare.go +270 -0
- package/linthost/rules_no_restricted_imports.go +105 -0
- package/linthost/rules_no_restricted_syntax.go +49 -0
- package/linthost/rules_no_shadow.go +147 -0
- package/linthost/rules_no_unreachable.go +77 -0
- package/linthost/rules_no_useless_assignment.go +120 -0
- package/linthost/rules_no_useless_constructor.go +245 -0
- package/linthost/rules_no_useless_return.go +51 -0
- package/linthost/rules_params.go +1 -1
- package/linthost/rules_playwright.go +788 -0
- package/linthost/rules_prefer_arrow_callback.go +124 -0
- package/linthost/rules_prefer_destructuring.go +98 -0
- package/linthost/rules_prefer_named_capture_group.go +129 -0
- package/linthost/rules_prefer_rest_params.go +94 -0
- package/linthost/rules_problems.go +41 -30
- package/linthost/rules_promise.go +1057 -2
- package/linthost/rules_protos.go +2 -2
- package/linthost/rules_react.go +773 -0
- package/linthost/rules_react_extras.go +227 -0
- package/linthost/rules_react_hooks.go +848 -0
- package/linthost/rules_react_perf.go +293 -0
- package/linthost/rules_react_refresh.go +583 -0
- package/linthost/rules_regexp.go +410 -0
- package/linthost/rules_security.go +830 -0
- package/linthost/rules_self.go +2 -2
- package/linthost/rules_solid.go +1073 -0
- package/linthost/rules_sort_imports.go +69 -0
- package/linthost/rules_sort_keys.go +134 -0
- package/linthost/rules_storybook.go +1176 -0
- package/linthost/rules_strings.go +4 -4
- package/linthost/rules_suggestions.go +38 -38
- package/linthost/rules_tanstack_query.go +844 -0
- package/linthost/rules_testing_library.go +1204 -0
- package/linthost/rules_throw.go +1 -1
- package/linthost/rules_ts.go +19 -19
- package/linthost/rules_ts_async.go +399 -0
- package/linthost/rules_ts_class_literal_property_style.go +115 -0
- package/linthost/rules_ts_consistent_type_exports.go +256 -0
- package/linthost/rules_ts_explicit_function_return_type.go +67 -0
- package/linthost/rules_ts_extra.go +159 -36
- package/linthost/rules_ts_no_base_to_string.go +218 -0
- package/linthost/rules_ts_no_confusing_void.go +72 -0
- package/linthost/rules_ts_no_deprecated.go +195 -0
- package/linthost/rules_ts_no_for_in_array.go +84 -0
- package/linthost/rules_ts_no_magic_numbers.go +124 -0
- package/linthost/rules_ts_no_meaningless_void_operator.go +84 -0
- package/linthost/rules_ts_no_misused_spread.go +104 -0
- package/linthost/rules_ts_no_redundant_type_constituents.go +113 -0
- package/linthost/rules_ts_no_restricted_types.go +62 -0
- package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +129 -0
- package/linthost/rules_ts_no_unnecessary_condition.go +250 -0
- package/linthost/rules_ts_no_unnecessary_qualifier.go +118 -0
- package/linthost/rules_ts_no_unnecessary_template_expression.go +178 -0
- package/linthost/rules_ts_no_unnecessary_type_arguments.go +234 -0
- package/linthost/rules_ts_no_unnecessary_type_assertion.go +157 -0
- package/linthost/rules_ts_no_unsafe_argument.go +82 -0
- package/linthost/rules_ts_no_unsafe_assignment.go +102 -0
- package/linthost/rules_ts_no_unsafe_call.go +82 -0
- package/linthost/rules_ts_no_unsafe_enum_comparison.go +235 -0
- package/linthost/rules_ts_no_unsafe_member_access.go +58 -0
- package/linthost/rules_ts_no_unsafe_return.go +126 -0
- package/linthost/rules_ts_no_unsafe_unary_minus.go +81 -0
- package/linthost/rules_ts_no_useless_constructor.go +52 -0
- package/linthost/rules_ts_non_nullable_type_assertion_style.go +108 -0
- package/linthost/rules_ts_parameter_properties.go +38 -0
- package/linthost/rules_ts_prefer_find.go +178 -0
- package/linthost/rules_ts_prefer_includes.go +255 -0
- package/linthost/rules_ts_prefer_nullish_coalescing.go +104 -0
- package/linthost/rules_ts_prefer_optional_chain.go +228 -0
- package/linthost/rules_ts_prefer_promise_reject_errors.go +176 -0
- package/linthost/rules_ts_prefer_readonly.go +73 -0
- package/linthost/rules_ts_prefer_reduce_type_parameter.go +116 -0
- package/linthost/rules_ts_prefer_regexp_exec.go +122 -0
- package/linthost/rules_ts_prefer_return_this_type.go +135 -0
- package/linthost/rules_ts_prefer_string_starts_ends_with.go +360 -0
- package/linthost/rules_ts_promise_function_async.go +77 -0
- package/linthost/rules_ts_related_getter_setter_pairs.go +113 -0
- package/linthost/rules_ts_require_array_sort_compare.go +96 -0
- package/linthost/rules_ts_restrict_plus_operands.go +127 -0
- package/linthost/rules_ts_restrict_template_expressions.go +95 -0
- package/linthost/rules_ts_simple.go +387 -0
- package/linthost/rules_ts_sort_type_constituents.go +144 -0
- package/linthost/rules_ts_strict_boolean_expressions.go +157 -0
- package/linthost/rules_ts_switch_exhaustiveness_check.go +147 -0
- package/linthost/rules_ts_unbound_method.go +126 -0
- package/linthost/rules_tsdoc.go +136 -0
- package/linthost/rules_unicorn_better_regex.go +27 -0
- package/linthost/rules_unicorn_catch_error_name.go +46 -0
- package/linthost/rules_unicorn_consistent_assert.go +47 -0
- package/linthost/rules_unicorn_consistent_date_clone.go +54 -0
- package/linthost/rules_unicorn_consistent_destructuring.go +25 -0
- package/linthost/rules_unicorn_consistent_empty_array_spread.go +62 -0
- package/linthost/rules_unicorn_consistent_existence_index_check.go +80 -0
- package/linthost/rules_unicorn_consistent_function_scoping.go +25 -0
- package/linthost/rules_unicorn_consistent_template_literal_escape.go +25 -0
- package/linthost/rules_unicorn_custom_error_definition.go +138 -0
- package/linthost/rules_unicorn_empty_brace_spaces.go +73 -0
- package/linthost/rules_unicorn_error_message.go +64 -0
- package/linthost/rules_unicorn_escape_case.go +51 -0
- package/linthost/rules_unicorn_expiring_todo_comments.go +78 -0
- package/linthost/rules_unicorn_explicit_length_check.go +88 -0
- package/linthost/rules_unicorn_filename_case.go +29 -0
- package/linthost/rules_unicorn_import_style.go +28 -0
- package/linthost/rules_unicorn_isolated_functions.go +29 -0
- package/linthost/rules_unicorn_new_for_builtins.go +87 -0
- package/linthost/rules_unicorn_no_abusive_eslint_disable.go +63 -0
- package/linthost/rules_unicorn_no_accessor_recursion.go +115 -0
- package/linthost/rules_unicorn_no_anonymous_default_export.go +74 -0
- package/linthost/rules_unicorn_no_array_callback_reference.go +65 -0
- package/linthost/rules_unicorn_no_array_for_each.go +40 -0
- package/linthost/rules_unicorn_no_array_method_this_argument.go +61 -0
- package/linthost/rules_unicorn_no_array_reduce.go +41 -0
- package/linthost/rules_unicorn_no_array_reverse.go +44 -0
- package/linthost/rules_unicorn_no_array_sort.go +43 -0
- package/linthost/rules_unicorn_no_await_expression_member.go +40 -0
- package/linthost/rules_unicorn_no_await_in_promise_methods.go +69 -0
- package/linthost/rules_unicorn_no_console_spaces.go +61 -0
- package/linthost/rules_unicorn_no_document_cookie.go +41 -0
- package/linthost/rules_unicorn_no_empty_file.go +44 -0
- package/linthost/rules_unicorn_no_for_loop.go +102 -0
- package/linthost/rules_unicorn_no_hex_escape.go +42 -0
- package/linthost/rules_unicorn_no_immediate_mutation.go +90 -0
- package/linthost/rules_unicorn_no_instanceof_builtins.go +66 -0
- package/linthost/rules_unicorn_no_invalid_fetch_options.go +79 -0
- package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +51 -0
- package/linthost/rules_unicorn_no_keyword_prefix.go +101 -0
- package/linthost/rules_unicorn_no_lonely_if.go +44 -0
- package/linthost/rules_unicorn_no_magic_array_flat_depth.go +51 -0
- package/linthost/rules_unicorn_no_named_default.go +54 -0
- package/linthost/rules_unicorn_no_negated_condition.go +85 -0
- package/linthost/rules_unicorn_no_negation_in_equality_check.go +50 -0
- package/linthost/rules_unicorn_no_nested_ternary.go +43 -0
- package/linthost/rules_unicorn_no_new_array.go +30 -0
- package/linthost/rules_unicorn_no_new_buffer.go +31 -0
- package/linthost/rules_unicorn_no_null.go +24 -0
- package/linthost/rules_unicorn_no_object_as_default_parameter.go +48 -0
- package/linthost/rules_unicorn_no_process_exit.go +43 -0
- package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +59 -0
- package/linthost/rules_unicorn_no_static_only_class.go +56 -0
- package/linthost/rules_unicorn_no_thenable.go +74 -0
- package/linthost/rules_unicorn_no_this_assignment.go +35 -0
- package/linthost/rules_unicorn_no_typeof_undefined.go +58 -0
- package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +49 -0
- package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +70 -0
- package/linthost/rules_unicorn_no_unnecessary_await.go +51 -0
- package/linthost/rules_unicorn_no_unnecessary_polyfills.go +32 -0
- package/linthost/rules_unicorn_no_unnecessary_slice_end.go +48 -0
- package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +115 -0
- package/linthost/rules_unicorn_no_unreadable_iife.go +50 -0
- package/linthost/rules_unicorn_no_unused_properties.go +30 -0
- package/linthost/rules_unicorn_no_useless_collection_argument.go +63 -0
- package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +46 -0
- package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +81 -0
- package/linthost/rules_unicorn_no_useless_iterator_to_array.go +72 -0
- package/linthost/rules_unicorn_no_useless_length_check.go +144 -0
- package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +81 -0
- package/linthost/rules_unicorn_no_useless_spread.go +67 -0
- package/linthost/rules_unicorn_no_useless_switch_case.go +55 -0
- package/linthost/rules_unicorn_no_useless_undefined.go +55 -0
- package/linthost/rules_unicorn_no_zero_fractions.go +52 -0
- package/linthost/rules_unicorn_number_literal_case.go +69 -0
- package/linthost/rules_unicorn_numeric_separators_style.go +75 -0
- package/linthost/rules_unicorn_prefer_add_event_listener.go +66 -0
- package/linthost/rules_unicorn_prefer_array_find.go +51 -0
- package/linthost/rules_unicorn_prefer_array_flat.go +52 -0
- package/linthost/rules_unicorn_prefer_array_flat_map.go +63 -0
- package/linthost/rules_unicorn_prefer_array_index_of.go +147 -0
- package/linthost/rules_unicorn_prefer_array_some.go +67 -0
- package/linthost/rules_unicorn_prefer_at.go +77 -0
- package/linthost/rules_unicorn_prefer_bigint_literals.go +77 -0
- package/linthost/rules_unicorn_prefer_blob_reading_methods.go +44 -0
- package/linthost/rules_unicorn_prefer_class_fields.go +93 -0
- package/linthost/rules_unicorn_prefer_classlist_toggle.go +120 -0
- package/linthost/rules_unicorn_prefer_code_point.go +49 -0
- package/linthost/rules_unicorn_prefer_date_now.go +78 -0
- package/linthost/rules_unicorn_prefer_default_parameters.go +144 -0
- package/linthost/rules_unicorn_prefer_dom_node_append.go +40 -0
- package/linthost/rules_unicorn_prefer_dom_node_dataset.go +55 -0
- package/linthost/rules_unicorn_prefer_dom_node_remove.go +41 -0
- package/linthost/rules_unicorn_prefer_dom_node_text_content.go +37 -0
- package/linthost/rules_unicorn_prefer_event_target.go +36 -0
- package/linthost/rules_unicorn_prefer_export_from.go +129 -0
- package/linthost/rules_unicorn_prefer_global_this.go +127 -0
- package/linthost/rules_unicorn_prefer_import_meta_properties.go +66 -0
- package/linthost/rules_unicorn_prefer_includes.go +149 -0
- package/linthost/rules_unicorn_prefer_json_parse_buffer.go +65 -0
- package/linthost/rules_unicorn_prefer_keyboard_event_key.go +38 -0
- package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +48 -0
- package/linthost/rules_unicorn_prefer_math_min_max.go +60 -0
- package/linthost/rules_unicorn_prefer_math_trunc.go +62 -0
- package/linthost/rules_unicorn_prefer_modern_dom_apis.go +47 -0
- package/linthost/rules_unicorn_prefer_modern_math_apis.go +70 -0
- package/linthost/rules_unicorn_prefer_module.go +50 -0
- package/linthost/rules_unicorn_prefer_native_coercion_functions.go +114 -0
- package/linthost/rules_unicorn_prefer_negative_index.go +74 -0
- package/linthost/rules_unicorn_prefer_node_protocol.go +122 -0
- package/linthost/rules_unicorn_prefer_number_properties.go +88 -0
- package/linthost/rules_unicorn_prefer_object_from_entries.go +55 -0
- package/linthost/rules_unicorn_prefer_optional_catch_binding.go +62 -0
- package/linthost/rules_unicorn_prefer_prototype_methods.go +54 -0
- package/linthost/rules_unicorn_prefer_query_selector.go +56 -0
- package/linthost/rules_unicorn_prefer_reflect_apply.go +36 -0
- package/linthost/rules_unicorn_prefer_regexp_test_rule.go +80 -0
- package/linthost/rules_unicorn_prefer_response_static_json.go +53 -0
- package/linthost/rules_unicorn_prefer_set_has.go +42 -0
- package/linthost/rules_unicorn_prefer_set_size.go +48 -0
- package/linthost/rules_unicorn_prefer_simple_condition_first.go +34 -0
- package/linthost/rules_unicorn_prefer_single_call.go +96 -0
- package/linthost/rules_unicorn_prefer_spread.go +51 -0
- package/linthost/rules_unicorn_prefer_string_raw.go +43 -0
- package/linthost/rules_unicorn_prefer_string_replace_all.go +95 -0
- package/linthost/rules_unicorn_prefer_string_slice.go +43 -0
- package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +148 -0
- package/linthost/rules_unicorn_prefer_string_trim_start_end.go +48 -0
- package/linthost/rules_unicorn_prefer_structured_clone.go +71 -0
- package/linthost/rules_unicorn_prefer_switch.go +103 -0
- package/linthost/rules_unicorn_prefer_ternary.go +71 -0
- package/linthost/rules_unicorn_prefer_top_level_await.go +72 -0
- package/linthost/rules_unicorn_prefer_type_error.go +127 -0
- package/linthost/rules_unicorn_prevent_abbreviations.go +127 -0
- package/linthost/rules_unicorn_relative_url_style.go +49 -0
- package/linthost/rules_unicorn_require_array_join_separator.go +45 -0
- package/linthost/rules_unicorn_require_module_attributes.go +54 -0
- package/linthost/rules_unicorn_require_module_specifiers.go +55 -0
- package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +43 -0
- package/linthost/rules_unicorn_require_post_message_target_origin.go +44 -0
- package/linthost/rules_unicorn_string_content.go +27 -0
- package/linthost/rules_unicorn_switch_case_braces.go +42 -0
- package/linthost/rules_unicorn_switch_case_break_position.go +31 -0
- package/linthost/rules_unicorn_template_indent.go +28 -0
- package/linthost/rules_unicorn_text_encoding_identifier_case.go +72 -0
- package/linthost/rules_unicorn_throw_new_error.go +61 -0
- package/linthost/rules_var.go +10 -4
- package/linthost/rules_vitest.go +568 -0
- package/package.json +3 -3
- package/plugin/main.go +49 -3
- package/rule/astutil/astutil.go +10 -3
- package/rule/rule.go +12 -10
- package/src/defaultFormat.ts +17 -10
- package/src/index.ts +65 -43
- package/src/structures/ITtscLintConfig.ts +14 -8
- package/src/structures/TtscLintRuleSetting.ts +55 -0
- package/src/structures/format/ITtscLintFormat.ts +141 -0
- package/src/structures/format/ITtscLintFormatJsDoc.ts +18 -0
- package/src/structures/format/ITtscLintFormatSortImports.ts +62 -0
- package/src/structures/format/index.ts +3 -0
- package/src/structures/index.ts +3 -4
- package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +117 -0
- package/src/structures/rules/ITtscLintBoundariesRules.ts +91 -0
- package/src/structures/rules/ITtscLintContributorRules.ts +20 -0
- package/src/structures/rules/ITtscLintCoreRules.ts +1378 -0
- package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
- package/src/structures/rules/ITtscLintCypressRules.ts +141 -0
- package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +200 -0
- package/src/structures/rules/ITtscLintFunctionalRules.ts +197 -0
- package/src/structures/rules/ITtscLintJestRules.ts +209 -0
- package/src/structures/rules/ITtscLintJsdocRules.ts +146 -0
- package/src/structures/rules/ITtscLintJsxA11yRules.ts +331 -0
- package/src/structures/rules/ITtscLintNextjsRules.ts +201 -0
- package/src/structures/rules/ITtscLintPlaywrightRules.ts +343 -0
- package/src/structures/rules/ITtscLintPromiseRules.ts +196 -0
- package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
- package/src/structures/rules/ITtscLintReactPerfRules.ts +53 -0
- package/src/structures/rules/ITtscLintReactRuleOptions.ts +41 -0
- package/src/structures/rules/ITtscLintReactRules.ts +308 -0
- package/src/structures/rules/ITtscLintRegexpRules.ts +204 -0
- package/src/structures/rules/ITtscLintRuleOptionsMap.ts +88 -0
- package/src/structures/rules/ITtscLintRules.ts +77 -0
- package/src/structures/rules/ITtscLintSecurityRules.ts +155 -0
- package/src/structures/rules/ITtscLintSolidRules.ts +199 -0
- package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +22 -0
- package/src/structures/rules/ITtscLintStorybookRules.ts +184 -0
- package/src/structures/rules/ITtscLintTanstackQueryRules.ts +96 -0
- package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +23 -0
- package/src/structures/rules/ITtscLintTestingLibraryRules.ts +325 -0
- package/src/structures/rules/ITtscLintTypeScriptRules.ts +1172 -0
- package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
- package/src/structures/rules/ITtscLintVitestRules.ts +146 -0
- package/src/structures/rules/index.ts +31 -0
- package/lib/structures/ITtscLintFormatConfig.d.ts +0 -153
- package/lib/structures/ITtscLintFormatConfig.js.map +0 -1
- package/lib/structures/TtscLintRule.d.ts +0 -17
- package/lib/structures/TtscLintRule.js.map +0 -1
- package/lib/structures/TtscLintRuleMap.d.ts +0 -46
- package/lib/structures/TtscLintRuleMap.js.map +0 -1
- package/lib/structures/TtscLintRuleOptions.d.ts +0 -137
- package/lib/structures/TtscLintRuleOptions.js.map +0 -1
- package/src/structures/ITtscLintFormatConfig.ts +0 -168
- package/src/structures/TtscLintRule.ts +0 -160
- package/src/structures/TtscLintRuleMap.ts +0 -55
- package/src/structures/TtscLintRuleOptions.ts +0 -151
|
@@ -0,0 +1,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
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// unicorn/prefer-regexp-test: `if ("abc".match(/a/))` and
|
|
2
|
+
// `if (/a/.exec("abc"))` use match-array / null returns to encode a
|
|
3
|
+
// boolean question. `RegExp#test()` returns a boolean directly, avoids
|
|
4
|
+
// allocating the match result, and reads exactly like the question
|
|
5
|
+
// being asked.
|
|
6
|
+
//
|
|
7
|
+
// AST-only and parent-driven: visit each `CallExpression` whose callee
|
|
8
|
+
// is `PropertyAccess(_, match|exec)`, then confirm the call sits in a
|
|
9
|
+
// boolean position — the condition slot of `if`/`?:`, the operand of a
|
|
10
|
+
// unary `!`, or one of the short-circuit binary operators `&&`, `||`,
|
|
11
|
+
// `??`. Matches that aren't in a boolean position may still use the
|
|
12
|
+
// returned array, so they're out of scope.
|
|
13
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-regexp-test.md
|
|
14
|
+
package linthost
|
|
15
|
+
|
|
16
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
17
|
+
|
|
18
|
+
type unicornPreferRegexpTest struct{}
|
|
19
|
+
|
|
20
|
+
func (unicornPreferRegexpTest) Name() string { return "unicorn/prefer-regexp-test" }
|
|
21
|
+
func (unicornPreferRegexpTest) Visits() []shimast.Kind {
|
|
22
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
23
|
+
}
|
|
24
|
+
func (unicornPreferRegexpTest) Check(ctx *Context, node *shimast.Node) {
|
|
25
|
+
call := node.AsCallExpression()
|
|
26
|
+
if call == nil || call.Expression == nil ||
|
|
27
|
+
call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
31
|
+
if access == nil {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
switch identifierText(access.Name()) {
|
|
35
|
+
case "match", "exec":
|
|
36
|
+
default:
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
if !unicornPreferRegexpTestInBooleanPosition(node) {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
ctx.Report(node, "Prefer `RegExp#test()` over `String#match()` / `RegExp#exec()` in a boolean context.")
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// unicornPreferRegexpTestInBooleanPosition reports whether `node` sits in
|
|
46
|
+
// a position that consumes only its truthiness: the condition of an
|
|
47
|
+
// `if` / ternary, the operand of `!`, or one side of `&&` / `||` / `??`.
|
|
48
|
+
func unicornPreferRegexpTestInBooleanPosition(node *shimast.Node) bool {
|
|
49
|
+
parent := node.Parent
|
|
50
|
+
if parent == nil {
|
|
51
|
+
return false
|
|
52
|
+
}
|
|
53
|
+
switch parent.Kind {
|
|
54
|
+
case shimast.KindIfStatement:
|
|
55
|
+
ifStmt := parent.AsIfStatement()
|
|
56
|
+
return ifStmt != nil && ifStmt.Expression == node
|
|
57
|
+
case shimast.KindConditionalExpression:
|
|
58
|
+
cond := parent.AsConditionalExpression()
|
|
59
|
+
return cond != nil && cond.Condition == node
|
|
60
|
+
case shimast.KindPrefixUnaryExpression:
|
|
61
|
+
pre := parent.AsPrefixUnaryExpression()
|
|
62
|
+
return pre != nil && pre.Operator == shimast.KindExclamationToken
|
|
63
|
+
case shimast.KindBinaryExpression:
|
|
64
|
+
bin := parent.AsBinaryExpression()
|
|
65
|
+
if bin == nil || bin.OperatorToken == nil {
|
|
66
|
+
return false
|
|
67
|
+
}
|
|
68
|
+
switch bin.OperatorToken.Kind {
|
|
69
|
+
case shimast.KindAmpersandAmpersandToken,
|
|
70
|
+
shimast.KindBarBarToken,
|
|
71
|
+
shimast.KindQuestionQuestionToken:
|
|
72
|
+
return true
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return false
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
func init() {
|
|
79
|
+
Register(unicornPreferRegexpTest{})
|
|
80
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// unicorn/prefer-response-static-json: `new Response(JSON.stringify(value), …)`
|
|
2
|
+
// is the manual two-step recipe — stringify then construct — that the
|
|
3
|
+
// platform's `Response.json(value, …)` static factory now performs in
|
|
4
|
+
// one call. The static factory also sets `Content-Type: application/json`
|
|
5
|
+
// automatically; the manual form leaves the header to the author.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: visit each `NewExpression`. Match when the callee identifier
|
|
8
|
+
// is `Response` AND the first argument is a `CallExpression` whose
|
|
9
|
+
// callee is the property chain `JSON.stringify`. Other arguments (init
|
|
10
|
+
// options) are intentionally not inspected — the rule fires regardless
|
|
11
|
+
// of headers/status because the simpler factory handles both shapes.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-response-static-json.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
16
|
+
|
|
17
|
+
type unicornPreferResponseStaticJson struct{}
|
|
18
|
+
|
|
19
|
+
func (unicornPreferResponseStaticJson) Name() string {
|
|
20
|
+
return "unicorn/prefer-response-static-json"
|
|
21
|
+
}
|
|
22
|
+
func (unicornPreferResponseStaticJson) Visits() []shimast.Kind {
|
|
23
|
+
return []shimast.Kind{shimast.KindNewExpression}
|
|
24
|
+
}
|
|
25
|
+
func (unicornPreferResponseStaticJson) Check(ctx *Context, node *shimast.Node) {
|
|
26
|
+
ne := node.AsNewExpression()
|
|
27
|
+
if ne == nil || identifierText(ne.Expression) != "Response" {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
if ne.Arguments == nil || len(ne.Arguments.Nodes) == 0 {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
first := stripParens(ne.Arguments.Nodes[0])
|
|
34
|
+
if first == nil || first.Kind != shimast.KindCallExpression {
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
call := first.AsCallExpression()
|
|
38
|
+
if call == nil || call.Expression == nil ||
|
|
39
|
+
call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
43
|
+
if access == nil ||
|
|
44
|
+
identifierText(access.Expression) != "JSON" ||
|
|
45
|
+
identifierText(access.Name()) != "stringify" {
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
ctx.Report(node, "Prefer `Response.json(value)` over `new Response(JSON.stringify(value), ...)`.")
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
func init() {
|
|
52
|
+
Register(unicornPreferResponseStaticJson{})
|
|
53
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// unicorn/prefer-set-has: `[a, b, c].includes(x)` is `O(n)` per lookup,
|
|
2
|
+
// while `new Set([a, b, c]).has(x)` is `O(1)` after a single `O(n)`
|
|
3
|
+
// construction. For repeated membership lookups against a fixed
|
|
4
|
+
// collection the `Set` form is meaningfully faster and clearer about
|
|
5
|
+
// intent.
|
|
6
|
+
//
|
|
7
|
+
// AST-only minimum-viable port: only the literal-array-receiver shape
|
|
8
|
+
// (`[…].includes(x)`) is reported. The upstream rule also reasons
|
|
9
|
+
// about typed variable receivers, which requires type-flow analysis
|
|
10
|
+
// out of scope for this slice; expanding to typed receivers is a
|
|
11
|
+
// follow-up.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-set-has.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
16
|
+
|
|
17
|
+
type unicornPreferSetHas struct{}
|
|
18
|
+
|
|
19
|
+
func (unicornPreferSetHas) Name() string { return "unicorn/prefer-set-has" }
|
|
20
|
+
func (unicornPreferSetHas) Visits() []shimast.Kind {
|
|
21
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
22
|
+
}
|
|
23
|
+
func (unicornPreferSetHas) Check(ctx *Context, node *shimast.Node) {
|
|
24
|
+
call := node.AsCallExpression()
|
|
25
|
+
if call == nil || call.Expression == nil ||
|
|
26
|
+
call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
30
|
+
if access == nil || identifierText(access.Name()) != "includes" {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
receiver := stripParens(access.Expression)
|
|
34
|
+
if receiver == nil || receiver.Kind != shimast.KindArrayLiteralExpression {
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
ctx.Report(node, "Prefer `Set#has()` over `Array#includes()` for repeated membership lookups against a constant collection.")
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func init() {
|
|
41
|
+
Register(unicornPreferSetHas{})
|
|
42
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// unicorn/prefer-set-size: `[...set].length` materializes the entire Set
|
|
2
|
+
// into a throwaway array just to read its element count. `Set#size` is a
|
|
3
|
+
// constant-time property that returns the same value without the
|
|
4
|
+
// allocation, and reads more naturally for the intent the code expresses.
|
|
5
|
+
//
|
|
6
|
+
// AST-only: visit each `PropertyAccessExpression`, match when the
|
|
7
|
+
// accessed property is named `length` AND the receiver is an
|
|
8
|
+
// array-literal expression whose only element is a SpreadElement (i.e.
|
|
9
|
+
// `[...x]`). The contents of the spread are not inspected — the
|
|
10
|
+
// syntactic shape `[...x].length` is the signal regardless of whether
|
|
11
|
+
// the spread source is statically a Set.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-set-size.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
16
|
+
|
|
17
|
+
type unicornPreferSetSize struct{}
|
|
18
|
+
|
|
19
|
+
func (unicornPreferSetSize) Name() string { return "unicorn/prefer-set-size" }
|
|
20
|
+
func (unicornPreferSetSize) Visits() []shimast.Kind {
|
|
21
|
+
return []shimast.Kind{shimast.KindPropertyAccessExpression}
|
|
22
|
+
}
|
|
23
|
+
func (unicornPreferSetSize) Check(ctx *Context, node *shimast.Node) {
|
|
24
|
+
access := node.AsPropertyAccessExpression()
|
|
25
|
+
if access == nil {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
if identifierText(access.Name()) != "length" {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
receiver := stripParens(access.Expression)
|
|
32
|
+
if receiver == nil || receiver.Kind != shimast.KindArrayLiteralExpression {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
arr := receiver.AsArrayLiteralExpression()
|
|
36
|
+
if arr == nil || arr.Elements == nil || len(arr.Elements.Nodes) != 1 {
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
only := arr.Elements.Nodes[0]
|
|
40
|
+
if only == nil || only.Kind != shimast.KindSpreadElement {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
ctx.Report(node, "Prefer `Set#size` over `[...set].length`.")
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
func init() {
|
|
47
|
+
Register(unicornPreferSetSize{})
|
|
48
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// unicorn/prefer-simple-condition-first: when a `&&`/`||` chain mixes
|
|
2
|
+
// a "simple" operand (a bare identifier, a small literal comparison)
|
|
3
|
+
// with a "complex" one (a function call, a property chain), short-
|
|
4
|
+
// circuit evaluation reads more naturally if the simple operand sits
|
|
5
|
+
// to the left — the cheap test is the gate, the expensive test runs
|
|
6
|
+
// only if the gate passes.
|
|
7
|
+
//
|
|
8
|
+
// Escape-hatch / no-op port: ranking arbitrary expressions by
|
|
9
|
+
// "simpleness" requires a stable complexity heuristic the upstream rule
|
|
10
|
+
// embeds across hundreds of lines (literal counts, identifier depth,
|
|
11
|
+
// call-chain weight, parenthesization). Without a faithful port of that
|
|
12
|
+
// heuristic the rule would either over-fire on equally-weighted operands
|
|
13
|
+
// or under-fire on the cases it is meant to catch; either way users get
|
|
14
|
+
// confusing diagnostics. Registered so the typed-key/Go-registry parity
|
|
15
|
+
// check passes and so users can configure the rule, but it intentionally
|
|
16
|
+
// reports nothing until the heuristic lands in a follow-up.
|
|
17
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-simple-condition-first.md
|
|
18
|
+
package linthost
|
|
19
|
+
|
|
20
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
21
|
+
|
|
22
|
+
type unicornPreferSimpleConditionFirst struct{}
|
|
23
|
+
|
|
24
|
+
func (unicornPreferSimpleConditionFirst) Name() string {
|
|
25
|
+
return "unicorn/prefer-simple-condition-first"
|
|
26
|
+
}
|
|
27
|
+
func (unicornPreferSimpleConditionFirst) Visits() []shimast.Kind { return nil }
|
|
28
|
+
func (unicornPreferSimpleConditionFirst) Check(_ *Context, _ *shimast.Node) {
|
|
29
|
+
// Intentionally empty — see file header for the escape-hatch rationale.
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
func init() {
|
|
33
|
+
Register(unicornPreferSimpleConditionFirst{})
|
|
34
|
+
}
|