@ttsc/lint 0.14.0-dev.20260529.2 → 0.14.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 +23 -25
- package/lib/defaultFormat.d.ts +10 -6
- package/lib/defaultFormat.js +10 -6
- package/lib/defaultFormat.js.map +1 -1
- package/lib/structures/ITtscLintConfig.d.ts +5 -5
- package/lib/structures/TtscLintRuleSetting.d.ts +19 -19
- package/lib/structures/{ITtscLintFormat.d.ts → format/ITtscLintFormat.d.ts} +45 -70
- package/lib/structures/format/ITtscLintFormat.js.map +1 -0
- package/lib/structures/format/ITtscLintFormatJsDoc.d.ts +15 -0
- package/lib/structures/format/ITtscLintFormatJsDoc.js +3 -0
- 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 +1 -1
- package/lib/structures/index.js +1 -1
- package/lib/structures/index.js.map +1 -1
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.d.ts +18 -27
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js +4 -5
- package/lib/structures/rules/ITtscLintBoundariesRuleOptions.js.map +1 -1
- package/lib/structures/rules/ITtscLintBoundariesRules.d.ts +29 -33
- package/lib/structures/rules/ITtscLintContributorRules.d.ts +6 -7
- package/lib/structures/rules/ITtscLintCoreRules.d.ts +380 -408
- package/lib/structures/rules/ITtscLintCypressRuleOptions.d.ts +5 -5
- package/lib/structures/rules/ITtscLintCypressRuleOptions.js +2 -2
- package/lib/structures/rules/ITtscLintCypressRules.d.ts +34 -38
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.d.ts +21 -24
- package/lib/structures/rules/ITtscLintFunctionalRuleOptions.js +2 -2
- package/lib/structures/rules/ITtscLintFunctionalRules.d.ts +51 -56
- package/lib/structures/rules/ITtscLintJestRules.d.ts +63 -74
- package/lib/structures/rules/ITtscLintJsdocRules.d.ts +47 -54
- package/lib/structures/rules/ITtscLintJsxA11yRules.d.ts +94 -102
- package/lib/structures/rules/ITtscLintNextjsRules.d.ts +50 -55
- package/lib/structures/rules/ITtscLintPlaywrightRules.d.ts +104 -122
- package/lib/structures/rules/ITtscLintPromiseRules.d.ts +62 -71
- package/lib/structures/rules/ITtscLintReactPerfRuleOptions.d.ts +4 -4
- package/lib/structures/rules/ITtscLintReactPerfRules.d.ts +17 -19
- package/lib/structures/rules/ITtscLintReactRuleOptions.d.ts +8 -10
- package/lib/structures/rules/ITtscLintReactRuleOptions.js +1 -2
- package/lib/structures/rules/ITtscLintReactRuleOptions.js.map +1 -1
- package/lib/structures/rules/ITtscLintReactRules.d.ts +91 -104
- package/lib/structures/rules/ITtscLintRegexpRules.d.ts +46 -54
- package/lib/structures/rules/ITtscLintRuleOptionsMap.d.ts +7 -8
- package/lib/structures/rules/ITtscLintSecurityRules.d.ts +45 -52
- package/lib/structures/rules/ITtscLintSolidRules.d.ts +53 -56
- package/lib/structures/rules/ITtscLintStorybookRuleOptions.d.ts +3 -4
- package/lib/structures/rules/ITtscLintStorybookRules.d.ts +60 -69
- package/lib/structures/rules/ITtscLintTanstackQueryRules.d.ts +31 -37
- package/lib/structures/rules/ITtscLintTestingLibraryRuleOptions.d.ts +2 -3
- package/lib/structures/rules/ITtscLintTestingLibraryRules.d.ts +102 -119
- package/lib/structures/rules/ITtscLintTypeScriptRules.d.ts +460 -518
- package/lib/structures/rules/ITtscLintVitestRules.d.ts +43 -51
- package/linthost/config.go +89 -72
- package/linthost/config_format.go +265 -99
- package/linthost/directives.go +5 -1
- package/linthost/display_width.go +72 -0
- package/linthost/fix.go +26 -1
- package/linthost/format.go +222 -25
- package/linthost/format_editor_settings.go +262 -0
- package/linthost/lsp.go +8 -4
- package/linthost/print_dispatch.go +3 -0
- package/linthost/print_doc.go +13 -0
- package/linthost/print_engine.go +68 -11
- package/linthost/print_nodes_array.go +167 -5
- package/linthost/print_nodes_call.go +786 -77
- package/linthost/print_nodes_function.go +43 -0
- package/linthost/print_nodes_imports.go +64 -14
- package/linthost/print_nodes_list.go +214 -8
- package/linthost/print_nodes_object.go +14 -6
- package/linthost/print_nodes_ternary.go +147 -0
- package/linthost/rules_boundaries.go +400 -400
- package/linthost/rules_camelcase.go +81 -81
- package/linthost/rules_complexity.go +52 -51
- package/linthost/rules_consistent_return.go +81 -81
- package/linthost/rules_core_extra.go +472 -472
- package/linthost/rules_curly.go +43 -43
- package/linthost/rules_default_case.go +15 -15
- package/linthost/rules_default_case_last.go +22 -22
- package/linthost/rules_format_arrow_parens.go +213 -0
- package/linthost/rules_format_bracket_spacing.go +117 -0
- package/linthost/rules_format_clause_join.go +179 -0
- package/linthost/rules_format_declaration_header.go +664 -0
- package/linthost/rules_format_indent.go +616 -0
- package/linthost/rules_format_jsdoc.go +4 -4
- 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 +180 -69
- package/linthost/rules_format_quote_props.go +169 -0
- package/linthost/rules_format_quotes.go +75 -29
- package/linthost/rules_format_semi.go +185 -10
- package/linthost/rules_format_sort_imports.go +517 -121
- package/linthost/rules_format_statement_split.go +368 -0
- package/linthost/rules_format_ternary_nullish_parens.go +77 -0
- package/linthost/rules_format_trailing_comma.go +21 -2
- package/linthost/rules_format_whitespace.go +336 -0
- package/linthost/rules_functional.go +688 -688
- package/linthost/rules_gap.go +146 -11
- package/linthost/rules_grouped_accessor_pairs.go +60 -60
- package/linthost/rules_guard_for_in.go +122 -122
- package/linthost/rules_id_length.go +44 -44
- package/linthost/rules_imports.go +11 -3
- package/linthost/rules_init_declarations.go +25 -25
- package/linthost/rules_jsx_a11y.go +844 -844
- package/linthost/rules_max_classes_per_file.go +24 -24
- package/linthost/rules_max_depth.go +43 -43
- package/linthost/rules_max_lines.go +53 -53
- package/linthost/rules_max_lines_per_function.go +28 -28
- package/linthost/rules_max_nested_callbacks.go +26 -26
- package/linthost/rules_max_params.go +20 -20
- package/linthost/rules_max_statements.go +29 -29
- package/linthost/rules_nextjs.go +5 -5
- package/linthost/rules_no_else_return.go +38 -38
- package/linthost/rules_no_empty_named_blocks.go +45 -45
- package/linthost/rules_no_import_assign.go +96 -96
- package/linthost/rules_no_invalid_this.go +19 -19
- package/linthost/rules_no_loop_func.go +43 -43
- package/linthost/rules_no_magic_numbers.go +60 -60
- package/linthost/rules_no_mixed_operators.go +44 -44
- package/linthost/rules_no_param_reassign.go +64 -64
- package/linthost/rules_no_restricted_imports.go +45 -45
- package/linthost/rules_no_restricted_syntax.go +17 -17
- package/linthost/rules_no_shadow.go +112 -112
- package/linthost/rules_no_unreachable.go +36 -36
- package/linthost/rules_no_useless_assignment.go +79 -79
- package/linthost/rules_no_useless_constructor.go +167 -167
- package/linthost/rules_no_useless_return.go +28 -28
- package/linthost/rules_prefer_arrow_callback.go +74 -74
- package/linthost/rules_prefer_destructuring.go +61 -61
- package/linthost/rules_prefer_named_capture_group.go +87 -87
- package/linthost/rules_prefer_rest_params.go +61 -61
- package/linthost/rules_promise.go +800 -800
- package/linthost/rules_react.go +600 -600
- package/linthost/rules_react_extras.go +162 -162
- package/linthost/rules_react_hooks.go +2 -2
- package/linthost/rules_react_perf.go +231 -231
- package/linthost/rules_regexp.go +293 -293
- package/linthost/rules_security.go +613 -613
- package/linthost/rules_sort_imports.go +37 -37
- package/linthost/rules_sort_keys.go +88 -88
- package/linthost/rules_suggestions.go +13 -0
- package/linthost/rules_ts.go +2 -2
- package/linthost/rules_ts_async.go +247 -247
- package/linthost/rules_ts_class_literal_property_style.go +64 -64
- package/linthost/rules_ts_consistent_type_exports.go +209 -209
- package/linthost/rules_ts_explicit_function_return_type.go +35 -35
- package/linthost/rules_ts_extra.go +6 -2
- package/linthost/rules_ts_no_base_to_string.go +140 -140
- package/linthost/rules_ts_no_confusing_void.go +28 -28
- package/linthost/rules_ts_no_deprecated.go +110 -110
- package/linthost/rules_ts_no_for_in_array.go +45 -45
- package/linthost/rules_ts_no_magic_numbers.go +67 -67
- package/linthost/rules_ts_no_meaningless_void_operator.go +44 -44
- package/linthost/rules_ts_no_misused_spread.go +64 -64
- package/linthost/rules_ts_no_redundant_type_constituents.go +72 -72
- package/linthost/rules_ts_no_restricted_types.go +28 -28
- package/linthost/rules_ts_no_unnecessary_boolean_literal_compare.go +87 -87
- package/linthost/rules_ts_no_unnecessary_condition.go +184 -184
- package/linthost/rules_ts_no_unnecessary_qualifier.go +72 -72
- package/linthost/rules_ts_no_unnecessary_template_expression.go +120 -120
- package/linthost/rules_ts_no_unnecessary_type_arguments.go +171 -171
- package/linthost/rules_ts_no_unnecessary_type_assertion.go +90 -90
- package/linthost/rules_ts_no_unsafe_argument.go +50 -50
- package/linthost/rules_ts_no_unsafe_assignment.go +60 -60
- package/linthost/rules_ts_no_unsafe_call.go +40 -40
- package/linthost/rules_ts_no_unsafe_enum_comparison.go +147 -147
- package/linthost/rules_ts_no_unsafe_member_access.go +29 -29
- package/linthost/rules_ts_no_unsafe_return.go +64 -64
- package/linthost/rules_ts_no_unsafe_unary_minus.go +42 -42
- package/linthost/rules_ts_no_useless_constructor.go +20 -20
- package/linthost/rules_ts_non_nullable_type_assertion_style.go +60 -60
- package/linthost/rules_ts_parameter_properties.go +10 -10
- package/linthost/rules_ts_prefer_find.go +116 -116
- package/linthost/rules_ts_prefer_includes.go +173 -173
- package/linthost/rules_ts_prefer_nullish_coalescing.go +54 -54
- package/linthost/rules_ts_prefer_optional_chain.go +156 -156
- package/linthost/rules_ts_prefer_promise_reject_errors.go +104 -104
- package/linthost/rules_ts_prefer_readonly.go +31 -31
- package/linthost/rules_ts_prefer_reduce_type_parameter.go +74 -74
- package/linthost/rules_ts_prefer_regexp_exec.go +69 -69
- package/linthost/rules_ts_prefer_return_this_type.go +79 -79
- package/linthost/rules_ts_prefer_string_starts_ends_with.go +237 -237
- package/linthost/rules_ts_promise_function_async.go +41 -41
- package/linthost/rules_ts_related_getter_setter_pairs.go +61 -61
- package/linthost/rules_ts_require_array_sort_compare.go +58 -58
- package/linthost/rules_ts_restrict_plus_operands.go +82 -82
- package/linthost/rules_ts_restrict_template_expressions.go +50 -50
- package/linthost/rules_ts_simple.go +249 -249
- package/linthost/rules_ts_sort_type_constituents.go +88 -88
- package/linthost/rules_ts_strict_boolean_expressions.go +103 -103
- package/linthost/rules_ts_switch_exhaustiveness_check.go +90 -90
- package/linthost/rules_ts_unbound_method.go +65 -65
- package/linthost/rules_tsdoc.go +88 -88
- package/linthost/rules_unicorn_better_regex.go +1 -1
- package/linthost/rules_unicorn_catch_error_name.go +19 -19
- package/linthost/rules_unicorn_consistent_assert.go +20 -20
- package/linthost/rules_unicorn_consistent_date_clone.go +27 -27
- package/linthost/rules_unicorn_consistent_destructuring.go +3 -3
- package/linthost/rules_unicorn_consistent_empty_array_spread.go +34 -34
- package/linthost/rules_unicorn_consistent_existence_index_check.go +42 -42
- package/linthost/rules_unicorn_consistent_function_scoping.go +3 -3
- package/linthost/rules_unicorn_consistent_template_literal_escape.go +3 -3
- package/linthost/rules_unicorn_custom_error_definition.go +92 -92
- package/linthost/rules_unicorn_empty_brace_spaces.go +47 -47
- package/linthost/rules_unicorn_error_message.go +34 -34
- package/linthost/rules_unicorn_escape_case.go +14 -14
- package/linthost/rules_unicorn_expiring_todo_comments.go +36 -36
- package/linthost/rules_unicorn_explicit_length_check.go +51 -51
- package/linthost/rules_unicorn_filename_case.go +1 -1
- package/linthost/rules_unicorn_import_style.go +1 -1
- package/linthost/rules_unicorn_isolated_functions.go +2 -2
- package/linthost/rules_unicorn_new_for_builtins.go +49 -49
- package/linthost/rules_unicorn_no_abusive_eslint_disable.go +31 -31
- package/linthost/rules_unicorn_no_accessor_recursion.go +69 -69
- package/linthost/rules_unicorn_no_anonymous_default_export.go +40 -40
- package/linthost/rules_unicorn_no_array_callback_reference.go +33 -33
- package/linthost/rules_unicorn_no_array_for_each.go +14 -14
- package/linthost/rules_unicorn_no_array_method_this_argument.go +29 -29
- package/linthost/rules_unicorn_no_array_reduce.go +15 -15
- package/linthost/rules_unicorn_no_array_reverse.go +17 -17
- package/linthost/rules_unicorn_no_array_sort.go +17 -17
- package/linthost/rules_unicorn_no_await_expression_member.go +12 -12
- package/linthost/rules_unicorn_no_await_in_promise_methods.go +38 -38
- package/linthost/rules_unicorn_no_console_spaces.go +30 -30
- package/linthost/rules_unicorn_no_document_cookie.go +13 -13
- package/linthost/rules_unicorn_no_empty_file.go +16 -16
- package/linthost/rules_unicorn_no_for_loop.go +58 -58
- package/linthost/rules_unicorn_no_hex_escape.go +11 -11
- package/linthost/rules_unicorn_no_immediate_mutation.go +55 -55
- package/linthost/rules_unicorn_no_instanceof_builtins.go +34 -34
- package/linthost/rules_unicorn_no_invalid_fetch_options.go +52 -52
- package/linthost/rules_unicorn_no_invalid_remove_event_listener.go +25 -25
- package/linthost/rules_unicorn_no_keyword_prefix.go +56 -56
- package/linthost/rules_unicorn_no_lonely_if.go +21 -21
- package/linthost/rules_unicorn_no_magic_array_flat_depth.go +22 -22
- package/linthost/rules_unicorn_no_named_default.go +25 -25
- package/linthost/rules_unicorn_no_negated_condition.go +54 -54
- package/linthost/rules_unicorn_no_negation_in_equality_check.go +23 -23
- package/linthost/rules_unicorn_no_nested_ternary.go +15 -15
- package/linthost/rules_unicorn_no_new_array.go +5 -5
- package/linthost/rules_unicorn_no_new_buffer.go +5 -5
- package/linthost/rules_unicorn_no_null.go +2 -2
- package/linthost/rules_unicorn_no_object_as_default_parameter.go +19 -19
- package/linthost/rules_unicorn_no_process_exit.go +17 -17
- package/linthost/rules_unicorn_no_single_promise_in_promise_methods.go +29 -29
- package/linthost/rules_unicorn_no_static_only_class.go +27 -27
- package/linthost/rules_unicorn_no_thenable.go +47 -47
- package/linthost/rules_unicorn_no_this_assignment.go +10 -10
- package/linthost/rules_unicorn_no_typeof_undefined.go +31 -31
- package/linthost/rules_unicorn_no_unnecessary_array_flat_depth.go +23 -23
- package/linthost/rules_unicorn_no_unnecessary_array_splice_count.go +37 -37
- package/linthost/rules_unicorn_no_unnecessary_await.go +24 -24
- package/linthost/rules_unicorn_no_unnecessary_slice_end.go +22 -22
- package/linthost/rules_unicorn_no_unreadable_array_destructuring.go +67 -67
- package/linthost/rules_unicorn_no_unreadable_iife.go +22 -22
- package/linthost/rules_unicorn_no_useless_collection_argument.go +34 -34
- package/linthost/rules_unicorn_no_useless_error_capture_stack_trace.go +18 -18
- package/linthost/rules_unicorn_no_useless_fallback_in_spread.go +49 -49
- package/linthost/rules_unicorn_no_useless_iterator_to_array.go +41 -41
- package/linthost/rules_unicorn_no_useless_length_check.go +82 -82
- package/linthost/rules_unicorn_no_useless_promise_resolve_reject.go +42 -42
- package/linthost/rules_unicorn_no_useless_spread.go +38 -38
- package/linthost/rules_unicorn_no_useless_switch_case.go +29 -29
- package/linthost/rules_unicorn_no_useless_undefined.go +25 -25
- package/linthost/rules_unicorn_no_zero_fractions.go +17 -17
- package/linthost/rules_unicorn_number_literal_case.go +33 -33
- package/linthost/rules_unicorn_numeric_separators_style.go +36 -36
- package/linthost/rules_unicorn_prefer_add_event_listener.go +30 -30
- package/linthost/rules_unicorn_prefer_array_find.go +27 -27
- package/linthost/rules_unicorn_prefer_array_flat.go +25 -25
- package/linthost/rules_unicorn_prefer_array_flat_map.go +37 -37
- package/linthost/rules_unicorn_prefer_array_index_of.go +108 -108
- package/linthost/rules_unicorn_prefer_array_some.go +43 -43
- package/linthost/rules_unicorn_prefer_at.go +42 -42
- package/linthost/rules_unicorn_prefer_bigint_literals.go +42 -42
- package/linthost/rules_unicorn_prefer_blob_reading_methods.go +15 -15
- package/linthost/rules_unicorn_prefer_class_fields.go +57 -57
- package/linthost/rules_unicorn_prefer_classlist_toggle.go +76 -76
- package/linthost/rules_unicorn_prefer_code_point.go +21 -21
- package/linthost/rules_unicorn_prefer_date_now.go +47 -47
- package/linthost/rules_unicorn_prefer_default_parameters.go +96 -96
- package/linthost/rules_unicorn_prefer_dom_node_append.go +14 -14
- package/linthost/rules_unicorn_prefer_dom_node_dataset.go +27 -27
- package/linthost/rules_unicorn_prefer_dom_node_remove.go +17 -17
- package/linthost/rules_unicorn_prefer_dom_node_text_content.go +11 -11
- package/linthost/rules_unicorn_prefer_event_target.go +10 -10
- package/linthost/rules_unicorn_prefer_export_from.go +99 -99
- package/linthost/rules_unicorn_prefer_global_this.go +91 -91
- package/linthost/rules_unicorn_prefer_import_meta_properties.go +38 -38
- package/linthost/rules_unicorn_prefer_includes.go +108 -108
- package/linthost/rules_unicorn_prefer_json_parse_buffer.go +37 -37
- package/linthost/rules_unicorn_prefer_keyboard_event_key.go +10 -10
- package/linthost/rules_unicorn_prefer_logical_operator_over_ternary.go +20 -20
- package/linthost/rules_unicorn_prefer_math_min_max.go +33 -33
- package/linthost/rules_unicorn_prefer_math_trunc.go +32 -32
- package/linthost/rules_unicorn_prefer_modern_dom_apis.go +18 -18
- package/linthost/rules_unicorn_prefer_modern_math_apis.go +38 -38
- package/linthost/rules_unicorn_prefer_module.go +22 -22
- package/linthost/rules_unicorn_prefer_native_coercion_functions.go +73 -73
- package/linthost/rules_unicorn_prefer_negative_index.go +46 -46
- package/linthost/rules_unicorn_prefer_node_protocol.go +90 -90
- package/linthost/rules_unicorn_prefer_number_properties.go +57 -57
- package/linthost/rules_unicorn_prefer_object_from_entries.go +26 -26
- package/linthost/rules_unicorn_prefer_optional_catch_binding.go +24 -24
- package/linthost/rules_unicorn_prefer_prototype_methods.go +25 -25
- package/linthost/rules_unicorn_prefer_query_selector.go +25 -25
- package/linthost/rules_unicorn_prefer_reflect_apply.go +10 -10
- package/linthost/rules_unicorn_prefer_regexp_test_rule.go +47 -47
- package/linthost/rules_unicorn_prefer_response_static_json.go +26 -26
- package/linthost/rules_unicorn_prefer_set_has.go +16 -16
- package/linthost/rules_unicorn_prefer_set_size.go +22 -22
- package/linthost/rules_unicorn_prefer_simple_condition_first.go +3 -3
- package/linthost/rules_unicorn_prefer_single_call.go +59 -59
- package/linthost/rules_unicorn_prefer_spread.go +24 -24
- package/linthost/rules_unicorn_prefer_string_raw.go +12 -12
- package/linthost/rules_unicorn_prefer_string_replace_all.go +46 -46
- package/linthost/rules_unicorn_prefer_string_slice.go +17 -17
- package/linthost/rules_unicorn_prefer_string_starts_ends_with.go +104 -104
- package/linthost/rules_unicorn_prefer_string_trim_start_end.go +21 -21
- package/linthost/rules_unicorn_prefer_structured_clone.go +36 -36
- package/linthost/rules_unicorn_prefer_switch.go +65 -65
- package/linthost/rules_unicorn_prefer_ternary.go +35 -35
- package/linthost/rules_unicorn_prefer_top_level_await.go +34 -34
- package/linthost/rules_unicorn_prefer_type_error.go +84 -84
- package/linthost/rules_unicorn_prevent_abbreviations.go +68 -68
- package/linthost/rules_unicorn_relative_url_style.go +19 -19
- package/linthost/rules_unicorn_require_array_join_separator.go +18 -18
- package/linthost/rules_unicorn_require_module_attributes.go +25 -25
- package/linthost/rules_unicorn_require_module_specifiers.go +28 -28
- package/linthost/rules_unicorn_require_number_to_fixed_digits_argument.go +18 -18
- package/linthost/rules_unicorn_require_post_message_target_origin.go +18 -18
- package/linthost/rules_unicorn_string_content.go +1 -1
- package/linthost/rules_unicorn_switch_case_braces.go +16 -16
- package/linthost/rules_unicorn_switch_case_break_position.go +3 -3
- package/linthost/rules_unicorn_template_indent.go +1 -1
- package/linthost/rules_unicorn_text_encoding_identifier_case.go +36 -36
- package/linthost/rules_unicorn_throw_new_error.go +30 -30
- package/linthost/rules_var.go +273 -3
- package/package.json +3 -3
- package/src/defaultFormat.ts +11 -7
- package/src/structures/ITtscLintConfig.ts +5 -5
- package/src/structures/TtscLintRuleSetting.ts +19 -19
- package/src/structures/{ITtscLintFormat.ts → format/ITtscLintFormat.ts} +48 -75
- package/src/structures/format/ITtscLintFormatJsDoc.ts +16 -0
- package/src/structures/format/ITtscLintFormatSortImports.ts +62 -0
- package/src/structures/format/index.ts +3 -0
- package/src/structures/index.ts +1 -1
- package/src/structures/rules/ITtscLintBoundariesRuleOptions.ts +20 -31
- package/src/structures/rules/ITtscLintBoundariesRules.ts +32 -36
- package/src/structures/rules/ITtscLintContributorRules.ts +6 -7
- package/src/structures/rules/ITtscLintCoreRules.ts +380 -408
- package/src/structures/rules/ITtscLintCypressRuleOptions.ts +5 -5
- package/src/structures/rules/ITtscLintCypressRules.ts +34 -38
- package/src/structures/rules/ITtscLintFunctionalRuleOptions.ts +28 -41
- package/src/structures/rules/ITtscLintFunctionalRules.ts +51 -56
- package/src/structures/rules/ITtscLintJestRules.ts +63 -74
- package/src/structures/rules/ITtscLintJsdocRules.ts +47 -54
- package/src/structures/rules/ITtscLintJsxA11yRules.ts +94 -102
- package/src/structures/rules/ITtscLintNextjsRules.ts +50 -55
- package/src/structures/rules/ITtscLintPlaywrightRules.ts +104 -122
- package/src/structures/rules/ITtscLintPromiseRules.ts +62 -71
- package/src/structures/rules/ITtscLintReactPerfRuleOptions.ts +4 -4
- package/src/structures/rules/ITtscLintReactPerfRules.ts +17 -19
- package/src/structures/rules/ITtscLintReactRuleOptions.ts +8 -10
- package/src/structures/rules/ITtscLintReactRules.ts +91 -104
- package/src/structures/rules/ITtscLintRegexpRules.ts +46 -54
- package/src/structures/rules/ITtscLintRuleOptionsMap.ts +7 -8
- package/src/structures/rules/ITtscLintSecurityRules.ts +45 -52
- package/src/structures/rules/ITtscLintSolidRules.ts +53 -56
- package/src/structures/rules/ITtscLintStorybookRuleOptions.ts +3 -4
- package/src/structures/rules/ITtscLintStorybookRules.ts +60 -69
- package/src/structures/rules/ITtscLintTanstackQueryRules.ts +31 -37
- package/src/structures/rules/ITtscLintTestingLibraryRuleOptions.ts +2 -3
- package/src/structures/rules/ITtscLintTestingLibraryRules.ts +102 -119
- package/src/structures/rules/ITtscLintTypeScriptRules.ts +460 -518
- package/src/structures/rules/ITtscLintVitestRules.ts +43 -51
- package/lib/structures/ITtscLintFormat.js.map +0 -1
- /package/lib/structures/{ITtscLintFormat.js → format/ITtscLintFormat.js} +0 -0
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
package linthost
|
|
12
12
|
|
|
13
13
|
import (
|
|
14
|
-
|
|
14
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
15
15
|
)
|
|
16
16
|
|
|
17
17
|
// noAwaitInLoop reports an `await` expression evaluated inside the body
|
|
@@ -28,30 +28,30 @@ type noAwaitInLoop struct{}
|
|
|
28
28
|
|
|
29
29
|
func (noAwaitInLoop) Name() string { return "no-await-in-loop" }
|
|
30
30
|
func (noAwaitInLoop) Visits() []shimast.Kind {
|
|
31
|
-
|
|
31
|
+
return []shimast.Kind{shimast.KindAwaitExpression}
|
|
32
32
|
}
|
|
33
33
|
func (noAwaitInLoop) Check(ctx *Context, node *shimast.Node) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
34
|
+
for cur := node.Parent; cur != nil; cur = cur.Parent {
|
|
35
|
+
if isFunctionLikeKind(cur) {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
switch cur.Kind {
|
|
39
|
+
case shimast.KindForStatement,
|
|
40
|
+
shimast.KindWhileStatement,
|
|
41
|
+
shimast.KindDoStatement,
|
|
42
|
+
shimast.KindForInStatement:
|
|
43
|
+
ctx.Report(node, "Unexpected `await` inside a loop — iterations run sequentially; prefer `Promise.all` when independent.")
|
|
44
|
+
return
|
|
45
|
+
case shimast.KindForOfStatement:
|
|
46
|
+
// `for await … of` loops are exempt by design — the await
|
|
47
|
+
// is the iteration itself, not a sequential block.
|
|
48
|
+
if isForAwaitOfStatement(ctx.File, cur) {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
ctx.Report(node, "Unexpected `await` inside a loop — iterations run sequentially; prefer `Promise.all` when independent.")
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
// isForAwaitOfStatement reports whether the for-of statement at `node`
|
|
@@ -61,28 +61,28 @@ func (noAwaitInLoop) Check(ctx *Context, node *shimast.Node) {
|
|
|
61
61
|
// in the small window before the opening parenthesis. The width 24
|
|
62
62
|
// covers any reasonable spacing/comment-free header.
|
|
63
63
|
func isForAwaitOfStatement(file *shimast.SourceFile, node *shimast.Node) bool {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
64
|
+
if file == nil || node == nil {
|
|
65
|
+
return false
|
|
66
|
+
}
|
|
67
|
+
forPos := keywordStart(file, node, "for")
|
|
68
|
+
if forPos < 0 {
|
|
69
|
+
return false
|
|
70
|
+
}
|
|
71
|
+
src := file.Text()
|
|
72
|
+
limit := forPos + 24
|
|
73
|
+
if limit > len(src) {
|
|
74
|
+
limit = len(src)
|
|
75
|
+
}
|
|
76
|
+
if node.End() < limit {
|
|
77
|
+
limit = node.End()
|
|
78
|
+
}
|
|
79
|
+
for i := forPos + 3; i < limit; i++ {
|
|
80
|
+
if src[i] == '(' {
|
|
81
|
+
limit = i
|
|
82
|
+
break
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return findKeyword(file, forPos+3, limit, "await") >= 0
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
// noDupeClassMembers reports two declarations of the same member on a
|
|
@@ -98,52 +98,52 @@ type noDupeClassMembers struct{}
|
|
|
98
98
|
|
|
99
99
|
func (noDupeClassMembers) Name() string { return "no-dupe-class-members" }
|
|
100
100
|
func (noDupeClassMembers) Visits() []shimast.Kind {
|
|
101
|
-
|
|
101
|
+
return []shimast.Kind{shimast.KindClassDeclaration, shimast.KindClassExpression}
|
|
102
102
|
}
|
|
103
103
|
func (noDupeClassMembers) Check(ctx *Context, node *shimast.Node) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
104
|
+
members := classMembers(node)
|
|
105
|
+
if len(members) == 0 {
|
|
106
|
+
return
|
|
107
|
+
}
|
|
108
|
+
type slot struct {
|
|
109
|
+
name string
|
|
110
|
+
static bool
|
|
111
|
+
kind string
|
|
112
|
+
}
|
|
113
|
+
seen := map[slot]*shimast.Node{}
|
|
114
|
+
for _, member := range members {
|
|
115
|
+
if member == nil {
|
|
116
|
+
continue
|
|
117
|
+
}
|
|
118
|
+
name, kind, ok := classMemberSlot(member)
|
|
119
|
+
if !ok {
|
|
120
|
+
continue
|
|
121
|
+
}
|
|
122
|
+
key := slot{name: name, static: hasModifier(member, shimast.KindStaticKeyword), kind: kind}
|
|
123
|
+
if prior, exists := seen[key]; exists {
|
|
124
|
+
_ = prior
|
|
125
|
+
ctx.Report(member, "Duplicate class member `"+name+"`.")
|
|
126
|
+
continue
|
|
127
|
+
}
|
|
128
|
+
seen[key] = member
|
|
129
|
+
}
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
// classMembers returns the member list of a class declaration or
|
|
133
133
|
// expression. Returns nil for any other kind so the helper is safe to
|
|
134
134
|
// call from a multi-visit rule.
|
|
135
135
|
func classMembers(node *shimast.Node) []*shimast.Node {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
136
|
+
switch node.Kind {
|
|
137
|
+
case shimast.KindClassDeclaration:
|
|
138
|
+
if decl := node.AsClassDeclaration(); decl != nil && decl.Members != nil {
|
|
139
|
+
return decl.Members.Nodes
|
|
140
|
+
}
|
|
141
|
+
case shimast.KindClassExpression:
|
|
142
|
+
if expr := node.AsClassExpression(); expr != nil && expr.Members != nil {
|
|
143
|
+
return expr.Members.Nodes
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return nil
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
// classMemberSlot extracts the (name, kind) identity for a class
|
|
@@ -152,30 +152,30 @@ func classMembers(node *shimast.Node) []*shimast.Node {
|
|
|
152
152
|
// getter/setter pairs from regular method/property declarations so a
|
|
153
153
|
// getter+setter on the same name does not trip the dupe check.
|
|
154
154
|
func classMemberSlot(member *shimast.Node) (string, string, bool) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
155
|
+
if member == nil {
|
|
156
|
+
return "", "", false
|
|
157
|
+
}
|
|
158
|
+
switch member.Kind {
|
|
159
|
+
case shimast.KindMethodDeclaration,
|
|
160
|
+
shimast.KindPropertyDeclaration,
|
|
161
|
+
shimast.KindGetAccessor,
|
|
162
|
+
shimast.KindSetAccessor:
|
|
163
|
+
name := classMemberName(member)
|
|
164
|
+
if name == "" {
|
|
165
|
+
return "", "", false
|
|
166
|
+
}
|
|
167
|
+
var kind string
|
|
168
|
+
switch member.Kind {
|
|
169
|
+
case shimast.KindGetAccessor:
|
|
170
|
+
kind = "get"
|
|
171
|
+
case shimast.KindSetAccessor:
|
|
172
|
+
kind = "set"
|
|
173
|
+
default:
|
|
174
|
+
kind = "data"
|
|
175
|
+
}
|
|
176
|
+
return name, kind, true
|
|
177
|
+
}
|
|
178
|
+
return "", "", false
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
// classMemberName returns the textual name of a class member identifier
|
|
@@ -183,19 +183,19 @@ func classMemberSlot(member *shimast.Node) (string, string, bool) {
|
|
|
183
183
|
// the caller can skip them — the rule cannot prove equivalence of two
|
|
184
184
|
// computed expressions statically.
|
|
185
185
|
func classMemberName(member *shimast.Node) string {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
186
|
+
name := member.Name()
|
|
187
|
+
if name == nil {
|
|
188
|
+
return ""
|
|
189
|
+
}
|
|
190
|
+
switch name.Kind {
|
|
191
|
+
case shimast.KindIdentifier, shimast.KindPrivateIdentifier:
|
|
192
|
+
return identifierText(name)
|
|
193
|
+
case shimast.KindStringLiteral:
|
|
194
|
+
return stringLiteralText(name)
|
|
195
|
+
case shimast.KindNumericLiteral:
|
|
196
|
+
return numericLiteralText(name)
|
|
197
|
+
}
|
|
198
|
+
return ""
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
// noThisBeforeSuper reports a derived constructor that references
|
|
@@ -213,114 +213,114 @@ type noThisBeforeSuper struct{}
|
|
|
213
213
|
|
|
214
214
|
func (noThisBeforeSuper) Name() string { return "no-this-before-super" }
|
|
215
215
|
func (noThisBeforeSuper) Visits() []shimast.Kind {
|
|
216
|
-
|
|
216
|
+
return []shimast.Kind{shimast.KindConstructor}
|
|
217
217
|
}
|
|
218
218
|
func (noThisBeforeSuper) Check(ctx *Context, node *shimast.Node) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
219
|
+
parent := node.Parent
|
|
220
|
+
if parent == nil || !classExtendsAnother(parent) {
|
|
221
|
+
return
|
|
222
|
+
}
|
|
223
|
+
ctor := node.AsConstructorDeclaration()
|
|
224
|
+
if ctor == nil || ctor.Body == nil {
|
|
225
|
+
return
|
|
226
|
+
}
|
|
227
|
+
var superCallPos = -1
|
|
228
|
+
walkConstructorBody(ctor.Body, func(child *shimast.Node) {
|
|
229
|
+
if child == nil || superCallPos >= 0 {
|
|
230
|
+
return
|
|
231
|
+
}
|
|
232
|
+
if child.Kind == shimast.KindCallExpression {
|
|
233
|
+
call := child.AsCallExpression()
|
|
234
|
+
if call != nil && call.Expression != nil && call.Expression.Kind == shimast.KindSuperKeyword {
|
|
235
|
+
superCallPos = child.Pos()
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
})
|
|
239
|
+
walkConstructorBody(ctor.Body, func(child *shimast.Node) {
|
|
240
|
+
if child == nil {
|
|
241
|
+
return
|
|
242
|
+
}
|
|
243
|
+
// Skip the call to super() itself.
|
|
244
|
+
if child.Kind == shimast.KindCallExpression {
|
|
245
|
+
call := child.AsCallExpression()
|
|
246
|
+
if call != nil && call.Expression != nil && call.Expression.Kind == shimast.KindSuperKeyword {
|
|
247
|
+
return
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
switch child.Kind {
|
|
251
|
+
case shimast.KindThisKeyword:
|
|
252
|
+
if superCallPos < 0 || child.Pos() < superCallPos {
|
|
253
|
+
ctx.Report(child, "`this` referenced before `super()` call in a derived constructor.")
|
|
254
|
+
}
|
|
255
|
+
case shimast.KindPropertyAccessExpression:
|
|
256
|
+
access := child.AsPropertyAccessExpression()
|
|
257
|
+
if access != nil && access.Expression != nil && access.Expression.Kind == shimast.KindSuperKeyword {
|
|
258
|
+
if superCallPos < 0 || child.Pos() < superCallPos {
|
|
259
|
+
ctx.Report(child, "`super.` access before `super()` call in a derived constructor.")
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
})
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
// classExtendsAnother reports whether the class declaration/expression
|
|
267
267
|
// has a non-empty `extends` heritage clause. Base classes (no extends)
|
|
268
268
|
// are skipped — `this` is legal before any super call there.
|
|
269
269
|
func classExtendsAnother(class *shimast.Node) bool {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
270
|
+
var clauses []*shimast.Node
|
|
271
|
+
switch class.Kind {
|
|
272
|
+
case shimast.KindClassDeclaration:
|
|
273
|
+
decl := class.AsClassDeclaration()
|
|
274
|
+
if decl == nil || decl.HeritageClauses == nil {
|
|
275
|
+
return false
|
|
276
|
+
}
|
|
277
|
+
clauses = decl.HeritageClauses.Nodes
|
|
278
|
+
case shimast.KindClassExpression:
|
|
279
|
+
expr := class.AsClassExpression()
|
|
280
|
+
if expr == nil || expr.HeritageClauses == nil {
|
|
281
|
+
return false
|
|
282
|
+
}
|
|
283
|
+
clauses = expr.HeritageClauses.Nodes
|
|
284
|
+
default:
|
|
285
|
+
return false
|
|
286
|
+
}
|
|
287
|
+
for _, clause := range clauses {
|
|
288
|
+
if clause == nil {
|
|
289
|
+
continue
|
|
290
|
+
}
|
|
291
|
+
hc := clause.AsHeritageClause()
|
|
292
|
+
if hc == nil || hc.Token != shimast.KindExtendsKeyword {
|
|
293
|
+
continue
|
|
294
|
+
}
|
|
295
|
+
if hc.Types != nil && len(hc.Types.Nodes) > 0 {
|
|
296
|
+
return true
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return false
|
|
300
300
|
}
|
|
301
301
|
|
|
302
302
|
// walkConstructorBody walks every descendant of body, skipping into
|
|
303
303
|
// nested function-like scopes so a `this` inside an inner arrow does
|
|
304
304
|
// not get attributed to the surrounding constructor.
|
|
305
305
|
func walkConstructorBody(body *shimast.Node, visit func(*shimast.Node)) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
306
|
+
if body == nil {
|
|
307
|
+
return
|
|
308
|
+
}
|
|
309
|
+
var walk func(*shimast.Node)
|
|
310
|
+
walk = func(n *shimast.Node) {
|
|
311
|
+
if n == nil {
|
|
312
|
+
return
|
|
313
|
+
}
|
|
314
|
+
if n != body && isFunctionLikeKind(n) {
|
|
315
|
+
return
|
|
316
|
+
}
|
|
317
|
+
visit(n)
|
|
318
|
+
n.ForEachChild(func(child *shimast.Node) bool {
|
|
319
|
+
walk(child)
|
|
320
|
+
return false
|
|
321
|
+
})
|
|
322
|
+
}
|
|
323
|
+
walk(body)
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
// preferObjectSpread reports `Object.assign({}, …)` calls that should
|
|
@@ -338,43 +338,43 @@ type preferObjectSpread struct{}
|
|
|
338
338
|
|
|
339
339
|
func (preferObjectSpread) Name() string { return "prefer-object-spread" }
|
|
340
340
|
func (preferObjectSpread) Visits() []shimast.Kind {
|
|
341
|
-
|
|
341
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
342
342
|
}
|
|
343
343
|
func (preferObjectSpread) Check(ctx *Context, node *shimast.Node) {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
344
|
+
call := node.AsCallExpression()
|
|
345
|
+
if call == nil || call.Expression == nil || call.Arguments == nil {
|
|
346
|
+
return
|
|
347
|
+
}
|
|
348
|
+
obj, method, ok := promisePropertyAccessParts(call.Expression)
|
|
349
|
+
if !ok || method != "assign" {
|
|
350
|
+
return
|
|
351
|
+
}
|
|
352
|
+
if identifierText(obj) != "Object" {
|
|
353
|
+
return
|
|
354
|
+
}
|
|
355
|
+
if len(call.Arguments.Nodes) < 2 {
|
|
356
|
+
return
|
|
357
|
+
}
|
|
358
|
+
first := stripParens(call.Arguments.Nodes[0])
|
|
359
|
+
if first == nil || first.Kind != shimast.KindObjectLiteralExpression {
|
|
360
|
+
return
|
|
361
|
+
}
|
|
362
|
+
if objectLiteralIsEmpty(first) {
|
|
363
|
+
ctx.Report(node, "Prefer object spread `{ ...a, ...b }` over `Object.assign({}, a, b)`.")
|
|
364
|
+
}
|
|
365
365
|
}
|
|
366
366
|
|
|
367
367
|
// objectLiteralIsEmpty reports whether node is the literal `{}` (no
|
|
368
368
|
// properties, no shorthand assignments, no spreads).
|
|
369
369
|
func objectLiteralIsEmpty(node *shimast.Node) bool {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
370
|
+
if node == nil || node.Kind != shimast.KindObjectLiteralExpression {
|
|
371
|
+
return false
|
|
372
|
+
}
|
|
373
|
+
lit := node.AsObjectLiteralExpression()
|
|
374
|
+
if lit == nil || lit.Properties == nil {
|
|
375
|
+
return true
|
|
376
|
+
}
|
|
377
|
+
return len(lit.Properties.Nodes) == 0
|
|
378
378
|
}
|
|
379
379
|
|
|
380
380
|
// noDuplicateImports reports two import declarations that resolve to
|
|
@@ -391,29 +391,29 @@ type noDuplicateImports struct{}
|
|
|
391
391
|
|
|
392
392
|
func (noDuplicateImports) Name() string { return "no-duplicate-imports" }
|
|
393
393
|
func (noDuplicateImports) Visits() []shimast.Kind {
|
|
394
|
-
|
|
394
|
+
return []shimast.Kind{shimast.KindSourceFile}
|
|
395
395
|
}
|
|
396
396
|
func (noDuplicateImports) Check(ctx *Context, node *shimast.Node) {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
397
|
+
seen := map[string]bool{}
|
|
398
|
+
node.ForEachChild(func(child *shimast.Node) bool {
|
|
399
|
+
if child == nil || child.Kind != shimast.KindImportDeclaration {
|
|
400
|
+
return false
|
|
401
|
+
}
|
|
402
|
+
decl := child.AsImportDeclaration()
|
|
403
|
+
if decl == nil || decl.ModuleSpecifier == nil {
|
|
404
|
+
return false
|
|
405
|
+
}
|
|
406
|
+
spec := stringLiteralText(decl.ModuleSpecifier)
|
|
407
|
+
if spec == "" {
|
|
408
|
+
return false
|
|
409
|
+
}
|
|
410
|
+
if seen[spec] {
|
|
411
|
+
ctx.Report(child, "Module `"+spec+"` is already imported above; consolidate the imports.")
|
|
412
|
+
return false
|
|
413
|
+
}
|
|
414
|
+
seen[spec] = true
|
|
415
|
+
return false
|
|
416
|
+
})
|
|
417
417
|
}
|
|
418
418
|
|
|
419
419
|
// getterReturn reports a `get` accessor whose body completes without
|
|
@@ -425,16 +425,16 @@ type getterReturn struct{}
|
|
|
425
425
|
|
|
426
426
|
func (getterReturn) Name() string { return "getter-return" }
|
|
427
427
|
func (getterReturn) Visits() []shimast.Kind {
|
|
428
|
-
|
|
428
|
+
return []shimast.Kind{shimast.KindGetAccessor}
|
|
429
429
|
}
|
|
430
430
|
func (getterReturn) Check(ctx *Context, node *shimast.Node) {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
431
|
+
accessor := node.AsGetAccessorDeclaration()
|
|
432
|
+
if accessor == nil || accessor.Body == nil {
|
|
433
|
+
return
|
|
434
|
+
}
|
|
435
|
+
if !getterBodyAlwaysReturns(accessor.Body) {
|
|
436
|
+
ctx.Report(node, "Getter must return a value.")
|
|
437
|
+
}
|
|
438
438
|
}
|
|
439
439
|
|
|
440
440
|
// getterBodyAlwaysReturns walks a `get` accessor body and reports
|
|
@@ -442,44 +442,44 @@ func (getterReturn) Check(ctx *Context, node *shimast.Node) {
|
|
|
442
442
|
// shallow approximation — sufficient for the common case where the
|
|
443
443
|
// getter's body is a sequence of statements ending in `return X`.
|
|
444
444
|
func getterBodyAlwaysReturns(body *shimast.Node) bool {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
445
|
+
if body == nil || body.Kind != shimast.KindBlock {
|
|
446
|
+
return false
|
|
447
|
+
}
|
|
448
|
+
statements := body.Statements()
|
|
449
|
+
if len(statements) == 0 {
|
|
450
|
+
return false
|
|
451
|
+
}
|
|
452
|
+
last := statements[len(statements)-1]
|
|
453
|
+
return statementReturnsValue(last)
|
|
454
454
|
}
|
|
455
455
|
|
|
456
456
|
// statementReturnsValue checks if a statement is a value-returning
|
|
457
457
|
// `return X;`, a `throw`, a block that ends in one of those, or a
|
|
458
458
|
// conditional whose every branch returns a value.
|
|
459
459
|
func statementReturnsValue(stmt *shimast.Node) bool {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
460
|
+
if stmt == nil {
|
|
461
|
+
return false
|
|
462
|
+
}
|
|
463
|
+
switch stmt.Kind {
|
|
464
|
+
case shimast.KindReturnStatement:
|
|
465
|
+
ret := stmt.AsReturnStatement()
|
|
466
|
+
return ret != nil && ret.Expression != nil
|
|
467
|
+
case shimast.KindThrowStatement:
|
|
468
|
+
return true
|
|
469
|
+
case shimast.KindBlock:
|
|
470
|
+
stmts := stmt.Statements()
|
|
471
|
+
if len(stmts) == 0 {
|
|
472
|
+
return false
|
|
473
|
+
}
|
|
474
|
+
return statementReturnsValue(stmts[len(stmts)-1])
|
|
475
|
+
case shimast.KindIfStatement:
|
|
476
|
+
ifStmt := stmt.AsIfStatement()
|
|
477
|
+
if ifStmt == nil || ifStmt.ThenStatement == nil || ifStmt.ElseStatement == nil {
|
|
478
|
+
return false
|
|
479
|
+
}
|
|
480
|
+
return statementReturnsValue(ifStmt.ThenStatement) && statementReturnsValue(ifStmt.ElseStatement)
|
|
481
|
+
}
|
|
482
|
+
return false
|
|
483
483
|
}
|
|
484
484
|
|
|
485
485
|
// noNewSymbol reports `new Symbol(...)`. `Symbol` is a function but not
|
|
@@ -492,16 +492,16 @@ type noNewSymbol struct{}
|
|
|
492
492
|
|
|
493
493
|
func (noNewSymbol) Name() string { return "no-new-symbol" }
|
|
494
494
|
func (noNewSymbol) Visits() []shimast.Kind {
|
|
495
|
-
|
|
495
|
+
return []shimast.Kind{shimast.KindNewExpression}
|
|
496
496
|
}
|
|
497
497
|
func (noNewSymbol) Check(ctx *Context, node *shimast.Node) {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
498
|
+
ne := node.AsNewExpression()
|
|
499
|
+
if ne == nil {
|
|
500
|
+
return
|
|
501
|
+
}
|
|
502
|
+
if identifierText(ne.Expression) == "Symbol" {
|
|
503
|
+
ctx.Report(node, "`Symbol` cannot be called with `new`.")
|
|
504
|
+
}
|
|
505
505
|
}
|
|
506
506
|
|
|
507
507
|
// noConstructorReturn reports a constructor body that contains a
|
|
@@ -514,22 +514,22 @@ type noConstructorReturn struct{}
|
|
|
514
514
|
|
|
515
515
|
func (noConstructorReturn) Name() string { return "no-constructor-return" }
|
|
516
516
|
func (noConstructorReturn) Visits() []shimast.Kind {
|
|
517
|
-
|
|
517
|
+
return []shimast.Kind{shimast.KindConstructor}
|
|
518
518
|
}
|
|
519
519
|
func (noConstructorReturn) Check(ctx *Context, node *shimast.Node) {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
520
|
+
ctor := node.AsConstructorDeclaration()
|
|
521
|
+
if ctor == nil || ctor.Body == nil {
|
|
522
|
+
return
|
|
523
|
+
}
|
|
524
|
+
walkConstructorBody(ctor.Body, func(child *shimast.Node) {
|
|
525
|
+
if child == nil || child.Kind != shimast.KindReturnStatement {
|
|
526
|
+
return
|
|
527
|
+
}
|
|
528
|
+
ret := child.AsReturnStatement()
|
|
529
|
+
if ret != nil && ret.Expression != nil {
|
|
530
|
+
ctx.Report(child, "Class constructors should not return a value.")
|
|
531
|
+
}
|
|
532
|
+
})
|
|
533
533
|
}
|
|
534
534
|
|
|
535
535
|
// noUnsafeOptionalChaining reports member access or call expressions
|
|
@@ -543,47 +543,47 @@ type noUnsafeOptionalChaining struct{}
|
|
|
543
543
|
|
|
544
544
|
func (noUnsafeOptionalChaining) Name() string { return "no-unsafe-optional-chaining" }
|
|
545
545
|
func (noUnsafeOptionalChaining) Visits() []shimast.Kind {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
546
|
+
return []shimast.Kind{
|
|
547
|
+
shimast.KindPropertyAccessExpression,
|
|
548
|
+
shimast.KindElementAccessExpression,
|
|
549
|
+
shimast.KindCallExpression,
|
|
550
|
+
}
|
|
551
551
|
}
|
|
552
552
|
func (noUnsafeOptionalChaining) Check(ctx *Context, node *shimast.Node) {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
553
|
+
var receiver *shimast.Node
|
|
554
|
+
switch node.Kind {
|
|
555
|
+
case shimast.KindPropertyAccessExpression:
|
|
556
|
+
access := node.AsPropertyAccessExpression()
|
|
557
|
+
if access == nil {
|
|
558
|
+
return
|
|
559
|
+
}
|
|
560
|
+
// If this access is itself optional, the chain continues — safe.
|
|
561
|
+
if access.QuestionDotToken != nil {
|
|
562
|
+
return
|
|
563
|
+
}
|
|
564
|
+
receiver = access.Expression
|
|
565
|
+
case shimast.KindElementAccessExpression:
|
|
566
|
+
access := node.AsElementAccessExpression()
|
|
567
|
+
if access == nil {
|
|
568
|
+
return
|
|
569
|
+
}
|
|
570
|
+
if access.QuestionDotToken != nil {
|
|
571
|
+
return
|
|
572
|
+
}
|
|
573
|
+
receiver = access.Expression
|
|
574
|
+
case shimast.KindCallExpression:
|
|
575
|
+
call := node.AsCallExpression()
|
|
576
|
+
if call == nil {
|
|
577
|
+
return
|
|
578
|
+
}
|
|
579
|
+
if call.QuestionDotToken != nil {
|
|
580
|
+
return
|
|
581
|
+
}
|
|
582
|
+
receiver = call.Expression
|
|
583
|
+
}
|
|
584
|
+
if receiverEndsWithOptionalChain(receiver) {
|
|
585
|
+
ctx.Report(node, "Unsafe access after an optional chain — continue the chain with `?.` or check for nullish above.")
|
|
586
|
+
}
|
|
587
587
|
}
|
|
588
588
|
|
|
589
589
|
// receiverEndsWithOptionalChain reports whether the receiver expression
|
|
@@ -594,27 +594,27 @@ func (noUnsafeOptionalChaining) Check(ctx *Context, node *shimast.Node) {
|
|
|
594
594
|
// at runtime the chain still resolves to undefined when the optional
|
|
595
595
|
// link short-circuits, so we look through `NonNullExpression` too.
|
|
596
596
|
func receiverEndsWithOptionalChain(node *shimast.Node) bool {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
597
|
+
node = stripParens(node)
|
|
598
|
+
if node == nil {
|
|
599
|
+
return false
|
|
600
|
+
}
|
|
601
|
+
if node.Kind == shimast.KindNonNullExpression {
|
|
602
|
+
if nn := node.AsNonNullExpression(); nn != nil {
|
|
603
|
+
return receiverEndsWithOptionalChain(nn.Expression)
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
switch node.Kind {
|
|
607
|
+
case shimast.KindPropertyAccessExpression:
|
|
608
|
+
access := node.AsPropertyAccessExpression()
|
|
609
|
+
return access != nil && access.QuestionDotToken != nil
|
|
610
|
+
case shimast.KindElementAccessExpression:
|
|
611
|
+
access := node.AsElementAccessExpression()
|
|
612
|
+
return access != nil && access.QuestionDotToken != nil
|
|
613
|
+
case shimast.KindCallExpression:
|
|
614
|
+
call := node.AsCallExpression()
|
|
615
|
+
return call != nil && call.QuestionDotToken != nil
|
|
616
|
+
}
|
|
617
|
+
return false
|
|
618
618
|
}
|
|
619
619
|
|
|
620
620
|
// preferObjectHasOwn reports calls of the form
|
|
@@ -628,30 +628,30 @@ type preferObjectHasOwn struct{}
|
|
|
628
628
|
|
|
629
629
|
func (preferObjectHasOwn) Name() string { return "prefer-object-has-own" }
|
|
630
630
|
func (preferObjectHasOwn) Visits() []shimast.Kind {
|
|
631
|
-
|
|
631
|
+
return []shimast.Kind{shimast.KindCallExpression}
|
|
632
632
|
}
|
|
633
633
|
func (preferObjectHasOwn) Check(ctx *Context, node *shimast.Node) {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
634
|
+
call := node.AsCallExpression()
|
|
635
|
+
if call == nil || call.Expression == nil {
|
|
636
|
+
return
|
|
637
|
+
}
|
|
638
|
+
// Pattern: Object.prototype.hasOwnProperty.call(obj, key)
|
|
639
|
+
outer, method, ok := promisePropertyAccessParts(call.Expression)
|
|
640
|
+
if !ok || method != "call" {
|
|
641
|
+
return
|
|
642
|
+
}
|
|
643
|
+
inner, name, ok := promisePropertyAccessParts(outer)
|
|
644
|
+
if !ok || name != "hasOwnProperty" {
|
|
645
|
+
return
|
|
646
|
+
}
|
|
647
|
+
base, prop, ok := promisePropertyAccessParts(inner)
|
|
648
|
+
if !ok || prop != "prototype" {
|
|
649
|
+
return
|
|
650
|
+
}
|
|
651
|
+
if identifierText(base) != "Object" {
|
|
652
|
+
return
|
|
653
|
+
}
|
|
654
|
+
ctx.Report(node, "Prefer `Object.hasOwn(obj, key)` over `Object.prototype.hasOwnProperty.call(obj, key)`.")
|
|
655
655
|
}
|
|
656
656
|
|
|
657
657
|
// noImplicitCoercion reports the most common implicit coercion idioms:
|
|
@@ -664,76 +664,76 @@ type noImplicitCoercion struct{}
|
|
|
664
664
|
|
|
665
665
|
func (noImplicitCoercion) Name() string { return "no-implicit-coercion" }
|
|
666
666
|
func (noImplicitCoercion) Visits() []shimast.Kind {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
667
|
+
return []shimast.Kind{
|
|
668
|
+
shimast.KindPrefixUnaryExpression,
|
|
669
|
+
shimast.KindBinaryExpression,
|
|
670
|
+
}
|
|
671
671
|
}
|
|
672
672
|
func (noImplicitCoercion) Check(ctx *Context, node *shimast.Node) {
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
673
|
+
switch node.Kind {
|
|
674
|
+
case shimast.KindPrefixUnaryExpression:
|
|
675
|
+
prefix := node.AsPrefixUnaryExpression()
|
|
676
|
+
if prefix == nil || prefix.Operand == nil {
|
|
677
|
+
return
|
|
678
|
+
}
|
|
679
|
+
switch prefix.Operator {
|
|
680
|
+
case shimast.KindExclamationToken:
|
|
681
|
+
// `!!x` → Boolean(x). The inner expression must be another `!`.
|
|
682
|
+
inner := stripParens(prefix.Operand)
|
|
683
|
+
if inner == nil || inner.Kind != shimast.KindPrefixUnaryExpression {
|
|
684
|
+
return
|
|
685
|
+
}
|
|
686
|
+
innerPrefix := inner.AsPrefixUnaryExpression()
|
|
687
|
+
if innerPrefix != nil && innerPrefix.Operator == shimast.KindExclamationToken {
|
|
688
|
+
ctx.Report(node, "Prefer `Boolean(x)` over `!!x` for explicit boolean coercion.")
|
|
689
|
+
}
|
|
690
|
+
case shimast.KindPlusToken:
|
|
691
|
+
// `+x` where x is not a numeric literal → Number(x). Skip
|
|
692
|
+
// numeric literals because `+0` / `+1` are the canonical form
|
|
693
|
+
// for explicit positive numbers.
|
|
694
|
+
operand := stripParens(prefix.Operand)
|
|
695
|
+
if operand == nil || operand.Kind == shimast.KindNumericLiteral {
|
|
696
|
+
return
|
|
697
|
+
}
|
|
698
|
+
ctx.Report(node, "Prefer `Number(x)` over `+x` for explicit number coercion.")
|
|
699
|
+
}
|
|
700
|
+
case shimast.KindBinaryExpression:
|
|
701
|
+
bin := node.AsBinaryExpression()
|
|
702
|
+
if bin == nil || bin.OperatorToken == nil || bin.OperatorToken.Kind != shimast.KindPlusToken {
|
|
703
|
+
return
|
|
704
|
+
}
|
|
705
|
+
// `"" + x` or `x + ""` → String(x).
|
|
706
|
+
left := stripParens(bin.Left)
|
|
707
|
+
right := stripParens(bin.Right)
|
|
708
|
+
if isEmptyStringLiteral(left) && right != nil && !isEmptyStringLiteral(right) {
|
|
709
|
+
ctx.Report(node, "Prefer `String(x)` over `\"\" + x` for explicit string coercion.")
|
|
710
|
+
return
|
|
711
|
+
}
|
|
712
|
+
if isEmptyStringLiteral(right) && left != nil && !isEmptyStringLiteral(left) {
|
|
713
|
+
ctx.Report(node, "Prefer `String(x)` over `x + \"\"` for explicit string coercion.")
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
716
|
}
|
|
717
717
|
|
|
718
718
|
// isEmptyStringLiteral reports whether node is the literal `""` or
|
|
719
|
-
//
|
|
719
|
+
// `”` (an empty-string string literal).
|
|
720
720
|
func isEmptyStringLiteral(node *shimast.Node) bool {
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
721
|
+
if node == nil || node.Kind != shimast.KindStringLiteral {
|
|
722
|
+
return false
|
|
723
|
+
}
|
|
724
|
+
return stringLiteralText(node) == ""
|
|
725
725
|
}
|
|
726
726
|
|
|
727
727
|
func init() {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
728
|
+
Register(noAwaitInLoop{})
|
|
729
|
+
Register(noConstructorReturn{})
|
|
730
|
+
Register(noDupeClassMembers{})
|
|
731
|
+
Register(noDuplicateImports{})
|
|
732
|
+
Register(noImplicitCoercion{})
|
|
733
|
+
Register(noNewSymbol{})
|
|
734
|
+
Register(noThisBeforeSuper{})
|
|
735
|
+
Register(noUnsafeOptionalChaining{})
|
|
736
|
+
Register(getterReturn{})
|
|
737
|
+
Register(preferObjectHasOwn{})
|
|
738
|
+
Register(preferObjectSpread{})
|
|
739
739
|
}
|