From 571a23e51320a5e686f70792f69a423dafcee1a7 Mon Sep 17 00:00:00 2001 From: Dunqing Date: Wed, 8 Jan 2025 12:13:43 +0800 Subject: [PATCH] fix(transformer/arrow-functions): store super_methods to Stack to fix nested async methods --- .../src/common/arrow_function_converter.rs | 29 ++++++++++--------- tasks/coverage/snapshots/semantic_misc.snap | 18 ++++++------ .../snapshots/oxc.snap.md | 8 ++--- 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/crates/oxc_transformer/src/common/arrow_function_converter.rs b/crates/oxc_transformer/src/common/arrow_function_converter.rs index 1c5c92b53e42d9..b4d3c8bf3c4df0 100644 --- a/crates/oxc_transformer/src/common/arrow_function_converter.rs +++ b/crates/oxc_transformer/src/common/arrow_function_converter.rs @@ -93,7 +93,7 @@ use rustc_hash::{FxBuildHasher, FxHashSet}; use oxc_allocator::{Box as ArenaBox, Vec as ArenaVec}; use oxc_ast::{ast::*, visit::walk_mut::walk_expression, VisitMut, NONE}; -use oxc_data_structures::stack::{NonEmptyStack, SparseStack}; +use oxc_data_structures::stack::{NonEmptyStack, SparseStack, Stack}; use oxc_semantic::{ReferenceFlags, SymbolId}; use oxc_span::{CompactStr, GetSpan, SPAN}; use oxc_syntax::{ @@ -144,7 +144,7 @@ pub struct ArrowFunctionConverter<'a> { renamed_arguments_symbol_ids: FxHashSet, // TODO(improve-on-babel): `FxHashMap` would suffice here. Iteration order is not important. // Only using `FxIndexMap` for predictable iteration order to match Babel's output. - super_methods: Option, SuperMethodInfo<'a>>>, + super_methods_stack: Stack, SuperMethodInfo<'a>>>, } impl ArrowFunctionConverter<'_> { @@ -164,7 +164,7 @@ impl ArrowFunctionConverter<'_> { constructor_super_stack: NonEmptyStack::new(false), arguments_needs_transform_stack: NonEmptyStack::new(false), renamed_arguments_symbol_ids: FxHashSet::default(), - super_methods: None, + super_methods_stack: Stack::new(), } } } @@ -210,7 +210,7 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> { self.constructor_super_stack.push(false); if self.is_async_only() && func.r#async && Self::is_class_method_like_ancestor(ctx.parent()) { - self.super_methods = Some(FxIndexMap::default()); + self.super_methods_stack.push(FxIndexMap::default()); } } @@ -617,7 +617,7 @@ impl<'a> ArrowFunctionConverter<'a> { /// whose body includes the original `super` expression. The arrow function's name /// is generated based on the property name, such as `_superprop_getProperty`. /// - /// The `super` expressions are temporarily stored in [`Self::super_methods`] + /// The `super` expressions are temporarily stored in [`Self::super_methods_stack`] /// and eventually inserted by [`Self::insert_variable_statement_at_the_top_of_statements`].` /// /// ## Example @@ -640,7 +640,7 @@ impl<'a> ArrowFunctionConverter<'a> { assign_value: Option<&mut Expression<'a>>, ctx: &mut TraverseCtx<'a>, ) -> Option> { - let super_methods = self.super_methods.as_mut()?; + let super_methods = self.super_methods_stack.last_mut()?; let mut argument = None; let mut property = ""; @@ -718,7 +718,7 @@ impl<'a> ArrowFunctionConverter<'a> { call: &mut CallExpression<'a>, ctx: &mut TraverseCtx<'a>, ) -> Option> { - if self.super_methods.is_none() || !call.callee.is_member_expression() { + if self.super_methods_stack.last().is_none() || !call.callee.is_member_expression() { return None; } @@ -757,7 +757,7 @@ impl<'a> ArrowFunctionConverter<'a> { ctx: &mut TraverseCtx<'a>, ) -> Option> { // Check if the left of the assignment is a `super` member expression. - if self.super_methods.is_none() + if self.super_methods_stack.last().is_none() || !assignment.left.as_member_expression().is_some_and(|m| m.object().is_super()) { return None; @@ -1052,10 +1052,11 @@ impl<'a> ArrowFunctionConverter<'a> { let arguments = self.create_arguments_var_declarator(target_scope_id, arguments_var, ctx); let is_class_method_like = Self::is_class_method_like_ancestor(ctx.parent()); - let super_method_count = self.super_methods.as_ref().map_or(0, FxIndexMap::len); - let declarations_count = usize::from(arguments.is_some()) - + if is_class_method_like { super_method_count } else { 0 } - + usize::from(this_var.is_some()); + let super_methods = + if is_class_method_like { self.super_methods_stack.pop() } else { None }; + let super_method_count = super_methods.as_ref().map_or(0, FxIndexMap::len); + let declarations_count = + usize::from(arguments.is_some()) + super_method_count + usize::from(this_var.is_some()); // Exit if no declarations to be inserted if declarations_count == 0 { @@ -1072,8 +1073,8 @@ impl<'a> ArrowFunctionConverter<'a> { // `_superprop_setSomething = _value => super.something = _value;` // `_superprop_set = (_prop, _value) => super[_prop] = _value;` if is_class_method_like { - if let Some(super_methods) = self.super_methods.as_mut() { - declarations.extend(super_methods.drain(..).map(|(key, super_method)| { + if let Some(super_methods) = super_methods { + declarations.extend(super_methods.into_iter().map(|(key, super_method)| { Self::generate_super_method( target_scope_id, super_method, diff --git a/tasks/coverage/snapshots/semantic_misc.snap b/tasks/coverage/snapshots/semantic_misc.snap index cba9ef692b4040..519b4ba84010ca 100644 --- a/tasks/coverage/snapshots/semantic_misc.snap +++ b/tasks/coverage/snapshots/semantic_misc.snap @@ -42,19 +42,19 @@ after transform: ScopeId(0): ["BrowserWorkingCopyBackupTracker", "CancellationTo rebuilt : ScopeId(0): ["BrowserWorkingCopyBackupTracker", "DisposableStore", "EditorService", "IEditorGroupsService", "IEditorService", "IFilesConfigurationService", "ILifecycleService", "ILogService", "IWorkingCopyBackupService", "IWorkingCopyEditorService", "IWorkingCopyService", "InMemoryTestWorkingCopyBackupService", "LifecyclePhase", "Schemas", "TestServiceAccessor", "TestWorkingCopy", "URI", "UntitledTextEditorInput", "VSBuffer", "_asyncToGenerator", "_defineProperty", "assert", "bufferToReadable", "createEditorPart", "ensureNoDisposablesAreLeakedInTestSuite", "isWindows", "registerTestResourceEditor", "timeout", "toResource", "toTypedWorkingCopyId", "toUntypedWorkingCopyId", "workbenchInstantiationService", "workbenchTeardown"] Symbol reference IDs mismatch for "URI": after transform: SymbolId(1): [ReferenceId(109), ReferenceId(117), ReferenceId(156), ReferenceId(158), ReferenceId(160), ReferenceId(162)] -rebuilt : SymbolId(1): [ReferenceId(161), ReferenceId(163), ReferenceId(165), ReferenceId(167)] +rebuilt : SymbolId(1): [ReferenceId(160), ReferenceId(162), ReferenceId(164), ReferenceId(166)] Symbol reference IDs mismatch for "IEditorService": after transform: SymbolId(2): [ReferenceId(23), ReferenceId(24), ReferenceId(67), ReferenceId(184)] -rebuilt : SymbolId(2): [ReferenceId(17), ReferenceId(60), ReferenceId(188)] +rebuilt : SymbolId(2): [ReferenceId(17), ReferenceId(59), ReferenceId(187)] Symbol reference IDs mismatch for "IEditorGroupsService": after transform: SymbolId(4): [ReferenceId(25), ReferenceId(26), ReferenceId(57), ReferenceId(176)] -rebuilt : SymbolId(3): [ReferenceId(18), ReferenceId(51), ReferenceId(181)] +rebuilt : SymbolId(3): [ReferenceId(18), ReferenceId(50), ReferenceId(180)] Symbol reference IDs mismatch for "EditorService": after transform: SymbolId(5): [ReferenceId(61), ReferenceId(64), ReferenceId(178), ReferenceId(181)] -rebuilt : SymbolId(4): [ReferenceId(57), ReferenceId(185)] +rebuilt : SymbolId(4): [ReferenceId(56), ReferenceId(184)] Symbol reference IDs mismatch for "IWorkingCopyBackupService": after transform: SymbolId(7): [ReferenceId(11), ReferenceId(12), ReferenceId(51), ReferenceId(170)] -rebuilt : SymbolId(5): [ReferenceId(11), ReferenceId(45), ReferenceId(175)] +rebuilt : SymbolId(5): [ReferenceId(11), ReferenceId(44), ReferenceId(174)] Symbol reference IDs mismatch for "IFilesConfigurationService": after transform: SymbolId(10): [ReferenceId(13), ReferenceId(14)] rebuilt : SymbolId(8): [ReferenceId(12)] @@ -72,19 +72,19 @@ after transform: SymbolId(17): [ReferenceId(38), ReferenceId(87)] rebuilt : SymbolId(13): [ReferenceId(31)] Symbol reference IDs mismatch for "InMemoryTestWorkingCopyBackupService": after transform: SymbolId(19): [ReferenceId(43), ReferenceId(46), ReferenceId(165)] -rebuilt : SymbolId(15): [ReferenceId(40), ReferenceId(170)] +rebuilt : SymbolId(15): [ReferenceId(39), ReferenceId(169)] Symbol reference IDs mismatch for "TestServiceAccessor": after transform: SymbolId(21): [ReferenceId(1), ReferenceId(40), ReferenceId(71), ReferenceId(155), ReferenceId(188)] -rebuilt : SymbolId(17): [ReferenceId(64), ReferenceId(192)] +rebuilt : SymbolId(17): [ReferenceId(63), ReferenceId(191)] Symbol reference IDs mismatch for "IWorkingCopyEditorService": after transform: SymbolId(32): [ReferenceId(21), ReferenceId(22)] rebuilt : SymbolId(26): [ReferenceId(16)] Symbol reference IDs mismatch for "TestWorkingCopyBackupTracker": after transform: SymbolId(39): [ReferenceId(42), ReferenceId(74), ReferenceId(154), ReferenceId(215)] -rebuilt : SymbolId(35): [ReferenceId(67), ReferenceId(219)] +rebuilt : SymbolId(35): [ReferenceId(66), ReferenceId(218)] Unresolved reference IDs mismatch for "Promise": after transform: [ReferenceId(36), ReferenceId(39), ReferenceId(82), ReferenceId(114), ReferenceId(153), ReferenceId(282)] -rebuilt : [ReferenceId(292)] +rebuilt : [ReferenceId(291)] tasks/coverage/misc/pass/oxc-4449.ts semantic error: Bindings mismatch: diff --git a/tasks/transform_conformance/snapshots/oxc.snap.md b/tasks/transform_conformance/snapshots/oxc.snap.md index 167bfce8e293f8..8c4c1e30b1e2b4 100644 --- a/tasks/transform_conformance/snapshots/oxc.snap.md +++ b/tasks/transform_conformance/snapshots/oxc.snap.md @@ -1,6 +1,6 @@ commit: 54a8389f -Passed: 122/141 +Passed: 123/141 # All Passed: * babel-plugin-transform-class-static-block @@ -9,6 +9,7 @@ Passed: 122/141 * babel-plugin-transform-optional-catch-binding * babel-plugin-transform-async-generator-functions * babel-plugin-transform-object-rest-spread +* babel-plugin-transform-async-to-generator * babel-plugin-transform-exponentiation-operator * babel-plugin-transform-arrow-functions * babel-preset-typescript @@ -45,11 +46,6 @@ after transform: SymbolId(0): [ReferenceId(0), ReferenceId(2), ReferenceId(6), R rebuilt : SymbolId(0): [ReferenceId(0), ReferenceId(2), ReferenceId(6), ReferenceId(10)] -# babel-plugin-transform-async-to-generator (17/18) -* super/nested/input.js -x Output mismatch - - # babel-plugin-transform-typescript (2/10) * class-property-definition/input.ts Unresolved references mismatch: