Skip to content

Commit

Permalink
fix(transformer/arrow-functions): do not transform super that inside …
Browse files Browse the repository at this point in the history
…nested non-async method
  • Loading branch information
Dunqing authored and overlookmotel committed Jan 8, 2025
1 parent e4d66e4 commit 63b2501
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 7 deletions.
34 changes: 29 additions & 5 deletions crates/oxc_transformer/src/common/arrow_function_converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, Stack};
use oxc_data_structures::stack::{NonEmptyStack, SparseStack};
use oxc_semantic::{ReferenceFlags, SymbolId};
use oxc_span::{CompactStr, GetSpan, SPAN};
use oxc_syntax::{
Expand Down Expand Up @@ -144,7 +144,7 @@ pub struct ArrowFunctionConverter<'a> {
renamed_arguments_symbol_ids: FxHashSet<SymbolId>,
// 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_stack: Stack<FxIndexMap<SuperMethodKey<'a>, SuperMethodInfo<'a>>>,
super_methods_stack: SparseStack<FxIndexMap<SuperMethodKey<'a>, SuperMethodInfo<'a>>>,
}

impl ArrowFunctionConverter<'_> {
Expand All @@ -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_stack: Stack::new(),
super_methods_stack: SparseStack::new(),
}
}
}
Expand Down Expand Up @@ -208,9 +208,33 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
self.this_var_stack.push(None);
self.arguments_var_stack.push(None);
self.constructor_super_stack.push(false);
if self.is_async_only() && func.r#async && Self::is_class_method_like_ancestor(ctx.parent())

if self.is_async_only()
&& (func.r#async ||
// is used to confirm if it is a nested class method.
self.super_methods_stack.len() != 0)
&& Self::is_class_method_like_ancestor(ctx.parent())
{
self.super_methods_stack.push(FxIndexMap::default());
// Only `super` that inside async methods need to be transformed, if it is a
// nested class method and it is not async, we still need to push a `None` to
// `self.super_methods_stack`, because if we don't get a `FxIndexMap` from
// `self.super_methods_stack.last_mut()`, that means we don't need to transform.
// See how to transform `super` in `self.transform_member_expression_for_super`
//
// ```js
// class Outer {
// async method() {
// class Inner extends Outer {
// normal() {
// // `super.value` should not be transformed, because it is not in an async method
// super.value
// }
// }
// }
// }
// ```
let super_methods = if func.r#async { Some(FxIndexMap::default()) } else { None };
self.super_methods_stack.push(super_methods);
}
}

Expand Down
8 changes: 6 additions & 2 deletions tasks/transform_conformance/snapshots/oxc.snap.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
commit: 54a8389f

Passed: 123/141
Passed: 122/141

# All Passed:
* babel-plugin-transform-class-static-block
Expand All @@ -9,7 +9,6 @@ Passed: 123/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
Expand Down Expand Up @@ -46,6 +45,11 @@ 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:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Root {}
class Outer extends Root {
value = 0
async method() {
() => super.value;

class Inner extends Outer {
normal() {
console.log(super.value);
}
async method() {
() => super.value;
}
};

() => super.value;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class Root {}
class Outer extends Root {
constructor(...args) {
super(...args);
babelHelpers.defineProperty(this, "value", 0);
}
method() {
var _superprop_getValue = () => super.value;
return babelHelpers.asyncToGenerator(function* () {
() => _superprop_getValue();
class Inner extends Outer {
normal() {
console.log(super.value);
}
method() {
var _superprop_getValue2 = () => super.value;
return babelHelpers.asyncToGenerator(function* () {
() => _superprop_getValue2();
})();
}
}
;
() => _superprop_getValue();
})();
}
}
;
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const outer = {

const inner = {
value: 0,
normal() {
console.log(super.value);
},
async method() {
() => super.value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const outer = {

const inner = {
value: 0,
normal() {
console.log(super.value);
},
method() {
var _superprop_getValue2 = () => super.value;
return babelHelpers.asyncToGenerator(function* () {
Expand Down

0 comments on commit 63b2501

Please sign in to comment.