mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
fix(transformer/arrow-functions): transform this and super incorrectly in async arrow function (#8435)
close: #8385 This PR is to solve the missing `super` transform in the async arrow function, and `_this = this` inserts to an incorrect place. These problems are all about the async arrow function, which is a part of the init of class property. Learn more at #8387. The output matches Babel's output except for static prop as Babel transforms incorrectly.
This commit is contained in:
parent
0358c6f6c3
commit
c444de8be1
8 changed files with 209 additions and 52 deletions
|
|
@ -144,7 +144,8 @@ pub struct ArrowFunctionConverter<'a> {
|
||||||
renamed_arguments_symbol_ids: FxHashSet<SymbolId>,
|
renamed_arguments_symbol_ids: FxHashSet<SymbolId>,
|
||||||
// TODO(improve-on-babel): `FxHashMap` would suffice here. Iteration order is not important.
|
// 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.
|
// Only using `FxIndexMap` for predictable iteration order to match Babel's output.
|
||||||
super_methods_stack: SparseStack<FxIndexMap<SuperMethodKey<'a>, SuperMethodInfo<'a>>>,
|
super_methods_stack: NonEmptyStack<FxIndexMap<SuperMethodKey<'a>, SuperMethodInfo<'a>>>,
|
||||||
|
super_needs_transform_stack: NonEmptyStack<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ArrowFunctionConverter<'_> {
|
impl ArrowFunctionConverter<'_> {
|
||||||
|
|
@ -164,7 +165,8 @@ impl ArrowFunctionConverter<'_> {
|
||||||
constructor_super_stack: NonEmptyStack::new(false),
|
constructor_super_stack: NonEmptyStack::new(false),
|
||||||
arguments_needs_transform_stack: NonEmptyStack::new(false),
|
arguments_needs_transform_stack: NonEmptyStack::new(false),
|
||||||
renamed_arguments_symbol_ids: FxHashSet::default(),
|
renamed_arguments_symbol_ids: FxHashSet::default(),
|
||||||
super_methods_stack: SparseStack::new(),
|
super_methods_stack: NonEmptyStack::new(FxIndexMap::default()),
|
||||||
|
super_needs_transform_stack: NonEmptyStack::new(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -198,10 +200,12 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
|
||||||
debug_assert!(self.constructor_super_stack.len() == 1);
|
debug_assert!(self.constructor_super_stack.len() == 1);
|
||||||
// TODO: This assertion currently failing because we don't handle `super` in arrow functions
|
// TODO: This assertion currently failing because we don't handle `super` in arrow functions
|
||||||
// in class static properties correctly.
|
// in class static properties correctly.
|
||||||
// e.g. `class C { static f = async () => super.prop; }`
|
// e.g. `class C { static f = () => super.prop; }`
|
||||||
// debug_assert!(self.constructor_super_stack.last() == &false);
|
// debug_assert!(self.constructor_super_stack.last() == &false);
|
||||||
debug_assert!(self.super_methods_stack.len() == 1);
|
debug_assert!(self.super_methods_stack.len() == 1);
|
||||||
debug_assert!(self.super_methods_stack.last().is_none());
|
debug_assert!(self.super_methods_stack.last().is_empty());
|
||||||
|
debug_assert!(self.super_needs_transform_stack.len() == 1);
|
||||||
|
debug_assert!(self.super_needs_transform_stack.last() == &false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_function(&mut self, func: &mut Function<'a>, ctx: &mut TraverseCtx<'a>) {
|
fn enter_function(&mut self, func: &mut Function<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
|
|
@ -213,32 +217,9 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
|
||||||
self.arguments_var_stack.push(None);
|
self.arguments_var_stack.push(None);
|
||||||
self.constructor_super_stack.push(false);
|
self.constructor_super_stack.push(false);
|
||||||
|
|
||||||
if self.is_async_only()
|
if Self::is_class_method_like_ancestor(ctx.parent()) {
|
||||||
&& (func.r#async || self.super_methods_stack.len() > 1)
|
self.super_methods_stack.push(FxIndexMap::default());
|
||||||
&& Self::is_class_method_like_ancestor(ctx.parent())
|
self.super_needs_transform_stack.push(func.r#async);
|
||||||
{
|
|
||||||
// `self.super_methods_stack.len() > 1` means we are in a nested class method
|
|
||||||
//
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -264,14 +245,11 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
|
||||||
};
|
};
|
||||||
let this_var = self.this_var_stack.pop();
|
let this_var = self.this_var_stack.pop();
|
||||||
let arguments_var = self.arguments_var_stack.pop();
|
let arguments_var = self.arguments_var_stack.pop();
|
||||||
let super_methods = if self.is_async_only()
|
let super_methods = Self::is_class_method_like_ancestor(ctx.parent()).then(|| {
|
||||||
&& (func.r#async || self.super_methods_stack.len() > 1)
|
self.super_needs_transform_stack.pop();
|
||||||
&& Self::is_class_method_like_ancestor(ctx.parent())
|
|
||||||
{
|
|
||||||
self.super_methods_stack.pop()
|
self.super_methods_stack.pop()
|
||||||
} else {
|
});
|
||||||
None
|
|
||||||
};
|
|
||||||
self.insert_variable_statement_at_the_top_of_statements(
|
self.insert_variable_statement_at_the_top_of_statements(
|
||||||
scope_id,
|
scope_id,
|
||||||
&mut body.statements,
|
&mut body.statements,
|
||||||
|
|
@ -286,11 +264,41 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
|
||||||
fn enter_arrow_function_expression(
|
fn enter_arrow_function_expression(
|
||||||
&mut self,
|
&mut self,
|
||||||
arrow: &mut ArrowFunctionExpression<'a>,
|
arrow: &mut ArrowFunctionExpression<'a>,
|
||||||
_ctx: &mut TraverseCtx<'a>,
|
ctx: &mut TraverseCtx<'a>,
|
||||||
) {
|
) {
|
||||||
if self.is_async_only() {
|
if self.is_async_only() {
|
||||||
let previous = *self.arguments_needs_transform_stack.last();
|
let previous = *self.arguments_needs_transform_stack.last();
|
||||||
self.arguments_needs_transform_stack.push(previous || arrow.r#async);
|
self.arguments_needs_transform_stack.push(previous || arrow.r#async);
|
||||||
|
|
||||||
|
if Self::if_ancestor_of_class_property_definition_value(ctx) {
|
||||||
|
self.this_var_stack.push(None);
|
||||||
|
self.super_methods_stack.push(FxIndexMap::default());
|
||||||
|
}
|
||||||
|
self.super_needs_transform_stack
|
||||||
|
.push(arrow.r#async || *self.super_needs_transform_stack.last());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exit_arrow_function_expression(
|
||||||
|
&mut self,
|
||||||
|
arrow: &mut ArrowFunctionExpression<'a>,
|
||||||
|
ctx: &mut TraverseCtx<'a>,
|
||||||
|
) {
|
||||||
|
if self.is_async_only() {
|
||||||
|
if Self::if_ancestor_of_class_property_definition_value(ctx) {
|
||||||
|
let this_var = self.this_var_stack.pop();
|
||||||
|
let super_methods = self.super_methods_stack.pop();
|
||||||
|
self.insert_variable_statement_at_the_top_of_statements(
|
||||||
|
arrow.scope_id(),
|
||||||
|
&mut arrow.body.statements,
|
||||||
|
this_var,
|
||||||
|
None,
|
||||||
|
Some(super_methods),
|
||||||
|
ctx,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.super_needs_transform_stack.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -318,6 +326,7 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.this_var_stack.push(None);
|
self.this_var_stack.push(None);
|
||||||
|
self.super_methods_stack.push(FxIndexMap::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit_static_block(&mut self, block: &mut StaticBlock<'a>, ctx: &mut TraverseCtx<'a>) {
|
fn exit_static_block(&mut self, block: &mut StaticBlock<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
|
|
@ -326,14 +335,14 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let this_var = self.this_var_stack.pop();
|
let this_var = self.this_var_stack.pop();
|
||||||
|
let super_methods = self.super_methods_stack.pop();
|
||||||
self.insert_variable_statement_at_the_top_of_statements(
|
self.insert_variable_statement_at_the_top_of_statements(
|
||||||
block.scope_id(),
|
block.scope_id(),
|
||||||
&mut block.body,
|
&mut block.body,
|
||||||
this_var,
|
this_var,
|
||||||
// `arguments` is not allowed to be used in static blocks
|
// `arguments` is not allowed to be used in static blocks
|
||||||
None,
|
None,
|
||||||
// `super()` Only allowed in class constructor
|
Some(super_methods),
|
||||||
None,
|
|
||||||
ctx,
|
ctx,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -390,6 +399,36 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
|
||||||
match_member_expression!(Expression) => {
|
match_member_expression!(Expression) => {
|
||||||
self.transform_member_expression_for_super(expr, None, ctx)
|
self.transform_member_expression_for_super(expr, None, ctx)
|
||||||
}
|
}
|
||||||
|
Expression::ArrowFunctionExpression(arrow) => {
|
||||||
|
// TODO: If the async arrow function without `this` or `super` usage, we can skip this step.
|
||||||
|
if self.is_async_only()
|
||||||
|
&& arrow.r#async
|
||||||
|
&& Self::if_ancestor_of_class_property_definition_value(ctx)
|
||||||
|
{
|
||||||
|
// Inside class property definition value, since async arrow function will be
|
||||||
|
// converted to a generator function by `AsyncToGenerator` plugin, ensure
|
||||||
|
// `_this = this` and `super` methods are inserted correctly. We need to
|
||||||
|
// wrap the async arrow function with an normal arrow function IIFE.
|
||||||
|
//
|
||||||
|
// ```js
|
||||||
|
// class A {
|
||||||
|
// prop = async () => {}
|
||||||
|
// }
|
||||||
|
// // to
|
||||||
|
// class A {
|
||||||
|
// prop = (() => { return async () => {} })();
|
||||||
|
// }
|
||||||
|
// ```
|
||||||
|
Some(Self::wrap_arrow_function_with_iife(
|
||||||
|
arrow.span,
|
||||||
|
arrow.scope_id(),
|
||||||
|
expr,
|
||||||
|
ctx,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -404,7 +443,9 @@ impl<'a> Traverse<'a> for ArrowFunctionConverter<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Expression::ArrowFunctionExpression(arrow_function_expr) = expr {
|
if let Expression::ArrowFunctionExpression(arrow_function_expr) = expr {
|
||||||
if self.is_async_only() && !arrow_function_expr.r#async {
|
// TODO: Here should return early as long as the async-to-generator plugin is enabled,
|
||||||
|
// but currently we don't know which plugin is enabled.
|
||||||
|
if self.is_async_only() || arrow_function_expr.r#async {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -640,6 +681,19 @@ impl<'a> ArrowFunctionConverter<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check whether the ancestor is an [`Ancestor::PropertyDefinitionValue`],
|
||||||
|
/// return false if it's reached the statement.
|
||||||
|
fn if_ancestor_of_class_property_definition_value(ctx: &mut TraverseCtx<'a>) -> bool {
|
||||||
|
for ancestor in ctx.ancestors() {
|
||||||
|
if ancestor.is_parent_of_statement() {
|
||||||
|
return false;
|
||||||
|
} else if matches!(ancestor, Ancestor::PropertyDefinitionValue(_)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
/// Transforms a `MemberExpression` whose object is a `super` expression.
|
/// Transforms a `MemberExpression` whose object is a `super` expression.
|
||||||
///
|
///
|
||||||
/// In the [`AsyncToGenerator`](crate::es2017::AsyncToGenerator) and
|
/// In the [`AsyncToGenerator`](crate::es2017::AsyncToGenerator) and
|
||||||
|
|
@ -679,7 +733,11 @@ impl<'a> ArrowFunctionConverter<'a> {
|
||||||
assign_value: Option<&mut Expression<'a>>,
|
assign_value: Option<&mut Expression<'a>>,
|
||||||
ctx: &mut TraverseCtx<'a>,
|
ctx: &mut TraverseCtx<'a>,
|
||||||
) -> Option<Expression<'a>> {
|
) -> Option<Expression<'a>> {
|
||||||
let super_methods = self.super_methods_stack.last_mut()?;
|
if !*self.super_needs_transform_stack.last() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let super_methods = self.super_methods_stack.last_mut();
|
||||||
|
|
||||||
let mut argument = None;
|
let mut argument = None;
|
||||||
let mut property = "";
|
let mut property = "";
|
||||||
|
|
@ -757,7 +815,7 @@ impl<'a> ArrowFunctionConverter<'a> {
|
||||||
call: &mut CallExpression<'a>,
|
call: &mut CallExpression<'a>,
|
||||||
ctx: &mut TraverseCtx<'a>,
|
ctx: &mut TraverseCtx<'a>,
|
||||||
) -> Option<Expression<'a>> {
|
) -> Option<Expression<'a>> {
|
||||||
if self.super_methods_stack.last().is_none() || !call.callee.is_member_expression() {
|
if !*self.super_needs_transform_stack.last() || !call.callee.is_member_expression() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -796,7 +854,7 @@ impl<'a> ArrowFunctionConverter<'a> {
|
||||||
ctx: &mut TraverseCtx<'a>,
|
ctx: &mut TraverseCtx<'a>,
|
||||||
) -> Option<Expression<'a>> {
|
) -> Option<Expression<'a>> {
|
||||||
// Check if the left of the assignment is a `super` member expression.
|
// Check if the left of the assignment is a `super` member expression.
|
||||||
if self.super_methods_stack.last().is_none()
|
if !*self.super_needs_transform_stack.last()
|
||||||
|| !assignment.left.as_member_expression().is_some_and(|m| m.object().is_super())
|
|| !assignment.left.as_member_expression().is_some_and(|m| m.object().is_super())
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
|
|
@ -1149,6 +1207,43 @@ impl<'a> ArrowFunctionConverter<'a> {
|
||||||
|
|
||||||
statements.insert(0, stmt);
|
statements.insert(0, stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrap an arrow function with IIFE
|
||||||
|
///
|
||||||
|
/// `() => {}` -> `(() => { return () => {}; })()`
|
||||||
|
fn wrap_arrow_function_with_iife(
|
||||||
|
span: Span,
|
||||||
|
scope_id: ScopeId,
|
||||||
|
expr: &mut Expression<'a>,
|
||||||
|
ctx: &mut TraverseCtx<'a>,
|
||||||
|
) -> Expression<'a> {
|
||||||
|
let kind = FormalParameterKind::ArrowFormalParameters;
|
||||||
|
let params = ctx.ast.formal_parameters(SPAN, kind, ctx.ast.vec(), NONE);
|
||||||
|
let statement = ctx.ast.statement_return(SPAN, Some(ctx.ast.move_expression(expr)));
|
||||||
|
let statements = ctx.ast.vec1(statement);
|
||||||
|
let body = ctx.ast.function_body(SPAN, ctx.ast.vec(), statements);
|
||||||
|
let parent_scope_id = ctx
|
||||||
|
.create_child_scope(ctx.current_scope_id(), ScopeFlags::Arrow | ScopeFlags::Function);
|
||||||
|
ctx.scopes_mut().change_parent_id(scope_id, Some(parent_scope_id));
|
||||||
|
let arrow = ctx.ast.alloc_arrow_function_expression_with_scope_id(
|
||||||
|
SPAN,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
NONE,
|
||||||
|
params,
|
||||||
|
NONE,
|
||||||
|
body,
|
||||||
|
parent_scope_id,
|
||||||
|
);
|
||||||
|
// IIFE
|
||||||
|
ctx.ast.expression_call(
|
||||||
|
span,
|
||||||
|
Expression::ArrowFunctionExpression(arrow),
|
||||||
|
NONE,
|
||||||
|
ctx.ast.vec(),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Visitor for inserting `this` after `super` in constructor body.
|
/// Visitor for inserting `this` after `super` in constructor body.
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,14 @@ impl<'a> Traverse<'a> for Common<'a, '_> {
|
||||||
self.arrow_function_converter.enter_arrow_function_expression(arrow, ctx);
|
self.arrow_function_converter.enter_arrow_function_expression(arrow, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn exit_arrow_function_expression(
|
||||||
|
&mut self,
|
||||||
|
arrow: &mut ArrowFunctionExpression<'a>,
|
||||||
|
ctx: &mut TraverseCtx<'a>,
|
||||||
|
) {
|
||||||
|
self.arrow_function_converter.exit_arrow_function_expression(arrow, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
fn enter_function_body(&mut self, body: &mut FunctionBody<'a>, ctx: &mut TraverseCtx<'a>) {
|
fn enter_function_body(&mut self, body: &mut FunctionBody<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
self.arrow_function_converter.enter_function_body(body, ctx);
|
self.arrow_function_converter.enter_function_body(body, ctx);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -281,6 +281,7 @@ impl<'a> Traverse<'a> for TransformerImpl<'a, '_> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
|
self.common.enter_expression(expr, ctx);
|
||||||
if let Some(typescript) = self.x0_typescript.as_mut() {
|
if let Some(typescript) = self.x0_typescript.as_mut() {
|
||||||
typescript.enter_expression(expr, ctx);
|
typescript.enter_expression(expr, ctx);
|
||||||
}
|
}
|
||||||
|
|
@ -290,15 +291,14 @@ impl<'a> Traverse<'a> for TransformerImpl<'a, '_> {
|
||||||
self.x2_es2018.enter_expression(expr, ctx);
|
self.x2_es2018.enter_expression(expr, ctx);
|
||||||
self.x2_es2016.enter_expression(expr, ctx);
|
self.x2_es2016.enter_expression(expr, ctx);
|
||||||
self.x4_regexp.enter_expression(expr, ctx);
|
self.x4_regexp.enter_expression(expr, ctx);
|
||||||
self.common.enter_expression(expr, ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||||
|
self.common.exit_expression(expr, ctx);
|
||||||
self.x1_jsx.exit_expression(expr, ctx);
|
self.x1_jsx.exit_expression(expr, ctx);
|
||||||
self.x2_es2022.exit_expression(expr, ctx);
|
self.x2_es2022.exit_expression(expr, ctx);
|
||||||
self.x2_es2018.exit_expression(expr, ctx);
|
self.x2_es2018.exit_expression(expr, ctx);
|
||||||
self.x2_es2017.exit_expression(expr, ctx);
|
self.x2_es2017.exit_expression(expr, ctx);
|
||||||
self.common.exit_expression(expr, ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enter_simple_assignment_target(
|
fn enter_simple_assignment_target(
|
||||||
|
|
@ -477,6 +477,8 @@ impl<'a> Traverse<'a> for TransformerImpl<'a, '_> {
|
||||||
arrow: &mut ArrowFunctionExpression<'a>,
|
arrow: &mut ArrowFunctionExpression<'a>,
|
||||||
ctx: &mut TraverseCtx<'a>,
|
ctx: &mut TraverseCtx<'a>,
|
||||||
) {
|
) {
|
||||||
|
self.common.exit_arrow_function_expression(arrow, ctx);
|
||||||
|
|
||||||
// Some plugins may add new statements to the ArrowFunctionExpression's body,
|
// Some plugins may add new statements to the ArrowFunctionExpression's body,
|
||||||
// which can cause issues with the `() => x;` case, as it only allows a single statement.
|
// which can cause issues with the `() => x;` case, as it only allows a single statement.
|
||||||
// To address this, we wrap the last statement in a return statement and set the expression to false.
|
// To address this, we wrap the last statement in a return statement and set the expression to false.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
commit: 54a8389f
|
commit: 54a8389f
|
||||||
|
|
||||||
Passed: 126/148
|
Passed: 129/150
|
||||||
|
|
||||||
# All Passed:
|
# All Passed:
|
||||||
* babel-plugin-transform-class-static-block
|
* babel-plugin-transform-class-static-block
|
||||||
|
|
@ -10,6 +10,7 @@ Passed: 126/148
|
||||||
* babel-plugin-transform-optional-catch-binding
|
* babel-plugin-transform-optional-catch-binding
|
||||||
* babel-plugin-transform-async-generator-functions
|
* babel-plugin-transform-async-generator-functions
|
||||||
* babel-plugin-transform-object-rest-spread
|
* babel-plugin-transform-object-rest-spread
|
||||||
|
* babel-plugin-transform-async-to-generator
|
||||||
* babel-plugin-transform-exponentiation-operator
|
* babel-plugin-transform-exponentiation-operator
|
||||||
* babel-plugin-transform-arrow-functions
|
* babel-plugin-transform-arrow-functions
|
||||||
* babel-preset-typescript
|
* babel-preset-typescript
|
||||||
|
|
@ -46,11 +47,6 @@ after transform: SymbolId(0): [ReferenceId(0), ReferenceId(2), ReferenceId(6), R
|
||||||
rebuilt : SymbolId(0): [ReferenceId(0), ReferenceId(2), ReferenceId(6), ReferenceId(10)]
|
rebuilt : SymbolId(0): [ReferenceId(0), ReferenceId(2), ReferenceId(6), ReferenceId(10)]
|
||||||
|
|
||||||
|
|
||||||
# babel-plugin-transform-async-to-generator (20/21)
|
|
||||||
* class/static-block/input.js
|
|
||||||
x Output mismatch
|
|
||||||
|
|
||||||
|
|
||||||
# babel-plugin-transform-typescript (2/13)
|
# babel-plugin-transform-typescript (2/13)
|
||||||
* class-property-definition/input.ts
|
* class-property-definition/input.ts
|
||||||
Unresolved references mismatch:
|
Unresolved references mismatch:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
class Cls {
|
||||||
|
prop = async () => (this, super.prop)
|
||||||
|
static prop = async () => (this, super.prop)
|
||||||
|
|
||||||
|
nested = () => {
|
||||||
|
async () => (this, super.prop);
|
||||||
|
}
|
||||||
|
static nested = () => {
|
||||||
|
async () => (this, super.prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
class Cls {
|
||||||
|
prop = (() => {
|
||||||
|
var _superprop_getProp = () => super.prop, _this = this;
|
||||||
|
return babelHelpers.asyncToGenerator(function* () {
|
||||||
|
return _this, _superprop_getProp();
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
static prop = (() => {
|
||||||
|
var _superprop_getProp2 = () => super.prop, _this2 = this;
|
||||||
|
return babelHelpers.asyncToGenerator(function* () {
|
||||||
|
return _this2, _superprop_getProp2();
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
nested = () => {
|
||||||
|
var _superprop_getProp3 = () => super.prop, _this3 = this;
|
||||||
|
/*#__PURE__*/babelHelpers.asyncToGenerator(function* () {
|
||||||
|
return _this3, _superprop_getProp3();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
static nested = () => {
|
||||||
|
var _superprop_getProp4 = () => super.prop, _this4 = this;
|
||||||
|
/*#__PURE__*/babelHelpers.asyncToGenerator(function* () {
|
||||||
|
return _this4, _superprop_getProp4();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
class Cls {
|
||||||
|
prop = async () => { super.prop }
|
||||||
|
static prop = async () => { super.prop; }
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
class Cls {
|
||||||
|
prop = (() => {
|
||||||
|
var _superprop_getProp = () => super.prop;
|
||||||
|
return babelHelpers.asyncToGenerator(function* () {
|
||||||
|
_superprop_getProp();
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
static prop = (() => {
|
||||||
|
var _superprop_getProp2 = () => super.prop;
|
||||||
|
return babelHelpers.asyncToGenerator(function* () {
|
||||||
|
_superprop_getProp2();
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue