diff --git a/crates/oxc_ast/src/ast_builder_impl.rs b/crates/oxc_ast/src/ast_builder_impl.rs index 47d98436579ce0..e428056f0f3259 100644 --- a/crates/oxc_ast/src/ast_builder_impl.rs +++ b/crates/oxc_ast/src/ast_builder_impl.rs @@ -147,6 +147,45 @@ impl<'a> AstBuilder<'a> { mem::replace(decl, empty_decl) } + /// Move a formal parameters out by replacing it with an empty [FormalParameters]. + #[inline] + pub fn move_formal_parameters(self, params: &mut FormalParameters<'a>) -> FormalParameters<'a> { + let empty_params = self.formal_parameters(Span::default(), params.kind, self.vec(), NONE); + mem::replace(params, empty_params) + } + + /// Move a function out by replacing it with an empty [Function] + #[inline] + pub fn move_function(self, function: &mut Function<'a>) -> Function<'a> { + let params = self.formal_parameters( + Span::default(), + FormalParameterKind::FormalParameter, + self.vec(), + NONE, + ); + let empty_function = self.function( + FunctionType::FunctionDeclaration, + Span::default(), + None, + false, + false, + false, + NONE, + NONE, + params, + NONE, + NONE, + ); + mem::replace(function, empty_function) + } + + /// Move a function body out by replacing it with an empty [FunctionBody]. + #[inline] + pub fn move_function_body(self, body: &mut FunctionBody<'a>) -> FunctionBody<'a> { + let empty_body = self.function_body(Span::default(), self.vec(), self.vec()); + mem::replace(body, empty_body) + } + /// Move an array element out by replacing it with an /// [elision](ArrayExpressionElement::Elision). pub fn move_array_expression_element( diff --git a/crates/oxc_transformer/src/common/statement_injector.rs b/crates/oxc_transformer/src/common/statement_injector.rs index 6a390b2b599010..d3387614e5f144 100644 --- a/crates/oxc_transformer/src/common/statement_injector.rs +++ b/crates/oxc_transformer/src/common/statement_injector.rs @@ -78,7 +78,6 @@ impl<'a> StatementInjectorStore<'a> { } /// Add a statement to be inserted immediately after the target statement. - #[expect(dead_code)] pub fn insert_after(&self, target: Address, stmt: Statement<'a>) { let mut insertions = self.insertions.borrow_mut(); let adjacent_stmts = insertions.entry(target).or_default(); @@ -131,145 +130,8 @@ impl<'a> StatementInjectorStore<'a> { new_statements.push(stmt); new_statements.extend(adjacent_stmts.into_iter().map(|s| s.stmt)); } - } - } - - *statements = new_statements; - } -} -//! Utility transform to add new statements before or after the specified statement. -//! -//! `StatementInjectorStore` contains a `FxHashMap>`. It is stored on `TransformCtx`. -//! -//! `StatementInjector` transform inserts new statements before or after a statement which is determined by the address of the statement. -//! -//! Other transforms can add statements to the store with following methods: -//! -//! ```rs -//! self.ctx.statement_injector.insert_before(address, statement); -//! self.ctx.statement_injector.insert_after(address, statement); -//! self.ctx.statement_injector.insert_many_after(address, statements); -//! ``` - -use std::cell::RefCell; - -use oxc_allocator::{Address, Vec as OxcVec}; - -use oxc_ast::{address::GetAddress, ast::*}; -use oxc_traverse::{Traverse, TraverseCtx}; -use rustc_hash::FxHashMap; - -use crate::TransformCtx; - -/// Transform that inserts any statements which have been requested insertion via `StatementInjectorStore` -pub struct StatementInjector<'a, 'ctx> { - ctx: &'ctx TransformCtx<'a>, -} - -impl<'a, 'ctx> StatementInjector<'a, 'ctx> { - pub fn new(ctx: &'ctx TransformCtx<'a>) -> Self { - Self { ctx } - } -} - -impl<'a, 'ctx> Traverse<'a> for StatementInjector<'a, 'ctx> { - fn exit_statements( - &mut self, - statements: &mut OxcVec<'a, Statement<'a>>, - ctx: &mut TraverseCtx<'a>, - ) { - self.ctx.statement_injector.insert_into_statements(statements, ctx); - } -} - -enum Direction { - Before, - After, -} - -struct AdjacentStatement<'a> { - stmt: Statement<'a>, - direction: Direction, -} - -/// Store for statements to be added to the statements. -pub struct StatementInjectorStore<'a> { - insertions: RefCell>>>, -} - -// Public methods -impl<'a> StatementInjectorStore<'a> { - /// Create new `StatementInjectorStore`. - pub fn new() -> Self { - Self { insertions: RefCell::new(FxHashMap::default()) } - } - - /// Add a statement to be inserted immediately before the target statement. - #[expect(dead_code)] - pub fn insert_before(&self, target: Address, stmt: Statement<'a>) { - let mut insertions = self.insertions.borrow_mut(); - let adjacent_stmts = insertions.entry(target).or_default(); - let index = adjacent_stmts - .iter() - .position(|s| matches!(s.direction, Direction::After)) - .unwrap_or(adjacent_stmts.len()); - adjacent_stmts.insert(index, AdjacentStatement { stmt, direction: Direction::Before }); - } - - /// Add a statement to be inserted immediately after the target statement. - #[expect(dead_code)] - pub fn insert_after(&self, target: Address, stmt: Statement<'a>) { - let mut insertions = self.insertions.borrow_mut(); - let adjacent_stmts = insertions.entry(target).or_default(); - adjacent_stmts.push(AdjacentStatement { stmt, direction: Direction::After }); - } - - /// Add multiple statements to be inserted immediately after the target statement. - #[expect(dead_code)] - pub fn insert_many_after(&self, target: Address, stmts: Vec>) { - let mut insertions = self.insertions.borrow_mut(); - let adjacent_stmts = insertions.entry(target).or_default(); - adjacent_stmts.extend( - stmts.into_iter().map(|stmt| AdjacentStatement { stmt, direction: Direction::After }), - ); - } - - /// Insert statements immediately before / after the target statement. - pub(self) fn insert_into_statements( - &self, - statements: &mut OxcVec<'a, Statement<'a>>, - ctx: &mut TraverseCtx<'a>, - ) { - let mut insertions = self.insertions.borrow_mut(); - if insertions.is_empty() { - return; - } - - let new_statement_count = statements - .iter() - .filter_map(|s| insertions.get(&s.address()).map(Vec::len)) - .sum::(); - if new_statement_count == 0 { - return; - } - - let mut new_statements = ctx.ast.vec_with_capacity(statements.len() + new_statement_count); - - for stmt in statements.drain(..) { - if let Some(mut adjacent_stmts) = insertions.remove(&stmt.address()) { - let first_after_stmt_index = adjacent_stmts - .iter() - .position(|s| matches!(s.direction, Direction::After)) - .unwrap_or(adjacent_stmts.len()); - if first_after_stmt_index != 0 { - let right = adjacent_stmts.split_off(first_after_stmt_index); - new_statements.extend(adjacent_stmts.into_iter().map(|s| s.stmt)); - new_statements.push(stmt); - new_statements.extend(right.into_iter().map(|s| s.stmt)); - } else { - new_statements.push(stmt); - new_statements.extend(adjacent_stmts.into_iter().map(|s| s.stmt)); - } + } else { + new_statements.push(stmt); } } diff --git a/crates/oxc_transformer/src/es2017/async_to_generator.rs b/crates/oxc_transformer/src/es2017/async_to_generator.rs index 0e60db75e356ed..43c5a2b368ee1f 100644 --- a/crates/oxc_transformer/src/es2017/async_to_generator.rs +++ b/crates/oxc_transformer/src/es2017/async_to_generator.rs @@ -40,16 +40,12 @@ //! * Babel helper implementation: //! * Async / Await TC39 proposal: -use oxc_ast::{ - ast::{ - ArrowFunctionExpression, Expression, Function, FunctionType, Statement, - VariableDeclarationKind, - }, - NONE, -}; -use oxc_semantic::ScopeFlags; -use oxc_span::{GetSpan, SPAN}; -use oxc_traverse::{Ancestor, Traverse, TraverseCtx}; +use oxc_allocator::{Box, GetAddress}; +use oxc_ast::ast::*; +use oxc_ast::NONE; +use oxc_semantic::{NodeId, ReferenceFlags, ScopeFlags, ScopeId, SymbolFlags}; +use oxc_span::{Atom, GetSpan, SPAN}; +use oxc_traverse::{Ancestor, BoundIdentifier, Traverse, TraverseCtx}; use crate::{common::helper_loader::Helper, TransformCtx}; @@ -96,11 +92,9 @@ impl<'a, 'ctx> Traverse<'a> for AsyncToGenerator<'a, 'ctx> { ); } } else if let Expression::FunctionExpression(func) = expr { - if !func.r#async || func.generator { - return; + if let Some(new_expr) = self.transform_function_expression(func, ctx) { + *expr = new_expr; } - let new_function = self.transform_function(func, ctx); - *expr = ctx.ast.expression_from_function(new_function); } else if let Expression::ArrowFunctionExpression(arrow) = expr { if !arrow.r#async { return; @@ -111,80 +105,149 @@ impl<'a, 'ctx> Traverse<'a> for AsyncToGenerator<'a, 'ctx> { fn exit_statement(&mut self, stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) { if let Statement::FunctionDeclaration(func) = stmt { - if !func.r#async || func.generator { - return; + if let Some(new_statement) = self.transform_function_declaration(func, ctx) { + self.ctx.statement_injector.insert_after(stmt.address(), new_statement); } - let new_function = self.transform_function(func, ctx); - if let Some(id) = func.id.take() { - *stmt = ctx.ast.statement_declaration(ctx.ast.declaration_variable( + } + } +} + +impl<'a, 'ctx> AsyncToGenerator<'a, 'ctx> { + fn transform_function_expression( + &self, + func: &mut Box<'a, Function<'a>>, + ctx: &mut TraverseCtx<'a>, + ) -> Option> { + if !func.r#async || func.generator || func.is_typescript_syntax() { + return None; + } + + func.r#async = false; + let id = func.id.take(); + let body = func.body.take().unwrap(); + let params = ctx.ast.move_formal_parameters(&mut func.params); + let scope_id = func.scope_id.get().unwrap(); + + // TODO: Handle `ignoreFunctionLength` + // + if id.is_none() && !params.has_parameter() { + return Some(self.apply_helper_function(scope_id, params, body, ctx)); + } + + // _ref + let ref_bound = ctx.generate_uid( + id.as_ref().map_or_else(|| "ref", |id| id.name.as_str()), + scope_id, + SymbolFlags::FunctionScopedVariable, + ); + + let apply_function = { + let scope_id = ctx.create_child_scope(scope_id, ScopeFlags::Function); + let id = id.as_ref().map(|id| { + // Add binding to scope + let symbol_id = ctx.symbols_mut().create_symbol( SPAN, - VariableDeclarationKind::Const, - ctx.ast.vec1(ctx.ast.variable_declarator( - SPAN, - VariableDeclarationKind::Const, - ctx.ast.binding_pattern( - ctx.ast.binding_pattern_kind_from_binding_identifier(id), - NONE, - false, - ), - Some(ctx.ast.expression_from_function(new_function)), - false, - )), - false, - )); + id.name.clone().into_compact_str(), + SymbolFlags::FunctionScopedVariable | SymbolFlags::Function, + scope_id, + NodeId::DUMMY, + ); + ctx.ast.binding_identifier_with_symbol_id(SPAN, id.name.clone(), symbol_id) + }); + let params = Self::generate_placeholder_parameters(¶ms, scope_id, ctx); + let statements = ctx.ast.vec1(Self::generate_apply_call_statement(&ref_bound, ctx)); + let body = ctx.ast.function_body(SPAN, ctx.ast.vec(), statements); + Self::create_function(id, params, body, scope_id, ctx) + }; + + { + let mut statements = ctx.ast.vec_with_capacity(3); + let expression = self.apply_helper_function(scope_id, params, body, ctx); + statements.push(Self::get_helper_call_declaration(&ref_bound, expression, ctx)); + + if let Some(id) = apply_function.id.as_ref() { + let reference = ctx.create_bound_reference_id( + SPAN, + id.name.clone(), + id.symbol_id.get().unwrap(), + ReferenceFlags::Read, + ); + let statement = Statement::from(ctx.ast.declaration_from_function(apply_function)); + statements.push(statement); + let argument = Some(ctx.ast.expression_from_identifier_reference(reference)); + statements.push(ctx.ast.statement_return(SPAN, argument)); } else { - *stmt = - ctx.ast.statement_declaration(ctx.ast.declaration_from_function(new_function)); + let statement_return = ctx + .ast + .statement_return(SPAN, Some(ctx.ast.expression_from_function(apply_function))); + statements.push(statement_return); } + + func.body.replace(ctx.ast.alloc_function_body(SPAN, ctx.ast.vec(), statements)); } + + // Self reference call + let callee = ctx.ast.expression_from_function(ctx.ast.move_function(func)); + Some(ctx.ast.expression_call(SPAN, callee, NONE, ctx.ast.vec(), false)) } -} -impl<'a, 'ctx> AsyncToGenerator<'a, 'ctx> { - fn transform_function( + /// ```js + /// function NAME(PARAMS) { return REF.apply(this, arguments); } + /// function REF() { + /// REF = FUNCTION; + /// return REF.apply(this, arguments); + /// } + /// ``` + fn transform_function_declaration( &self, - func: &mut Function<'a>, + func: &mut Box<'a, Function<'a>>, ctx: &mut TraverseCtx<'a>, - ) -> Function<'a> { - let target = ctx.ast.function( - func.r#type, - SPAN, - None, - true, - false, - false, - func.type_parameters.take(), - func.this_param.take(), - ctx.ast.alloc(ctx.ast.formal_parameters( - SPAN, - func.params.kind, - ctx.ast.move_vec(&mut func.params.items), - func.params.rest.take(), - )), - func.return_type.take(), - func.body.take(), + ) -> Option> { + if !func.r#async || func.generator || func.is_typescript_syntax() { + return None; + } + + func.r#async = false; + let body = func.body.take().unwrap(); + let params = ctx.ast.move_formal_parameters(&mut func.params); + + // _ref + let ref_bound = ctx.generate_uid_in_current_scope( + func.id.as_ref().map_or_else(|| "ref", |id| id.name.as_str()), + SymbolFlags::FunctionScopedVariable, ); - let parameters = - ctx.ast.vec1(ctx.ast.argument_expression(ctx.ast.expression_from_function(target))); - let call = self.ctx.helper_call_expr(Helper::AsyncToGenerator, parameters, ctx); - let returns = ctx.ast.return_statement(SPAN, Some(call)); - let body = Statement::ReturnStatement(ctx.ast.alloc(returns)); - let body = ctx.ast.function_body(SPAN, ctx.ast.vec(), ctx.ast.vec1(body)); - let body = ctx.ast.alloc(body); - let params = ctx.ast.formal_parameters(SPAN, func.params.kind, ctx.ast.vec(), NONE); - ctx.ast.function( - FunctionType::FunctionExpression, - SPAN, - None, - false, - false, - false, - func.type_parameters.take(), - func.this_param.take(), - params, - func.return_type.take(), - Some(body), - ) + + // Modify the wrapper function + { + func.params = + Self::generate_placeholder_parameters(¶ms, func.scope_id.get().unwrap(), ctx); + let statements = ctx.ast.vec1(Self::generate_apply_call_statement(&ref_bound, ctx)); + func.body.replace(ctx.ast.alloc_function_body(SPAN, ctx.ast.vec(), statements)); + } + + let mut statements = ctx.ast.vec_with_capacity(2); + + let expression = self.apply_helper_function(ctx.current_scope_id(), params, body, ctx); + statements.push(Self::get_helper_call_assignment( + ref_bound.create_read_write_reference(ctx), + expression, + ctx, + )); + statements.push(Self::generate_apply_call_statement(&ref_bound, ctx)); + + let apply_function = { + let params = Self::create_empty_params(ctx); + let body = ctx.ast.function_body(SPAN, ctx.ast.vec(), statements); + Self::create_function( + Some(ref_bound.create_binding_identifier()), + params, + body, + ctx.current_scope_id(), + ctx, + ) + }; + + Some(Statement::from(ctx.ast.declaration_from_function(apply_function))) } fn transform_arrow_function( @@ -192,11 +255,7 @@ impl<'a, 'ctx> AsyncToGenerator<'a, 'ctx> { arrow: &mut ArrowFunctionExpression<'a>, ctx: &mut TraverseCtx<'a>, ) -> Expression<'a> { - let mut body = ctx.ast.function_body( - SPAN, - ctx.ast.move_vec(&mut arrow.body.directives), - ctx.ast.move_vec(&mut arrow.body.statements), - ); + let mut body = ctx.ast.move_function_body(&mut arrow.body); // If the arrow's expression is true, we need to wrap the only one expression with return statement. if arrow.expression { @@ -208,24 +267,191 @@ impl<'a, 'ctx> AsyncToGenerator<'a, 'ctx> { *statement = ctx.ast.statement_return(expression.span(), Some(expression)); } - let r#type = FunctionType::FunctionExpression; - let parameters = ctx.ast.alloc(ctx.ast.formal_parameters( + let scope_id = arrow.scope_id.get().unwrap(); + ctx.scopes_mut().get_flags_mut(scope_id).remove(ScopeFlags::Arrow); + + self.apply_helper_function( + scope_id, + ctx.ast.move_formal_parameters(&mut arrow.params), + ctx.ast.alloc(body), + ctx, + ) + } + + /// Passing specified parameters to create a function. + fn create_function( + id: Option>, + params: Box<'a, FormalParameters<'a>>, + body: FunctionBody<'a>, + scope_id: ScopeId, + ctx: &mut TraverseCtx<'a>, + ) -> Function<'a> { + let r#type = if id.is_some() { + FunctionType::FunctionDeclaration + } else { + FunctionType::FunctionExpression + }; + ctx.ast.function_with_scope_id( + r#type, SPAN, - arrow.params.kind, - ctx.ast.move_vec(&mut arrow.params.items), - arrow.params.rest.take(), + id, + false, + false, + false, + NONE, + NONE, + params, + NONE, + Some(body), + scope_id, + ) + } + + /// Call `apply` method for the passed-in reference, with `this` and `arguments` as arguments. + /// + /// ```js + /// ref_bound.apply(this, arguments); + /// ``` + fn generate_apply_call_statement( + ref_bound: &BoundIdentifier<'a>, + ctx: &mut TraverseCtx<'a>, + ) -> Statement<'a> { + let symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), "arguments"); + let arguments_ident = + ctx.create_reference_id(SPAN, Atom::from("arguments"), symbol_id, ReferenceFlags::Read); + let arguments_ident = ctx.ast.expression_from_identifier_reference(arguments_ident); + + // (this, arguments) + let mut arguments = ctx.ast.vec_with_capacity(2); + arguments.push(ctx.ast.argument_expression(ctx.ast.expression_this(SPAN))); + arguments.push(ctx.ast.argument_expression(arguments_ident)); + // _ref.apply + let callee = ctx.ast.expression_member(ctx.ast.member_expression_static( + SPAN, + ref_bound.create_read_expression(ctx), + ctx.ast.identifier_name(SPAN, "apply"), + false, )); - let body = Some(body); - let mut function = ctx - .ast - .function(r#type, SPAN, None, true, false, false, NONE, NONE, parameters, NONE, body); - function.scope_id = arrow.scope_id.clone(); - if let Some(scope_id) = function.scope_id.get() { - ctx.scopes_mut().get_flags_mut(scope_id).remove(ScopeFlags::Arrow); - } + let argument = ctx.ast.expression_call(SPAN, callee, NONE, arguments, false); + ctx.ast.statement_return(SPAN, Some(argument)) + } + /// Returns an [`Expression`] that calls [`Helper::AsyncToGenerator`] helper function with arguments + /// constructed from the passed-in parameters, body, and scope_id. + /// + /// The generated code looks like: + /// ```js + /// asyncToGenerator(function* (PARAMS) { + /// BODY + /// }); + /// ``` + fn apply_helper_function( + &self, + scope_id: ScopeId, + parameters: FormalParameters<'a>, + body: Box<'a, FunctionBody<'a>>, + ctx: &mut TraverseCtx<'a>, + ) -> Expression<'a> { + let r#type = FunctionType::FunctionExpression; + let function = ctx.ast.function_with_scope_id( + r#type, + SPAN, + None, + true, + false, + false, + NONE, + NONE, + parameters, + NONE, + Some(body), + scope_id, + ); let arguments = ctx.ast.vec1(ctx.ast.argument_expression(ctx.ast.expression_from_function(function))); self.ctx.helper_call_expr(Helper::AsyncToGenerator, arguments, ctx) } + + /// Generate a [`VariableDeclaration`] for the ref and pass the expression as init of [`VariableDeclarator`] + /// + /// The generated code looks like: + /// ```js + /// var ref = EXPRESSION; + /// ``` + fn get_helper_call_declaration( + ref_bound: &BoundIdentifier<'a>, + expression: Expression<'a>, + ctx: &mut TraverseCtx<'a>, + ) -> Statement<'a> { + let declarations = ctx.ast.vec1(ctx.ast.variable_declarator( + SPAN, + VariableDeclarationKind::Var, + ref_bound.create_binding_pattern(ctx), + Some(expression), + false, + )); + ctx.ast.statement_declaration(ctx.ast.declaration_variable( + SPAN, + VariableDeclarationKind::Var, + declarations, + false, + )) + } + + /// Generate an [`AssignmentExpression`] for the ident and pass the expression as the right side of the assignment. + /// + /// The generated code looks like: + /// ```js + /// ident = EXPRESSION; + /// ``` + fn get_helper_call_assignment( + ident: IdentifierReference<'a>, + expression: Expression<'a>, + ctx: &mut TraverseCtx<'a>, + ) -> Statement<'a> { + let expression = ctx.ast.expression_assignment( + SPAN, + AssignmentOperator::Assign, + AssignmentTarget::from( + ctx.ast.simple_assignment_target_from_identifier_reference(ident), + ), + expression, + ); + ctx.ast.statement_expression(SPAN, expression) + } + + /// Generate placeholder [`FormalParameters`] which named `_x` based on the passed-in parameters. + ///J `function p(x, y, z, d = 0, ...rest) {}` -> `function* (_x, _x1, _x2) {}` + fn generate_placeholder_parameters( + params: &FormalParameters<'a>, + scope_id: ScopeId, + ctx: &mut TraverseCtx<'a>, + ) -> Box<'a, FormalParameters<'a>> { + let mut parameters = ctx.ast.vec_with_capacity(params.items.len()); + for param in ¶ms.items { + let binding = ctx.generate_uid("x", scope_id, SymbolFlags::FunctionScopedVariable); + parameters.push( + ctx.ast.plain_formal_parameter(param.span(), binding.create_binding_pattern(ctx)), + ); + } + let parameters = ctx.ast.alloc_formal_parameters( + SPAN, + FormalParameterKind::FormalParameter, + parameters, + NONE, + ); + + parameters + } + + /// Create an empty [FormalParameters] with [FormalParameterKind::FormalParameter]. + fn create_empty_params(ctx: &mut TraverseCtx<'a>) -> Box<'a, FormalParameters<'a>> { + let apply_function_params = ctx.ast.alloc_formal_parameters( + SPAN, + FormalParameterKind::FormalParameter, + ctx.ast.vec(), + NONE, + ); + apply_function_params + } } diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index 2a60003e24a737..90a2efd431b474 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -241,7 +241,6 @@ impl<'a, 'ctx> Traverse<'a> for TransformerImpl<'a, 'ctx> { fn exit_function(&mut self, func: &mut Function<'a>, ctx: &mut TraverseCtx<'a>) { self.x0_typescript.exit_function(func, ctx); self.x1_react.exit_function(func, ctx); - self.x2_es2017.exit_function(func, ctx); self.x3_es2015.exit_function(func, ctx); } diff --git a/tasks/transform_conformance/snapshots/babel.snap.md b/tasks/transform_conformance/snapshots/babel.snap.md index 4faa31262c0e60..bf32e4d53bed2a 100644 --- a/tasks/transform_conformance/snapshots/babel.snap.md +++ b/tasks/transform_conformance/snapshots/babel.snap.md @@ -1,6 +1,6 @@ commit: d20b314c -Passed: 348/1058 +Passed: 349/1058 # All Passed: * babel-plugin-transform-class-static-block @@ -1632,7 +1632,7 @@ x Output mismatch x Output mismatch -# babel-plugin-transform-async-to-generator (2/24) +# babel-plugin-transform-async-to-generator (3/24) * assumption-ignoreFunctionLength-true/basic/input.mjs x Output mismatch @@ -1649,19 +1649,177 @@ x Output mismatch x Output mismatch * async-to-generator/function-arity/input.js -x Output mismatch +Bindings mismatch: +after transform: ScopeId(0): ["_foo", "foo"] +rebuilt : ScopeId(3): ["a", "b"] +Scope flags mismatch: +after transform: ScopeId(0): ScopeFlags(Top) +rebuilt : ScopeId(3): ScopeFlags(Function) +Scope parent mismatch: +after transform: ScopeId(0): None +rebuilt : ScopeId(3): Some(ScopeId(2)) +Scope children mismatch: +after transform: ScopeId(0): [ScopeId(1), ScopeId(2), ScopeId(3)] +rebuilt : ScopeId(3): [] +Bindings mismatch: +after transform: ScopeId(1): ["_x", "a", "b"] +rebuilt : ScopeId(1): ["_x"] +Scope parent mismatch: +after transform: ScopeId(1): Some(ScopeId(0)) +rebuilt : ScopeId(1): Some(ScopeId(0)) +Bindings mismatch: +after transform: ScopeId(2): ["_name", "a", "b", "name"] +rebuilt : ScopeId(5): ["a", "b"] +Scope parent mismatch: +after transform: ScopeId(2): Some(ScopeId(0)) +rebuilt : ScopeId(5): Some(ScopeId(4)) +Scope children mismatch: +after transform: ScopeId(2): [ScopeId(4)] +rebuilt : ScopeId(5): [] +Scope parent mismatch: +after transform: ScopeId(4): Some(ScopeId(2)) +rebuilt : ScopeId(6): Some(ScopeId(4)) +Bindings mismatch: +after transform: ScopeId(3): ["_ref", "a", "b"] +rebuilt : ScopeId(8): ["a", "b"] +Scope parent mismatch: +after transform: ScopeId(3): Some(ScopeId(0)) +rebuilt : ScopeId(8): Some(ScopeId(7)) +Scope children mismatch: +after transform: ScopeId(3): [ScopeId(5)] +rebuilt : ScopeId(8): [] +Scope parent mismatch: +after transform: ScopeId(5): Some(ScopeId(3)) +rebuilt : ScopeId(9): Some(ScopeId(7)) +Symbol scope ID mismatch for "foo": +after transform: SymbolId(0): ScopeId(0) +rebuilt : SymbolId(0): ScopeId(0) +Symbol scope ID mismatch for "_foo": +after transform: SymbolId(8): ScopeId(0) +rebuilt : SymbolId(2): ScopeId(0) +Symbol scope ID mismatch for "a": +after transform: SymbolId(1): ScopeId(1) +rebuilt : SymbolId(3): ScopeId(3) +Symbol scope ID mismatch for "b": +after transform: SymbolId(2): ScopeId(1) +rebuilt : SymbolId(4): ScopeId(3) +Symbol scope ID mismatch for "_name": +after transform: SymbolId(10): ScopeId(2) +rebuilt : SymbolId(5): ScopeId(4) +Symbol flags mismatch for "name": +after transform: SymbolId(11): SymbolFlags(FunctionScopedVariable | Function) +rebuilt : SymbolId(8): SymbolFlags(FunctionScopedVariable) +Symbol scope ID mismatch for "name": +after transform: SymbolId(11): ScopeId(4) +rebuilt : SymbolId(8): ScopeId(4) +Symbol scope ID mismatch for "_ref": +after transform: SymbolId(13): ScopeId(3) +rebuilt : SymbolId(10): ScopeId(7) * async-to-generator/object-method-with-super/input.js x Output mismatch * async-to-generator/shadowed-promise/input.js -x Output mismatch +Bindings mismatch: +after transform: ScopeId(0): ["Promise", "_foo", "foo"] +rebuilt : ScopeId(3): [] +Scope flags mismatch: +after transform: ScopeId(0): ScopeFlags(Top) +rebuilt : ScopeId(3): ScopeFlags(Function) +Scope parent mismatch: +after transform: ScopeId(0): None +rebuilt : ScopeId(3): Some(ScopeId(2)) +Scope children mismatch: +after transform: ScopeId(0): [ScopeId(1)] +rebuilt : ScopeId(3): [ScopeId(4)] +Scope parent mismatch: +after transform: ScopeId(1): Some(ScopeId(0)) +rebuilt : ScopeId(1): Some(ScopeId(0)) +Scope children mismatch: +after transform: ScopeId(1): [ScopeId(2)] +rebuilt : ScopeId(1): [] +Scope parent mismatch: +after transform: ScopeId(2): Some(ScopeId(1)) +rebuilt : ScopeId(4): Some(ScopeId(3)) +Symbol scope ID mismatch for "Promise": +after transform: SymbolId(0): ScopeId(0) +rebuilt : SymbolId(0): ScopeId(0) +Symbol scope ID mismatch for "foo": +after transform: SymbolId(1): ScopeId(0) +rebuilt : SymbolId(1): ScopeId(0) +Symbol scope ID mismatch for "_foo": +after transform: SymbolId(3): ScopeId(0) +rebuilt : SymbolId(2): ScopeId(0) * async-to-generator/shadowed-promise-import/input.mjs -x Output mismatch +Bindings mismatch: +after transform: ScopeId(0): ["Promise", "_foo", "foo"] +rebuilt : ScopeId(3): [] +Scope flags mismatch: +after transform: ScopeId(0): ScopeFlags(Top) +rebuilt : ScopeId(3): ScopeFlags(Function) +Scope parent mismatch: +after transform: ScopeId(0): None +rebuilt : ScopeId(3): Some(ScopeId(2)) +Scope children mismatch: +after transform: ScopeId(0): [ScopeId(1)] +rebuilt : ScopeId(3): [] +Scope parent mismatch: +after transform: ScopeId(1): Some(ScopeId(0)) +rebuilt : ScopeId(1): Some(ScopeId(0)) +Symbol scope ID mismatch for "Promise": +after transform: SymbolId(0): ScopeId(0) +rebuilt : SymbolId(0): ScopeId(0) +Symbol scope ID mismatch for "foo": +after transform: SymbolId(1): ScopeId(0) +rebuilt : SymbolId(1): ScopeId(0) +Symbol scope ID mismatch for "_foo": +after transform: SymbolId(2): ScopeId(0) +rebuilt : SymbolId(2): ScopeId(0) * async-to-generator/shadowed-promise-nested/input.js -x Output mismatch +Bindings mismatch: +after transform: ScopeId(0): ["Promise", "_foo", "foo"] +rebuilt : ScopeId(3): ["Promise", "_bar", "bar"] +Scope flags mismatch: +after transform: ScopeId(0): ScopeFlags(Top) +rebuilt : ScopeId(3): ScopeFlags(Function) +Scope parent mismatch: +after transform: ScopeId(0): None +rebuilt : ScopeId(3): Some(ScopeId(2)) +Scope children mismatch: +after transform: ScopeId(0): [ScopeId(1)] +rebuilt : ScopeId(3): [ScopeId(4), ScopeId(5)] +Bindings mismatch: +after transform: ScopeId(1): ["Promise", "_bar", "bar"] +rebuilt : ScopeId(6): [] +Scope parent mismatch: +after transform: ScopeId(1): Some(ScopeId(0)) +rebuilt : ScopeId(6): Some(ScopeId(5)) +Scope children mismatch: +after transform: ScopeId(1): [ScopeId(2)] +rebuilt : ScopeId(6): [] +Scope parent mismatch: +after transform: ScopeId(2): Some(ScopeId(1)) +rebuilt : ScopeId(4): Some(ScopeId(3)) +Symbol scope ID mismatch for "Promise": +after transform: SymbolId(0): ScopeId(0) +rebuilt : SymbolId(0): ScopeId(0) +Symbol scope ID mismatch for "foo": +after transform: SymbolId(1): ScopeId(0) +rebuilt : SymbolId(1): ScopeId(0) +Symbol scope ID mismatch for "_foo": +after transform: SymbolId(5): ScopeId(0) +rebuilt : SymbolId(2): ScopeId(0) +Symbol scope ID mismatch for "Promise": +after transform: SymbolId(2): ScopeId(1) +rebuilt : SymbolId(3): ScopeId(3) +Symbol scope ID mismatch for "bar": +after transform: SymbolId(3): ScopeId(1) +rebuilt : SymbolId(4): ScopeId(3) +Symbol scope ID mismatch for "_bar": +after transform: SymbolId(4): ScopeId(1) +rebuilt : SymbolId(5): ScopeId(3) * bluebird-coroutines/arrow-function/input.js x Output mismatch @@ -1682,14 +1840,40 @@ x Output mismatch x Output mismatch * regression/8783/input.js -x Output mismatch +Scope children mismatch: +after transform: ScopeId(0): [ScopeId(1)] +rebuilt : ScopeId(0): [ScopeId(1)] +Bindings mismatch: +after transform: ScopeId(1): ["_poll", "poll"] +rebuilt : ScopeId(2): [] +Scope parent mismatch: +after transform: ScopeId(1): Some(ScopeId(0)) +rebuilt : ScopeId(2): Some(ScopeId(1)) +Scope children mismatch: +after transform: ScopeId(1): [ScopeId(2)] +rebuilt : ScopeId(2): [] +Scope parent mismatch: +after transform: ScopeId(2): Some(ScopeId(1)) +rebuilt : ScopeId(3): Some(ScopeId(1)) +Symbol scope ID mismatch for "_poll": +after transform: SymbolId(1): ScopeId(1) +rebuilt : SymbolId(0): ScopeId(1) +Symbol flags mismatch for "poll": +after transform: SymbolId(2): SymbolFlags(FunctionScopedVariable | Function) +rebuilt : SymbolId(1): SymbolFlags(FunctionScopedVariable) +Symbol scope ID mismatch for "poll": +after transform: SymbolId(2): ScopeId(2) +rebuilt : SymbolId(1): ScopeId(1) +Symbol reference IDs mismatch for "poll": +after transform: SymbolId(2): [ReferenceId(7)] +rebuilt : SymbolId(1): [ReferenceId(4), ReferenceId(7)] +Reference symbol mismatch for "poll": +after transform: SymbolId(0) "poll" +rebuilt : SymbolId(1) "poll" * regression/T7108/input.js x Output mismatch -* regression/T7194/input.js -x Output mismatch - * regression/gh-6923/input.js x Output mismatch