From c778cba9d5e828b7d021fe32297e798954e35575 Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Mon, 22 Sep 2025 14:04:26 +0000 Subject: [PATCH] chore(rust): MSRV 1.88.0 (#13977) This broke the linter ast nodes detector --- Cargo.toml | 2 +- apps/oxfmt/src/walk.rs | 21 +- crates/oxc_allocator/src/vec2/raw_vec.rs | 8 +- crates/oxc_ast/src/ast_impl/js.rs | 16 +- crates/oxc_ast/src/ast_impl/literal.rs | 8 +- crates/oxc_ast/src/ast_impl/ts.rs | 8 +- crates/oxc_ast_macros/src/ast.rs | 8 +- crates/oxc_cfg/src/builder/context.rs | 9 +- crates/oxc_codegen/src/binary_expr_visitor.rs | 16 +- crates/oxc_codegen/src/gen.rs | 54 +-- crates/oxc_codegen/src/lib.rs | 91 ++--- crates/oxc_diagnostics/src/reporter.rs | 66 ++-- .../src/constant_evaluation/call_expr.rs | 18 +- .../oxc_formatter/src/formatter/builders.rs | 8 +- .../oxc_formatter/src/formatter/comments.rs | 16 +- .../src/formatter/source_text.rs | 8 +- .../src/parentheses/expression.rs | 18 +- .../src/utils/assignment_like.rs | 8 +- .../src/write/arrow_function_expression.rs | 51 ++- crates/oxc_isolated_declarations/src/class.rs | 9 +- .../src/declaration.rs | 11 +- .../oxc_isolated_declarations/src/function.rs | 21 +- .../oxc_isolated_declarations/src/inferrer.rs | 12 +- crates/oxc_isolated_declarations/src/lib.rs | 84 ++--- .../oxc_isolated_declarations/src/module.rs | 8 +- .../src/signatures.rs | 9 +- crates/oxc_language_server/src/backend.rs | 32 +- crates/oxc_linter/src/ast_util.rs | 65 ++-- crates/oxc_linter/src/config/config_store.rs | 44 +-- crates/oxc_linter/src/context/mod.rs | 16 +- .../src/generated/rule_runner_impls.rs | 27 +- crates/oxc_linter/src/lib.rs | 8 +- .../rules/eslint/class_methods_use_this.rs | 10 +- crates/oxc_linter/src/rules/eslint/curly.rs | 8 +- .../oxc_linter/src/rules/eslint/func_names.rs | 22 +- .../oxc_linter/src/rules/eslint/func_style.rs | 8 +- .../src/rules/eslint/getter_return.rs | 11 +- .../src/rules/eslint/guard_for_in.rs | 14 +- .../oxc_linter/src/rules/eslint/no_alert.rs | 8 +- .../oxc_linter/src/rules/eslint/no_caller.rs | 11 +- .../src/rules/eslint/no_dupe_else_if.rs | 8 +- .../src/rules/eslint/no_dupe_keys.rs | 13 +- .../src/rules/eslint/no_duplicate_imports.rs | 70 ++-- .../oxc_linter/src/rules/eslint/no_empty.rs | 45 ++- .../src/rules/eslint/no_empty_static_block.rs | 18 +- .../src/rules/eslint/no_extend_native.rs | 8 +- .../src/rules/eslint/no_extra_label.rs | 16 +- .../src/rules/eslint/no_fallthrough.rs | 8 +- .../src/rules/eslint/no_import_assign.rs | 23 +- .../src/rules/eslint/no_inner_declarations.rs | 19 +- .../src/rules/eslint/no_iterator.rs | 16 +- .../oxc_linter/src/rules/eslint/no_labels.rs | 21 +- .../src/rules/eslint/no_loss_of_precision.rs | 8 +- .../eslint/no_misleading_character_class.rs | 10 +- .../src/rules/eslint/no_multi_assign.rs | 14 +- .../src/rules/eslint/no_nested_ternary.rs | 10 +- crates/oxc_linter/src/rules/eslint/no_new.rs | 8 +- .../src/rules/eslint/no_obj_calls.rs | 13 +- .../src/rules/eslint/no_regex_spaces.rs | 8 +- .../src/rules/eslint/no_restricted_imports.rs | 6 +- .../src/rules/eslint/no_self_assign.rs | 22 +- .../eslint/no_shadow_restricted_names.rs | 17 +- .../src/rules/eslint/no_unneeded_ternary.rs | 38 +- .../src/rules/eslint/no_unreachable.rs | 10 +- .../src/rules/eslint/no_unsafe_finally.rs | 28 +- .../no_unused_vars/fixers/fix_symbol.rs | 10 +- .../eslint/no_unused_vars/fixers/fix_vars.rs | 9 +- .../src/rules/eslint/no_useless_concat.rs | 20 +- .../src/rules/eslint/no_useless_escape.rs | 39 +- crates/oxc_linter/src/rules/eslint/no_var.rs | 36 +- crates/oxc_linter/src/rules/eslint/no_void.rs | 9 +- .../src/rules/eslint/prefer_destructuring.rs | 8 +- .../eslint/prefer_exponentiation_operator.rs | 11 +- .../rules/eslint/prefer_numeric_literals.rs | 16 +- .../src/rules/eslint/prefer_object_spread.rs | 13 +- .../src/rules/eslint/preserve_caught_error.rs | 8 +- crates/oxc_linter/src/rules/eslint/radix.rs | 22 +- .../src/rules/eslint/require_yield.rs | 15 +- .../src/rules/eslint/sort_imports.rs | 5 +- .../oxc_linter/src/rules/eslint/sort_vars.rs | 9 +- .../oxc_linter/src/rules/eslint/use_isnan.rs | 8 +- .../src/rules/eslint/valid_typeof.rs | 48 ++- .../oxc_linter/src/rules/import/extensions.rs | 6 +- .../src/rules/import/group_exports.rs | 8 +- .../oxc_linter/src/rules/import/namespace.rs | 30 +- .../src/rules/import/no_absolute_path.rs | 9 +- crates/oxc_linter/src/rules/import/no_amd.rs | 22 +- .../import/no_anonymous_default_export.rs | 17 +- .../src/rules/import/no_commonjs.rs | 8 +- .../oxc_linter/src/rules/import/no_cycle.rs | 12 +- .../src/rules/import/no_duplicates.rs | 14 +- .../src/rules/import/no_mutable_exports.rs | 8 +- .../src/rules/jest/no_conditional_expect.rs | 8 +- .../src/rules/jest/no_deprecated_functions.rs | 14 +- .../src/rules/jest/no_disabled_tests.rs | 13 +- .../jest/no_interpolation_in_snapshots.rs | 8 +- .../rules/jest/no_standalone_expect/mod.rs | 11 +- .../src/rules/jest/prefer_called_with.rs | 14 +- .../src/rules/jest/prefer_hooks_in_order.rs | 22 +- .../src/rules/jest/prefer_jest_mocked.rs | 8 +- .../oxc_linter/src/rules/jest/prefer_to_be.rs | 8 +- .../oxc_linter/src/rules/jest/prefer_todo.rs | 8 +- .../oxc_linter/src/rules/jest/require_hook.rs | 21 +- .../src/rules/jest/valid_describe_callback.rs | 17 +- .../oxc_linter/src/rules/jest/valid_expect.rs | 21 +- .../oxc_linter/src/rules/jest/valid_title.rs | 52 +-- .../src/rules/jsdoc/implements_on_classes.rs | 8 +- .../src/rules/jsdoc/require_returns.rs | 90 ++--- .../jsdoc/require_returns_description.rs | 10 +- .../src/rules/jsdoc/require_yields.rs | 11 +- .../oxc_linter/src/rules/jsx_a11y/alt_text.rs | 33 +- .../rules/jsx_a11y/anchor_ambiguous_text.rs | 19 +- .../src/rules/jsx_a11y/aria_role.rs | 64 ++-- .../src/rules/jsx_a11y/heading_has_content.rs | 8 +- .../jsx_a11y/label_has_associated_control.rs | 16 +- crates/oxc_linter/src/rules/jsx_a11y/lang.rs | 8 +- .../jsx_a11y/mouse_events_have_key_events.rs | 8 +- .../jsx_a11y/no_aria_hidden_on_focusable.rs | 26 +- .../src/rules/jsx_a11y/no_autofocus.rs | 30 +- .../src/rules/jsx_a11y/no_redundant_roles.rs | 22 +- .../rules/jsx_a11y/prefer_tag_over_role.rs | 20 +- .../rules/jsx_a11y/tabindex_no_positive.rs | 14 +- .../src/rules/nextjs/inline_script_id.rs | 8 +- .../src/rules/nextjs/next_script_for_ga.rs | 13 +- .../rules/nextjs/no_async_client_component.rs | 37 +- ...ore_interactive_script_outside_document.rs | 25 +- .../nextjs/no_head_import_in_document.rs | 12 +- .../rules/nextjs/no_html_link_for_pages.rs | 11 +- .../src/rules/nextjs/no_img_element.rs | 12 +- .../nextjs/no_script_component_in_head.rs | 16 +- .../rules/nextjs/no_title_in_document_head.rs | 16 +- .../oxc_linter/src/rules/nextjs/no_typos.rs | 40 +- .../src/rules/node/no_exports_assign.rs | 16 +- .../src/rules/oxc/bad_bitwise_operator.rs | 16 +- .../src/rules/oxc/bad_char_at_comparison.rs | 16 +- .../src/rules/oxc/const_comparisons.rs | 20 +- .../src/rules/oxc/no_accumulating_spread.rs | 10 +- .../rules/oxc/no_async_endpoint_handlers.rs | 9 +- .../src/rules/oxc/no_barrel_file.rs | 7 +- .../src/rules/oxc/only_used_in_recursion.rs | 20 +- .../src/rules/promise/no_return_wrap.rs | 8 +- .../oxc_linter/src/rules/promise/spec_only.rs | 8 +- .../src/rules/react/button_has_type.rs | 8 +- .../checked_requires_onchange_or_readonly.rs | 28 +- .../src/rules/react/exhaustive_deps.rs | 8 +- .../src/rules/react/forbid_elements.rs | 11 +- .../src/rules/react/iframe_missing_sandbox.rs | 8 +- .../src/rules/react/jsx_boolean_value.rs | 42 +-- .../src/rules/react/jsx_handler_names.rs | 12 +- crates/oxc_linter/src/rules/react/jsx_key.rs | 30 +- .../src/rules/react/jsx_no_target_blank.rs | 8 +- .../rules/react/jsx_no_useless_fragment.rs | 19 +- .../src/rules/react/no_children_prop.rs | 25 +- .../oxc_linter/src/rules/react/no_danger.rs | 11 +- .../rules/react/no_danger_with_children.rs | 8 +- .../rules/react/no_direct_mutation_state.rs | 38 +- .../src/rules/react/no_render_return_value.rs | 49 ++- .../src/rules/react/no_string_refs.rs | 20 +- .../src/rules/react/require_render_return.rs | 8 +- .../src/rules/react/self_closing_comp.rs | 6 +- .../src/rules/react/style_prop_object.rs | 50 ++- .../src/rules/typescript/array_type.rs | 97 +++-- .../src/rules/typescript/ban_ts_comment.rs | 16 +- .../consistent_generic_constructors.rs | 27 +- .../consistent_indexed_object_style.rs | 120 +++--- .../typescript/consistent_type_imports.rs | 208 +++++------ .../explicit_function_return_type.rs | 24 +- .../explicit_module_boundary_types.rs | 8 +- .../src/rules/typescript/no_dynamic_delete.rs | 11 +- .../rules/typescript/no_empty_interface.rs | 14 +- .../rules/typescript/no_inferrable_types.rs | 34 +- .../src/rules/typescript/no_misused_new.rs | 30 +- ...no_non_null_asserted_nullish_coalescing.rs | 11 +- .../rules/typescript/no_require_imports.rs | 11 +- ...necessary_parameter_property_assignment.rs | 8 +- .../no_unsafe_declaration_merging.rs | 8 +- .../typescript/prefer_enum_initializers.rs | 16 +- .../src/rules/typescript/prefer_for_of.rs | 8 +- .../typescript/prefer_literal_enum_member.rs | 65 ++-- .../src/rules/unicorn/catch_error_name.rs | 24 +- .../consistent_existence_index_check.rs | 13 +- .../unicorn/consistent_function_scoping.rs | 25 +- .../src/rules/unicorn/new_for_builtins.rs | 11 +- .../src/rules/unicorn/no_array_for_each.rs | 8 +- .../src/rules/unicorn/no_array_reduce.rs | 21 +- .../unicorn/no_await_in_promise_methods.rs | 27 +- .../src/rules/unicorn/no_document_cookie.rs | 8 +- .../rules/unicorn/no_instanceof_builtins.rs | 42 +-- .../rules/unicorn/no_invalid_fetch_options.rs | 44 +-- .../unicorn/no_negation_in_equality_check.rs | 8 +- .../oxc_linter/src/rules/unicorn/no_null.rs | 10 +- .../src/rules/unicorn/no_process_exit.rs | 28 +- .../src/rules/unicorn/no_thenable.rs | 49 ++- .../rules/unicorn/no_unnecessary_slice_end.rs | 25 +- .../no_unreadable_array_destructuring.rs | 20 +- .../rules/unicorn/numeric_separators_style.rs | 56 +-- .../src/rules/unicorn/prefer_array_find.rs | 282 ++++++-------- .../src/rules/unicorn/prefer_array_flat.rs | 78 ++-- .../rules/unicorn/prefer_array_index_of.rs | 23 +- .../src/rules/unicorn/prefer_array_some.rs | 65 ++-- .../src/rules/unicorn/prefer_date_now.rs | 50 ++- .../src/rules/unicorn/prefer_global_this.rs | 44 +-- .../prefer_logical_operator_over_ternary.rs | 15 +- .../src/rules/unicorn/prefer_math_trunc.rs | 5 +- .../rules/unicorn/prefer_modern_dom_apis.rs | 34 +- .../prefer_native_coercion_functions.rs | 57 ++- .../rules/unicorn/prefer_number_properties.rs | 8 +- .../unicorn/prefer_object_from_entries.rs | 54 ++- .../src/rules/unicorn/prefer_regexp_test.rs | 9 +- .../src/rules/unicorn/prefer_spread.rs | 16 +- .../src/rules/unicorn/prefer_string_raw.rs | 23 +- .../unicorn/prefer_string_starts_ends_with.rs | 36 +- .../unicorn/require_array_join_separator.rs | 37 +- ...require_number_to_fixed_digits_argument.rs | 46 +-- .../src/rules/vitest/no_import_node_test.rs | 12 +- .../src/rules/vitest/prefer_to_be_truthy.rs | 46 +-- ...l_test_context_for_concurrent_snapshots.rs | 13 +- .../src/rules/vue/no_multiple_slot_args.rs | 15 +- crates/oxc_linter/src/utils/react.rs | 44 ++- crates/oxc_linter/src/utils/regex.rs | 14 +- crates/oxc_linter/src/utils/unicorn.rs | 49 ++- crates/oxc_linter/src/utils/url.rs | 8 +- crates/oxc_macros/src/declare_oxc_lint.rs | 11 +- crates/oxc_mangler/src/keep_names.rs | 13 +- .../src/peephole/fold_constants.rs | 186 +++++---- .../minimize_conditional_expression.rs | 218 ++++++----- .../src/peephole/minimize_conditions.rs | 22 +- .../minimize_expression_in_boolean_context.rs | 14 +- .../src/peephole/minimize_if_statement.rs | 70 ++-- .../peephole/minimize_logical_expression.rs | 10 +- .../src/peephole/minimize_statements.rs | 297 +++++++-------- crates/oxc_minifier/src/peephole/mod.rs | 18 +- .../src/peephole/remove_dead_code.rs | 81 ++-- .../src/peephole/remove_unused_expression.rs | 74 ++-- .../src/peephole/replace_known_methods.rs | 33 +- .../peephole/substitute_alternate_syntax.rs | 69 ++-- crates/oxc_parser/src/error_handler.rs | 10 +- crates/oxc_parser/src/js/binding.rs | 8 +- crates/oxc_parser/src/js/class.rs | 89 +++-- crates/oxc_parser/src/js/expression.rs | 86 +++-- crates/oxc_parser/src/js/function.rs | 9 +- crates/oxc_parser/src/js/statement.rs | 22 +- crates/oxc_parser/src/lexer/trivia_builder.rs | 8 +- crates/oxc_parser/src/lexer/unicode.rs | 16 +- crates/oxc_parser/src/lib.rs | 10 +- crates/oxc_parser/src/ts/types.rs | 22 +- .../pattern_parser/pattern_parser_impl.rs | 352 +++++++++--------- .../string_literal_parser/parser_impl.rs | 20 +- .../template_literal_parser/parser_impl.rs | 39 +- crates/oxc_semantic/src/binder.rs | 20 +- crates/oxc_semantic/src/builder.rs | 33 +- crates/oxc_semantic/src/checker/javascript.rs | 42 +-- crates/oxc_semantic/src/checker/mod.rs | 8 +- crates/oxc_semantic/src/checker/typescript.rs | 54 ++- crates/oxc_semantic/src/class/builder.rs | 121 +++--- crates/oxc_semantic/src/jsdoc/parser/utils.rs | 16 +- crates/oxc_semantic/src/label.rs | 8 +- crates/oxc_semantic/src/node.rs | 8 +- .../src/common/arrow_function_converter.rs | 57 ++- .../oxc_transformer/src/common/duplicate.rs | 19 +- .../src/decorator/legacy/metadata.rs | 16 +- .../src/es2017/async_to_generator.rs | 20 +- .../es2018/async_generator_functions/mod.rs | 12 +- .../src/es2020/optional_chaining.rs | 62 +-- .../es2022/class_properties/class_details.rs | 8 +- .../es2022/class_properties/constructor.rs | 81 ++-- .../es2022/class_properties/private_field.rs | 19 +- .../static_block_and_prop_init.rs | 18 +- .../src/es2022/class_static_block.rs | 16 +- crates/oxc_transformer/src/jsx/jsx_impl.rs | 8 +- crates/oxc_transformer/src/jsx/jsx_self.rs | 13 +- crates/oxc_transformer/src/jsx/jsx_source.rs | 13 +- crates/oxc_transformer/src/jsx/refresh.rs | 40 +- .../oxc_transformer/src/options/babel/mod.rs | 16 +- .../src/plugins/styled_components.rs | 43 +-- .../oxc_transformer/src/typescript/class.rs | 33 +- .../oxc_transformer/src/typescript/module.rs | 11 +- .../src/replace_global_defines.rs | 14 +- 278 files changed, 3780 insertions(+), 4144 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9a9024195e921..ee518e42621ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ description = "A collection of JavaScript tools written in Rust." edition = "2024" # MSRV Policy N-2 (12 weeks). # Balance between the core contributors enjoying the latest version of rustc, while waiting for dependents to catch up. -rust-version = "1.87.0" +rust-version = "1.88.0" # [workspace.lints.rust] diff --git a/apps/oxfmt/src/walk.rs b/apps/oxfmt/src/walk.rs index 2fd9b25b571c1..2479adcae79d4 100644 --- a/apps/oxfmt/src/walk.rs +++ b/apps/oxfmt/src/walk.rs @@ -33,17 +33,16 @@ impl ignore::ParallelVisitor for WalkVisitor { match entry { Ok(entry) => { // Skip if we can't get file type or if it's a directory - if let Some(file_type) = entry.file_type() { - if !file_type.is_dir() { - if let Some(source_type) = get_supported_source_type(entry.path()) { - let walk_entry = - WalkEntry { path: entry.path().as_os_str().into(), source_type }; - // Send each entry immediately through the channel - // If send fails, the receiver has been dropped, so stop walking - if self.sender.send(walk_entry).is_err() { - return ignore::WalkState::Quit; - } - } + if let Some(file_type) = entry.file_type() + && !file_type.is_dir() + && let Some(source_type) = get_supported_source_type(entry.path()) + { + let walk_entry = + WalkEntry { path: entry.path().as_os_str().into(), source_type }; + // Send each entry immediately through the channel + // If send fails, the receiver has been dropped, so stop walking + if self.sender.send(walk_entry).is_err() { + return ignore::WalkState::Quit; } } ignore::WalkState::Continue diff --git a/crates/oxc_allocator/src/vec2/raw_vec.rs b/crates/oxc_allocator/src/vec2/raw_vec.rs index c4572d8e62ee2..b9af17be6f53f 100644 --- a/crates/oxc_allocator/src/vec2/raw_vec.rs +++ b/crates/oxc_allocator/src/vec2/raw_vec.rs @@ -815,10 +815,10 @@ impl RawVec<'_, T, A> { /// Not sure what safety invariants of this method are! TODO pub unsafe fn dealloc_buffer(&mut self) { let elem_size = mem::size_of::(); - if elem_size != 0 { - if let Some(layout) = self.current_layout() { - self.alloc.dealloc(self.ptr.cast(), layout); - } + if elem_size != 0 + && let Some(layout) = self.current_layout() + { + self.alloc.dealloc(self.ptr.cast(), layout); } } } diff --git a/crates/oxc_ast/src/ast_impl/js.rs b/crates/oxc_ast/src/ast_impl/js.rs index 87fcaada1c2af..32ec9f0ed6441 100644 --- a/crates/oxc_ast/src/ast_impl/js.rs +++ b/crates/oxc_ast/src/ast_impl/js.rs @@ -1537,20 +1537,20 @@ impl FunctionBody<'_> { impl<'a> ArrowFunctionExpression<'a> { /// Get expression part of `ArrowFunctionExpression`: `() => expression_part`. pub fn get_expression(&self) -> Option<&Expression<'a>> { - if self.expression { - if let Statement::ExpressionStatement(expr_stmt) = &self.body.statements[0] { - return Some(&expr_stmt.expression); - } + if self.expression + && let Statement::ExpressionStatement(expr_stmt) = &self.body.statements[0] + { + return Some(&expr_stmt.expression); } None } /// Get expression part of `ArrowFunctionExpression`: `() => expression_part`. pub fn get_expression_mut(&mut self) -> Option<&mut Expression<'a>> { - if self.expression { - if let Statement::ExpressionStatement(expr_stmt) = &mut self.body.statements[0] { - return Some(&mut expr_stmt.expression); - } + if self.expression + && let Statement::ExpressionStatement(expr_stmt) = &mut self.body.statements[0] + { + return Some(&mut expr_stmt.expression); } None } diff --git a/crates/oxc_ast/src/ast_impl/literal.rs b/crates/oxc_ast/src/ast_impl/literal.rs index 27c5d10645c17..cea847356c5d8 100644 --- a/crates/oxc_ast/src/ast_impl/literal.rs +++ b/crates/oxc_ast/src/ast_impl/literal.rs @@ -87,10 +87,10 @@ impl StringLiteral<'_> { while let Some(c) = chars.next() { if c == '\\' && chars.next() == Some('u') { let hex = &chars.as_str()[..4]; - if let Ok(hex) = u32::from_str_radix(hex, 16) { - if (0xd800..=0xdfff).contains(&hex) { - return false; - } + if let Ok(hex) = u32::from_str_radix(hex, 16) + && (0xd800..=0xdfff).contains(&hex) + { + return false; } } } diff --git a/crates/oxc_ast/src/ast_impl/ts.rs b/crates/oxc_ast/src/ast_impl/ts.rs index 46ac6eca6b390..aab40bbb0bc01 100644 --- a/crates/oxc_ast/src/ast_impl/ts.rs +++ b/crates/oxc_ast/src/ast_impl/ts.rs @@ -94,10 +94,10 @@ impl<'a> TSTypeName<'a> { /// Returns `true` if this is a reference to `const`. pub fn is_const(&self) -> bool { - if let TSTypeName::IdentifierReference(ident) = self { - if ident.name == "const" { - return true; - } + if let TSTypeName::IdentifierReference(ident) = self + && ident.name == "const" + { + return true; } false } diff --git a/crates/oxc_ast_macros/src/ast.rs b/crates/oxc_ast_macros/src/ast.rs index c41689cfa877a..b7a84605e4700 100644 --- a/crates/oxc_ast_macros/src/ast.rs +++ b/crates/oxc_ast_macros/src/ast.rs @@ -64,10 +64,10 @@ fn modify_struct(item: &mut ItemStruct, args: TokenStream) -> TokenStream { /// Mutates `item` in place, re-ordering its fields. fn reorder_struct_fields(item: &mut ItemStruct, args: TokenStream) -> Result<(), &'static str> { // Skip foreign types - if let Some(TokenTree::Ident(ident)) = args.into_iter().next() { - if ident == "foreign" { - return Ok(()); - } + if let Some(TokenTree::Ident(ident)) = args.into_iter().next() + && ident == "foreign" + { + return Ok(()); } // Get struct data diff --git a/crates/oxc_cfg/src/builder/context.rs b/crates/oxc_cfg/src/builder/context.rs index f08b8e5b9a9d0..8f9ba5a6ac062 100644 --- a/crates/oxc_cfg/src/builder/context.rs +++ b/crates/oxc_cfg/src/builder/context.rs @@ -132,12 +132,11 @@ impl<'a, 'c> QueryCtx<'a, 'c> { // mark the upper label continue jump point the same as ours if it isn't already assigned, // NOTE: if it is already assigned there's a resolution before this context. - if let Some(jmp) = continue_jmp { - if let Some(label_ctx @ RefCtxCursor(Ctx { continue_jmp: None, .. })) = + if let Some(jmp) = continue_jmp + && let Some(label_ctx @ RefCtxCursor(Ctx { continue_jmp: None, .. })) = self.0.immediate_labeled_ctx() - { - label_ctx.mark_continue(jmp); - } + { + label_ctx.mark_continue(jmp); } } diff --git a/crates/oxc_codegen/src/binary_expr_visitor.rs b/crates/oxc_codegen/src/binary_expr_visitor.rs index 77154c5512ffb..386db267ca7ba 100644 --- a/crates/oxc_codegen/src/binary_expr_visitor.rs +++ b/crates/oxc_codegen/src/binary_expr_visitor.rs @@ -186,15 +186,15 @@ impl<'a> BinaryExpressionVisitor<'a> { match self.operator { BinaryishOperator::Logical(LogicalOperator::Coalesce) => { - if let Expression::LogicalExpression(logical_expr) = e.left() { - if matches!(logical_expr.operator, LogicalOperator::And | LogicalOperator::Or) { - self.left_precedence = Precedence::Prefix; - } + if let Expression::LogicalExpression(logical_expr) = e.left() + && matches!(logical_expr.operator, LogicalOperator::And | LogicalOperator::Or) + { + self.left_precedence = Precedence::Prefix; } - if let Expression::LogicalExpression(logical_expr) = e.right() { - if matches!(logical_expr.operator, LogicalOperator::And | LogicalOperator::Or) { - self.right_precedence = Precedence::Prefix; - } + if let Expression::LogicalExpression(logical_expr) = e.right() + && matches!(logical_expr.operator, LogicalOperator::And | LogicalOperator::Or) + { + self.right_precedence = Precedence::Prefix; } } BinaryishOperator::Binary(BinaryOperator::Exponential) => { diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index e72763a549d4f..916fe21381d62 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -945,10 +945,11 @@ impl Gen for ImportAttribute<'_> { impl Gen for ExportNamedDeclaration<'_> { fn r#gen(&self, p: &mut Codegen, ctx: Context) { p.print_comments_at(self.span.start); - if let Some(Declaration::FunctionDeclaration(func)) = &self.declaration { - if func.pure && p.options.print_annotation_comment() { - p.print_str(NO_SIDE_EFFECTS_NEW_LINE_COMMENT); - } + if let Some(Declaration::FunctionDeclaration(func)) = &self.declaration + && func.pure + && p.options.print_annotation_comment() + { + p.print_str(NO_SIDE_EFFECTS_NEW_LINE_COMMENT); } p.add_source_mapping(self.span); p.print_indent(); @@ -1092,10 +1093,11 @@ impl Gen for ExportAllDeclaration<'_> { impl Gen for ExportDefaultDeclaration<'_> { fn r#gen(&self, p: &mut Codegen, ctx: Context) { p.print_comments_at(self.span.start); - if let ExportDefaultDeclarationKind::FunctionDeclaration(func) = &self.declaration { - if func.pure && p.options.print_annotation_comment() { - p.print_str(NO_SIDE_EFFECTS_NEW_LINE_COMMENT); - } + if let ExportDefaultDeclarationKind::FunctionDeclaration(func) = &self.declaration + && func.pure + && p.options.print_annotation_comment() + { + p.print_str(NO_SIDE_EFFECTS_NEW_LINE_COMMENT); } p.add_source_mapping(self.span); p.print_indent(); @@ -1586,10 +1588,10 @@ impl Gen for ObjectProperty<'_> { if let PropertyKey::StaticIdentifier(key) = &self.key { if key.name == "__proto__" { shorthand = self.shorthand; - } else if let Expression::Identifier(ident) = self.value.without_parentheses() { - if key.name == p.get_identifier_reference_name(ident) { - shorthand = true; - } + } else if let Expression::Identifier(ident) = self.value.without_parentheses() + && key.name == p.get_identifier_reference_name(ident) + { + shorthand = true; } } @@ -1597,12 +1599,11 @@ impl Gen for ObjectProperty<'_> { // "{ -1: 0 }" must be printed as "{ [-1]: 0 }" // "{ 1/0: 0 }" must be printed as "{ [1/0]: 0 }" - if !computed { - if let Some(Expression::NumericLiteral(n)) = self.key.as_expression() { - if n.value.is_sign_negative() || n.value.is_infinite() { - computed = true; - } - } + if !computed + && let Some(Expression::NumericLiteral(n)) = self.key.as_expression() + && (n.value.is_sign_negative() || n.value.is_infinite()) + { + computed = true; } if !shorthand { @@ -2811,10 +2812,9 @@ impl Gen for BindingProperty<'_> { BindingPatternKind::AssignmentPattern(assignment_pattern) => { if let BindingPatternKind::BindingIdentifier(ident) = &assignment_pattern.left.kind + && key.name == p.get_binding_identifier_name(ident) { - if key.name == p.get_binding_identifier_name(ident) { - shorthand = true; - } + shorthand = true; } } _ => {} @@ -3205,12 +3205,12 @@ impl Gen for TSTemplateLiteralType<'_> { fn r#gen(&self, p: &mut Codegen, ctx: Context) { p.print_str("`"); for (index, item) in self.quasis.iter().enumerate() { - if index != 0 { - if let Some(types) = self.types.get(index - 1) { - p.print_str("${"); - types.print(p, ctx); - p.print_str("}"); - } + if index != 0 + && let Some(types) = self.types.get(index - 1) + { + p.print_str("${"); + types.print(p, ctx); + p.print_str("}"); } p.print_str(item.value.raw.as_str()); } diff --git a/crates/oxc_codegen/src/lib.rs b/crates/oxc_codegen/src/lib.rs index 40c502ef64df3..f77a51c46ecbe 100644 --- a/crates/oxc_codegen/src/lib.rs +++ b/crates/oxc_codegen/src/lib.rs @@ -575,16 +575,17 @@ impl<'a> Codegen<'a> { // Ensure first string literal is not a directive. let mut first_needs_parens = false; - if directives.is_empty() && !self.options.minify { - if let Statement::ExpressionStatement(s) = first { - let s = s.expression.without_parentheses(); - if matches!(s, Expression::StringLiteral(_)) { - first_needs_parens = true; - self.print_ascii_byte(b'('); - s.print_expr(self, Precedence::Lowest, ctx); - self.print_ascii_byte(b')'); - self.print_semicolon_after_statement(); - } + if directives.is_empty() + && !self.options.minify + && let Statement::ExpressionStatement(s) = first + { + let s = s.expression.without_parentheses(); + if matches!(s, Expression::StringLiteral(_)) { + first_needs_parens = true; + self.print_ascii_byte(b'('); + s.print_expr(self, Precedence::Lowest, ctx); + self.print_ascii_byte(b')'); + self.print_semicolon_after_statement(); } } @@ -674,24 +675,23 @@ impl<'a> Codegen<'a> { } fn get_identifier_reference_name(&self, reference: &IdentifierReference<'a>) -> &'a str { - if let Some(scoping) = &self.scoping { - if let Some(reference_id) = reference.reference_id.get() { - if let Some(name) = scoping.get_reference_name(reference_id) { - // SAFETY: Hack the lifetime to be part of the allocator. - return unsafe { std::mem::transmute_copy(&name) }; - } - } + if let Some(scoping) = &self.scoping + && let Some(reference_id) = reference.reference_id.get() + && let Some(name) = scoping.get_reference_name(reference_id) + { + // SAFETY: Hack the lifetime to be part of the allocator. + return unsafe { std::mem::transmute_copy(&name) }; } reference.name.as_str() } fn get_binding_identifier_name(&self, ident: &BindingIdentifier<'a>) -> &'a str { - if let Some(scoping) = &self.scoping { - if let Some(symbol_id) = ident.symbol_id.get() { - let name = scoping.symbol_name(symbol_id); - // SAFETY: Hack the lifetime to be part of the allocator. - return unsafe { std::mem::transmute_copy(&name) }; - } + if let Some(scoping) = &self.scoping + && let Some(symbol_id) = ident.symbol_id.get() + { + let name = scoping.symbol_name(symbol_id); + // SAFETY: Hack the lifetime to be part of the allocator. + return unsafe { std::mem::transmute_copy(&name) }; } ident.name.as_str() } @@ -800,16 +800,17 @@ impl<'a> Codegen<'a> { // Check for numbers ending with zeros (but not hex numbers) // The `!is_hex` check is necessary to prevent hex numbers like `0x8000000000000000` // from being incorrectly converted to scientific notation - if !is_hex && best_candidate.ends_with('0') { - if let Some(len) = best_candidate.bytes().rev().position(|c| c != b'0') { - let base = &best_candidate[0..best_candidate.len() - len]; - let exp_str_len = itoa::Buffer::new().format(len).len(); - // Calculate expected length: base + 'e' + len - let expected_len = base.len() + 1 + exp_str_len; - if expected_len < best_candidate.len() { - best_candidate = format!("{base}e{len}").into(); - debug_assert_eq!(best_candidate.len(), expected_len); - } + if !is_hex + && best_candidate.ends_with('0') + && let Some(len) = best_candidate.bytes().rev().position(|c| c != b'0') + { + let base = &best_candidate[0..best_candidate.len() - len]; + let exp_str_len = itoa::Buffer::new().format(len).len(); + // Calculate expected length: base + 'e' + len + let expected_len = base.len() + 1 + exp_str_len; + if expected_len < best_candidate.len() { + best_candidate = format!("{base}e{len}").into(); + debug_assert_eq!(best_candidate.len(), expected_len); } } @@ -836,26 +837,26 @@ impl<'a> Codegen<'a> { } fn add_source_mapping(&mut self, span: Span) { - if let Some(sourcemap_builder) = self.sourcemap_builder.as_mut() { - if !span.is_empty() { - sourcemap_builder.add_source_mapping(self.code.as_bytes(), span.start, None); - } + if let Some(sourcemap_builder) = self.sourcemap_builder.as_mut() + && !span.is_empty() + { + sourcemap_builder.add_source_mapping(self.code.as_bytes(), span.start, None); } } fn add_source_mapping_end(&mut self, span: Span) { - if let Some(sourcemap_builder) = self.sourcemap_builder.as_mut() { - if !span.is_empty() { - sourcemap_builder.add_source_mapping(self.code.as_bytes(), span.end, None); - } + if let Some(sourcemap_builder) = self.sourcemap_builder.as_mut() + && !span.is_empty() + { + sourcemap_builder.add_source_mapping(self.code.as_bytes(), span.end, None); } } fn add_source_mapping_for_name(&mut self, span: Span, name: &str) { - if let Some(sourcemap_builder) = self.sourcemap_builder.as_mut() { - if !span.is_empty() { - sourcemap_builder.add_source_mapping_for_name(self.code.as_bytes(), span, name); - } + if let Some(sourcemap_builder) = self.sourcemap_builder.as_mut() + && !span.is_empty() + { + sourcemap_builder.add_source_mapping_for_name(self.code.as_bytes(), span, name); } } } diff --git a/crates/oxc_diagnostics/src/reporter.rs b/crates/oxc_diagnostics/src/reporter.rs index 0b6108a5908e8..00796d51691a4 100644 --- a/crates/oxc_diagnostics/src/reporter.rs +++ b/crates/oxc_diagnostics/src/reporter.rs @@ -116,41 +116,37 @@ impl Info { let mut severity = Severity::Warning; let rule_id = diagnostic.code().map(|code| code.to_string()); - if let Some(mut labels) = diagnostic.labels() { - if let Some(source) = diagnostic.source_code() { - if let Some(label) = labels.next() { - if let Ok(span_content) = source.read_span(label.inner(), 0, 0) { - start.line = span_content.line() + 1; - start.column = span_content.column() + 1; - - let end_offset = label.inner().offset() + label.inner().len(); - - if let Ok(span_content) = - source.read_span(&SourceSpan::from((end_offset, 0)), 0, 0) - { - end.line = span_content.line() + 1; - end.column = span_content.column() + 1; - } - - if let Some(name) = span_content.name() { - filename = name.to_string(); - } - if matches!(diagnostic.severity(), Some(Severity::Error)) { - severity = Severity::Error; - } - - message = diagnostic.to_string(); - // Our messages usually are in format `eslint(rule): message`. - // Trim off before the colon. - if let Some((_, msg)) = message.split_once(':') { - // Equivalent to `message = msg.trim().to_string()`, but operates in place - let msg = msg.trim(); - let start = msg.as_ptr() as usize - message.as_str().as_ptr() as usize; - message.truncate(start + msg.len()); - message.replace_range(..start, ""); - } - } - } + if let Some(mut labels) = diagnostic.labels() + && let Some(source) = diagnostic.source_code() + && let Some(label) = labels.next() + && let Ok(span_content) = source.read_span(label.inner(), 0, 0) + { + start.line = span_content.line() + 1; + start.column = span_content.column() + 1; + + let end_offset = label.inner().offset() + label.inner().len(); + + if let Ok(span_content) = source.read_span(&SourceSpan::from((end_offset, 0)), 0, 0) { + end.line = span_content.line() + 1; + end.column = span_content.column() + 1; + } + + if let Some(name) = span_content.name() { + filename = name.to_string(); + } + if matches!(diagnostic.severity(), Some(Severity::Error)) { + severity = Severity::Error; + } + + message = diagnostic.to_string(); + // Our messages usually are in format `eslint(rule): message`. + // Trim off before the colon. + if let Some((_, msg)) = message.split_once(':') { + // Equivalent to `message = msg.trim().to_string()`, but operates in place + let msg = msg.trim(); + let start = msg.as_ptr() as usize - message.as_str().as_ptr() as usize; + message.truncate(start + msg.len()); + message.replace_range(..start, ""); } } diff --git a/crates/oxc_ecmascript/src/constant_evaluation/call_expr.rs b/crates/oxc_ecmascript/src/constant_evaluation/call_expr.rs index 7a9f94d89d03d..5c5d9c4b6cc1b 100644 --- a/crates/oxc_ecmascript/src/constant_evaluation/call_expr.rs +++ b/crates/oxc_ecmascript/src/constant_evaluation/call_expr.rs @@ -191,10 +191,10 @@ fn try_fold_string_substring_or_slice<'a>( { return None; } - if let (Some(start), Some(end)) = (start_idx, end_idx) { - if start > end { - return None; - } + if let (Some(start), Some(end)) = (start_idx, end_idx) + && start > end + { + return None; } Some(ConstantValue::String(Cow::Owned(s.value.as_str().substring(start_idx, end_idx)))) @@ -327,10 +327,12 @@ fn try_fold_to_string<'a>( if args.is_empty() { radix = 10; } - if let Some(Argument::NumericLiteral(n)) = args.first() { - if n.value >= 2.0 && n.value <= 36.0 && n.value.fract() == 0.0 { - radix = n.value as u32; - } + if let Some(Argument::NumericLiteral(n)) = args.first() + && n.value >= 2.0 + && n.value <= 36.0 + && n.value.fract() == 0.0 + { + radix = n.value as u32; } if radix == 0 { return None; diff --git a/crates/oxc_formatter/src/formatter/builders.rs b/crates/oxc_formatter/src/formatter/builders.rs index e806fa8df4576..c31d91a731859 100644 --- a/crates/oxc_formatter/src/formatter/builders.rs +++ b/crates/oxc_formatter/src/formatter/builders.rs @@ -2366,10 +2366,10 @@ where /// Adds a new entry to the join output. pub fn entry(&mut self, entry: &dyn Format<'ast>) -> &mut Self { self.result = self.result.and_then(|()| { - if let Some(with) = &self.with { - if self.has_elements { - with.fmt(self.fmt)?; - } + if let Some(with) = &self.with + && self.has_elements + { + with.fmt(self.fmt)?; } self.has_elements = true; diff --git a/crates/oxc_formatter/src/formatter/comments.rs b/crates/oxc_formatter/src/formatter/comments.rs index d7aa21eb64fcd..e42abba8f367d 100644 --- a/crates/oxc_formatter/src/formatter/comments.rs +++ b/crates/oxc_formatter/src/formatter/comments.rs @@ -361,14 +361,14 @@ impl<'a> Comments<'a> { break; } else if self.source_text.is_end_of_line_comment(comment) { - if let SiblingNode::IfStatement(if_stmt) = enclosing_node { - if if_stmt.consequent.span() == preceding_span { - // If comment is after the `else` keyword, it is not a trailing comment of consequent. - if source_text[preceding_span.end as usize..comment.span.start as usize] - .contains("else") - { - return &[]; - } + if let SiblingNode::IfStatement(if_stmt) = enclosing_node + && if_stmt.consequent.span() == preceding_span + { + // If comment is after the `else` keyword, it is not a trailing comment of consequent. + if source_text[preceding_span.end as usize..comment.span.start as usize] + .contains("else") + { + return &[]; } } diff --git a/crates/oxc_formatter/src/formatter/source_text.rs b/crates/oxc_formatter/src/formatter/source_text.rs index ec76164543647..93f44820ca26b 100644 --- a/crates/oxc_formatter/src/formatter/source_text.rs +++ b/crates/oxc_formatter/src/formatter/source_text.rs @@ -145,10 +145,10 @@ impl<'a> SourceText<'a> { let comments = comments.unprinted_comments(); // Should skip the leading comments of the node. - if let Some(comment) = comments.first() { - if comment.span.end < start { - start = comment.span.start; - } + if let Some(comment) = comments.first() + && comment.span.end < start + { + start = comment.span.start; } // Count the newlines in the leading trivia of the next node diff --git a/crates/oxc_formatter/src/parentheses/expression.rs b/crates/oxc_formatter/src/parentheses/expression.rs index 138d34454f469..fb77a1d909133 100644 --- a/crates/oxc_formatter/src/parentheses/expression.rs +++ b/crates/oxc_formatter/src/parentheses/expression.rs @@ -267,15 +267,15 @@ impl<'a> NeedsParentheses<'a> for AstNode<'a, NewExpression<'a>> { impl<'a> NeedsParentheses<'a> for AstNode<'a, UpdateExpression<'a>> { fn needs_parentheses(&self, f: &Formatter<'_, 'a>) -> bool { let parent = self.parent; - if self.prefix() { - if let AstNodes::UnaryExpression(unary) = parent { - let parent_operator = unary.operator(); - let operator = self.operator(); - return (parent_operator == UnaryOperator::UnaryPlus - && operator == UpdateOperator::Increment) - || (parent_operator == UnaryOperator::UnaryNegation - && operator == UpdateOperator::Decrement); - } + if self.prefix() + && let AstNodes::UnaryExpression(unary) = parent + { + let parent_operator = unary.operator(); + let operator = self.operator(); + return (parent_operator == UnaryOperator::UnaryPlus + && operator == UpdateOperator::Increment) + || (parent_operator == UnaryOperator::UnaryNegation + && operator == UpdateOperator::Decrement); } unary_like_expression_needs_parens(UnaryLike::UpdateExpression(self)) } diff --git a/crates/oxc_formatter/src/utils/assignment_like.rs b/crates/oxc_formatter/src/utils/assignment_like.rs index e674938210bda..507a801ba23b1 100644 --- a/crates/oxc_formatter/src/utils/assignment_like.rs +++ b/crates/oxc_formatter/src/utils/assignment_like.rs @@ -292,14 +292,12 @@ impl<'a> AssignmentLike<'a, '_> { if let Some(Expression::CallExpression(call_expression)) = &right_expression.map(AsRef::as_ref) - { - if call_expression + && call_expression .callee .get_identifier_reference() .is_some_and(|ident| ident.name == "require") - { - return AssignmentLikeLayout::NeverBreakAfterOperator; - } + { + return AssignmentLikeLayout::NeverBreakAfterOperator; } if self.should_break_left_hand_side() { diff --git a/crates/oxc_formatter/src/write/arrow_function_expression.rs b/crates/oxc_formatter/src/write/arrow_function_expression.rs index 440b7b278d6da..7b51af2bc7445 100644 --- a/crates/oxc_formatter/src/write/arrow_function_expression.rs +++ b/crates/oxc_formatter/src/write/arrow_function_expression.rs @@ -297,32 +297,28 @@ impl<'a, 'b> ArrowFunctionLayout<'a, 'b> { let mut should_break = false; loop { - if current.expression() { - if let Some(AstNodes::ExpressionStatement(expr_stmt)) = + if current.expression() + && let Some(AstNodes::ExpressionStatement(expr_stmt)) = current.body().statements().first().map(AstNode::::as_ast_nodes) - { - if let AstNodes::ArrowFunctionExpression(next) = - &expr_stmt.expression().as_ast_nodes() - { - if matches!( - options.call_arg_layout, - None | Some(GroupedCallArgumentLayout::GroupedLastArgument) - ) { - should_break = should_break || Self::should_break_chain(current); - - should_break = should_break || Self::should_break_chain(next); - - if head.is_none() { - head = Some(current); - } else { - middle.push(current); - } + && let AstNodes::ArrowFunctionExpression(next) = + &expr_stmt.expression().as_ast_nodes() + && matches!( + options.call_arg_layout, + None | Some(GroupedCallArgumentLayout::GroupedLastArgument) + ) + { + should_break = should_break || Self::should_break_chain(current); - current = next; - continue; - } - } + should_break = should_break || Self::should_break_chain(next); + + if head.is_none() { + head = Some(current); + } else { + middle.push(current); } + + current = next; + continue; } break match head { None => ArrowFunctionLayout::Single(current), @@ -930,12 +926,11 @@ pub struct FormatMaybeCachedFunctionBody<'a, 'b> { impl<'a> FormatMaybeCachedFunctionBody<'a, '_> { fn format(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> { - if self.expression { - if let AstNodes::ExpressionStatement(s) = + if self.expression + && let AstNodes::ExpressionStatement(s) = &self.body.statements().first().unwrap().as_ast_nodes() - { - return s.expression().fmt(f); - } + { + return s.expression().fmt(f); } self.body.fmt(f) } diff --git a/crates/oxc_isolated_declarations/src/class.rs b/crates/oxc_isolated_declarations/src/class.rs index 4e14764a7da10..0ce862b1fdffa 100644 --- a/crates/oxc_isolated_declarations/src/class.rs +++ b/crates/oxc_isolated_declarations/src/class.rs @@ -453,8 +453,8 @@ impl<'a> IsolatedDeclarations<'a> { ) } else { let mut params = params.clone_in(self.ast.allocator); - if let Some(param) = params.items.first_mut() { - if let Some(annotation) = + if let Some(param) = params.items.first_mut() + && let Some(annotation) = accessor_annotations.iter().find_map(|(key, annotation)| { if method.key.content_eq(key) { Some( @@ -465,9 +465,8 @@ impl<'a> IsolatedDeclarations<'a> { None } }) - { - param.pattern.type_annotation = annotation; - } + { + param.pattern.type_annotation = annotation; } params } diff --git a/crates/oxc_isolated_declarations/src/declaration.rs b/crates/oxc_isolated_declarations/src/declaration.rs index 2eac1d6aeb14f..fe049d3c5038b 100644 --- a/crates/oxc_isolated_declarations/src/declaration.rs +++ b/crates/oxc_isolated_declarations/src/declaration.rs @@ -55,12 +55,11 @@ impl<'a> IsolatedDeclarations<'a> { return None; } - if check_binding { - if let Some(name) = decl.id.get_identifier_name() { - if !self.scope.has_value_reference(&name) { - return None; - } - } + if check_binding + && let Some(name) = decl.id.get_identifier_name() + && !self.scope.has_value_reference(&name) + { + return None; } let mut binding_type = None; diff --git a/crates/oxc_isolated_declarations/src/function.rs b/crates/oxc_isolated_declarations/src/function.rs index 09c5a71176561..81e616078ceb2 100644 --- a/crates/oxc_isolated_declarations/src/function.rs +++ b/crates/oxc_isolated_declarations/src/function.rs @@ -43,13 +43,12 @@ impl<'a> IsolatedDeclarations<'a> { is_remaining_params_have_required: bool, ) -> Option> { let pattern = ¶m.pattern; - if let BindingPatternKind::AssignmentPattern(pattern) = &pattern.kind { - if pattern.left.kind.is_destructuring_pattern() - && pattern.left.type_annotation.is_none() - { - self.error(parameter_must_have_explicit_type(param.span)); - return None; - } + if let BindingPatternKind::AssignmentPattern(pattern) = &pattern.kind + && pattern.left.kind.is_destructuring_pattern() + && pattern.left.type_annotation.is_none() + { + self.error(parameter_must_have_explicit_type(param.span)); + return None; } let is_assignment_pattern = pattern.kind.is_assignment_pattern(); @@ -139,10 +138,10 @@ impl<'a> IsolatedDeclarations<'a> { }), ); - if let Some(rest) = ¶ms.rest { - if rest.argument.type_annotation.is_none() { - self.error(parameter_must_have_explicit_type(rest.span)); - } + if let Some(rest) = ¶ms.rest + && rest.argument.type_annotation.is_none() + { + self.error(parameter_must_have_explicit_type(rest.span)); } self.ast.alloc_formal_parameters( diff --git a/crates/oxc_isolated_declarations/src/inferrer.rs b/crates/oxc_isolated_declarations/src/inferrer.rs index 914587033abb8..feb23e716026d 100644 --- a/crates/oxc_isolated_declarations/src/inferrer.rs +++ b/crates/oxc_isolated_declarations/src/inferrer.rs @@ -128,12 +128,12 @@ impl<'a> IsolatedDeclarations<'a> { return None; } - if function.expression { - if let Some(Statement::ExpressionStatement(stmt)) = function.body.statements.first() { - return self.infer_type_from_expression(&stmt.expression).map(|type_annotation| { - self.ast.alloc_ts_type_annotation(SPAN, type_annotation) - }); - } + if function.expression + && let Some(Statement::ExpressionStatement(stmt)) = function.body.statements.first() + { + return self + .infer_type_from_expression(&stmt.expression) + .map(|type_annotation| self.ast.alloc_ts_type_annotation(SPAN, type_annotation)); } FunctionReturnType::infer(self, &function.body) diff --git a/crates/oxc_isolated_declarations/src/lib.rs b/crates/oxc_isolated_declarations/src/lib.rs index cfee3cc65382b..f24d070adc79b 100644 --- a/crates/oxc_isolated_declarations/src/lib.rs +++ b/crates/oxc_isolated_declarations/src/lib.rs @@ -208,12 +208,11 @@ impl<'a> IsolatedDeclarations<'a> { let mut decl = decl.clone_in(self.ast.allocator); // Remove export keyword from all statements in `declare module "xxx" { ... }` - if !is_global { - if let Some(body) = + if !is_global + && let Some(body) = decl.body.as_mut().and_then(|body| body.as_module_block_mut()) - { - self.strip_export_keyword(&mut body.body); - } + { + self.strip_export_keyword(&mut body.body); } // We need to visit the module declaration to collect all references @@ -376,10 +375,9 @@ impl<'a> IsolatedDeclarations<'a> { if matches!( new_stmt, Statement::ExportDefaultDeclaration(_) | Statement::TSExportAssignment(_) - ) { - if let Some(export_external_var_statement) = extra_export_var_statement.take() { - new_stmts.push(export_external_var_statement); - } + ) && let Some(export_external_var_statement) = extra_export_var_statement.take() + { + new_stmts.push(export_external_var_statement); } new_stmts.push(new_stmt); continue; @@ -574,20 +572,19 @@ impl<'a> IsolatedDeclarations<'a> { match stmt { Statement::ExportNamedDeclaration(decl) => match decl.declaration.as_ref() { Some(Declaration::FunctionDeclaration(func)) => { - if func.body.is_some() { - if let Some(id) = func.id.as_ref() { - can_expando_function_names.insert(id.name); - } + if func.body.is_some() + && let Some(id) = func.id.as_ref() + { + can_expando_function_names.insert(id.name); } } Some(Declaration::VariableDeclaration(decl)) => { for declarator in &decl.declarations { if declarator.id.type_annotation.is_none() && declarator.init.as_ref().is_some_and(Expression::is_function) + && let Some(name) = declarator.id.get_identifier_name() { - if let Some(name) = declarator.id.get_identifier_name() { - can_expando_function_names.insert(name); - } + can_expando_function_names.insert(name); } } } @@ -596,55 +593,44 @@ impl<'a> IsolatedDeclarations<'a> { Statement::ExportDefaultDeclaration(decl) => { if let ExportDefaultDeclarationKind::FunctionDeclaration(func) = &decl.declaration + && func.body.is_some() + && let Some(name) = func.name() { - if func.body.is_some() { - if let Some(name) = func.name() { - can_expando_function_names.insert(name); - } - } + can_expando_function_names.insert(name); } } Statement::FunctionDeclaration(func) => { - if func.body.is_some() { - if let Some(name) = func.name() { - if self.scope.has_value_reference(&name) { - can_expando_function_names.insert(name); - } - } + if func.body.is_some() + && let Some(name) = func.name() + && self.scope.has_value_reference(&name) + { + can_expando_function_names.insert(name); } } Statement::VariableDeclaration(decl) => { for declarator in &decl.declarations { if declarator.id.type_annotation.is_none() && declarator.init.as_ref().is_some_and(Expression::is_function) + && let Some(name) = declarator.id.get_identifier_name() + && self.scope.has_value_reference(&name) { - if let Some(name) = declarator.id.get_identifier_name() { - if self.scope.has_value_reference(&name) { - can_expando_function_names.insert(name); - } - } + can_expando_function_names.insert(name); } } } Statement::ExpressionStatement(stmt) => { - if let Expression::AssignmentExpression(assignment) = &stmt.expression { - if let AssignmentTarget::StaticMemberExpression(static_member_expr) = + if let Expression::AssignmentExpression(assignment) = &stmt.expression + && let AssignmentTarget::StaticMemberExpression(static_member_expr) = &assignment.left - { - if let Expression::Identifier(ident) = &static_member_expr.object { - if can_expando_function_names.contains(&ident.name) - && !assignable_properties_for_namespace - .get(&ident.name.as_str()) - .is_some_and(|properties| { - properties.contains(&static_member_expr.property.name) - }) - { - self.error(function_with_assigning_properties( - static_member_expr.span, - )); - } - } - } + && let Expression::Identifier(ident) = &static_member_expr.object + && can_expando_function_names.contains(&ident.name) + && !assignable_properties_for_namespace + .get(&ident.name.as_str()) + .is_some_and(|properties| { + properties.contains(&static_member_expr.property.name) + }) + { + self.error(function_with_assigning_properties(static_member_expr.span)); } } diff --git a/crates/oxc_isolated_declarations/src/module.rs b/crates/oxc_isolated_declarations/src/module.rs index ccbfa313085b0..f8af0ef028a58 100644 --- a/crates/oxc_isolated_declarations/src/module.rs +++ b/crates/oxc_isolated_declarations/src/module.rs @@ -183,10 +183,10 @@ impl<'a> IsolatedDeclarations<'a> { /// ``` pub(crate) fn strip_export_keyword(&self, stmts: &mut ArenaVec<'a, Statement<'a>>) { stmts.iter_mut().for_each(|stmt| { - if let Statement::ExportNamedDeclaration(decl) = stmt { - if let Some(declaration) = &mut decl.declaration { - *stmt = Statement::from(declaration.take_in(self.ast)); - } + if let Statement::ExportNamedDeclaration(decl) = stmt + && let Some(declaration) = &mut decl.declaration + { + *stmt = Statement::from(declaration.take_in(self.ast)); } }); } diff --git a/crates/oxc_isolated_declarations/src/signatures.rs b/crates/oxc_isolated_declarations/src/signatures.rs index 34c2e25b6f916..dec7a2ae88623 100644 --- a/crates/oxc_isolated_declarations/src/signatures.rs +++ b/crates/oxc_isolated_declarations/src/signatures.rs @@ -44,12 +44,11 @@ impl<'a> IsolatedDeclarations<'a> { }); for (requires_inference, param, return_type) in method_annotations.into_values() { - if requires_inference { - if let (Some(Some(annotation)), Some(option)) + if requires_inference + && let (Some(Some(annotation)), Some(option)) | (Some(option), Some(Some(annotation))) = (param, return_type) - { - option.replace(annotation.clone_in(self.ast.allocator)); - } + { + option.replace(annotation.clone_in(self.ast.allocator)); } } } diff --git a/crates/oxc_language_server/src/backend.rs b/crates/oxc_language_server/src/backend.rs index 1ee1cf523faaa..c07ee8a52ea3c 100644 --- a/crates/oxc_language_server/src/backend.rs +++ b/crates/oxc_language_server/src/backend.rs @@ -342,15 +342,15 @@ impl LanguageServer for Backend { }); } - if !removing_registrations.is_empty() { - if let Err(err) = self.client.unregister_capability(removing_registrations).await { - warn!("sending unregisterCapability.didChangeWatchedFiles failed: {err}"); - } + if !removing_registrations.is_empty() + && let Err(err) = self.client.unregister_capability(removing_registrations).await + { + warn!("sending unregisterCapability.didChangeWatchedFiles failed: {err}"); } - if !adding_registrations.is_empty() { - if let Err(err) = self.client.register_capability(adding_registrations).await { - warn!("sending registerCapability.didChangeWatchedFiles failed: {err}"); - } + if !adding_registrations.is_empty() + && let Err(err) = self.client.register_capability(adding_registrations).await + { + warn!("sending registerCapability.didChangeWatchedFiles failed: {err}"); } } @@ -457,16 +457,16 @@ impl LanguageServer for Backend { // tell client to stop / start watching for files if self.capabilities.get().is_some_and(|capabilities| capabilities.dynamic_watchers) { - if !added_registrations.is_empty() { - if let Err(err) = self.client.register_capability(added_registrations).await { - warn!("sending registerCapability.didChangeWatchedFiles failed: {err}"); - } + if !added_registrations.is_empty() + && let Err(err) = self.client.register_capability(added_registrations).await + { + warn!("sending registerCapability.didChangeWatchedFiles failed: {err}"); } - if !removed_registrations.is_empty() { - if let Err(err) = self.client.unregister_capability(removed_registrations).await { - warn!("sending unregisterCapability.didChangeWatchedFiles failed: {err}"); - } + if !removed_registrations.is_empty() + && let Err(err) = self.client.unregister_capability(removed_registrations).await + { + warn!("sending unregisterCapability.didChangeWatchedFiles failed: {err}"); } } } diff --git a/crates/oxc_linter/src/ast_util.rs b/crates/oxc_linter/src/ast_util.rs index 4b04747861c79..690240749bcb2 100644 --- a/crates/oxc_linter/src/ast_util.rs +++ b/crates/oxc_linter/src/ast_util.rs @@ -147,16 +147,11 @@ impl<'a> IsConstant<'a, '_> for Expression<'a> { impl<'a> IsConstant<'a, '_> for CallExpression<'a> { fn is_constant(&self, _in_boolean_position: bool, semantic: &Semantic<'a>) -> bool { - if let Expression::Identifier(ident) = &self.callee { - if ident.name == "Boolean" - && self - .arguments - .iter() - .next() - .is_none_or(|first| first.is_constant(true, semantic)) - { - return semantic.is_reference_to_global_variable(ident); - } + if let Expression::Identifier(ident) = &self.callee + && ident.name == "Boolean" + && self.arguments.iter().next().is_none_or(|first| first.is_constant(true, semantic)) + { + return semantic.is_reference_to_global_variable(ident); } false } @@ -328,16 +323,16 @@ pub fn is_method_call<'a>( min_arg_count: Option, max_arg_count: Option, ) -> bool { - if let Some(min_arg_count) = min_arg_count { - if call_expr.arguments.len() < min_arg_count { - return false; - } + if let Some(min_arg_count) = min_arg_count + && call_expr.arguments.len() < min_arg_count + { + return false; } - if let Some(max_arg_count) = max_arg_count { - if call_expr.arguments.len() > max_arg_count { - return false; - } + if let Some(max_arg_count) = max_arg_count + && call_expr.arguments.len() > max_arg_count + { + return false; } let Some(member_expr) = call_expr.callee.get_member_expr() else { @@ -371,15 +366,15 @@ pub fn is_new_expression<'a>( min_arg_count: Option, max_arg_count: Option, ) -> bool { - if let Some(min_arg_count) = min_arg_count { - if new_expr.arguments.len() < min_arg_count { - return false; - } + if let Some(min_arg_count) = min_arg_count + && new_expr.arguments.len() < min_arg_count + { + return false; } - if let Some(max_arg_count) = max_arg_count { - if new_expr.arguments.len() > max_arg_count { - return false; - } + if let Some(max_arg_count) = max_arg_count + && new_expr.arguments.len() > max_arg_count + { + return false; } let Expression::Identifier(ident) = new_expr.callee.without_parentheses() else { @@ -745,12 +740,11 @@ pub fn is_default_this_binding<'a>( .is_some_and(|name| name == "apply" || name == "bind" || name == "call") { let node = outermost_paren_parent(parent, semantic).unwrap(); - if let AstKind::CallExpression(call_expr) = node.kind() { - if let Some(arg) = + if let AstKind::CallExpression(call_expr) = node.kind() + && let Some(arg) = call_expr.arguments.first().and_then(|arg| arg.as_expression()) - { - return arg.is_null_or_undefined(); - } + { + return arg.is_null_or_undefined(); } } return true; @@ -810,10 +804,11 @@ pub fn get_static_property_name<'a>(parent_node: &AstNode<'a>) -> Option Some(Cow::Owned(regex.regex.to_string())), PropertyKey::BigIntLiteral(bigint) => Some(Cow::Borrowed(bigint.value.as_str())), PropertyKey::TemplateLiteral(template) => { - if template.expressions.is_empty() && template.quasis.len() == 1 { - if let Some(cooked) = &template.quasis[0].value.cooked { - return Some(Cow::Borrowed(cooked.as_str())); - } + if template.expressions.is_empty() + && template.quasis.len() == 1 + && let Some(cooked) = &template.quasis[0].value.cooked + { + return Some(Cow::Borrowed(cooked.as_str())); } None diff --git a/crates/oxc_linter/src/config/config_store.rs b/crates/oxc_linter/src/config/config_store.rs index c1b6de62637db..22fdebc344da6 100644 --- a/crates/oxc_linter/src/config/config_store.rs +++ b/crates/oxc_linter/src/config/config_store.rs @@ -189,30 +189,30 @@ impl Config { let mut configured_plugins = self.base.config.plugins.builtin; for override_config in overrides_to_apply { - if let Some(override_plugins) = &override_config.plugins { - if *override_plugins != plugins { - // Only apply categories to plugins that: - // 1. Are in the current accumulated plugin set - // 2. Have NOT been configured yet (not in root or previous overrides) - let unconfigured_plugins = plugins.builtin & !configured_plugins; - - if !unconfigured_plugins.is_empty() { - for (rule, severity) in all_rules.iter().filter_map(|rule| { - let rule_plugin = BuiltinLintPlugins::from(rule.plugin_name()); - // Only apply categories to rules from unconfigured plugins - if unconfigured_plugins.contains(rule_plugin) { - self.categories - .get(&rule.category()) - .map(|severity| (rule.clone(), severity)) - } else { - None - } - }) { - rules.entry(rule).or_insert(*severity); + if let Some(override_plugins) = &override_config.plugins + && *override_plugins != plugins + { + // Only apply categories to plugins that: + // 1. Are in the current accumulated plugin set + // 2. Have NOT been configured yet (not in root or previous overrides) + let unconfigured_plugins = plugins.builtin & !configured_plugins; + + if !unconfigured_plugins.is_empty() { + for (rule, severity) in all_rules.iter().filter_map(|rule| { + let rule_plugin = BuiltinLintPlugins::from(rule.plugin_name()); + // Only apply categories to rules from unconfigured plugins + if unconfigured_plugins.contains(rule_plugin) { + self.categories + .get(&rule.category()) + .map(|severity| (rule.clone(), severity)) + } else { + None } - // Mark these plugins as configured - configured_plugins |= unconfigured_plugins; + }) { + rules.entry(rule).or_insert(*severity); } + // Mark these plugins as configured + configured_plugins |= unconfigured_plugins; } } diff --git a/crates/oxc_linter/src/context/mod.rs b/crates/oxc_linter/src/context/mod.rs index 0814ceb1b6075..f904dbf126c06 100644 --- a/crates/oxc_linter/src/context/mod.rs +++ b/crates/oxc_linter/src/context/mod.rs @@ -188,10 +188,10 @@ impl<'a> LintContext<'a> { } for env in self.env().iter() { - if let Some(env) = GLOBALS.get(env) { - if let Some(value) = env.get(var) { - return Some(GlobalValue::from(*value)); - } + if let Some(env) = GLOBALS.get(env) + && let Some(value) = env.get(var) + { + return Some(GlobalValue::from(*value)); } } @@ -209,10 +209,10 @@ impl<'a> LintContext<'a> { return true; } for env in self.env().iter() { - if let Some(env) = GLOBALS.get(env) { - if env.contains_key(var) { - return true; - } + if let Some(env) = GLOBALS.get(env) + && env.contains_key(var) + { + return true; } } false diff --git a/crates/oxc_linter/src/generated/rule_runner_impls.rs b/crates/oxc_linter/src/generated/rule_runner_impls.rs index 29affc3de18dd..087a0c08a8fbd 100644 --- a/crates/oxc_linter/src/generated/rule_runner_impls.rs +++ b/crates/oxc_linter/src/generated/rule_runner_impls.rs @@ -136,8 +136,7 @@ impl RuleRunner for crate::rules::eslint::no_bitwise::NoBitwise { } impl RuleRunner for crate::rules::eslint::no_caller::NoCaller { - const NODE_TYPES: Option<&AstTypesBitset> = - Some(&AstTypesBitset::from_types(&[AstType::StaticMemberExpression])); + const NODE_TYPES: Option<&AstTypesBitset> = None; } impl RuleRunner for crate::rules::eslint::no_case_declarations::NoCaseDeclarations { @@ -251,8 +250,7 @@ impl RuleRunner for crate::rules::eslint::no_empty_pattern::NoEmptyPattern { } impl RuleRunner for crate::rules::eslint::no_empty_static_block::NoEmptyStaticBlock { - const NODE_TYPES: Option<&AstTypesBitset> = - Some(&AstTypesBitset::from_types(&[AstType::StaticBlock])); + const NODE_TYPES: Option<&AstTypesBitset> = None; } impl RuleRunner for crate::rules::eslint::no_eq_null::NoEqNull { @@ -365,8 +363,7 @@ impl RuleRunner for crate::rules::eslint::no_negated_condition::NoNegatedConditi } impl RuleRunner for crate::rules::eslint::no_nested_ternary::NoNestedTernary { - const NODE_TYPES: Option<&AstTypesBitset> = - Some(&AstTypesBitset::from_types(&[AstType::ConditionalExpression])); + const NODE_TYPES: Option<&AstTypesBitset> = None; } impl RuleRunner for crate::rules::eslint::no_new::NoNew { @@ -580,8 +577,7 @@ impl RuleRunner for crate::rules::eslint::no_useless_rename::NoUselessRename { } impl RuleRunner for crate::rules::eslint::no_var::NoVar { - const NODE_TYPES: Option<&AstTypesBitset> = - Some(&AstTypesBitset::from_types(&[AstType::VariableDeclaration])); + const NODE_TYPES: Option<&AstTypesBitset> = None; } impl RuleRunner for crate::rules::eslint::no_void::NoVoid { @@ -660,8 +656,7 @@ impl RuleRunner for crate::rules::eslint::require_await::RequireAwait { } impl RuleRunner for crate::rules::eslint::require_yield::RequireYield { - const NODE_TYPES: Option<&AstTypesBitset> = - Some(&AstTypesBitset::from_types(&[AstType::Function])); + const NODE_TYPES: Option<&AstTypesBitset> = None; } impl RuleRunner for crate::rules::eslint::sort_imports::SortImports { @@ -1137,8 +1132,7 @@ impl RuleRunner for crate::rules::jsx_a11y::aria_props::AriaProps { } impl RuleRunner for crate::rules::jsx_a11y::aria_role::AriaRole { - const NODE_TYPES: Option<&AstTypesBitset> = - Some(&AstTypesBitset::from_types(&[AstType::JSXElement])); + const NODE_TYPES: Option<&AstTypesBitset> = None; } impl RuleRunner for crate::rules::jsx_a11y::aria_unsupported_elements::AriaUnsupportedElements { @@ -1346,8 +1340,7 @@ impl RuleRunner for crate::rules::nextjs::no_title_in_document_head::NoTitleInDo } impl RuleRunner for crate::rules::nextjs::no_typos::NoTypos { - const NODE_TYPES: Option<&AstTypesBitset> = - Some(&AstTypesBitset::from_types(&[AstType::ExportNamedDeclaration])); + const NODE_TYPES: Option<&AstTypesBitset> = None; } impl RuleRunner for crate::rules::nextjs::no_unwanted_polyfillio::NoUnwantedPolyfillio { @@ -1835,8 +1828,7 @@ impl RuleRunner for crate::rules::typescript::no_dynamic_delete::NoDynamicDelete } impl RuleRunner for crate::rules::typescript::no_empty_interface::NoEmptyInterface { - const NODE_TYPES: Option<&AstTypesBitset> = - Some(&AstTypesBitset::from_types(&[AstType::TSInterfaceDeclaration])); + const NODE_TYPES: Option<&AstTypesBitset> = None; } impl RuleRunner for crate::rules::typescript::no_empty_object_type::NoEmptyObjectType { @@ -2316,8 +2308,7 @@ impl RuleRunner } impl RuleRunner for crate::rules::unicorn::no_process_exit::NoProcessExit { - const NODE_TYPES: Option<&AstTypesBitset> = - Some(&AstTypesBitset::from_types(&[AstType::CallExpression])); + const NODE_TYPES: Option<&AstTypesBitset> = None; } impl RuleRunner diff --git a/crates/oxc_linter/src/lib.rs b/crates/oxc_linter/src/lib.rs index 81b93090087a9..0af763f08e4f2 100644 --- a/crates/oxc_linter/src/lib.rs +++ b/crates/oxc_linter/src/lib.rs @@ -302,10 +302,10 @@ impl Linter { self.run_external_rules(&external_rules, path, &mut ctx_host, allocator); - if let Some(severity) = self.options.report_unused_directive { - if severity.is_warn_deny() { - ctx_host.report_unused_directives(severity.into()); - } + if let Some(severity) = self.options.report_unused_directive + && severity.is_warn_deny() + { + ctx_host.report_unused_directives(severity.into()); } // no next `