fix(transformer/async-to-generator): incorrect transform when super expression is inside async method (#7171)

After transformation, super expressions have moved to unexpected places. This PR replaces super expression to call expression, and then inserts the super methods to the top of the method body.

For example:

Before:
```js
class G {
  async method() {
    super.foo()
  }
}
```

After:
```js
class G {
  method() {
    var _superprop_getFoo = () => super.foo,
      _this = this;
    return _asyncToGenerator(function* () {
      _superprop_getFoo().call(_this);
    })();
  }
}```
This commit is contained in:
Dunqing 2024-11-08 08:18:45 +00:00
parent 1910227590
commit ede10dc030
12 changed files with 487 additions and 89 deletions

View file

@ -87,8 +87,8 @@
//! The Implementation based on
//! <https://github.com/babel/babel/blob/d20b314c14533ab86351ecf6ca6b7296b66a57b3/packages/babel-traverse/src/path/conversion.ts#L170-L247>
use oxc_allocator::{Box as ArenaBox, Vec as ArenaVec};
use oxc_ast::ast::*;
use oxc_allocator::{Box as ArenaBox, String as ArenaString, Vec as ArenaVec};
use oxc_ast::{ast::*, AstBuilder, NONE};
use oxc_data_structures::stack::SparseStack;
use oxc_span::SPAN;
use oxc_syntax::{
@ -96,6 +96,7 @@ use oxc_syntax::{
symbol::SymbolFlags,
};
use oxc_traverse::{Ancestor, BoundIdentifier, Traverse, TraverseCtx};
use rustc_hash::FxHashMap;
use crate::TransformOptions;
@ -112,9 +113,19 @@ pub enum ArrowFunctionConverterMode {
AsyncOnly,
}
struct SuperMethodInfo<'a> {
binding: BoundIdentifier<'a>,
super_expr: Expression<'a>,
/// If it is true, the method should accept a prop parameter.
is_computed: bool,
/// If it is true, the method should accept a value parameter.
is_assignment: bool,
}
pub struct ArrowFunctionConverter<'a> {
mode: ArrowFunctionConverterMode,
this_var_stack: SparseStack<BoundIdentifier<'a>>,
super_methods: Option<FxHashMap<Atom<'a>, SuperMethodInfo<'a>>>,
}
impl<'a> ArrowFunctionConverter<'a> {
@ -129,7 +140,7 @@ impl<'a> ArrowFunctionConverter<'a> {
ArrowFunctionConverterMode::Disabled
};
// `SparseStack` is created with 1 empty entry, for `Program`
Self { mode, this_var_stack: SparseStack::new() }
Self { mode, this_var_stack: SparseStack::new(), super_methods: None }
}
}
@ -143,25 +154,27 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
return;
}
if let Some(this_var) = self.this_var_stack.take_last() {
let target_scope_id = program.scope_id();
Self::insert_this_var_statement_at_the_top_of_statements(
&mut program.body,
target_scope_id,
&this_var,
ctx,
);
}
let this_var = self.this_var_stack.take_last();
self.insert_variable_statement_at_the_top_of_statements(
program.scope_id(),
&mut program.body,
this_var,
ctx,
);
debug_assert!(self.this_var_stack.len() == 1);
debug_assert!(self.this_var_stack.last().is_none());
}
fn enter_function(&mut self, _func: &mut Function<'a>, _ctx: &mut TraverseCtx<'a>) {
if self.is_disabled() {
fn enter_function(&mut self, func: &mut Function<'a>, ctx: &mut TraverseCtx<'a>) {
if self.is_disabled() || func.body.is_none() {
return;
}
self.this_var_stack.push(None);
if self.is_async_only() && func.r#async && Self::is_class_method_like_ancestor(ctx.parent())
{
self.super_methods = Some(FxHashMap::default());
}
}
/// ```ts
@ -180,17 +193,17 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
return;
}
if let Some(this_var) = self.this_var_stack.pop() {
let target_scope_id = func.scope_id();
let Some(body) = &mut func.body else { unreachable!() };
Self::insert_this_var_statement_at_the_top_of_statements(
&mut body.statements,
target_scope_id,
&this_var,
ctx,
);
}
let scope_id = func.scope_id();
let Some(body) = &mut func.body else {
return;
};
let this_var = self.this_var_stack.pop();
self.insert_variable_statement_at_the_top_of_statements(
scope_id,
&mut body.statements,
this_var,
ctx,
);
}
fn enter_static_block(&mut self, _block: &mut StaticBlock<'a>, _ctx: &mut TraverseCtx<'a>) {
@ -206,15 +219,13 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
return;
}
if let Some(this_var) = self.this_var_stack.pop() {
let target_scope_id = block.scope_id();
Self::insert_this_var_statement_at_the_top_of_statements(
&mut block.body,
target_scope_id,
&this_var,
ctx,
);
}
let this_var = self.this_var_stack.pop();
self.insert_variable_statement_at_the_top_of_statements(
block.scope_id(),
&mut block.body,
this_var,
ctx,
);
}
fn enter_jsx_element_name(
@ -254,10 +265,22 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
return;
}
if let Expression::ThisExpression(this) = expr {
if let Some(ident) = self.get_this_identifier(this.span, ctx) {
*expr = Expression::Identifier(ident);
let new_expr = match expr {
Expression::ThisExpression(this) => {
self.get_this_identifier(this.span, ctx).map(Expression::Identifier)
}
Expression::CallExpression(call) => self.transform_call_expression_for_super(call, ctx),
Expression::AssignmentExpression(assignment) => {
self.transform_assignment_expression_for_super(assignment, ctx)
}
match_member_expression!(Expression) => {
self.transform_member_expression_for_super(expr, None, ctx)
}
_ => return,
};
if let Some(new_expr) = new_expr {
*expr = new_expr;
}
}
@ -383,14 +406,16 @@ impl<'a> ArrowFunctionConverter<'a> {
// Arrow function
Ancestor::ArrowFunctionExpressionParams(func) => {
return if self.is_async_only() && !*func.r#async() {
None
// Continue checking the parent to see if it's inside an async function.
continue;
} else {
Some(func.scope_id().get().unwrap())
};
}
Ancestor::ArrowFunctionExpressionBody(func) => {
return if self.is_async_only() && !*func.r#async() {
None
// Continue checking the parent to see if it's inside an async function.
continue;
} else {
Some(func.scope_id().get().unwrap())
};
@ -461,34 +486,348 @@ impl<'a> ArrowFunctionConverter<'a> {
}
}
/// Insert `var _this = this;` at the top of the statements.
fn insert_this_var_statement_at_the_top_of_statements(
statements: &mut ArenaVec<'a, Statement<'a>>,
target_scope_id: ScopeId,
this_var: &BoundIdentifier<'a>,
/// Transforms a `MemberExpression` whose object is a `super` expression.
///
/// In the [`AsyncToGenerator`](crate::es2017::async_to_generator::AsyncToGenerator) and
/// [`AsyncGeneratorFunctions`](crate::es2018::async_generator_functions::AsyncGeneratorFunctions) plugins,
/// we move the body of an async method to a new generator function. This can cause
/// `super` expressions to appear in unexpected places, leading to syntax errors.
///
/// ## How it works
///
/// To correctly handle `super` expressions, we need to ensure that they remain
/// within the async method's body.
///
/// This function modifies the `super` expression to call a new arrow function
/// 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`]
/// and eventually inserted by [`Self::insert_variable_statement_at_the_top_of_statements`].`
///
/// ## Example
///
/// Before:
/// ```js
/// super.property;
/// super['property']
/// ```
///
/// After:
/// ```js
/// var _superprop_getProperty = () => super.property, _superprop_get = (_prop) => super[_prop];
/// _superprop_getProperty();
/// _superprop_get('property')
/// ```
fn transform_member_expression_for_super(
&mut self,
expr: &mut Expression<'a>,
assign_value: Option<&mut Expression<'a>>,
ctx: &mut TraverseCtx<'a>,
) {
let symbol_id = this_var.symbol_id;
let scope_id = ctx.symbols().get_scope_id(symbol_id);
// Because scope can be moved or deleted, we need to check the scope id again,
// if it's different, we need to move the binding to the target scope.
if target_scope_id != scope_id {
ctx.scopes_mut().move_binding(scope_id, target_scope_id, &this_var.name);
ctx.symbols_mut().set_scope_id(symbol_id, target_scope_id);
) -> Option<Expression<'a>> {
let super_methods = self.super_methods.as_mut()?;
let mut argument = None;
let mut property = Atom::empty();
let init = match expr.to_member_expression_mut() {
MemberExpression::ComputedMemberExpression(computed_member) => {
if !matches!(computed_member.object, Expression::Super(_)) {
return None;
}
// The property will as a parameter to pass to the new arrow function.
// `super[property]` to `_superprop_get(property)`
argument = Some(ctx.ast.move_expression(&mut computed_member.expression));
ctx.ast.move_expression(&mut computed_member.object)
}
MemberExpression::StaticMemberExpression(static_member) => {
if !matches!(static_member.object, Expression::Super(_)) {
return None;
}
// Used to generate the name of the arrow function.
property = static_member.property.name.clone();
ctx.ast.move_expression(expr)
}
MemberExpression::PrivateFieldExpression(_) => {
// Private fields can't be accessed by `super`.
return None;
}
};
let binding_name =
Self::generate_super_binding_name(assign_value.is_some(), &property, ctx.ast);
let super_info = super_methods.entry(binding_name.clone()).or_insert_with(|| {
let binding = ctx
.generate_uid_in_current_scope(&binding_name, SymbolFlags::FunctionScopedVariable);
SuperMethodInfo {
binding,
super_expr: init,
is_computed: argument.is_some(),
is_assignment: assign_value.is_some(),
}
});
let callee = super_info.binding.create_read_expression(ctx);
let mut arguments = ctx.ast.vec_with_capacity(
usize::from(assign_value.is_some()) + usize::from(argument.is_some()),
);
// _prop
if let Some(argument) = argument {
arguments.push(Argument::from(argument));
}
// _value
if let Some(assign_value) = assign_value {
arguments.push(Argument::from(ctx.ast.move_expression(assign_value)));
}
let call = ctx.ast.expression_call(SPAN, callee, NONE, arguments, false);
Some(call)
}
/// Transform a `CallExpression` whose callee is a `super` member expression.
///
/// This function modifies calls to `super` methods within arrow functions
/// to ensure the correct `this` context is maintained after transformation.
///
/// ## Example
///
/// Before:
/// ```js
/// super.method(a, b);
/// ```
///
/// After:
/// ```js
/// var _superprop_getMethod = () => super.method;
/// _superprop_getMethod.call(this, a, b);
/// ```
#[inline]
fn transform_call_expression_for_super(
&mut self,
call: &mut CallExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Option<Expression<'a>> {
if self.super_methods.is_none() || !call.callee.is_member_expression() {
return None;
}
let variable_declarator = ctx.ast.variable_declarator(
let object = self.transform_member_expression_for_super(&mut call.callee, None, ctx)?;
// Add `this` as the first argument and original arguments as the rest.
let mut arguments = ctx.ast.vec_with_capacity(call.arguments.len() + 1);
arguments.push(Argument::from(ctx.ast.expression_this(SPAN)));
arguments.extend(ctx.ast.move_vec(&mut call.arguments));
let property = ctx.ast.identifier_name(SPAN, "call");
let callee = ctx.ast.member_expression_static(SPAN, object, property, false);
let callee = Expression::from(callee);
Some(ctx.ast.expression_call(SPAN, callee, NONE, arguments, false))
}
/// Transform an `AssignmentExpression` whose assignment target is a `super` member expression.
///
/// In this function, we replace assignments to call a new arrow function whose body includes
/// [AssignmentExpression::left], and use [AssignmentExpression::right] as arguments for the call expression.
///
/// ## Example
///
/// Before:
/// ```js
/// super.value = true;
/// ```
///
/// After:
/// ```js
/// var _superprop_setValue = (_value) => super.value = _value;
/// _superprop_setValue(true);
/// ```
fn transform_assignment_expression_for_super(
&mut self,
assignment: &mut AssignmentExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Option<Expression<'a>> {
// Check if the left of the assignment is a `super` member expression.
if self.super_methods.is_none()
|| !assignment
.left
.as_member_expression()
.is_some_and(|m| matches!(m.object(), Expression::Super(_)))
{
return None;
}
let assignment_target = ctx.ast.move_assignment_target(&mut assignment.left);
let mut assignment_expr = Expression::from(assignment_target.into_member_expression());
self.transform_member_expression_for_super(
&mut assignment_expr,
Some(&mut assignment.right),
ctx,
)
}
/// Adjust the scope of the binding.
///
/// Since scope can be moved or deleted, we need to ensure the scope of the binding
/// same as the target scope, if it's mismatch, we need to move the binding to the target scope.
fn adjust_binding_scope(
target_scope_id: ScopeId,
binding: &BoundIdentifier<'a>,
ctx: &mut TraverseCtx<'a>,
) {
let original_scope_id = ctx.symbols().get_scope_id(binding.symbol_id);
if target_scope_id != original_scope_id {
ctx.symbols_mut().set_scope_id(binding.symbol_id, target_scope_id);
ctx.scopes_mut().move_binding(original_scope_id, target_scope_id, &binding.name);
}
}
/// Generate a variable declarator for the super method by the given [`SuperMethodInfo`].
fn generate_super_method(
target_scope_id: ScopeId,
super_method: SuperMethodInfo<'a>,
ctx: &mut TraverseCtx<'a>,
) -> VariableDeclarator<'a> {
let SuperMethodInfo { binding, super_expr: mut init, is_computed, is_assignment } =
super_method;
Self::adjust_binding_scope(target_scope_id, &binding, ctx);
let scope_id =
ctx.create_child_scope(target_scope_id, ScopeFlags::Arrow | ScopeFlags::Function);
let mut items = ctx.ast.vec_with_capacity(2);
// Create a parameter for the prop if it's a computed member expression.
if is_computed {
let param_binding =
ctx.generate_uid("prop", scope_id, SymbolFlags::FunctionScopedVariable);
let param = ctx.ast.formal_parameter(
SPAN,
ctx.ast.vec(),
param_binding.create_binding_pattern(ctx),
None,
false,
false,
);
items.push(param);
// `super` -> `super[prop]`
init = Expression::from(ctx.ast.member_expression_computed(
SPAN,
init,
param_binding.create_read_expression(ctx),
false,
));
};
// Create a parameter for the value if it's an assignment.
if is_assignment {
let param_binding =
ctx.generate_uid("value", scope_id, SymbolFlags::FunctionScopedVariable);
let param = ctx.ast.formal_parameter(
SPAN,
ctx.ast.vec(),
param_binding.create_binding_pattern(ctx),
None,
false,
false,
);
items.push(param);
// `super[prop]` -> `super[prop] = value`
let left = SimpleAssignmentTarget::from(init.into_member_expression());
let left = AssignmentTarget::from(left);
let right = param_binding.create_read_expression(ctx);
init = ctx.ast.expression_assignment(SPAN, AssignmentOperator::Assign, left, right);
}
let params = ctx.ast.formal_parameters(
SPAN,
FormalParameterKind::ArrowFormalParameters,
items,
NONE,
);
let statements = ctx.ast.vec1(ctx.ast.statement_expression(SPAN, init));
let body = ctx.ast.function_body(SPAN, ctx.ast.vec(), statements);
let init = ctx.ast.alloc_arrow_function_expression_with_scope_id(
SPAN, true, false, NONE, params, NONE, body, scope_id,
);
ctx.ast.variable_declarator(
SPAN,
VariableDeclarationKind::Var,
this_var.create_binding_pattern(ctx),
Some(ctx.ast.expression_this(SPAN)),
binding.create_binding_pattern(ctx),
Some(Expression::ArrowFunctionExpression(init)),
false,
);
)
}
/// Generate a binding name for the super method, like `_superprop_getXXX`.
fn generate_super_binding_name(
is_assignment: bool,
property: &Atom<'a>,
ast: AstBuilder<'a>,
) -> Atom<'a> {
let mut name = ArenaString::new_in(ast.allocator);
name.push_str("superprop_");
if is_assignment {
name.push_str("set");
} else {
name.push_str("get");
}
// Capitalize the first letter of the property name.
if let Some(first_byte) = property.as_bytes().first() {
name.push(first_byte.to_ascii_uppercase() as char);
}
if property.len() > 1 {
name.push_str(&property[1..]);
}
ast.atom(name.into_bump_str())
}
/// Insert variable statement at the top of the statements.
fn insert_variable_statement_at_the_top_of_statements(
&mut self,
target_scope_id: ScopeId,
statements: &mut ArenaVec<'a, Statement<'a>>,
this_var: Option<BoundIdentifier<'a>>,
ctx: &mut TraverseCtx<'a>,
) {
// `_superprop_getSomething = () => super.getSomething;`
let mut declarations = if Self::is_class_method_like_ancestor(ctx.parent()) {
if let Some(super_methods) = self.super_methods.as_mut() {
let mut declarations = ctx.ast.vec_with_capacity(super_methods.len() + 1);
declarations.extend(super_methods.drain().map(|(_, super_method)| {
Self::generate_super_method(target_scope_id, super_method, ctx)
}));
declarations
} else {
ctx.ast.vec_with_capacity(1)
}
} else {
ctx.ast.vec_with_capacity(1)
};
// `_this = this;`
if let Some(this_var) = this_var {
Self::adjust_binding_scope(target_scope_id, &this_var, ctx);
let variable_declarator = ctx.ast.variable_declarator(
SPAN,
VariableDeclarationKind::Var,
this_var.create_binding_pattern(ctx),
Some(ctx.ast.expression_this(SPAN)),
false,
);
declarations.push(variable_declarator);
}
// If there are no declarations, we don't need to insert a variable declaration.
if declarations.is_empty() {
return;
}
let stmt = ctx.ast.alloc_variable_declaration(
SPAN,
VariableDeclarationKind::Var,
ctx.ast.vec1(variable_declarator),
declarations,
false,
);

View file

@ -1,4 +1,4 @@
mod async_to_generator;
pub(crate) mod async_to_generator;
mod options;
use oxc_ast::ast::{Expression, Function, Statement};

View file

@ -1,4 +1,4 @@
mod async_generator_functions;
pub(crate) mod async_generator_functions;
mod object_rest_spread;
mod options;

View file

@ -57,19 +57,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", "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(147), ReferenceId(149), ReferenceId(151), ReferenceId(153)]
rebuilt : SymbolId(1): [ReferenceId(150), ReferenceId(152), ReferenceId(154), ReferenceId(156)]
Symbol reference IDs mismatch for "IEditorService":
after transform: SymbolId(2): [ReferenceId(23), ReferenceId(24), ReferenceId(67), ReferenceId(184)]
rebuilt : SymbolId(2): [ReferenceId(17), ReferenceId(55), ReferenceId(174)]
rebuilt : SymbolId(2): [ReferenceId(17), ReferenceId(58), ReferenceId(177)]
Symbol reference IDs mismatch for "IEditorGroupsService":
after transform: SymbolId(4): [ReferenceId(25), ReferenceId(26), ReferenceId(57), ReferenceId(176)]
rebuilt : SymbolId(3): [ReferenceId(18), ReferenceId(46), ReferenceId(167)]
rebuilt : SymbolId(3): [ReferenceId(18), ReferenceId(49), ReferenceId(170)]
Symbol reference IDs mismatch for "EditorService":
after transform: SymbolId(5): [ReferenceId(61), ReferenceId(64), ReferenceId(178), ReferenceId(181)]
rebuilt : SymbolId(4): [ReferenceId(52), ReferenceId(171)]
rebuilt : SymbolId(4): [ReferenceId(55), ReferenceId(174)]
Symbol reference IDs mismatch for "IWorkingCopyBackupService":
after transform: SymbolId(7): [ReferenceId(11), ReferenceId(12), ReferenceId(51), ReferenceId(170)]
rebuilt : SymbolId(5): [ReferenceId(11), ReferenceId(40), ReferenceId(161)]
rebuilt : SymbolId(5): [ReferenceId(11), ReferenceId(43), ReferenceId(164)]
Symbol reference IDs mismatch for "IFilesConfigurationService":
after transform: SymbolId(10): [ReferenceId(13), ReferenceId(14)]
rebuilt : SymbolId(8): [ReferenceId(12)]
@ -84,22 +84,22 @@ after transform: SymbolId(14): [ReferenceId(17), ReferenceId(18)]
rebuilt : SymbolId(11): [ReferenceId(14)]
Symbol reference IDs mismatch for "UntitledTextEditorInput":
after transform: SymbolId(17): [ReferenceId(38), ReferenceId(87)]
rebuilt : SymbolId(13): [ReferenceId(29)]
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(35), ReferenceId(156)]
rebuilt : SymbolId(15): [ReferenceId(38), ReferenceId(159)]
Symbol reference IDs mismatch for "TestServiceAccessor":
after transform: SymbolId(21): [ReferenceId(1), ReferenceId(40), ReferenceId(71), ReferenceId(155), ReferenceId(188)]
rebuilt : SymbolId(17): [ReferenceId(59), ReferenceId(178)]
rebuilt : SymbolId(17): [ReferenceId(62), ReferenceId(181)]
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(34): [ReferenceId(62), ReferenceId(205)]
rebuilt : SymbolId(34): [ReferenceId(65), ReferenceId(208)]
Unresolved reference IDs mismatch for "Promise":
after transform: [ReferenceId(36), ReferenceId(39), ReferenceId(82), ReferenceId(114), ReferenceId(153), ReferenceId(282)]
rebuilt : [ReferenceId(278)]
rebuilt : [ReferenceId(281)]
tasks/coverage/misc/pass/oxc-4449.ts
semantic error: Scope flags mismatch:

View file

@ -20458,13 +20458,22 @@ rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)
tasks/coverage/test262/test/language/expressions/object/method-definition/async-super-call-body.js
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(3): SymbolFlags(Import)
after transform: SymbolId(5): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)
tasks/coverage/test262/test/language/expressions/object/method-definition/async-super-call-param.js
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(4): SymbolFlags(Import)
after transform: SymbolId(5): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)
Symbol reference IDs mismatch for "_superprop_getMethod":
after transform: SymbolId(4): [ReferenceId(9)]
rebuilt : SymbolId(4): []
Reference symbol mismatch for "_superprop_getMethod":
after transform: SymbolId(4) "_superprop_getMethod"
rebuilt : <None>
Unresolved references mismatch:
after transform: ["$DONE", "Object", "assert", "require"]
rebuilt : ["$DONE", "Object", "_superprop_getMethod", "assert", "require"]
tasks/coverage/test262/test/language/expressions/object/method-definition/forbidden-ext/b1/async-gen-meth-forbidden-ext-direct-access-prop-arguments.js
semantic error: Symbol flags mismatch for "_wrapAsyncGenerator":
@ -24611,6 +24620,15 @@ tasks/coverage/test262/test/language/statements/class/definition/methods-async-s
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(4): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)
Symbol reference IDs mismatch for "_superprop_getMethod":
after transform: SymbolId(5): [ReferenceId(8)]
rebuilt : SymbolId(4): []
Reference symbol mismatch for "_superprop_getMethod":
after transform: SymbolId(5) "_superprop_getMethod"
rebuilt : <None>
Unresolved references mismatch:
after transform: ["$DONE", "assert", "require"]
rebuilt : ["$DONE", "_superprop_getMethod", "assert", "require"]
tasks/coverage/test262/test/language/statements/class/dstr/async-gen-meth-ary-init-iter-close.js
semantic error: Symbol flags mismatch for "_wrapAsyncGenerator":

View file

@ -38180,12 +38180,12 @@ rebuilt : ["arguments", "mp", "p", "require"]
tasks/coverage/typescript/tests/cases/conformance/async/es2017/asyncMethodWithSuperConflict_es6.ts
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(11): SymbolFlags(Import)
after transform: SymbolId(15): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)
tasks/coverage/typescript/tests/cases/conformance/async/es2017/asyncMethodWithSuper_es2017.ts
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(7): SymbolFlags(Import)
after transform: SymbolId(11): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)
tasks/coverage/typescript/tests/cases/conformance/async/es2017/asyncUseStrict_es2017.ts
@ -38566,8 +38566,8 @@ rebuilt : ["arguments", "require"]
tasks/coverage/typescript/tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction11_es5.ts
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(3): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)
after transform: SymbolId(4): SymbolFlags(Import)
rebuilt : SymbolId(1): SymbolFlags(FunctionScopedVariable)
tasks/coverage/typescript/tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction1_es5.ts
semantic error: Symbol flags mismatch for "_asyncToGenerator":
@ -38658,7 +38658,7 @@ rebuilt : ScopeId(1): []
tasks/coverage/typescript/tests/cases/conformance/async/es5/asyncMethodWithSuper_es5.ts
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(7): SymbolFlags(Import)
after transform: SymbolId(11): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)
tasks/coverage/typescript/tests/cases/conformance/async/es5/asyncMultiFile_es5.ts
@ -39173,10 +39173,10 @@ rebuilt : ["arguments", "mp", "p", "require"]
tasks/coverage/typescript/tests/cases/conformance/async/es6/asyncMethodWithSuper_es6.ts
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(21): SymbolFlags(Import)
after transform: SymbolId(25): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)
Symbol flags mismatch for "_wrapAsyncGenerator":
after transform: SymbolId(22): SymbolFlags(Import)
after transform: SymbolId(48): SymbolFlags(Import)
rebuilt : SymbolId(1): SymbolFlags(FunctionScopedVariable)
tasks/coverage/typescript/tests/cases/conformance/async/es6/asyncMultiFile_es6.ts
@ -47284,7 +47284,7 @@ rebuilt : ["o1", "o2", "o3", "o4"]
tasks/coverage/typescript/tests/cases/conformance/expressions/optionalChaining/callChain/superMethodCall.ts
semantic error: Symbol flags mismatch for "_asyncToGenerator":
after transform: SymbolId(2): SymbolFlags(Import)
after transform: SymbolId(3): SymbolFlags(Import)
rebuilt : SymbolId(0): SymbolFlags(FunctionScopedVariable)
tasks/coverage/typescript/tests/cases/conformance/expressions/optionalChaining/elementAccessChain/elementAccessChain.2.ts

View file

@ -1,6 +1,6 @@
commit: d20b314c
Passed: 314/626
Passed: 316/626
# All Passed:
* babel-plugin-transform-class-static-block
@ -13,7 +13,7 @@ Passed: 314/626
* babel-plugin-transform-react-jsx-source
# babel-preset-env (40/127)
# babel-preset-env (41/127)
* dynamic-import/auto-esm-unsupported-import-unsupported/input.mjs
x Output mismatch
@ -107,9 +107,6 @@ x Output mismatch
* plugins-integration/issue-7527/input.mjs
x Output mismatch
* plugins-integration/issue-9935/input.js
x Output mismatch
* plugins-integration/regression-2892/input.mjs
x Output mismatch
@ -463,7 +460,7 @@ x Output mismatch
x Output mismatch
# babel-plugin-transform-async-to-generator (10/24)
# babel-plugin-transform-async-to-generator (11/24)
* assumption-ignoreFunctionLength-true/basic/input.mjs
x Output mismatch
@ -476,9 +473,6 @@ x Output mismatch
* async-to-generator/async-iife-with-regenerator-spec/input.js
x Output mismatch
* async-to-generator/object-method-with-super/input.js
x Output mismatch
* bluebird-coroutines/arrow-function/input.js
x Output mismatch

View file

@ -1,6 +1,6 @@
commit: d20b314c
Passed: 80/89
Passed: 82/91
# All Passed:
* babel-plugin-transform-class-static-block

View file

@ -0,0 +1,10 @@
const Obj = {
value: 0,
async method() {
super.value = true;
() => {
super['value'] = true;
super.object.value = true;
}
}
}

View file

@ -0,0 +1,15 @@
const Obj = {
value: 0,
method() {
var _superprop_getObject = () => super.object,
_superprop_set = (_prop, _value) => super[_prop] = _value,
_superprop_setValue = _value2 => super.value = _value2;
return babelHelpers.asyncToGenerator(function* () {
_superprop_setValue(true);
() => {
_superprop_set('value', true);
_superprop_getObject().value = true;
};
})();
}
};

View file

@ -0,0 +1,9 @@
class Foo extends class {} {
async method() {
super['name'];
{
super['name']();
super['object']['name']();
}
}
}

View file

@ -0,0 +1,13 @@
class Foo extends class {} {
method() {
var _superprop_get = _prop => super[_prop],
_this = this;
return babelHelpers.asyncToGenerator(function* () {
_superprop_get('name');
{
_superprop_get('name').call(_this);
_superprop_get('object')['name']();
}
})();
}
}