@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,44 @@
|
|
|
1
|
+
// unicorn/prefer-blob-reading-methods: `FileReader#readAsArrayBuffer`
|
|
2
|
+
// and `FileReader#readAsText` predate the promise-returning `Blob`
|
|
3
|
+
// methods. They require attaching `load` / `error` listeners and reading
|
|
4
|
+
// `reader.result` in a callback, while `Blob#arrayBuffer()` and
|
|
5
|
+
// `Blob#text()` return a Promise that resolves to the same value
|
|
6
|
+
// directly. The newer shape is shorter, easier to reason about, and the
|
|
7
|
+
// rule discourages the legacy callback form.
|
|
8
|
+
//
|
|
9
|
+
// AST-only: visit each `CallExpression`, match a property-access callee
|
|
10
|
+
// whose method identifier is `readAsArrayBuffer` or `readAsText`, and
|
|
11
|
+
// fire on the call. The receiver is not type-checked — the syntactic
|
|
12
|
+
// shape is the signal regardless of whether the value is statically a
|
|
13
|
+
// `FileReader`.
|
|
14
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-blob-reading-methods.md
|
|
15
|
+
package linthost
|
|
16
|
+
|
|
17
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
18
|
+
|
|
19
|
+
type unicornPreferBlobReadingMethods struct{}
|
|
20
|
+
|
|
21
|
+
func (unicornPreferBlobReadingMethods) Name() string {
|
|
22
|
+
return "unicorn/prefer-blob-reading-methods"
|
|
23
|
+
}
|
|
24
|
+
func (unicornPreferBlobReadingMethods) Visits() []shimast.Kind {
|
|
25
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
26
|
+
}
|
|
27
|
+
func (unicornPreferBlobReadingMethods) Check(ctx *Context, node *shimast.Node) {
|
|
28
|
+
call := node.AsCallExpression()
|
|
29
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
33
|
+
if access == nil {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
switch identifierText(access.Name()) {
|
|
37
|
+
case "readAsArrayBuffer", "readAsText":
|
|
38
|
+
ctx.Report(node, "Prefer `Blob#arrayBuffer()` / `Blob#text()` over `FileReader#readAsArrayBuffer` / `readAsText`.")
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func init() {
|
|
43
|
+
Register(unicornPreferBlobReadingMethods{})
|
|
44
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// unicorn/prefer-class-fields: assigning a primitive literal to
|
|
2
|
+
// `this.<field>` inside a class constructor is a TC39-era pattern that
|
|
3
|
+
// modern class-field declarations now express directly. The class-field
|
|
4
|
+
// form is shorter, makes the field visible at the class level without
|
|
5
|
+
// stepping through the constructor body, and avoids accidentally
|
|
6
|
+
// re-initializing a property that was already declared with a typed
|
|
7
|
+
// declaration.
|
|
8
|
+
//
|
|
9
|
+
// AST-only: visit `KindConstructor`. For each top-level statement in the
|
|
10
|
+
// constructor body, fire on any `ExpressionStatement` whose expression
|
|
11
|
+
// is an `=` `BinaryExpression` whose LHS is a property access on
|
|
12
|
+
// `this` and whose RHS is a primitive literal (`StringLiteral`,
|
|
13
|
+
// `NumericLiteral`, `KindTrueKeyword`, `KindFalseKeyword`,
|
|
14
|
+
// `KindNullKeyword`). The check is per-assignment, not per-constructor,
|
|
15
|
+
// so a constructor mixing several such assignments reports each one.
|
|
16
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-class-fields.md
|
|
17
|
+
package linthost
|
|
18
|
+
|
|
19
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
20
|
+
|
|
21
|
+
type unicornPreferClassFields struct{}
|
|
22
|
+
|
|
23
|
+
func (unicornPreferClassFields) Name() string { return "unicorn/prefer-class-fields" }
|
|
24
|
+
func (unicornPreferClassFields) Visits() []shimast.Kind {
|
|
25
|
+
return []shimast.Kind{shimast.KindConstructor}
|
|
26
|
+
}
|
|
27
|
+
func (unicornPreferClassFields) Check(ctx *Context, node *shimast.Node) {
|
|
28
|
+
ctor := node.AsConstructorDeclaration()
|
|
29
|
+
if ctor == nil || ctor.Body == nil {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
body := ctor.Body.AsBlock()
|
|
33
|
+
if body == nil || body.Statements == nil {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
for _, stmt := range body.Statements.Nodes {
|
|
37
|
+
if stmt == nil || stmt.Kind != shimast.KindExpressionStatement {
|
|
38
|
+
continue
|
|
39
|
+
}
|
|
40
|
+
exprStmt := stmt.AsExpressionStatement()
|
|
41
|
+
if exprStmt == nil || exprStmt.Expression == nil {
|
|
42
|
+
continue
|
|
43
|
+
}
|
|
44
|
+
expr := stripParens(exprStmt.Expression)
|
|
45
|
+
if expr == nil || expr.Kind != shimast.KindBinaryExpression {
|
|
46
|
+
continue
|
|
47
|
+
}
|
|
48
|
+
bin := expr.AsBinaryExpression()
|
|
49
|
+
if bin == nil || bin.OperatorToken == nil || bin.OperatorToken.Kind != shimast.KindEqualsToken {
|
|
50
|
+
continue
|
|
51
|
+
}
|
|
52
|
+
lhs := stripParens(bin.Left)
|
|
53
|
+
if lhs == nil || lhs.Kind != shimast.KindPropertyAccessExpression {
|
|
54
|
+
continue
|
|
55
|
+
}
|
|
56
|
+
access := lhs.AsPropertyAccessExpression()
|
|
57
|
+
if access == nil {
|
|
58
|
+
continue
|
|
59
|
+
}
|
|
60
|
+
receiver := stripParens(access.Expression)
|
|
61
|
+
if receiver == nil || receiver.Kind != shimast.KindThisKeyword {
|
|
62
|
+
continue
|
|
63
|
+
}
|
|
64
|
+
rhs := stripParens(bin.Right)
|
|
65
|
+
if !isPrimitiveLiteralForClassField(rhs) {
|
|
66
|
+
continue
|
|
67
|
+
}
|
|
68
|
+
ctx.Report(expr, "Prefer class field declarations over constructor assignments to `this.field`.")
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// isPrimitiveLiteralForClassField reports whether `node` is one of the
|
|
73
|
+
// primitive-literal kinds that the prefer-class-fields rule treats as
|
|
74
|
+
// "trivially hoistable" to a class field initializer.
|
|
75
|
+
func isPrimitiveLiteralForClassField(node *shimast.Node) bool {
|
|
76
|
+
if node == nil {
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
switch node.Kind {
|
|
80
|
+
case shimast.KindStringLiteral,
|
|
81
|
+
shimast.KindNumericLiteral,
|
|
82
|
+
shimast.KindTrueKeyword,
|
|
83
|
+
shimast.KindFalseKeyword,
|
|
84
|
+
shimast.KindNullKeyword,
|
|
85
|
+
shimast.KindNoSubstitutionTemplateLiteral:
|
|
86
|
+
return true
|
|
87
|
+
}
|
|
88
|
+
return false
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
func init() {
|
|
92
|
+
Register(unicornPreferClassFields{})
|
|
93
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// unicorn/prefer-classlist-toggle: an `if (cond) el.classList.add(name)
|
|
2
|
+
// else el.classList.remove(name)` block can be collapsed into a single
|
|
3
|
+
// `el.classList.toggle(name, cond)` call. The toggle form is shorter,
|
|
4
|
+
// avoids accidental drift between the two branches, and matches the
|
|
5
|
+
// spec-blessed shape for conditional class management.
|
|
6
|
+
//
|
|
7
|
+
// AST-only minimum-viable port: visit `IfStatement` and match when both
|
|
8
|
+
// branches contain a single `ExpressionStatement` of
|
|
9
|
+
// `X.classList.add(arg)` and `X.classList.remove(arg)` (in either
|
|
10
|
+
// order), with identical receiver text on `X.classList` and identical
|
|
11
|
+
// argument text. Textual identity uses `nodeText` so this works without
|
|
12
|
+
// the Checker; receivers that differ at the type level but share their
|
|
13
|
+
// spelling will still match (the rule's signal is the syntactic shape
|
|
14
|
+
// of the two-branch toggle).
|
|
15
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-classlist-toggle.md
|
|
16
|
+
package linthost
|
|
17
|
+
|
|
18
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
19
|
+
|
|
20
|
+
type unicornPreferClasslistToggle struct{}
|
|
21
|
+
|
|
22
|
+
func (unicornPreferClasslistToggle) Name() string { return "unicorn/prefer-classlist-toggle" }
|
|
23
|
+
func (unicornPreferClasslistToggle) Visits() []shimast.Kind {
|
|
24
|
+
return []shimast.Kind{shimast.KindIfStatement}
|
|
25
|
+
}
|
|
26
|
+
func (unicornPreferClasslistToggle) Check(ctx *Context, node *shimast.Node) {
|
|
27
|
+
stmt := node.AsIfStatement()
|
|
28
|
+
if stmt == nil || stmt.ThenStatement == nil || stmt.ElseStatement == nil {
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
thenCall := classlistToggleSingleCall(stmt.ThenStatement)
|
|
32
|
+
elseCall := classlistToggleSingleCall(stmt.ElseStatement)
|
|
33
|
+
if thenCall == nil || elseCall == nil {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
thenMethod, thenReceiver, thenArg := classlistAddRemoveParts(thenCall)
|
|
37
|
+
elseMethod, elseReceiver, elseArg := classlistAddRemoveParts(elseCall)
|
|
38
|
+
if thenMethod == "" || elseMethod == "" {
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
// One branch must be `add`, the other `remove` — order does not
|
|
42
|
+
// matter; the toggle rewrite is symmetric.
|
|
43
|
+
if !((thenMethod == "add" && elseMethod == "remove") ||
|
|
44
|
+
(thenMethod == "remove" && elseMethod == "add")) {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
if nodeText(ctx.File, thenReceiver) != nodeText(ctx.File, elseReceiver) {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
if nodeText(ctx.File, thenArg) != nodeText(ctx.File, elseArg) {
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
ctx.Report(node, "Prefer `classList.toggle(name, condition)` over manual `add`/`remove` branches.")
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// classlistToggleSingleCall returns the single CallExpression inside a
|
|
57
|
+
// then/else branch — accepting either a bare ExpressionStatement or a
|
|
58
|
+
// Block wrapping exactly one ExpressionStatement. Returns nil for any
|
|
59
|
+
// other shape.
|
|
60
|
+
func classlistToggleSingleCall(branch *shimast.Node) *shimast.Node {
|
|
61
|
+
if branch == nil {
|
|
62
|
+
return nil
|
|
63
|
+
}
|
|
64
|
+
stmt := branch
|
|
65
|
+
if branch.Kind == shimast.KindBlock {
|
|
66
|
+
block := branch.AsBlock()
|
|
67
|
+
if block == nil || block.Statements == nil || len(block.Statements.Nodes) != 1 {
|
|
68
|
+
return nil
|
|
69
|
+
}
|
|
70
|
+
stmt = block.Statements.Nodes[0]
|
|
71
|
+
}
|
|
72
|
+
if stmt == nil || stmt.Kind != shimast.KindExpressionStatement {
|
|
73
|
+
return nil
|
|
74
|
+
}
|
|
75
|
+
expr := stmt.AsExpressionStatement()
|
|
76
|
+
if expr == nil || expr.Expression == nil {
|
|
77
|
+
return nil
|
|
78
|
+
}
|
|
79
|
+
call := stripParens(expr.Expression)
|
|
80
|
+
if call == nil || call.Kind != shimast.KindCallExpression {
|
|
81
|
+
return nil
|
|
82
|
+
}
|
|
83
|
+
return call
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// classlistAddRemoveParts pulls (method, receiver, arg) out of a
|
|
87
|
+
// `X.classList.add(arg)` / `X.classList.remove(arg)` call, where
|
|
88
|
+
// `receiver` is the `X.classList` chain (the property-access expression
|
|
89
|
+
// node) and `arg` is the single argument. Returns ("", nil, nil) for
|
|
90
|
+
// any other shape.
|
|
91
|
+
func classlistAddRemoveParts(call *shimast.Node) (string, *shimast.Node, *shimast.Node) {
|
|
92
|
+
ce := call.AsCallExpression()
|
|
93
|
+
if ce == nil || ce.Expression == nil || ce.Arguments == nil || len(ce.Arguments.Nodes) != 1 {
|
|
94
|
+
return "", nil, nil
|
|
95
|
+
}
|
|
96
|
+
if ce.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
97
|
+
return "", nil, nil
|
|
98
|
+
}
|
|
99
|
+
access := ce.Expression.AsPropertyAccessExpression()
|
|
100
|
+
if access == nil {
|
|
101
|
+
return "", nil, nil
|
|
102
|
+
}
|
|
103
|
+
method := identifierText(access.Name())
|
|
104
|
+
if method != "add" && method != "remove" {
|
|
105
|
+
return "", nil, nil
|
|
106
|
+
}
|
|
107
|
+
receiver := access.Expression
|
|
108
|
+
if receiver == nil || receiver.Kind != shimast.KindPropertyAccessExpression {
|
|
109
|
+
return "", nil, nil
|
|
110
|
+
}
|
|
111
|
+
receiverAccess := receiver.AsPropertyAccessExpression()
|
|
112
|
+
if receiverAccess == nil || identifierText(receiverAccess.Name()) != "classList" {
|
|
113
|
+
return "", nil, nil
|
|
114
|
+
}
|
|
115
|
+
return method, receiver, ce.Arguments.Nodes[0]
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
func init() {
|
|
119
|
+
Register(unicornPreferClasslistToggle{})
|
|
120
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// unicorn/prefer-code-point: `String#charCodeAt` and
|
|
2
|
+
// `String.fromCharCode` operate on UTF-16 code units, so they split
|
|
3
|
+
// astral characters (anything above U+FFFF) into surrogate pairs and
|
|
4
|
+
// return numbers that no longer correspond to the Unicode code point
|
|
5
|
+
// the source string visually shows. `String#codePointAt` and
|
|
6
|
+
// `String.fromCodePoint` operate on full code points and round-trip
|
|
7
|
+
// astral characters correctly.
|
|
8
|
+
//
|
|
9
|
+
// AST-only: visit `CallExpression`, match property-access callees whose
|
|
10
|
+
// method identifier is `charCodeAt` or `fromCharCode`. For
|
|
11
|
+
// `fromCharCode` also require the receiver to be the literal identifier
|
|
12
|
+
// `String` so we only flag the static `String.fromCharCode` form; for
|
|
13
|
+
// `charCodeAt` the receiver may be anything (any string instance).
|
|
14
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-code-point.md
|
|
15
|
+
package linthost
|
|
16
|
+
|
|
17
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
18
|
+
|
|
19
|
+
type unicornPreferCodePoint struct{}
|
|
20
|
+
|
|
21
|
+
func (unicornPreferCodePoint) Name() string { return "unicorn/prefer-code-point" }
|
|
22
|
+
func (unicornPreferCodePoint) Visits() []shimast.Kind {
|
|
23
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
24
|
+
}
|
|
25
|
+
func (unicornPreferCodePoint) Check(ctx *Context, node *shimast.Node) {
|
|
26
|
+
call := node.AsCallExpression()
|
|
27
|
+
if call == nil || call.Expression == nil || 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 "charCodeAt":
|
|
36
|
+
// Instance call — receiver type is irrelevant.
|
|
37
|
+
ctx.Report(node, "Prefer `String#codePointAt()` / `String.fromCodePoint()` over `charCodeAt` / `fromCharCode`.")
|
|
38
|
+
case "fromCharCode":
|
|
39
|
+
// Static call — only the `String.fromCharCode(...)` shape.
|
|
40
|
+
if identifierText(access.Expression) != "String" {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
ctx.Report(node, "Prefer `String#codePointAt()` / `String.fromCodePoint()` over `charCodeAt` / `fromCharCode`.")
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
func init() {
|
|
48
|
+
Register(unicornPreferCodePoint{})
|
|
49
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// unicorn/prefer-date-now: three idioms compute the current epoch
|
|
2
|
+
// milliseconds at runtime — `new Date().getTime()`, `new Date().valueOf()`,
|
|
3
|
+
// and `+new Date()`. All three allocate a Date instance only to throw
|
|
4
|
+
// it away. `Date.now()` does the same thing with no allocation and
|
|
5
|
+
// reads as exactly what it means; the rule asks authors to switch.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: visit `KindCallExpression` (the `.getTime()` / `.valueOf()`
|
|
8
|
+
// callers) and `KindPrefixUnaryExpression` (the `+new Date()` form).
|
|
9
|
+
// Fire on:
|
|
10
|
+
//
|
|
11
|
+
// - `(new Date()).getTime()` / `(new Date()).valueOf()` — a call
|
|
12
|
+
// with no arguments whose callee is a PropertyAccessExpression
|
|
13
|
+
// on a NewExpression with callee `Date`.
|
|
14
|
+
// - `+new Date()` — a `+` prefix whose operand is a NewExpression
|
|
15
|
+
// with callee `Date`.
|
|
16
|
+
//
|
|
17
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-date-now.md
|
|
18
|
+
package linthost
|
|
19
|
+
|
|
20
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
21
|
+
|
|
22
|
+
type unicornPreferDateNow struct{}
|
|
23
|
+
|
|
24
|
+
func (unicornPreferDateNow) Name() string { return "unicorn/prefer-date-now" }
|
|
25
|
+
func (unicornPreferDateNow) Visits() []shimast.Kind {
|
|
26
|
+
return []shimast.Kind{shimast.KindCallExpression, shimast.KindPrefixUnaryExpression}
|
|
27
|
+
}
|
|
28
|
+
func (unicornPreferDateNow) Check(ctx *Context, node *shimast.Node) {
|
|
29
|
+
switch node.Kind {
|
|
30
|
+
case shimast.KindCallExpression:
|
|
31
|
+
call := node.AsCallExpression()
|
|
32
|
+
if call == nil || call.Expression == nil {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
if call.Arguments != nil && len(call.Arguments.Nodes) > 0 {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
access := stripParens(call.Expression)
|
|
39
|
+
if access == nil || access.Kind != shimast.KindPropertyAccessExpression {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
propAccess := access.AsPropertyAccessExpression()
|
|
43
|
+
if propAccess == nil {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
method := identifierText(propAccess.Name())
|
|
47
|
+
if method != "getTime" && method != "valueOf" {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
receiver := stripParens(propAccess.Expression)
|
|
51
|
+
if receiver == nil || receiver.Kind != shimast.KindNewExpression {
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
ne := receiver.AsNewExpression()
|
|
55
|
+
if ne == nil || identifierText(ne.Expression) != "Date" {
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
ctx.Report(node, "Prefer `Date.now()` over `new Date().getTime()` / `+new Date()`.")
|
|
59
|
+
case shimast.KindPrefixUnaryExpression:
|
|
60
|
+
prefix := node.AsPrefixUnaryExpression()
|
|
61
|
+
if prefix == nil || prefix.Operator != shimast.KindPlusToken || prefix.Operand == nil {
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
operand := stripParens(prefix.Operand)
|
|
65
|
+
if operand == nil || operand.Kind != shimast.KindNewExpression {
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
ne := operand.AsNewExpression()
|
|
69
|
+
if ne == nil || identifierText(ne.Expression) != "Date" {
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
ctx.Report(node, "Prefer `Date.now()` over `new Date().getTime()` / `+new Date()`.")
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
func init() {
|
|
77
|
+
Register(unicornPreferDateNow{})
|
|
78
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// unicorn/prefer-default-parameters: the legacy pattern of reassigning
|
|
2
|
+
// an undefined-or-falsy parameter to a literal at the top of a function
|
|
3
|
+
// body (`name = name ?? "guest"`) has been redundant since ES2015. A
|
|
4
|
+
// default-parameter expression (`name = "guest"`) covers the same case,
|
|
5
|
+
// reads as exactly what it means, and avoids both the visual noise and
|
|
6
|
+
// the missed-edit risk of keeping the name in three places.
|
|
7
|
+
//
|
|
8
|
+
// AST-only: visit every function-like declaration. Fire when the first
|
|
9
|
+
// body statement is `<param> = <param> ?? <literal>` — an
|
|
10
|
+
// `ExpressionStatement` containing an `=` `BinaryExpression` whose LHS
|
|
11
|
+
// is a bare identifier matching a parameter name, and whose RHS is a
|
|
12
|
+
// `??` `BinaryExpression` whose LHS is the same identifier and whose
|
|
13
|
+
// RHS is a primitive literal. The rule is conservative on purpose: it
|
|
14
|
+
// stays away from `||` (which has different semantics for falsy
|
|
15
|
+
// non-undefined values) and the explicit-ternary shape, since both add
|
|
16
|
+
// branches the default-parameter rewrite does not strictly preserve.
|
|
17
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-default-parameters.md
|
|
18
|
+
package linthost
|
|
19
|
+
|
|
20
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
21
|
+
|
|
22
|
+
type unicornPreferDefaultParameters struct{}
|
|
23
|
+
|
|
24
|
+
func (unicornPreferDefaultParameters) Name() string {
|
|
25
|
+
return "unicorn/prefer-default-parameters"
|
|
26
|
+
}
|
|
27
|
+
func (unicornPreferDefaultParameters) Visits() []shimast.Kind {
|
|
28
|
+
return []shimast.Kind{
|
|
29
|
+
shimast.KindFunctionDeclaration,
|
|
30
|
+
shimast.KindArrowFunction,
|
|
31
|
+
shimast.KindFunctionExpression,
|
|
32
|
+
shimast.KindMethodDeclaration,
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
func (unicornPreferDefaultParameters) Check(ctx *Context, node *shimast.Node) {
|
|
36
|
+
body := defaultParameterFunctionBody(node)
|
|
37
|
+
if body == nil {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
if body.Statements == nil || len(body.Statements.Nodes) == 0 {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
first := body.Statements.Nodes[0]
|
|
44
|
+
if first == nil || first.Kind != shimast.KindExpressionStatement {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
exprStmt := first.AsExpressionStatement()
|
|
48
|
+
if exprStmt == nil || exprStmt.Expression == nil {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
expr := stripParens(exprStmt.Expression)
|
|
52
|
+
if expr == nil || expr.Kind != shimast.KindBinaryExpression {
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
assign := expr.AsBinaryExpression()
|
|
56
|
+
if assign == nil || assign.OperatorToken == nil || assign.OperatorToken.Kind != shimast.KindEqualsToken {
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
target := identifierText(stripParens(assign.Left))
|
|
60
|
+
if target == "" {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
if !functionHasParameterNamed(node, target) {
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
rhs := stripParens(assign.Right)
|
|
67
|
+
if rhs == nil || rhs.Kind != shimast.KindBinaryExpression {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
coalesce := rhs.AsBinaryExpression()
|
|
71
|
+
if coalesce == nil || coalesce.OperatorToken == nil ||
|
|
72
|
+
coalesce.OperatorToken.Kind != shimast.KindQuestionQuestionToken {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
if identifierText(stripParens(coalesce.Left)) != target {
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
if !isLiteralExpression(stripParens(coalesce.Right)) {
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
ctx.Report(expr, "Prefer default parameters over `param = param ?? default` reassignments.")
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// defaultParameterFunctionBody returns the BlockStatement body of a
|
|
85
|
+
// function-like node, or nil when the function has an expression body
|
|
86
|
+
// (arrow `=> expr`) or an overload signature without a body. The
|
|
87
|
+
// rule only fires on statement-level reassignments, so a body-less
|
|
88
|
+
// shape is a non-match by definition.
|
|
89
|
+
func defaultParameterFunctionBody(node *shimast.Node) *shimast.Block {
|
|
90
|
+
if node == nil {
|
|
91
|
+
return nil
|
|
92
|
+
}
|
|
93
|
+
var body *shimast.Node
|
|
94
|
+
switch node.Kind {
|
|
95
|
+
case shimast.KindFunctionDeclaration:
|
|
96
|
+
if fn := node.AsFunctionDeclaration(); fn != nil {
|
|
97
|
+
body = fn.Body
|
|
98
|
+
}
|
|
99
|
+
case shimast.KindFunctionExpression:
|
|
100
|
+
if fn := node.AsFunctionExpression(); fn != nil {
|
|
101
|
+
body = fn.Body
|
|
102
|
+
}
|
|
103
|
+
case shimast.KindArrowFunction:
|
|
104
|
+
if fn := node.AsArrowFunction(); fn != nil {
|
|
105
|
+
body = fn.Body
|
|
106
|
+
}
|
|
107
|
+
case shimast.KindMethodDeclaration:
|
|
108
|
+
if fn := node.AsMethodDeclaration(); fn != nil {
|
|
109
|
+
body = fn.Body
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if body == nil || body.Kind != shimast.KindBlock {
|
|
113
|
+
return nil
|
|
114
|
+
}
|
|
115
|
+
return body.AsBlock()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// functionHasParameterNamed reports whether any parameter of the
|
|
119
|
+
// function-like node is a plain `Identifier` whose lexical text equals
|
|
120
|
+
// `name`. Destructured parameters are intentionally ignored — the rule
|
|
121
|
+
// cannot prove which inner binding a top-of-body reassignment refers to
|
|
122
|
+
// without semantic analysis.
|
|
123
|
+
func functionHasParameterNamed(node *shimast.Node, name string) bool {
|
|
124
|
+
if node == nil || name == "" {
|
|
125
|
+
return false
|
|
126
|
+
}
|
|
127
|
+
for _, p := range node.Parameters() {
|
|
128
|
+
if p == nil {
|
|
129
|
+
continue
|
|
130
|
+
}
|
|
131
|
+
decl := p.AsParameterDeclaration()
|
|
132
|
+
if decl == nil {
|
|
133
|
+
continue
|
|
134
|
+
}
|
|
135
|
+
if identifierText(decl.Name()) == name {
|
|
136
|
+
return true
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return false
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
func init() {
|
|
143
|
+
Register(unicornPreferDefaultParameters{})
|
|
144
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// unicorn/prefer-dom-node-append: `Node#appendChild` accepts a single
|
|
2
|
+
// child node, returns the appended node, and throws when handed a string
|
|
3
|
+
// — its `Node#append` successor accepts a variadic list of nodes and
|
|
4
|
+
// strings, returns `undefined`, and is the supported modern shape. The
|
|
5
|
+
// legacy form is what the rule discourages.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: visit each `CallExpression`, match a property-access callee
|
|
8
|
+
// whose method identifier is `appendChild`, and fire on the call. The
|
|
9
|
+
// receiver expression is not type-checked — the syntactic shape is the
|
|
10
|
+
// signal the rule wants to discourage, regardless of whether the value is
|
|
11
|
+
// known to be a `Node` at the type level.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-append.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
16
|
+
|
|
17
|
+
type unicornPreferDomNodeAppend struct{}
|
|
18
|
+
|
|
19
|
+
func (unicornPreferDomNodeAppend) Name() string { return "unicorn/prefer-dom-node-append" }
|
|
20
|
+
func (unicornPreferDomNodeAppend) Visits() []shimast.Kind {
|
|
21
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
22
|
+
}
|
|
23
|
+
func (unicornPreferDomNodeAppend) Check(ctx *Context, node *shimast.Node) {
|
|
24
|
+
call := node.AsCallExpression()
|
|
25
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
29
|
+
if access == nil {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
if identifierText(access.Name()) != "appendChild" {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
ctx.Report(node, "Prefer `Node#append()` over `Node#appendChild()`.")
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
func init() {
|
|
39
|
+
Register(unicornPreferDomNodeAppend{})
|
|
40
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// unicorn/prefer-dom-node-dataset: `Element#dataset` exposes every
|
|
2
|
+
// `data-*` attribute as a typed string property, including coordinated
|
|
3
|
+
// kebab-case → camelCase mapping and conversion to/from values. Reaching
|
|
4
|
+
// for `getAttribute("data-foo")` or `setAttribute("data-foo", …)`
|
|
5
|
+
// reintroduces string-key bookkeeping the platform already covers.
|
|
6
|
+
//
|
|
7
|
+
// AST-only: visit each `CallExpression`, match a property-access callee
|
|
8
|
+
// whose method identifier is `getAttribute` or `setAttribute`, and fire
|
|
9
|
+
// when the first argument is a `StringLiteral` whose text starts with
|
|
10
|
+
// `data-`. The literal-prefix gate isolates the data-attribute path from
|
|
11
|
+
// every other attribute the same methods reach.
|
|
12
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-dataset.md
|
|
13
|
+
package linthost
|
|
14
|
+
|
|
15
|
+
import (
|
|
16
|
+
"strings"
|
|
17
|
+
|
|
18
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
type unicornPreferDomNodeDataset struct{}
|
|
22
|
+
|
|
23
|
+
func (unicornPreferDomNodeDataset) Name() string { return "unicorn/prefer-dom-node-dataset" }
|
|
24
|
+
func (unicornPreferDomNodeDataset) Visits() []shimast.Kind {
|
|
25
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
26
|
+
}
|
|
27
|
+
func (unicornPreferDomNodeDataset) Check(ctx *Context, node *shimast.Node) {
|
|
28
|
+
call := node.AsCallExpression()
|
|
29
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
33
|
+
if access == nil {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
method := identifierText(access.Name())
|
|
37
|
+
if method != "getAttribute" && method != "setAttribute" {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) == 0 {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
first := call.Arguments.Nodes[0]
|
|
44
|
+
if first == nil || first.Kind != shimast.KindStringLiteral {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
if !strings.HasPrefix(stringLiteralText(first), "data-") {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
ctx.Report(node, "Prefer `.dataset` over `getAttribute` / `setAttribute` for `data-*` attributes.")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func init() {
|
|
54
|
+
Register(unicornPreferDomNodeDataset{})
|
|
55
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// unicorn/prefer-dom-node-remove: `parent.removeChild(child)` requires
|
|
2
|
+
// the caller to thread the parent through to detach a node — `child.remove()`
|
|
3
|
+
// is the supported modern shape and avoids the dangling-reference class
|
|
4
|
+
// of bugs where the wrong parent is consulted.
|
|
5
|
+
//
|
|
6
|
+
// AST-only: visit each `CallExpression`, match a property-access callee
|
|
7
|
+
// whose method identifier is `removeChild`, and fire when the call has
|
|
8
|
+
// exactly one argument. The single-argument gate isolates the canonical
|
|
9
|
+
// detach shape from custom `removeChild` overloads that take more.
|
|
10
|
+
// https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-dom-node-remove.md
|
|
11
|
+
package linthost
|
|
12
|
+
|
|
13
|
+
import shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
14
|
+
|
|
15
|
+
type unicornPreferDomNodeRemove struct{}
|
|
16
|
+
|
|
17
|
+
func (unicornPreferDomNodeRemove) Name() string { return "unicorn/prefer-dom-node-remove" }
|
|
18
|
+
func (unicornPreferDomNodeRemove) Visits() []shimast.Kind {
|
|
19
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
20
|
+
}
|
|
21
|
+
func (unicornPreferDomNodeRemove) Check(ctx *Context, node *shimast.Node) {
|
|
22
|
+
call := node.AsCallExpression()
|
|
23
|
+
if call == nil || call.Expression == nil || call.Expression.Kind != shimast.KindPropertyAccessExpression {
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
access := call.Expression.AsPropertyAccessExpression()
|
|
27
|
+
if access == nil {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
if identifierText(access.Name()) != "removeChild" {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
if call.Arguments == nil || len(call.Arguments.Nodes) != 1 {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
ctx.Report(node, "Prefer `ChildNode#remove()` over `parentNode.removeChild(child)`.")
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
func init() {
|
|
40
|
+
Register(unicornPreferDomNodeRemove{})
|
|
41
|
+
}
|