@ttsc/lint 0.13.1 → 0.14.0-dev.20260528
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +948 -69
- package/lib/defaultFormat.d.ts +9 -6
- package/lib/defaultFormat.js +9 -6
- package/lib/defaultFormat.js.map +1 -1
- package/lib/index.d.ts +46 -0
- package/lib/index.js +35 -10
- package/lib/index.js.map +1 -1
- package/lib/structures/ITtscLintConfig.d.ts +12 -6
- package/lib/structures/{ITtscLintFormatConfig.d.ts → ITtscLintFormat.d.ts} +2 -2
- package/lib/structures/{TtscLintRuleMap.js → ITtscLintFormat.js} +1 -1
- package/lib/structures/ITtscLintFormat.js.map +1 -0
- package/lib/structures/TtscLintRuleSetting.d.ts +49 -0
- package/lib/structures/{TtscLintRuleOptions.js → TtscLintRuleSetting.js} +1 -1
- package/lib/structures/TtscLintRuleSetting.js.map +1 -0
- package/lib/structures/index.d.ts +3 -4
- package/lib/structures/index.js +3 -4
- package/lib/structures/index.js.map +1 -1
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +104 -0
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +14 -0
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +79 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.js +3 -0
- package/lib/structures/rules/ITtscLintBoundariesRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintContributorRules.d.ts +17 -0
- package/lib/structures/rules/ITtscLintContributorRules.js +3 -0
- package/lib/structures/rules/ITtscLintContributorRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintCoreRules.d.ts +1257 -0
- package/lib/structures/{ITtscLintFormatConfig.js → rules/ITtscLintCoreRules.js} +1 -1
- package/lib/structures/rules/ITtscLintCoreRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +17 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js +10 -0
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintCypressRules.d.ts +129 -0
- package/lib/structures/rules/ITtscLintCypressRules.js +3 -0
- package/lib/structures/rules/ITtscLintCypressRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +157 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +13 -0
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +167 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.js +3 -0
- package/lib/structures/rules/ITtscLintFunctionalRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJestRules.d.ts +201 -0
- package/lib/structures/rules/ITtscLintJestRules.js +3 -0
- package/lib/structures/rules/ITtscLintJestRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJsdocRules.d.ts +140 -0
- package/lib/structures/rules/ITtscLintJsdocRules.js +3 -0
- package/lib/structures/rules/ITtscLintJsdocRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +302 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.js +3 -0
- package/lib/structures/rules/ITtscLintJsxA11yRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintNextjsRules.d.ts +185 -0
- package/lib/structures/rules/ITtscLintNextjsRules.js +3 -0
- package/lib/structures/rules/ITtscLintNextjsRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +330 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.js +3 -0
- package/lib/structures/rules/ITtscLintPlaywrightRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintPromiseRules.d.ts +188 -0
- package/lib/structures/rules/ITtscLintPromiseRules.js +3 -0
- package/lib/structures/rules/ITtscLintPromiseRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +18 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js +8 -0
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +51 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.js +3 -0
- package/lib/structures/rules/ITtscLintReactPerfRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +39 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.js +12 -0
- package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintReactRules.d.ts +289 -0
- package/lib/structures/rules/ITtscLintReactRules.js +3 -0
- package/lib/structures/rules/ITtscLintReactRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintRegexpRules.d.ts +190 -0
- package/lib/structures/rules/ITtscLintRegexpRules.js +3 -0
- package/lib/structures/rules/ITtscLintRegexpRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +66 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.js +3 -0
- package/lib/structures/rules/ITtscLintRuleOptionsMap.js.map +1 -0
- package/lib/structures/rules/ITtscLintRules.d.ts +55 -0
- package/lib/structures/{TtscLintRule.js → rules/ITtscLintRules.js} +1 -1
- package/lib/structures/rules/ITtscLintRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintSecurityRules.d.ts +148 -0
- package/lib/structures/rules/ITtscLintSecurityRules.js +3 -0
- package/lib/structures/rules/ITtscLintSecurityRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintSolidRules.d.ts +181 -0
- package/lib/structures/rules/ITtscLintSolidRules.js +3 -0
- package/lib/structures/rules/ITtscLintSolidRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +21 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.js +9 -0
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintStorybookRules.d.ts +174 -0
- package/lib/structures/rules/ITtscLintStorybookRules.js +3 -0
- package/lib/structures/rules/ITtscLintStorybookRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +94 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.js +3 -0
- package/lib/structures/rules/ITtscLintTanstackQueryRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +22 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js +10 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.js.map +1 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +310 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.js +3 -0
- package/lib/structures/rules/ITtscLintTestingLibraryRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +1132 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.js +3 -0
- package/lib/structures/rules/ITtscLintTypeScriptRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintUnicornRules.d.ts +997 -0
- package/lib/structures/rules/ITtscLintUnicornRules.js +3 -0
- package/lib/structures/rules/ITtscLintUnicornRules.js.map +1 -0
- package/lib/structures/rules/ITtscLintVitestRules.d.ts +141 -0
- package/lib/structures/rules/ITtscLintVitestRules.js +3 -0
- package/lib/structures/rules/ITtscLintVitestRules.js.map +1 -0
- package/lib/structures/rules/index.d.ts +31 -0
- package/lib/structures/rules/index.js +48 -0
- package/lib/structures/rules/index.js.map +1 -0
- package/linthost/ast_helpers.go +30 -5
- package/linthost/config.go +48 -17
- package/linthost/config_format.go +9 -9
- package/linthost/directives.go +67 -25
- package/linthost/dispatch.go +14 -3
- package/linthost/engine.go +152 -31
- package/linthost/fix.go +2 -2
- package/linthost/lsp.go +747 -0
- package/linthost/print_dispatch.go +2 -2
- package/linthost/print_nodes_function.go +2 -2
- package/linthost/print_nodes_object.go +1 -1
- package/linthost/rule_names.go +14 -0
- package/linthost/rules_arrays.go +2 -2
- package/linthost/rules_boundaries.go +532 -0
- package/linthost/rules_camelcase.go +133 -0
- package/linthost/rules_complexity.go +94 -0
- package/linthost/rules_consistent_return.go +130 -0
- package/linthost/rules_console.go +1 -1
- package/linthost/rules_core_extra.go +739 -0
- package/linthost/rules_curly.go +70 -0
- package/linthost/rules_cypress.go +608 -0
- package/linthost/rules_debugger.go +2 -2
- package/linthost/rules_default_case.go +39 -0
- package/linthost/rules_default_case_last.go +46 -0
- package/linthost/rules_dupes.go +3 -3
- package/linthost/rules_empty.go +3 -3
- package/linthost/rules_escape.go +44 -24
- package/linthost/rules_eval.go +2 -2
- package/linthost/rules_finally.go +2 -2
- package/linthost/rules_format_jsdoc.go +1 -1
- package/linthost/rules_format_print_width.go +9 -9
- package/linthost/rules_format_quotes.go +1 -1
- package/linthost/rules_format_semi.go +1 -1
- package/linthost/rules_format_sort_imports.go +1 -1
- package/linthost/rules_format_trailing_comma.go +1 -1
- package/linthost/rules_functional.go +967 -0
- package/linthost/rules_gap.go +24 -45
- package/linthost/rules_grouped_accessor_pairs.go +87 -0
- package/linthost/rules_guard_for_in.go +198 -0
- package/linthost/rules_id_length.go +77 -0
- package/linthost/rules_imports.go +70 -2
- package/linthost/rules_init_declarations.go +53 -0
- package/linthost/rules_jest.go +618 -0
- package/linthost/rules_jsdoc.go +502 -0
- package/linthost/rules_jsx_a11y.go +1264 -0
- package/linthost/rules_logic.go +12 -12
- package/linthost/rules_loops.go +1 -1
- package/linthost/rules_max_classes_per_file.go +58 -0
- package/linthost/rules_max_depth.go +83 -0
- package/linthost/rules_max_lines.go +101 -0
- package/linthost/rules_max_lines_per_function.go +57 -0
- package/linthost/rules_max_nested_callbacks.go +61 -0
- package/linthost/rules_max_params.go +49 -0
- package/linthost/rules_max_statements.go +59 -0
- package/linthost/rules_misc.go +1 -1
- package/linthost/rules_nextjs.go +697 -0
- package/linthost/rules_no_else_return.go +75 -0
- package/linthost/rules_no_empty_named_blocks.go +91 -0
- package/linthost/rules_no_extend_native.go +51 -0
- package/linthost/rules_no_import_assign.go +140 -0
- package/linthost/rules_no_invalid_this.go +52 -0
- package/linthost/rules_no_loop_func.go +85 -0
- package/linthost/rules_no_magic_numbers.go +123 -0
- package/linthost/rules_no_mixed_operators.go +80 -0
- package/linthost/rules_no_param_reassign.go +98 -0
- package/linthost/rules_no_redeclare.go +270 -0
- package/linthost/rules_no_restricted_imports.go +105 -0
- package/linthost/rules_no_restricted_syntax.go +49 -0
- package/linthost/rules_no_shadow.go +147 -0
- package/linthost/rules_no_unreachable.go +77 -0
- package/linthost/rules_no_useless_assignment.go +120 -0
- package/linthost/rules_no_useless_constructor.go +245 -0
- package/linthost/rules_no_useless_return.go +51 -0
- package/linthost/rules_params.go +1 -1
- package/linthost/rules_playwright.go +788 -0
- package/linthost/rules_prefer_arrow_callback.go +124 -0
- package/linthost/rules_prefer_destructuring.go +98 -0
- package/linthost/rules_prefer_named_capture_group.go +129 -0
- package/linthost/rules_prefer_rest_params.go +94 -0
- package/linthost/rules_problems.go +41 -30
- package/linthost/rules_promise.go +1128 -73
- package/linthost/rules_protos.go +2 -2
- package/linthost/rules_react.go +773 -0
- package/linthost/rules_react_extras.go +227 -0
- package/linthost/rules_react_hooks.go +848 -0
- package/linthost/rules_react_perf.go +293 -0
- package/linthost/rules_react_refresh.go +583 -0
- package/linthost/rules_regexp.go +410 -0
- package/linthost/rules_security.go +830 -0
- package/linthost/rules_self.go +2 -2
- package/linthost/rules_solid.go +1073 -0
- package/linthost/rules_sort_imports.go +69 -0
- package/linthost/rules_sort_keys.go +134 -0
- package/linthost/rules_storybook.go +1176 -0
- package/linthost/rules_strings.go +4 -4
- package/linthost/rules_suggestions.go +38 -38
- package/linthost/rules_tanstack_query.go +844 -0
- package/linthost/rules_testing_library.go +1204 -0
- package/linthost/rules_throw.go +1 -1
- package/linthost/rules_ts.go +19 -19
- package/linthost/rules_ts_async.go +399 -0
- package/linthost/rules_ts_class_literal_property_style.go +115 -0
- package/linthost/rules_ts_consistent_type_exports.go +256 -0
- package/linthost/rules_ts_explicit_function_return_type.go +67 -0
- package/linthost/rules_ts_extra.go +155 -36
- package/linthost/rules_ts_no_base_to_string.go +218 -0
- package/linthost/rules_ts_no_confusing_void.go +72 -0
- package/linthost/rules_ts_no_deprecated.go +195 -0
- package/linthost/rules_ts_no_for_in_array.go +84 -0
- package/linthost/rules_ts_no_magic_numbers.go +124 -0
- package/linthost/rules_ts_no_meaningless_void_operator.go +84 -0
- package/linthost/rules_ts_no_misused_spread.go +104 -0
- package/linthost/rules_ts_no_redundant_type_constituents.go +113 -0
- package/linthost/rules_ts_no_restricted_types.go +62 -0
- package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +129 -0
- package/linthost/rules_ts_no_unnecessary_condition.go +250 -0
- package/linthost/rules_ts_no_unnecessary_qualifier.go +118 -0
- package/linthost/rules_ts_no_unnecessary_template_expression.go +178 -0
- package/linthost/rules_ts_no_unnecessary_type_arguments.go +234 -0
- package/linthost/rules_ts_no_unnecessary_type_assertion.go +157 -0
- package/linthost/rules_ts_no_unsafe_argument.go +82 -0
- package/linthost/rules_ts_no_unsafe_assignment.go +102 -0
- package/linthost/rules_ts_no_unsafe_call.go +82 -0
- package/linthost/rules_ts_no_unsafe_enum_comparison.go +235 -0
- package/linthost/rules_ts_no_unsafe_member_access.go +58 -0
- package/linthost/rules_ts_no_unsafe_return.go +126 -0
- package/linthost/rules_ts_no_unsafe_unary_minus.go +81 -0
- package/linthost/rules_ts_no_useless_constructor.go +52 -0
- package/linthost/rules_ts_non_nullable_type_assertion_style.go +108 -0
- package/linthost/rules_ts_parameter_properties.go +38 -0
- package/linthost/rules_ts_prefer_find.go +178 -0
- package/linthost/rules_ts_prefer_includes.go +255 -0
- package/linthost/rules_ts_prefer_nullish_coalescing.go +104 -0
- package/linthost/rules_ts_prefer_optional_chain.go +228 -0
- package/linthost/rules_ts_prefer_promise_reject_errors.go +176 -0
- package/linthost/rules_ts_prefer_readonly.go +73 -0
- package/linthost/rules_ts_prefer_reduce_type_parameter.go +116 -0
- package/linthost/rules_ts_prefer_regexp_exec.go +122 -0
- package/linthost/rules_ts_prefer_return_this_type.go +135 -0
- package/linthost/rules_ts_prefer_string_starts_ends_with.go +360 -0
- package/linthost/rules_ts_promise_function_async.go +77 -0
- package/linthost/rules_ts_related_getter_setter_pairs.go +113 -0
- package/linthost/rules_ts_require_array_sort_compare.go +96 -0
- package/linthost/rules_ts_restrict_plus_operands.go +127 -0
- package/linthost/rules_ts_restrict_template_expressions.go +95 -0
- package/linthost/rules_ts_simple.go +387 -0
- package/linthost/rules_ts_sort_type_constituents.go +144 -0
- package/linthost/rules_ts_strict_boolean_expressions.go +157 -0
- package/linthost/rules_ts_switch_exhaustiveness_check.go +147 -0
- package/linthost/rules_ts_unbound_method.go +126 -0
- package/linthost/rules_tsdoc.go +136 -0
- package/linthost/rules_unicorn_better_regex.go +27 -0
- package/linthost/rules_unicorn_catch_error_name.go +46 -0
- package/linthost/rules_unicorn_consistent_assert.go +47 -0
- package/linthost/rules_unicorn_consistent_date_clone.go +54 -0
- package/linthost/rules_unicorn_consistent_destructuring.go +25 -0
- package/linthost/rules_unicorn_consistent_empty_array_spread.go +62 -0
- package/linthost/rules_unicorn_consistent_existence_index_check.go +80 -0
- package/linthost/rules_unicorn_consistent_function_scoping.go +25 -0
- package/linthost/rules_unicorn_consistent_template_literal_escape.go +25 -0
- package/linthost/rules_unicorn_custom_error_definition.go +138 -0
- package/linthost/rules_unicorn_empty_brace_spaces.go +73 -0
- package/linthost/rules_unicorn_error_message.go +64 -0
- package/linthost/rules_unicorn_escape_case.go +51 -0
- package/linthost/rules_unicorn_expiring_todo_comments.go +78 -0
- package/linthost/rules_unicorn_explicit_length_check.go +88 -0
- package/linthost/rules_unicorn_filename_case.go +29 -0
- package/linthost/rules_unicorn_import_style.go +28 -0
- package/linthost/rules_unicorn_isolated_functions.go +29 -0
- package/linthost/rules_unicorn_new_for_builtins.go +87 -0
- package/linthost/rules_unicorn_no_abusive_eslint_disable.go +63 -0
- package/linthost/rules_unicorn_no_accessor_recursion.go +115 -0
- package/linthost/rules_unicorn_no_anonymous_default_export.go +74 -0
- package/linthost/rules_unicorn_no_array_callback_reference.go +65 -0
- package/linthost/rules_unicorn_no_array_for_each.go +40 -0
- package/linthost/rules_unicorn_no_array_method_this_argument.go +61 -0
- package/linthost/rules_unicorn_no_array_reduce.go +41 -0
- package/linthost/rules_unicorn_no_array_reverse.go +44 -0
- package/linthost/rules_unicorn_no_array_sort.go +43 -0
- package/linthost/rules_unicorn_no_await_expression_member.go +40 -0
- package/linthost/rules_unicorn_no_await_in_promise_methods.go +69 -0
- package/linthost/rules_unicorn_no_console_spaces.go +61 -0
- package/linthost/rules_unicorn_no_document_cookie.go +41 -0
- package/linthost/rules_unicorn_no_empty_file.go +44 -0
- package/linthost/rules_unicorn_no_for_loop.go +102 -0
- package/linthost/rules_unicorn_no_hex_escape.go +42 -0
- package/linthost/rules_unicorn_no_immediate_mutation.go +90 -0
- package/linthost/rules_unicorn_no_instanceof_builtins.go +66 -0
- package/linthost/rules_unicorn_no_invalid_fetch_options.go +79 -0
- package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +51 -0
- package/linthost/rules_unicorn_no_keyword_prefix.go +101 -0
- package/linthost/rules_unicorn_no_lonely_if.go +44 -0
- package/linthost/rules_unicorn_no_magic_array_flat_depth.go +51 -0
- package/linthost/rules_unicorn_no_named_default.go +54 -0
- package/linthost/rules_unicorn_no_negated_condition.go +85 -0
- package/linthost/rules_unicorn_no_negation_in_equality_check.go +50 -0
- package/linthost/rules_unicorn_no_nested_ternary.go +43 -0
- package/linthost/rules_unicorn_no_new_array.go +30 -0
- package/linthost/rules_unicorn_no_new_buffer.go +31 -0
- package/linthost/rules_unicorn_no_null.go +24 -0
- package/linthost/rules_unicorn_no_object_as_default_parameter.go +48 -0
- package/linthost/rules_unicorn_no_process_exit.go +43 -0
- package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +59 -0
- package/linthost/rules_unicorn_no_static_only_class.go +56 -0
- package/linthost/rules_unicorn_no_thenable.go +74 -0
- package/linthost/rules_unicorn_no_this_assignment.go +35 -0
- package/linthost/rules_unicorn_no_typeof_undefined.go +58 -0
- package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +49 -0
- package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +70 -0
- package/linthost/rules_unicorn_no_unnecessary_await.go +51 -0
- package/linthost/rules_unicorn_no_unnecessary_polyfills.go +32 -0
- package/linthost/rules_unicorn_no_unnecessary_slice_end.go +48 -0
- package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +115 -0
- package/linthost/rules_unicorn_no_unreadable_iife.go +50 -0
- package/linthost/rules_unicorn_no_unused_properties.go +30 -0
- package/linthost/rules_unicorn_no_useless_collection_argument.go +63 -0
- package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +46 -0
- package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +81 -0
- package/linthost/rules_unicorn_no_useless_iterator_to_array.go +72 -0
- package/linthost/rules_unicorn_no_useless_length_check.go +144 -0
- package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +81 -0
- package/linthost/rules_unicorn_no_useless_spread.go +67 -0
- package/linthost/rules_unicorn_no_useless_switch_case.go +55 -0
- package/linthost/rules_unicorn_no_useless_undefined.go +55 -0
- package/linthost/rules_unicorn_no_zero_fractions.go +52 -0
- package/linthost/rules_unicorn_number_literal_case.go +69 -0
- package/linthost/rules_unicorn_numeric_separators_style.go +75 -0
- package/linthost/rules_unicorn_prefer_add_event_listener.go +66 -0
- package/linthost/rules_unicorn_prefer_array_find.go +51 -0
- package/linthost/rules_unicorn_prefer_array_flat.go +52 -0
- package/linthost/rules_unicorn_prefer_array_flat_map.go +63 -0
- package/linthost/rules_unicorn_prefer_array_index_of.go +147 -0
- package/linthost/rules_unicorn_prefer_array_some.go +67 -0
- package/linthost/rules_unicorn_prefer_at.go +77 -0
- package/linthost/rules_unicorn_prefer_bigint_literals.go +77 -0
- package/linthost/rules_unicorn_prefer_blob_reading_methods.go +44 -0
- package/linthost/rules_unicorn_prefer_class_fields.go +93 -0
- package/linthost/rules_unicorn_prefer_classlist_toggle.go +120 -0
- package/linthost/rules_unicorn_prefer_code_point.go +49 -0
- package/linthost/rules_unicorn_prefer_date_now.go +78 -0
- package/linthost/rules_unicorn_prefer_default_parameters.go +144 -0
- package/linthost/rules_unicorn_prefer_dom_node_append.go +40 -0
- package/linthost/rules_unicorn_prefer_dom_node_dataset.go +55 -0
- package/linthost/rules_unicorn_prefer_dom_node_remove.go +41 -0
- package/linthost/rules_unicorn_prefer_dom_node_text_content.go +37 -0
- package/linthost/rules_unicorn_prefer_event_target.go +36 -0
- package/linthost/rules_unicorn_prefer_export_from.go +129 -0
- package/linthost/rules_unicorn_prefer_global_this.go +127 -0
- package/linthost/rules_unicorn_prefer_import_meta_properties.go +66 -0
- package/linthost/rules_unicorn_prefer_includes.go +149 -0
- package/linthost/rules_unicorn_prefer_json_parse_buffer.go +65 -0
- package/linthost/rules_unicorn_prefer_keyboard_event_key.go +38 -0
- package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +48 -0
- package/linthost/rules_unicorn_prefer_math_min_max.go +60 -0
- package/linthost/rules_unicorn_prefer_math_trunc.go +62 -0
- package/linthost/rules_unicorn_prefer_modern_dom_apis.go +47 -0
- package/linthost/rules_unicorn_prefer_modern_math_apis.go +70 -0
- package/linthost/rules_unicorn_prefer_module.go +50 -0
- package/linthost/rules_unicorn_prefer_native_coercion_functions.go +114 -0
- package/linthost/rules_unicorn_prefer_negative_index.go +74 -0
- package/linthost/rules_unicorn_prefer_node_protocol.go +122 -0
- package/linthost/rules_unicorn_prefer_number_properties.go +88 -0
- package/linthost/rules_unicorn_prefer_object_from_entries.go +55 -0
- package/linthost/rules_unicorn_prefer_optional_catch_binding.go +62 -0
- package/linthost/rules_unicorn_prefer_prototype_methods.go +54 -0
- package/linthost/rules_unicorn_prefer_query_selector.go +56 -0
- package/linthost/rules_unicorn_prefer_reflect_apply.go +36 -0
- package/linthost/rules_unicorn_prefer_regexp_test_rule.go +80 -0
- package/linthost/rules_unicorn_prefer_response_static_json.go +53 -0
- package/linthost/rules_unicorn_prefer_set_has.go +42 -0
- package/linthost/rules_unicorn_prefer_set_size.go +48 -0
- package/linthost/rules_unicorn_prefer_simple_condition_first.go +34 -0
- package/linthost/rules_unicorn_prefer_single_call.go +96 -0
- package/linthost/rules_unicorn_prefer_spread.go +51 -0
- package/linthost/rules_unicorn_prefer_string_raw.go +43 -0
- package/linthost/rules_unicorn_prefer_string_replace_all.go +95 -0
- package/linthost/rules_unicorn_prefer_string_slice.go +43 -0
- package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +148 -0
- package/linthost/rules_unicorn_prefer_string_trim_start_end.go +48 -0
- package/linthost/rules_unicorn_prefer_structured_clone.go +71 -0
- package/linthost/rules_unicorn_prefer_switch.go +103 -0
- package/linthost/rules_unicorn_prefer_ternary.go +71 -0
- package/linthost/rules_unicorn_prefer_top_level_await.go +72 -0
- package/linthost/rules_unicorn_prefer_type_error.go +127 -0
- package/linthost/rules_unicorn_prevent_abbreviations.go +127 -0
- package/linthost/rules_unicorn_relative_url_style.go +49 -0
- package/linthost/rules_unicorn_require_array_join_separator.go +45 -0
- package/linthost/rules_unicorn_require_module_attributes.go +54 -0
- package/linthost/rules_unicorn_require_module_specifiers.go +55 -0
- package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +43 -0
- package/linthost/rules_unicorn_require_post_message_target_origin.go +44 -0
- package/linthost/rules_unicorn_string_content.go +27 -0
- package/linthost/rules_unicorn_switch_case_braces.go +42 -0
- package/linthost/rules_unicorn_switch_case_break_position.go +31 -0
- package/linthost/rules_unicorn_template_indent.go +28 -0
- package/linthost/rules_unicorn_text_encoding_identifier_case.go +72 -0
- package/linthost/rules_unicorn_throw_new_error.go +61 -0
- package/linthost/rules_var.go +4 -4
- package/linthost/rules_vitest.go +568 -0
- package/package.json +3 -3
- package/plugin/main.go +49 -3
- package/rule/astutil/astutil.go +10 -3
- package/rule/rule.go +12 -10
- package/src/defaultFormat.ts +11 -8
- package/src/index.ts +40 -16
- package/src/structures/ITtscLintConfig.ts +12 -6
- package/src/structures/{ITtscLintFormatConfig.ts → ITtscLintFormat.ts} +2 -2
- package/src/structures/TtscLintRuleSetting.ts +55 -0
- package/src/structures/index.ts +3 -4
- package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +128 -0
- package/src/structures/rules/ITtscLintBoundariesRules.ts +95 -0
- package/src/structures/rules/ITtscLintContributorRules.ts +21 -0
- package/src/structures/rules/ITtscLintCoreRules.ts +1406 -0
- package/src/structures/rules/ITtscLintCypressRuleOptions.ts +18 -0
- package/src/structures/rules/ITtscLintCypressRules.ts +145 -0
- package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +213 -0
- package/src/structures/rules/ITtscLintFunctionalRules.ts +202 -0
- package/src/structures/rules/ITtscLintJestRules.ts +220 -0
- package/src/structures/rules/ITtscLintJsdocRules.ts +153 -0
- package/src/structures/rules/ITtscLintJsxA11yRules.ts +339 -0
- package/src/structures/rules/ITtscLintNextjsRules.ts +206 -0
- package/src/structures/rules/ITtscLintPlaywrightRules.ts +361 -0
- package/src/structures/rules/ITtscLintPromiseRules.ts +205 -0
- package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +19 -0
- package/src/structures/rules/ITtscLintReactPerfRules.ts +55 -0
- package/src/structures/rules/ITtscLintReactRuleOptions.ts +43 -0
- package/src/structures/rules/ITtscLintReactRules.ts +321 -0
- package/src/structures/rules/ITtscLintRegexpRules.ts +212 -0
- package/src/structures/rules/ITtscLintRuleOptionsMap.ts +89 -0
- package/src/structures/rules/ITtscLintRules.ts +77 -0
- package/src/structures/rules/ITtscLintSecurityRules.ts +162 -0
- package/src/structures/rules/ITtscLintSolidRules.ts +202 -0
- package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +23 -0
- package/src/structures/rules/ITtscLintStorybookRules.ts +193 -0
- package/src/structures/rules/ITtscLintTanstackQueryRules.ts +102 -0
- package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +24 -0
- package/src/structures/rules/ITtscLintTestingLibraryRules.ts +342 -0
- package/src/structures/rules/ITtscLintTypeScriptRules.ts +1230 -0
- package/src/structures/rules/ITtscLintUnicornRules.ts +1143 -0
- package/src/structures/rules/ITtscLintVitestRules.ts +154 -0
- package/src/structures/rules/index.ts +31 -0
- package/lib/structures/ITtscLintFormatConfig.js.map +0 -1
- package/lib/structures/TtscLintRule.d.ts +0 -17
- package/lib/structures/TtscLintRule.js.map +0 -1
- package/lib/structures/TtscLintRuleMap.d.ts +0 -46
- package/lib/structures/TtscLintRuleMap.js.map +0 -1
- package/lib/structures/TtscLintRuleOptions.d.ts +0 -137
- package/lib/structures/TtscLintRuleOptions.js.map +0 -1
- package/src/structures/TtscLintRule.ts +0 -160
- package/src/structures/TtscLintRuleMap.ts +0 -55
- package/src/structures/TtscLintRuleOptions.ts +0 -151
|
@@ -11,10 +11,10 @@ import (
|
|
|
11
11
|
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
12
12
|
)
|
|
13
13
|
|
|
14
|
-
//
|
|
14
|
+
// noConfusingNonNullAssertion: `a! == b` reads ambiguously.
|
|
15
15
|
type noConfusingNonNullAssertion struct{}
|
|
16
16
|
|
|
17
|
-
func (noConfusingNonNullAssertion) Name() string { return "no-confusing-non-null-assertion" }
|
|
17
|
+
func (noConfusingNonNullAssertion) Name() string { return "typescript/no-confusing-non-null-assertion" }
|
|
18
18
|
func (noConfusingNonNullAssertion) Visits() []shimast.Kind {
|
|
19
19
|
return []shimast.Kind{shimast.KindBinaryExpression}
|
|
20
20
|
}
|
|
@@ -37,11 +37,11 @@ func (noConfusingNonNullAssertion) Check(ctx *Context, node *shimast.Node) {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
//
|
|
40
|
+
// noDuplicateEnumValues: `enum E { A = 1, B = 1 }` — duplicate values
|
|
41
41
|
// silently collapse.
|
|
42
42
|
type noDuplicateEnumValues struct{}
|
|
43
43
|
|
|
44
|
-
func (noDuplicateEnumValues) Name() string { return "no-duplicate-enum-values" }
|
|
44
|
+
func (noDuplicateEnumValues) Name() string { return "typescript/no-duplicate-enum-values" }
|
|
45
45
|
func (noDuplicateEnumValues) Visits() []shimast.Kind {
|
|
46
46
|
return []shimast.Kind{shimast.KindEnumDeclaration}
|
|
47
47
|
}
|
|
@@ -77,13 +77,13 @@ func (noDuplicateEnumValues) Check(ctx *Context, node *shimast.Node) {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
//
|
|
80
|
+
// noMixedEnums: forbid enums that mix numeric and string member shapes.
|
|
81
81
|
// A single enum with `{ A, B = "two" }` produces broken reverse mappings
|
|
82
82
|
// and surprising assignability. typescript-eslint recommended:
|
|
83
83
|
// https://typescript-eslint.io/rules/no-mixed-enums/
|
|
84
84
|
type noMixedEnums struct{}
|
|
85
85
|
|
|
86
|
-
func (noMixedEnums) Name() string { return "no-mixed-enums" }
|
|
86
|
+
func (noMixedEnums) Name() string { return "typescript/no-mixed-enums" }
|
|
87
87
|
func (noMixedEnums) Visits() []shimast.Kind {
|
|
88
88
|
return []shimast.Kind{shimast.KindEnumDeclaration}
|
|
89
89
|
}
|
|
@@ -137,10 +137,10 @@ func (noMixedEnums) Check(ctx *Context, node *shimast.Node) {
|
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
//
|
|
140
|
+
// noExtraNonNullAssertion: `a!!` / `a!?.b` collapses two assertions.
|
|
141
141
|
type noExtraNonNullAssertion struct{}
|
|
142
142
|
|
|
143
|
-
func (noExtraNonNullAssertion) Name() string { return "no-extra-non-null-assertion" }
|
|
143
|
+
func (noExtraNonNullAssertion) Name() string { return "typescript/no-extra-non-null-assertion" }
|
|
144
144
|
func (noExtraNonNullAssertion) Visits() []shimast.Kind {
|
|
145
145
|
return []shimast.Kind{shimast.KindNonNullExpression}
|
|
146
146
|
}
|
|
@@ -169,11 +169,11 @@ func (noExtraNonNullAssertion) Check(ctx *Context, node *shimast.Node) {
|
|
|
169
169
|
)
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
//
|
|
172
|
+
// noNonNullAssertedOptionalChain: `foo?.bar!` — the chain produces
|
|
173
173
|
// undefined; asserting non-null on the whole chain defeats the chain.
|
|
174
174
|
type noNonNullAssertedOptionalChain struct{}
|
|
175
175
|
|
|
176
|
-
func (noNonNullAssertedOptionalChain) Name() string { return "no-non-null-asserted-optional-chain" }
|
|
176
|
+
func (noNonNullAssertedOptionalChain) Name() string { return "typescript/no-non-null-asserted-optional-chain" }
|
|
177
177
|
func (noNonNullAssertedOptionalChain) Visits() []shimast.Kind {
|
|
178
178
|
return []shimast.Kind{shimast.KindNonNullExpression}
|
|
179
179
|
}
|
|
@@ -224,12 +224,12 @@ func containsOptionalChain(node *shimast.Node) bool {
|
|
|
224
224
|
return false
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
-
//
|
|
227
|
+
// noMisusedNew: declaring a `new` signature on a non-class interface
|
|
228
228
|
// or a `constructor` method on an interface — these don't do what
|
|
229
229
|
// authors expect.
|
|
230
230
|
type noMisusedNew struct{}
|
|
231
231
|
|
|
232
|
-
func (noMisusedNew) Name() string { return "no-misused-new" }
|
|
232
|
+
func (noMisusedNew) Name() string { return "typescript/no-misused-new" }
|
|
233
233
|
func (noMisusedNew) Visits() []shimast.Kind {
|
|
234
234
|
return []shimast.Kind{shimast.KindInterfaceDeclaration, shimast.KindTypeAliasDeclaration}
|
|
235
235
|
}
|
|
@@ -257,11 +257,109 @@ func (noMisusedNew) Check(ctx *Context, node *shimast.Node) {
|
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
//
|
|
260
|
+
// noUnnecessaryParameterPropertyAssignment: parameter properties already
|
|
261
|
+
// assign the constructor argument to `this.<name>` before the body runs.
|
|
262
|
+
// A body-level `this.x = x` immediately repeats that initialization.
|
|
263
|
+
type noUnnecessaryParameterPropertyAssignment struct{}
|
|
264
|
+
|
|
265
|
+
func (noUnnecessaryParameterPropertyAssignment) Name() string {
|
|
266
|
+
return "typescript/no-unnecessary-parameter-property-assignment"
|
|
267
|
+
}
|
|
268
|
+
func (noUnnecessaryParameterPropertyAssignment) Visits() []shimast.Kind {
|
|
269
|
+
return []shimast.Kind{shimast.KindConstructor}
|
|
270
|
+
}
|
|
271
|
+
func (noUnnecessaryParameterPropertyAssignment) Check(ctx *Context, node *shimast.Node) {
|
|
272
|
+
parameterProperties := map[string]bool{}
|
|
273
|
+
for _, param := range node.Parameters() {
|
|
274
|
+
name, ok := parameterPropertyName(param)
|
|
275
|
+
if ok {
|
|
276
|
+
parameterProperties[name] = true
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if len(parameterProperties) == 0 {
|
|
280
|
+
return
|
|
281
|
+
}
|
|
282
|
+
body := node.Body()
|
|
283
|
+
if body == nil || body.Kind != shimast.KindBlock {
|
|
284
|
+
return
|
|
285
|
+
}
|
|
286
|
+
block := body.AsBlock()
|
|
287
|
+
if block == nil || block.Statements == nil {
|
|
288
|
+
return
|
|
289
|
+
}
|
|
290
|
+
assigned := map[string]bool{}
|
|
291
|
+
for _, stmt := range block.Statements.Nodes {
|
|
292
|
+
property, value, ok := thisPropertyAssignment(stmt)
|
|
293
|
+
if !ok {
|
|
294
|
+
continue
|
|
295
|
+
}
|
|
296
|
+
if parameterProperties[property] && !assigned[property] && value == property {
|
|
297
|
+
ctx.Report(stmt, "This assignment repeats the constructor parameter property initialization.")
|
|
298
|
+
}
|
|
299
|
+
assigned[property] = true
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
func parameterPropertyName(param *shimast.Node) (string, bool) {
|
|
304
|
+
if param == nil || param.Kind != shimast.KindParameter {
|
|
305
|
+
return "", false
|
|
306
|
+
}
|
|
307
|
+
if !isParameterProperty(param) {
|
|
308
|
+
return "", false
|
|
309
|
+
}
|
|
310
|
+
decl := param.AsParameterDeclaration()
|
|
311
|
+
if decl == nil {
|
|
312
|
+
return "", false
|
|
313
|
+
}
|
|
314
|
+
name := identifierText(decl.Name())
|
|
315
|
+
return name, name != ""
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
func isParameterProperty(param *shimast.Node) bool {
|
|
319
|
+
return hasModifier(param, shimast.KindPublicKeyword) ||
|
|
320
|
+
hasModifier(param, shimast.KindPrivateKeyword) ||
|
|
321
|
+
hasModifier(param, shimast.KindProtectedKeyword) ||
|
|
322
|
+
hasModifier(param, shimast.KindReadonlyKeyword) ||
|
|
323
|
+
hasModifier(param, shimast.KindOverrideKeyword)
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
func thisPropertyAssignment(stmt *shimast.Node) (property string, value string, ok bool) {
|
|
327
|
+
if stmt == nil || stmt.Kind != shimast.KindExpressionStatement {
|
|
328
|
+
return "", "", false
|
|
329
|
+
}
|
|
330
|
+
exprStmt := stmt.AsExpressionStatement()
|
|
331
|
+
if exprStmt == nil || exprStmt.Expression == nil {
|
|
332
|
+
return "", "", false
|
|
333
|
+
}
|
|
334
|
+
expr := stripParens(exprStmt.Expression)
|
|
335
|
+
if expr == nil || expr.Kind != shimast.KindBinaryExpression {
|
|
336
|
+
return "", "", false
|
|
337
|
+
}
|
|
338
|
+
binary := expr.AsBinaryExpression()
|
|
339
|
+
if binary == nil || binary.OperatorToken == nil || binary.OperatorToken.Kind != shimast.KindEqualsToken {
|
|
340
|
+
return "", "", false
|
|
341
|
+
}
|
|
342
|
+
left := stripParens(binary.Left)
|
|
343
|
+
if left == nil || left.Kind != shimast.KindPropertyAccessExpression {
|
|
344
|
+
return "", "", false
|
|
345
|
+
}
|
|
346
|
+
access := left.AsPropertyAccessExpression()
|
|
347
|
+
if access == nil || access.Expression == nil || access.Expression.Kind != shimast.KindThisKeyword {
|
|
348
|
+
return "", "", false
|
|
349
|
+
}
|
|
350
|
+
property = identifierText(access.Name())
|
|
351
|
+
value = identifierText(stripParens(binary.Right))
|
|
352
|
+
if property == "" {
|
|
353
|
+
return "", "", false
|
|
354
|
+
}
|
|
355
|
+
return property, value, true
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// preferEnumInitializers: every enum member should have an explicit
|
|
261
359
|
// initializer (avoids order-dependent values).
|
|
262
360
|
type preferEnumInitializers struct{}
|
|
263
361
|
|
|
264
|
-
func (preferEnumInitializers) Name() string { return "prefer-enum-initializers" }
|
|
362
|
+
func (preferEnumInitializers) Name() string { return "typescript/prefer-enum-initializers" }
|
|
265
363
|
func (preferEnumInitializers) Visits() []shimast.Kind {
|
|
266
364
|
return []shimast.Kind{shimast.KindEnumDeclaration}
|
|
267
365
|
}
|
|
@@ -281,7 +379,7 @@ func (preferEnumInitializers) Check(ctx *Context, node *shimast.Node) {
|
|
|
281
379
|
}
|
|
282
380
|
}
|
|
283
381
|
|
|
284
|
-
//
|
|
382
|
+
// preferForOf: `for (let i = 0; i < arr.length; i++) { use(arr[i]) }`
|
|
285
383
|
// can usually be replaced with `for (const x of arr) { use(x); }`.
|
|
286
384
|
type preferForOf struct{}
|
|
287
385
|
|
|
@@ -351,13 +449,13 @@ func isCounterIncrement(node *shimast.Node, counter string) bool {
|
|
|
351
449
|
return false
|
|
352
450
|
}
|
|
353
451
|
|
|
354
|
-
//
|
|
452
|
+
// preferFunctionType: a single-call-signature interface or type alias
|
|
355
453
|
// is more readably written as a function type.
|
|
356
454
|
//
|
|
357
455
|
// interface F { (x: number): string } -> type F = (x: number) => string
|
|
358
456
|
type preferFunctionType struct{}
|
|
359
457
|
|
|
360
|
-
func (preferFunctionType) Name() string { return "prefer-function-type" }
|
|
458
|
+
func (preferFunctionType) Name() string { return "typescript/prefer-function-type" }
|
|
361
459
|
func (preferFunctionType) Visits() []shimast.Kind {
|
|
362
460
|
return []shimast.Kind{shimast.KindInterfaceDeclaration}
|
|
363
461
|
}
|
|
@@ -376,11 +474,30 @@ func (preferFunctionType) Check(ctx *Context, node *shimast.Node) {
|
|
|
376
474
|
ctx.Report(node, "Interface only has a call signature; use 'type' alias and function type instead.")
|
|
377
475
|
}
|
|
378
476
|
|
|
379
|
-
//
|
|
477
|
+
// methodSignatureStyle: prefer function-property signatures over method
|
|
478
|
+
// shorthand in interfaces and type literals. This implements the default
|
|
479
|
+
// @typescript-eslint mode (`property`) as a diagnostic-only rule.
|
|
480
|
+
type methodSignatureStyle struct{}
|
|
481
|
+
|
|
482
|
+
func (methodSignatureStyle) Name() string { return "typescript/method-signature-style" }
|
|
483
|
+
func (methodSignatureStyle) Visits() []shimast.Kind {
|
|
484
|
+
return []shimast.Kind{shimast.KindMethodSignature}
|
|
485
|
+
}
|
|
486
|
+
func (methodSignatureStyle) Check(ctx *Context, node *shimast.Node) {
|
|
487
|
+
if node.Parent == nil {
|
|
488
|
+
return
|
|
489
|
+
}
|
|
490
|
+
switch node.Parent.Kind {
|
|
491
|
+
case shimast.KindInterfaceDeclaration, shimast.KindTypeLiteral:
|
|
492
|
+
ctx.Report(node, "Use a function-property signature instead of a method signature.")
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// preferNamespaceKeyword: `module Foo {}` (TS namespace via `module`
|
|
380
497
|
// keyword) → `namespace Foo {}`.
|
|
381
498
|
type preferNamespaceKeyword struct{}
|
|
382
499
|
|
|
383
|
-
func (preferNamespaceKeyword) Name() string { return "prefer-namespace-keyword" }
|
|
500
|
+
func (preferNamespaceKeyword) Name() string { return "typescript/prefer-namespace-keyword" }
|
|
384
501
|
func (preferNamespaceKeyword) Visits() []shimast.Kind {
|
|
385
502
|
return []shimast.Kind{shimast.KindModuleDeclaration}
|
|
386
503
|
}
|
|
@@ -408,11 +525,11 @@ func (preferNamespaceKeyword) Check(ctx *Context, node *shimast.Node) {
|
|
|
408
525
|
)
|
|
409
526
|
}
|
|
410
527
|
|
|
411
|
-
//
|
|
528
|
+
// tripleSlashReference: `/// <reference path="..." />` directives.
|
|
412
529
|
// Discouraged in modern code in favor of `import`.
|
|
413
530
|
type tripleSlashReference struct{}
|
|
414
531
|
|
|
415
|
-
func (tripleSlashReference) Name() string { return "triple-slash-reference" }
|
|
532
|
+
func (tripleSlashReference) Name() string { return "typescript/triple-slash-reference" }
|
|
416
533
|
func (tripleSlashReference) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
|
|
417
534
|
func (tripleSlashReference) Check(ctx *Context, node *shimast.Node) {
|
|
418
535
|
if ctx.File == nil {
|
|
@@ -426,10 +543,10 @@ func (tripleSlashReference) Check(ctx *Context, node *shimast.Node) {
|
|
|
426
543
|
}
|
|
427
544
|
}
|
|
428
545
|
|
|
429
|
-
//
|
|
546
|
+
// noArrayDelete: `delete arr[0]` leaves a sparse hole. Use `splice`.
|
|
430
547
|
type noArrayDelete struct{}
|
|
431
548
|
|
|
432
|
-
func (noArrayDelete) Name() string { return "no-array-delete" }
|
|
549
|
+
func (noArrayDelete) Name() string { return "typescript/no-array-delete" }
|
|
433
550
|
func (noArrayDelete) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindDeleteExpression} }
|
|
434
551
|
func (noArrayDelete) Check(ctx *Context, node *shimast.Node) {
|
|
435
552
|
del := node.AsDeleteExpression()
|
|
@@ -451,7 +568,7 @@ func (noArrayDelete) Check(ctx *Context, node *shimast.Node) {
|
|
|
451
568
|
}
|
|
452
569
|
}
|
|
453
570
|
|
|
454
|
-
//
|
|
571
|
+
// consistentTypeImports: `import { Foo } from "./types"` where Foo is
|
|
455
572
|
// only used as a type → `import type { Foo } from "./types"`. We
|
|
456
573
|
// approximate by flagging every `import type` candidate where the
|
|
457
574
|
// specifier appears in a type-only context inside the file.
|
|
@@ -462,7 +579,7 @@ func (noArrayDelete) Check(ctx *Context, node *shimast.Node) {
|
|
|
462
579
|
// common case.
|
|
463
580
|
type consistentTypeImports struct{}
|
|
464
581
|
|
|
465
|
-
func (consistentTypeImports) Name() string { return "consistent-type-imports" }
|
|
582
|
+
func (consistentTypeImports) Name() string { return "typescript/consistent-type-imports" }
|
|
466
583
|
func (consistentTypeImports) Visits() []shimast.Kind {
|
|
467
584
|
return []shimast.Kind{shimast.KindImportDeclaration}
|
|
468
585
|
}
|
|
@@ -549,12 +666,12 @@ func allUsesAreTypeOnly(root *shimast.Node, names []string) bool {
|
|
|
549
666
|
return allOk
|
|
550
667
|
}
|
|
551
668
|
|
|
552
|
-
//
|
|
669
|
+
// noEmptyObjectType: `interface Foo {}` / `type Foo = {}`. ESLint
|
|
553
670
|
// flags empty types because they're equivalent to `unknown` (everything
|
|
554
671
|
// satisfies `{}`).
|
|
555
672
|
type noEmptyObjectType struct{}
|
|
556
673
|
|
|
557
|
-
func (noEmptyObjectType) Name() string { return "no-empty-object-type" }
|
|
674
|
+
func (noEmptyObjectType) Name() string { return "typescript/no-empty-object-type" }
|
|
558
675
|
func (noEmptyObjectType) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindTypeLiteral} }
|
|
559
676
|
func (noEmptyObjectType) Check(ctx *Context, node *shimast.Node) {
|
|
560
677
|
lit := node.AsTypeLiteralNode()
|
|
@@ -566,10 +683,10 @@ func (noEmptyObjectType) Check(ctx *Context, node *shimast.Node) {
|
|
|
566
683
|
}
|
|
567
684
|
}
|
|
568
685
|
|
|
569
|
-
//
|
|
686
|
+
// arrayType: `Array<T>` vs `T[]`. ESLint default mode prefers `T[]`.
|
|
570
687
|
type arrayType struct{}
|
|
571
688
|
|
|
572
|
-
func (arrayType) Name() string { return "array-type" }
|
|
689
|
+
func (arrayType) Name() string { return "typescript/array-type" }
|
|
573
690
|
func (arrayType) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindTypeReference} }
|
|
574
691
|
func (arrayType) Check(ctx *Context, node *shimast.Node) {
|
|
575
692
|
ref := node.AsTypeReferenceNode()
|
|
@@ -590,11 +707,11 @@ func (arrayType) Check(ctx *Context, node *shimast.Node) {
|
|
|
590
707
|
}
|
|
591
708
|
}
|
|
592
709
|
|
|
593
|
-
//
|
|
710
|
+
// consistentIndexedObjectStyle: `{ [key: string]: T }` vs
|
|
594
711
|
// `Record<string, T>`. ESLint default prefers `Record`.
|
|
595
712
|
type consistentIndexedObjectStyle struct{}
|
|
596
713
|
|
|
597
|
-
func (consistentIndexedObjectStyle) Name() string { return "consistent-indexed-object-style" }
|
|
714
|
+
func (consistentIndexedObjectStyle) Name() string { return "typescript/consistent-indexed-object-style" }
|
|
598
715
|
func (consistentIndexedObjectStyle) Visits() []shimast.Kind {
|
|
599
716
|
return []shimast.Kind{shimast.KindTypeLiteral}
|
|
600
717
|
}
|
|
@@ -611,17 +728,17 @@ func (consistentIndexedObjectStyle) Check(ctx *Context, node *shimast.Node) {
|
|
|
611
728
|
}
|
|
612
729
|
|
|
613
730
|
// no-explicit-any-rest-parameter — keeping this distinct from
|
|
614
|
-
//
|
|
731
|
+
// noExplicitAny: rest parameters typed `...args: any[]` are common
|
|
615
732
|
// enough that users want to allow them; this rule lets them ban that
|
|
616
733
|
// shape specifically.
|
|
617
734
|
//
|
|
618
735
|
// (Skipped: too narrow / overlaps with no-explicit-any.)
|
|
619
736
|
|
|
620
|
-
//
|
|
737
|
+
// banTslintComment: `// tslint:disable`. tslint is dead; comments
|
|
621
738
|
// referencing it should be cleaned up.
|
|
622
739
|
type banTslintComment struct{}
|
|
623
740
|
|
|
624
|
-
func (banTslintComment) Name() string { return "ban-tslint-comment" }
|
|
741
|
+
func (banTslintComment) Name() string { return "typescript/ban-tslint-comment" }
|
|
625
742
|
func (banTslintComment) Visits() []shimast.Kind { return []shimast.Kind{shimast.KindSourceFile} }
|
|
626
743
|
func (banTslintComment) Check(ctx *Context, node *shimast.Node) {
|
|
627
744
|
if ctx.File == nil {
|
|
@@ -644,12 +761,12 @@ func (banTslintComment) Check(ctx *Context, node *shimast.Node) {
|
|
|
644
761
|
}
|
|
645
762
|
}
|
|
646
763
|
|
|
647
|
-
//
|
|
764
|
+
// adjacentOverloadSignatures: function/method overloads must be
|
|
648
765
|
// declared next to each other. ESLint catches the visual confusion
|
|
649
766
|
// when overloads are interleaved with other members.
|
|
650
767
|
type adjacentOverloadSignatures struct{}
|
|
651
768
|
|
|
652
|
-
func (adjacentOverloadSignatures) Name() string { return "adjacent-overload-signatures" }
|
|
769
|
+
func (adjacentOverloadSignatures) Name() string { return "typescript/adjacent-overload-signatures" }
|
|
653
770
|
func (adjacentOverloadSignatures) Visits() []shimast.Kind {
|
|
654
771
|
return []shimast.Kind{shimast.KindInterfaceDeclaration, shimast.KindTypeLiteral, shimast.KindClassDeclaration, shimast.KindClassExpression, shimast.KindModuleBlock, shimast.KindSourceFile}
|
|
655
772
|
}
|
|
@@ -764,9 +881,11 @@ func init() {
|
|
|
764
881
|
Register(noExtraNonNullAssertion{})
|
|
765
882
|
Register(noNonNullAssertedOptionalChain{})
|
|
766
883
|
Register(noMisusedNew{})
|
|
884
|
+
Register(noUnnecessaryParameterPropertyAssignment{})
|
|
767
885
|
Register(preferEnumInitializers{})
|
|
768
886
|
Register(preferForOf{})
|
|
769
887
|
Register(preferFunctionType{})
|
|
888
|
+
Register(methodSignatureStyle{})
|
|
770
889
|
Register(preferNamespaceKeyword{})
|
|
771
890
|
Register(tripleSlashReference{})
|
|
772
891
|
Register(noArrayDelete{})
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// typescript/no-base-to-string: a string-coercion context that
|
|
2
|
+
// resolves `toString` to the default `Object.prototype.toString`
|
|
3
|
+
// produces the useless `"[object Object]"` placeholder at runtime.
|
|
4
|
+
// typescript-eslint:
|
|
5
|
+
// https://typescript-eslint.io/rules/no-base-to-string/
|
|
6
|
+
//
|
|
7
|
+
// Type-aware. The rule visits the three shapes that implicitly coerce
|
|
8
|
+
// a value through `toString`:
|
|
9
|
+
//
|
|
10
|
+
// - `${x}` — every interpolated expression in a TemplateExpression;
|
|
11
|
+
// - `x + y` — when one operand is statically string-typed the other
|
|
12
|
+
// operand is coerced;
|
|
13
|
+
// - `String(x)` — explicit one-argument coercion.
|
|
14
|
+
//
|
|
15
|
+
// A type is "safely stringifiable" when it is a primitive-like type
|
|
16
|
+
// (`string`-/`number`-/`bigint`-/`boolean`-like, `null`, `undefined`),
|
|
17
|
+
// when the Checker reports it as `any` / `unknown` / `never` (those
|
|
18
|
+
// escape strict reasoning the same way `await-thenable` lets them
|
|
19
|
+
// pass), or when it overrides `toString` away from the global
|
|
20
|
+
// `Object` interface. Unions are safe only when every constituent is
|
|
21
|
+
// safe; intersections are safe when any constituent is safe.
|
|
22
|
+
package linthost
|
|
23
|
+
|
|
24
|
+
import (
|
|
25
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
26
|
+
shimchecker "github.com/microsoft/typescript-go/shim/checker"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
type noBaseToString struct{}
|
|
30
|
+
|
|
31
|
+
func (noBaseToString) Name() string { return "typescript/no-base-to-string" }
|
|
32
|
+
func (noBaseToString) NeedsTypeChecker() bool {
|
|
33
|
+
return true
|
|
34
|
+
}
|
|
35
|
+
func (noBaseToString) Visits() []shimast.Kind {
|
|
36
|
+
return []shimast.Kind{
|
|
37
|
+
shimast.KindTemplateExpression,
|
|
38
|
+
shimast.KindBinaryExpression,
|
|
39
|
+
shimast.KindCallExpression,
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
func (noBaseToString) Check(ctx *Context, node *shimast.Node) {
|
|
43
|
+
if ctx.Checker == nil {
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
switch node.Kind {
|
|
47
|
+
case shimast.KindTemplateExpression:
|
|
48
|
+
expr := node.AsTemplateExpression()
|
|
49
|
+
if expr == nil || expr.TemplateSpans == nil {
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
for _, spanNode := range expr.TemplateSpans.Nodes {
|
|
53
|
+
span := spanNode.AsTemplateSpan()
|
|
54
|
+
if span == nil || span.Expression == nil {
|
|
55
|
+
continue
|
|
56
|
+
}
|
|
57
|
+
reportIfBaseToString(ctx, span.Expression)
|
|
58
|
+
}
|
|
59
|
+
case shimast.KindBinaryExpression:
|
|
60
|
+
bin := node.AsBinaryExpression()
|
|
61
|
+
if bin == nil || bin.OperatorToken == nil || bin.OperatorToken.Kind != shimast.KindPlusToken {
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
left := stripParens(bin.Left)
|
|
65
|
+
right := stripParens(bin.Right)
|
|
66
|
+
if left == nil || right == nil {
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
leftType := ctx.Checker.GetTypeAtLocation(left)
|
|
70
|
+
rightType := ctx.Checker.GetTypeAtLocation(right)
|
|
71
|
+
if isStringLikeType(leftType) {
|
|
72
|
+
if !isSafeToStringType(ctx.Checker, rightType) {
|
|
73
|
+
ctx.Report(right, baseToStringMessage)
|
|
74
|
+
}
|
|
75
|
+
} else if isStringLikeType(rightType) {
|
|
76
|
+
if !isSafeToStringType(ctx.Checker, leftType) {
|
|
77
|
+
ctx.Report(left, baseToStringMessage)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
case shimast.KindCallExpression:
|
|
81
|
+
call := node.AsCallExpression()
|
|
82
|
+
if call == nil || call.Expression == nil || call.Arguments == nil {
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
if call.Expression.Kind != shimast.KindIdentifier || identifierText(call.Expression) != "String" {
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
if len(call.Arguments.Nodes) != 1 {
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
reportIfBaseToString(ctx, call.Arguments.Nodes[0])
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const baseToStringMessage = "Value implicitly coerces to '[object Object]'. Override `toString` or pass an explicit string representation."
|
|
96
|
+
|
|
97
|
+
func reportIfBaseToString(ctx *Context, expr *shimast.Node) {
|
|
98
|
+
if expr == nil {
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
t := ctx.Checker.GetTypeAtLocation(expr)
|
|
102
|
+
if isSafeToStringType(ctx.Checker, t) {
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
ctx.Report(expr, baseToStringMessage)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// isStringLikeType reports whether t is provably string-typed (a
|
|
109
|
+
// literal, the primitive, a template-literal type, or any combination
|
|
110
|
+
// thereof). Used to decide whether the OTHER operand of a `+`
|
|
111
|
+
// expression is being coerced.
|
|
112
|
+
func isStringLikeType(t *shimchecker.Type) bool {
|
|
113
|
+
if t == nil {
|
|
114
|
+
return false
|
|
115
|
+
}
|
|
116
|
+
flags := t.Flags()
|
|
117
|
+
if flags&shimchecker.TypeFlagsStringLike != 0 {
|
|
118
|
+
return true
|
|
119
|
+
}
|
|
120
|
+
if flags&shimchecker.TypeFlagsUnion != 0 {
|
|
121
|
+
for _, part := range t.Types() {
|
|
122
|
+
if !isStringLikeType(part) {
|
|
123
|
+
return false
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return true
|
|
127
|
+
}
|
|
128
|
+
return false
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// isSafeToStringType reports whether `t` can be implicitly coerced to a
|
|
132
|
+
// string without producing the default `Object.prototype.toString`
|
|
133
|
+
// output. The shape mirrors `isAwaitable` in rules_promise.go: union
|
|
134
|
+
// constituents must all be safe; intersection constituents are safe
|
|
135
|
+
// when any one of them is. The `any` / `unknown` / `never` cases pass
|
|
136
|
+
// because flagging them would explode at generic-helper boundaries —
|
|
137
|
+
// the same conservatism `no-floating-promises` adopts.
|
|
138
|
+
func isSafeToStringType(checker *shimchecker.Checker, t *shimchecker.Type) bool {
|
|
139
|
+
if checker == nil || t == nil {
|
|
140
|
+
return true
|
|
141
|
+
}
|
|
142
|
+
flags := t.Flags()
|
|
143
|
+
if flags&(shimchecker.TypeFlagsAny|shimchecker.TypeFlagsUnknown|shimchecker.TypeFlagsNever) != 0 {
|
|
144
|
+
return true
|
|
145
|
+
}
|
|
146
|
+
if flags&(shimchecker.TypeFlagsStringLike|
|
|
147
|
+
shimchecker.TypeFlagsNumberLike|
|
|
148
|
+
shimchecker.TypeFlagsBigIntLike|
|
|
149
|
+
shimchecker.TypeFlagsBooleanLike|
|
|
150
|
+
shimchecker.TypeFlagsNull|
|
|
151
|
+
shimchecker.TypeFlagsUndefined) != 0 {
|
|
152
|
+
return true
|
|
153
|
+
}
|
|
154
|
+
if flags&shimchecker.TypeFlagsUnion != 0 {
|
|
155
|
+
for _, part := range t.Types() {
|
|
156
|
+
if !isSafeToStringType(checker, part) {
|
|
157
|
+
return false
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return true
|
|
161
|
+
}
|
|
162
|
+
if flags&shimchecker.TypeFlagsIntersection != 0 {
|
|
163
|
+
for _, part := range t.Types() {
|
|
164
|
+
if isSafeToStringType(checker, part) {
|
|
165
|
+
return true
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return false
|
|
169
|
+
}
|
|
170
|
+
return typeOverridesToString(checker, t)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// typeOverridesToString reports whether `t` carries a `toString` method
|
|
174
|
+
// that is NOT the default declaration on the global `Object` interface.
|
|
175
|
+
// The lib.es5.d.ts `Object` interface declares `toString(): string`; a
|
|
176
|
+
// custom override is what makes coercion meaningful at runtime. If no
|
|
177
|
+
// `toString` is reachable at all the type is treated as base — the
|
|
178
|
+
// only way to coerce it is the prototype-chain default.
|
|
179
|
+
func typeOverridesToString(checker *shimchecker.Checker, t *shimchecker.Type) bool {
|
|
180
|
+
prop := checker.GetPropertyOfType(t, "toString")
|
|
181
|
+
if prop == nil {
|
|
182
|
+
return false
|
|
183
|
+
}
|
|
184
|
+
for _, decl := range prop.Declarations {
|
|
185
|
+
if decl == nil {
|
|
186
|
+
continue
|
|
187
|
+
}
|
|
188
|
+
if !isObjectToStringDeclaration(decl) {
|
|
189
|
+
return true
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return false
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// isObjectToStringDeclaration reports whether `decl` is the
|
|
196
|
+
// `toString(): string` member that lives on the global `Object`
|
|
197
|
+
// interface in lib.es5.d.ts. Walking the parent chain stops at the
|
|
198
|
+
// nearest `interface Object {}` / `interface ObjectConstructor {}`
|
|
199
|
+
// declaration; anything else (Array, Date, Error, user classes, etc.)
|
|
200
|
+
// counts as a real override.
|
|
201
|
+
func isObjectToStringDeclaration(decl *shimast.Node) bool {
|
|
202
|
+
parent := decl.Parent
|
|
203
|
+
if parent == nil {
|
|
204
|
+
return false
|
|
205
|
+
}
|
|
206
|
+
if parent.Kind != shimast.KindInterfaceDeclaration {
|
|
207
|
+
return false
|
|
208
|
+
}
|
|
209
|
+
iface := parent.AsInterfaceDeclaration()
|
|
210
|
+
if iface == nil {
|
|
211
|
+
return false
|
|
212
|
+
}
|
|
213
|
+
return identifierText(iface.Name()) == "Object"
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
func init() {
|
|
217
|
+
Register(noBaseToString{})
|
|
218
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// noConfusingVoidExpression reports `void X` operator uses placed in
|
|
2
|
+
// positions where the surrounding context expects a value. The `void`
|
|
3
|
+
// operator always evaluates to `undefined`, so threading it through a
|
|
4
|
+
// binary expression, ternary, call argument, initializer, or `return`
|
|
5
|
+
// statement is almost always a confusion between the operator and the
|
|
6
|
+
// `void` type.
|
|
7
|
+
//
|
|
8
|
+
// Allowed positions:
|
|
9
|
+
// - statement: `void x;`
|
|
10
|
+
// - arrow function concise body: `() => void x`
|
|
11
|
+
// - operand of an enclosing `void`: `void void x` — only the outer
|
|
12
|
+
// `void` is checked; the inner one is acceptable as the `void`
|
|
13
|
+
// operand of another `void`.
|
|
14
|
+
//
|
|
15
|
+
// This rule is AST-only — it does not consult the Checker for the
|
|
16
|
+
// surrounding function's return type, so `return void X` from a
|
|
17
|
+
// `void`-returning function is still reported. This matches the
|
|
18
|
+
// behavior the upstream rule produces with its
|
|
19
|
+
// `ignoreVoidReturningFunctions: false` default.
|
|
20
|
+
//
|
|
21
|
+
// https://typescript-eslint.io/rules/no-confusing-void-expression/
|
|
22
|
+
package linthost
|
|
23
|
+
|
|
24
|
+
import (
|
|
25
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
type noConfusingVoidExpression struct{}
|
|
29
|
+
|
|
30
|
+
func (noConfusingVoidExpression) Name() string {
|
|
31
|
+
return "typescript/no-confusing-void-expression"
|
|
32
|
+
}
|
|
33
|
+
func (noConfusingVoidExpression) Visits() []shimast.Kind {
|
|
34
|
+
return []shimast.Kind{shimast.KindVoidExpression}
|
|
35
|
+
}
|
|
36
|
+
func (noConfusingVoidExpression) Check(ctx *Context, node *shimast.Node) {
|
|
37
|
+
if isValidVoidExpressionPosition(node) {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
ctx.Report(node, "Placing `void` operator in a value position is confusing — use it only as a statement, an arrow concise body, or inside another `void`.")
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// isValidVoidExpressionPosition reports whether the `void X`
|
|
44
|
+
// expression at `node` sits in one of the three permitted positions.
|
|
45
|
+
// Parenthesized expressions are transparent — `(void x)` keeps the
|
|
46
|
+
// same effective context as `void x` for the surrounding code.
|
|
47
|
+
func isValidVoidExpressionPosition(node *shimast.Node) bool {
|
|
48
|
+
parent := node.Parent
|
|
49
|
+
for parent != nil && parent.Kind == shimast.KindParenthesizedExpression {
|
|
50
|
+
node = parent
|
|
51
|
+
parent = parent.Parent
|
|
52
|
+
}
|
|
53
|
+
if parent == nil {
|
|
54
|
+
return false
|
|
55
|
+
}
|
|
56
|
+
switch parent.Kind {
|
|
57
|
+
case shimast.KindExpressionStatement:
|
|
58
|
+
return true
|
|
59
|
+
case shimast.KindVoidExpression:
|
|
60
|
+
// `void void x` — the inner `void` is the operand of another
|
|
61
|
+
// `void`, which discards the result anyway.
|
|
62
|
+
return true
|
|
63
|
+
case shimast.KindArrowFunction:
|
|
64
|
+
arrow := parent.AsArrowFunction()
|
|
65
|
+
return arrow != nil && arrow.Body == node
|
|
66
|
+
}
|
|
67
|
+
return false
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func init() {
|
|
71
|
+
Register(noConfusingVoidExpression{})
|
|
72
|
+
}
|