refactor(transformer): do not use AstBuilder::*_from_* methods (#7070)

Preparation for #7073. Avoid using `AstBuilder::*_from_*` methods to construct enums, use explicit construction instead.

Before:

```rs
let ident = self.ast.binding_pattern_kind_from_binding_identifier(ident);
```

After:

```rs
let ident = BindingPatternKind::BindingIdentifier(ident);
```

Often this produces shorter code, as well as (in my opinion) being easier to read.
This commit is contained in:
overlookmotel 2024-11-02 01:22:55 +00:00
parent 938ee8724d
commit d03e622b70
17 changed files with 175 additions and 231 deletions

View file

@ -274,7 +274,7 @@ impl<'a> HelperLoaderStore<'a> {
let symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), HELPER_VAR);
let ident =
ctx.create_reference_id(SPAN, Atom::from(HELPER_VAR), symbol_id, ReferenceFlags::Read);
let object = ctx.ast.expression_from_identifier_reference(ident);
let object = Expression::Identifier(ctx.alloc(ident));
let property = ctx.ast.identifier_name(SPAN, Atom::from(helper.name()));
Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false))
}

View file

@ -211,14 +211,13 @@ impl<'a> ModuleImportsStore<'a> {
),
}));
let import_stmt = ctx.ast.module_declaration_import_declaration(
Statement::from(ctx.ast.module_declaration_import_declaration(
SPAN,
Some(specifiers),
ctx.ast.string_literal(SPAN, source),
NONE,
ImportOrExportKind::Value,
);
ctx.ast.statement_module_declaration(import_stmt)
))
}
fn get_require(
@ -234,7 +233,7 @@ impl<'a> ModuleImportsStore<'a> {
require_symbol_id,
ReferenceFlags::read(),
);
let callee = ctx.ast.expression_from_identifier_reference(ident);
let callee = Expression::Identifier(ctx.alloc(ident));
let args = {
let arg = Argument::from(ctx.ast.expression_string_literal(SPAN, source));
@ -247,7 +246,6 @@ impl<'a> ModuleImportsStore<'a> {
let decl = ctx.ast.variable_declarator(SPAN, var_kind, id, Some(init), false);
ctx.ast.vec1(decl)
};
let var_decl = ctx.ast.declaration_variable(SPAN, var_kind, decl, false);
ctx.ast.statement_declaration(var_decl)
Statement::from(ctx.ast.declaration_variable(SPAN, var_kind, decl, false))
}
}

View file

@ -126,7 +126,7 @@
use serde::Deserialize;
use oxc_allocator::Vec as ArenaVec;
use oxc_allocator::{Box as ArenaBox, Vec as ArenaVec};
use oxc_ast::ast::*;
use oxc_data_structures::stack::SparseStack;
use oxc_span::SPAN;
@ -223,7 +223,7 @@ impl<'a> Traverse<'a> for ArrowFunctions<'a> {
) {
if let JSXElementName::ThisExpression(this) = element_name {
if let Some(ident) = self.get_this_identifier(this.span, ctx) {
*element_name = ctx.ast.jsx_element_name_from_identifier_reference(ident);
*element_name = JSXElementName::IdentifierReference(ident);
}
};
}
@ -235,7 +235,7 @@ impl<'a> Traverse<'a> for ArrowFunctions<'a> {
) {
if let JSXMemberExpressionObject::ThisExpression(this) = object {
if let Some(ident) = self.get_this_identifier(this.span, ctx) {
*object = ctx.ast.jsx_member_expression_object_from_identifier_reference(ident);
*object = JSXMemberExpressionObject::IdentifierReference(ident);
}
}
}
@ -243,7 +243,7 @@ impl<'a> Traverse<'a> for ArrowFunctions<'a> {
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
if let Expression::ThisExpression(this) = expr {
if let Some(ident) = self.get_this_identifier(this.span, ctx) {
*expr = ctx.ast.expression_from_identifier_reference(ident);
*expr = Expression::Identifier(ident);
}
}
}
@ -266,7 +266,7 @@ impl<'a> ArrowFunctions<'a> {
&mut self,
span: Span,
ctx: &mut TraverseCtx<'a>,
) -> Option<IdentifierReference<'a>> {
) -> Option<ArenaBox<'a, IdentifierReference<'a>>> {
// Find arrow function we are currently in (if we are)
let arrow_scope_id = Self::get_arrow_function_scope(ctx)?;
@ -289,7 +289,7 @@ impl<'a> ArrowFunctions<'a> {
.unwrap();
ctx.generate_uid("this", target_scope_id, SymbolFlags::FunctionScopedVariable)
});
Some(this_var.create_spanned_read_reference(span, ctx))
Some(ctx.ast.alloc(this_var.create_spanned_read_reference(span, ctx)))
}
/// Find arrow function we are currently in, if it's between current node, and where `this` is bound.

View file

@ -155,30 +155,31 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
// Make sure side-effects of evaluating `left` only happen once
let reference = ctx.scoping.symbols_mut().get_reference_mut(ident.reference_id().unwrap());
let pow_left = if let Some(symbol_id) = reference.symbol_id() {
// This variable is declared in scope so evaluating it multiple times can't trigger a getter.
// No need for a temp var.
// `left **= right` is being transformed to `left = Math.pow(left, right)`,
// so if `left` is no longer being read from, update its `ReferenceFlags`.
if matches!(ctx.ancestry.parent(), Ancestor::ExpressionStatementExpression(_)) {
*reference.flags_mut() = ReferenceFlags::Write;
}
let pow_left =
if let Some(symbol_id) = reference.symbol_id() {
// This variable is declared in scope so evaluating it multiple times can't trigger a getter.
// No need for a temp var.
// `left **= right` is being transformed to `left = Math.pow(left, right)`,
// so if `left` is no longer being read from, update its `ReferenceFlags`.
if matches!(ctx.ancestry.parent(), Ancestor::ExpressionStatementExpression(_)) {
*reference.flags_mut() = ReferenceFlags::Write;
}
ctx.ast.expression_from_identifier_reference(ctx.create_bound_reference_id(
SPAN,
ident.name.clone(),
symbol_id,
ReferenceFlags::Read,
))
} else {
// Unbound reference. Could possibly trigger a getter so we need to only evaluate it once.
// Assign to a temp var.
let reference = ctx.ast.expression_from_identifier_reference(
ctx.create_unbound_reference_id(SPAN, ident.name.clone(), ReferenceFlags::Read),
);
let binding = self.create_temp_var(reference, &mut temp_var_inits, ctx);
binding.create_read_expression(ctx)
};
Expression::Identifier(ctx.ast.alloc(ctx.create_bound_reference_id(
SPAN,
ident.name.clone(),
symbol_id,
ReferenceFlags::Read,
)))
} else {
// Unbound reference. Could possibly trigger a getter so we need to only evaluate it once.
// Assign to a temp var.
let reference = Expression::Identifier(ctx.ast.alloc(
ctx.create_unbound_reference_id(SPAN, ident.name.clone(), ReferenceFlags::Read),
));
let binding = self.create_temp_var(reference, &mut temp_var_inits, ctx);
binding.create_read_expression(ctx)
};
(pow_left, temp_var_inits)
}
@ -496,14 +497,12 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
if let Some(symbol_id) = symbol_id {
// This variable is declared in scope so evaluating it multiple times can't trigger a getter.
// No need for a temp var.
return ctx.ast.expression_from_identifier_reference(
ctx.create_bound_reference_id(
SPAN,
ident.name.clone(),
symbol_id,
ReferenceFlags::Read,
),
);
return Expression::Identifier(ctx.ast.alloc(ctx.create_bound_reference_id(
SPAN,
ident.name.clone(),
symbol_id,
ReferenceFlags::Read,
)));
}
// Unbound reference. Could possibly trigger a getter so we need to only evaluate it once.
// Assign to a temp var.
@ -551,7 +550,7 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
let math_symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), "Math");
let ident_math =
ctx.create_reference_id(SPAN, Atom::from("Math"), math_symbol_id, ReferenceFlags::Read);
let object = ctx.ast.expression_from_identifier_reference(ident_math);
let object = Expression::Identifier(ctx.alloc(ident_math));
let property = ctx.ast.identifier_name(SPAN, "pow");
let callee =
Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false));

View file

@ -299,17 +299,16 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> {
id.symbol_id.get().unwrap(),
ReferenceFlags::Read,
);
let statement = Statement::from(ctx.ast.declaration_from_function(caller_function));
let statement = Statement::FunctionDeclaration(caller_function);
statements.push(statement);
let argument = Some(ctx.ast.expression_from_identifier_reference(reference));
let argument = Some(Expression::Identifier(ctx.alloc(reference)));
statements.push(ctx.ast.statement_return(SPAN, argument));
} else {
// If the function doesn't have an id, then we need to return the function itself.
// `function() { ... }` -> `return function() { ... };`
let statement_return = ctx.ast.statement_return(
SPAN,
Some(ctx.ast.expression_from_function(caller_function)),
);
let statement_return = ctx
.ast
.statement_return(SPAN, Some(Expression::FunctionExpression(caller_function)));
statements.push(statement_return);
}
debug_assert!(wrapper_function.body.is_none());
@ -323,7 +322,8 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> {
}
// Construct the IIFE
let callee = ctx.ast.expression_from_function(ctx.ast.move_function(wrapper_function));
let callee =
Expression::FunctionExpression(ctx.alloc(ctx.ast.move_function(wrapper_function)));
ctx.ast.expression_call(SPAN, callee, NONE, ctx.ast.vec(), false)
}
@ -385,7 +385,7 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> {
let params = Self::create_empty_params(ctx);
let id = Some(bound_ident.create_binding_identifier(ctx));
let caller_function = Self::create_function(id, params, body, scope_id, ctx);
Statement::from(ctx.ast.declaration_from_function(caller_function))
Statement::FunctionDeclaration(caller_function)
}
}
@ -439,7 +439,7 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> {
.create_binding_identifier(ctx)
});
let function = Self::create_function(id, params, body, scope_id, ctx);
let argument = Some(ctx.ast.expression_from_function(function));
let argument = Some(Expression::FunctionExpression(function));
ctx.ast.statement_return(SPAN, argument)
};
@ -459,7 +459,7 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> {
let params = Self::create_empty_params(ctx);
let wrapper_function = Self::create_function(None, params, body, wrapper_scope_id, ctx);
// Construct the IIFE
let callee = ctx.ast.expression_from_function(wrapper_function);
let callee = Expression::FunctionExpression(wrapper_function);
ctx.ast.expression_call(SPAN, callee, NONE, ctx.ast.vec(), false)
}
}
@ -493,13 +493,13 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> {
body: ArenaBox<'a, FunctionBody<'a>>,
scope_id: ScopeId,
ctx: &mut TraverseCtx<'a>,
) -> Function<'a> {
) -> ArenaBox<'a, Function<'a>> {
let r#type = if id.is_some() {
FunctionType::FunctionDeclaration
} else {
FunctionType::FunctionExpression
};
ctx.ast.function_with_scope_id(
ctx.ast.alloc_function_with_scope_id(
r#type,
SPAN,
id,
@ -528,14 +528,14 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> {
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);
let arguments_ident = Argument::Identifier(ctx.alloc(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));
arguments.push(Argument::from(ctx.ast.expression_this(SPAN)));
arguments.push(arguments_ident);
// _ref.apply
let callee = ctx.ast.expression_member(ctx.ast.member_expression_static(
let callee = Expression::from(ctx.ast.member_expression_static(
SPAN,
bound_ident.create_read_expression(ctx),
ctx.ast.identifier_name(SPAN, "apply"),
@ -565,9 +565,7 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> {
) -> Expression<'a> {
let mut function = Self::create_function(None, params, body, scope_id, ctx);
function.generator = true;
let function_expression = ctx.ast.expression_from_function(function);
let argument = ctx.ast.argument_expression(function_expression);
let arguments = ctx.ast.vec1(argument);
let arguments = ctx.ast.vec1(Argument::FunctionExpression(function));
self.ctx.helper_call_expr(self.helper, arguments, ctx)
}
@ -595,7 +593,7 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> {
Some(init),
false,
));
ctx.ast.statement_declaration(ctx.ast.declaration_variable(
Statement::from(ctx.ast.declaration_variable(
SPAN,
VariableDeclarationKind::Var,
declarations,

View file

@ -18,7 +18,7 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
let step_key =
ctx.generate_uid("step", ctx.current_scope_id(), SymbolFlags::FunctionScopedVariable);
// step.value
let step_value = ctx.ast.expression_member(ctx.ast.member_expression_static(
let step_value = Expression::from(ctx.ast.member_expression_static(
SPAN,
step_key.create_read_expression(ctx),
ctx.ast.identifier_name(SPAN, "value"),
@ -30,14 +30,12 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
// for await (let i of test)
let mut declarator = variable.declarations.pop().unwrap();
declarator.init = Some(step_value);
let variable = ctx.ast.variable_declaration(
Statement::VariableDeclaration(ctx.ast.alloc_variable_declaration(
SPAN,
declarator.kind,
ctx.ast.vec1(declarator),
false,
);
let declaration = ctx.ast.declaration_from_variable(variable);
Statement::from(declaration)
))
}
left @ match_assignment_target!(ForStatementLeft) => {
// for await (i of test), for await ({ i } of test)
@ -131,7 +129,7 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
ctx.generate_uid("iteratorError", scope_id, SymbolFlags::FunctionScopedVariable);
let mut items = ctx.ast.vec_with_capacity(4);
items.push(ctx.ast.statement_declaration(ctx.ast.declaration_variable(
items.push(Statement::from(ctx.ast.declaration_variable(
SPAN,
VariableDeclarationKind::Var,
ctx.ast.vec1(ctx.ast.variable_declarator(
@ -143,7 +141,7 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
)),
false,
)));
items.push(ctx.ast.statement_declaration(ctx.ast.declaration_variable(
items.push(Statement::from(ctx.ast.declaration_variable(
SPAN,
VariableDeclarationKind::Var,
ctx.ast.vec1(ctx.ast.variable_declarator(
@ -155,7 +153,7 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
)),
false,
)));
items.push(ctx.ast.statement_declaration(ctx.ast.declaration_variable(
items.push(Statement::from(ctx.ast.declaration_variable(
SPAN,
VariableDeclarationKind::Var,
ctx.ast.vec1(ctx.ast.variable_declarator(
@ -176,7 +174,7 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
ctx.create_child_scope(block_scope_id, ScopeFlags::empty());
ctx.scopes_mut().change_parent_id(for_of_scope_id, Some(block_scope_id));
let for_statement = ctx.ast.for_statement_with_scope_id(
let for_statement = Statement::ForStatement(ctx.ast.alloc_for_statement_with_scope_id(
SPAN,
Some(ctx.ast.for_statement_init_variable_declaration(
SPAN,
@ -191,7 +189,7 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
SPAN,
get_identifier,
NONE,
ctx.ast.vec1(ctx.ast.argument_expression(object)),
ctx.ast.vec1(Argument::from(object)),
false,
)),
false,
@ -214,7 +212,7 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
ctx.ast.expression_unary(
SPAN,
UnaryOperator::LogicalNot,
ctx.ast.expression_member(ctx.ast.member_expression_static(
Expression::from(ctx.ast.member_expression_static(
SPAN,
ctx.ast.expression_parenthesized(
SPAN,
@ -226,14 +224,12 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
SPAN,
ctx.ast.expression_call(
SPAN,
ctx.ast.expression_member(
ctx.ast.member_expression_static(
SPAN,
iterator_key.create_read_expression(ctx),
ctx.ast.identifier_name(SPAN, "next"),
false,
),
),
Expression::from(ctx.ast.member_expression_static(
SPAN,
iterator_key.create_read_expression(ctx),
ctx.ast.identifier_name(SPAN, "next"),
false,
)),
NONE,
ctx.ast.vec(),
false,
@ -268,16 +264,15 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
);
}
ctx.ast.statement_from_block(ctx.ast.block_statement_with_scope_id(
Statement::BlockStatement(ctx.ast.alloc_block_statement_with_scope_id(
SPAN,
body,
for_statement_body_scope_id,
))
},
for_statement_scope_id,
);
let statement = ctx.ast.statement_from_for(for_statement);
ctx.ast.block_statement_with_scope_id(SPAN, ctx.ast.vec1(statement), block_scope_id)
));
ctx.ast.block_statement_with_scope_id(SPAN, ctx.ast.vec1(for_statement), block_scope_id)
};
let catch_clause = {
@ -339,7 +334,7 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
LogicalOperator::And,
ctx.ast.expression_binary(
SPAN,
ctx.ast.expression_member(ctx.ast.member_expression_static(
Expression::from(ctx.ast.member_expression_static(
SPAN,
iterator_key.create_read_expression(ctx),
ctx.ast.identifier_name(SPAN, "return"),
@ -349,7 +344,7 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
ctx.ast.expression_null_literal(SPAN),
),
),
ctx.ast.statement_from_block(ctx.ast.block_statement_with_scope_id(
Statement::BlockStatement(ctx.ast.alloc_block_statement_with_scope_id(
SPAN,
ctx.ast.vec1(ctx.ast.statement_expression(
SPAN,
@ -357,14 +352,12 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
SPAN,
ctx.ast.expression_call(
SPAN,
ctx.ast.expression_member(
ctx.ast.member_expression_static(
SPAN,
iterator_key.create_read_expression(ctx),
ctx.ast.identifier_name(SPAN, "return"),
false,
),
),
Expression::from(ctx.ast.member_expression_static(
SPAN,
iterator_key.create_read_expression(ctx),
ctx.ast.identifier_name(SPAN, "return"),
false,
)),
NONE,
ctx.ast.vec(),
false,
@ -390,7 +383,7 @@ impl<'a, 'ctx> AsyncGeneratorFunctions<'a, 'ctx> {
ctx.ast.statement_if(
SPAN,
iterator_had_error_key.create_read_expression(ctx),
ctx.ast.statement_from_block(ctx.ast.block_statement_with_scope_id(
Statement::BlockStatement(ctx.ast.alloc_block_statement_with_scope_id(
SPAN,
ctx.ast.vec1(ctx.ast.statement_throw(
SPAN,

View file

@ -143,7 +143,7 @@ impl<'a, 'ctx> ObjectRestSpread<'a, 'ctx> {
fn object_assign(symbol_id: Option<SymbolId>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
let ident =
ctx.create_reference_id(SPAN, Atom::from("Object"), symbol_id, ReferenceFlags::Read);
let object = ctx.ast.expression_from_identifier_reference(ident);
let object = Expression::Identifier(ctx.alloc(ident));
let property = ctx.ast.identifier_name(SPAN, Atom::from("assign"));
Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false))
}

View file

@ -142,8 +142,8 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> {
impl<'a, 'ctx> NullishCoalescingOperator<'a, 'ctx> {
fn clone_expression(expr: &Expression<'a>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
match expr {
Expression::Identifier(ident) => ctx.ast.expression_from_identifier_reference(
ctx.clone_identifier_reference(ident, ReferenceFlags::Read),
Expression::Identifier(ident) => Expression::Identifier(
ctx.ast.alloc(ctx.clone_identifier_reference(ident, ReferenceFlags::Read)),
),
_ => expr.clone_in(ctx.ast.allocator),
}

View file

@ -132,7 +132,7 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
let reference = ctx.symbols_mut().get_reference_mut(ident.reference_id().unwrap());
*reference.flags_mut() = ReferenceFlags::Read;
let symbol_id = reference.symbol_id();
let left_expr = ctx.ast.expression_from_identifier_reference(ident.clone());
let left_expr = Expression::Identifier(ctx.alloc(ident.clone()));
let ident = ctx.create_reference_id(
SPAN,
@ -140,9 +140,7 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
symbol_id,
ReferenceFlags::read_write(),
);
let assign_target = AssignmentTarget::from(
ctx.ast.simple_assignment_target_from_identifier_reference(ident),
);
let assign_target = AssignmentTarget::AssignmentTargetIdentifier(ctx.alloc(ident));
(left_expr, assign_target)
}
@ -171,9 +169,7 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
static_expr.property.clone_in(ctx.ast.allocator),
false,
);
let assign_target = AssignmentTarget::from(
ctx.ast.simple_assignment_target_member_expression(assign_expr),
);
let assign_target = AssignmentTarget::from(assign_expr);
(left_expr, assign_target)
} else {
@ -182,16 +178,13 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
// TODO: We should use static_expr.clone_in instead of cloning the properties,
// but currently clone_in will get rid of IdentifierReference's reference_id
let static_expr_cloned = ctx.ast.static_member_expression(
let static_expr_cloned = ctx.ast.alloc_static_member_expression(
static_expr.span,
Self::clone_expression(&object, ctx),
static_expr.property.clone_in(ctx.ast.allocator),
static_expr.optional,
);
let left_expr = ctx
.ast
.expression_member(ctx.ast.member_expression_from_static(static_expr_cloned));
let left_expr = Expression::StaticMemberExpression(static_expr_cloned);
let member_expr_moved = ctx.ast.member_expression_static(
static_expr.span,
@ -200,9 +193,7 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
static_expr.optional,
);
let assign_target = AssignmentTarget::from(
ctx.ast.simple_assignment_target_member_expression(member_expr_moved),
);
let assign_target = AssignmentTarget::from(member_expr_moved);
(left_expr, assign_target)
}
@ -259,7 +250,7 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
// TODO: ideally we should use computed_expr.clone_in instead of cloning the properties,
// but currently clone_in will get rid of IdentifierReference's reference_id
let new_compute_expr = ctx.ast.computed_member_expression(
let new_compute_expr = ctx.ast.alloc_computed_member_expression(
computed_expr.span,
Self::clone_expression(&object, ctx),
{
@ -278,12 +269,10 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
computed_expr.optional,
);
let left_expr = ctx
.ast
.expression_member(ctx.ast.member_expression_from_computed(new_compute_expr));
let left_expr = Expression::ComputedMemberExpression(new_compute_expr);
// obj[_key] = 1
let new_compute_expr = ctx.ast.computed_member_expression(
let new_compute_expr = ctx.ast.alloc_computed_member_expression(
computed_expr.span,
object,
{
@ -296,10 +285,7 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
computed_expr.optional,
);
let assign_target =
AssignmentTarget::from(ctx.ast.simple_assignment_target_member_expression(
ctx.ast.member_expression_from_computed(new_compute_expr),
));
let assign_target = AssignmentTarget::ComputedMemberExpression(new_compute_expr);
(left_expr, assign_target)
}
@ -312,8 +298,8 @@ impl<'a, 'ctx> LogicalAssignmentOperators<'a, 'ctx> {
/// TODO: remove this once <https://github.com/oxc-project/oxc/issues/4804> is resolved.
fn clone_expression(expr: &Expression<'a>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
match expr {
Expression::Identifier(ident) => ctx.ast.expression_from_identifier_reference(
ctx.clone_identifier_reference(ident, ReferenceFlags::Read),
Expression::Identifier(ident) => Expression::Identifier(
ctx.ast.alloc(ctx.clone_identifier_reference(ident, ReferenceFlags::Read)),
),
_ => expr.clone_in(ctx.ast.allocator),
}

View file

@ -363,7 +363,7 @@ impl<'a> Pragma<'a> {
if let Some(property) = self.property.as_ref() {
create_static_member_expression(object, property.clone(), ctx)
} else {
ctx.ast.expression_from_identifier_reference(object)
Expression::Identifier(ctx.alloc(object))
}
}
}
@ -722,7 +722,7 @@ impl<'a, 'ctx> JsxImpl<'a, 'ctx> {
ctx.ast.expression_string_literal(ident.span, ident.name.clone())
}
JSXElementName::IdentifierReference(ident) => {
ctx.ast.expression_from_identifier_reference(ident.as_ref().clone())
Expression::Identifier(ctx.alloc(ident.as_ref().clone()))
}
JSXElementName::MemberExpression(member_expr) => {
Self::transform_jsx_member_expression(member_expr, ctx)
@ -747,7 +747,7 @@ impl<'a, 'ctx> JsxImpl<'a, 'ctx> {
}
Bindings::AutomaticModule(bindings) => {
let ident = bindings.import_fragment(ctx);
ctx.ast.expression_from_identifier_reference(ident)
Expression::Identifier(ctx.alloc(ident))
}
}
}
@ -783,7 +783,7 @@ impl<'a, 'ctx> JsxImpl<'a, 'ctx> {
} else {
bindings.import_jsx(ctx)
};
ctx.ast.expression_from_identifier_reference(ident)
Expression::Identifier(ctx.alloc(ident))
}
}
}
@ -794,7 +794,7 @@ impl<'a, 'ctx> JsxImpl<'a, 'ctx> {
) -> Expression<'a> {
let object = match &expr.object {
JSXMemberExpressionObject::IdentifierReference(ident) => {
ctx.ast.expression_from_identifier_reference(ident.as_ref().clone())
Expression::Identifier(ctx.alloc(ident.as_ref().clone()))
}
JSXMemberExpressionObject::MemberExpression(expr) => {
Self::transform_jsx_member_expression(expr, ctx)
@ -866,16 +866,14 @@ impl<'a, 'ctx> JsxImpl<'a, 'ctx> {
JSXAttributeName::Identifier(ident) => {
let name = ident.name.clone();
if ident.name.contains('-') {
let expr = ctx.ast.expression_string_literal(ident.span, name);
ctx.ast.property_key_expression(expr)
PropertyKey::from(ctx.ast.expression_string_literal(ident.span, name))
} else {
ctx.ast.property_key_identifier_name(ident.span, name)
}
}
JSXAttributeName::NamespacedName(namespaced) => {
let name = ctx.ast.atom(&namespaced.to_string());
let expr = ctx.ast.expression_string_literal(namespaced.span, name);
ctx.ast.property_key_expression(expr)
PropertyKey::from(ctx.ast.expression_string_literal(namespaced.span, name))
}
}
}
@ -1042,7 +1040,7 @@ fn create_static_member_expression<'a>(
property_name: Atom<'a>,
ctx: &TraverseCtx<'a>,
) -> Expression<'a> {
let object = ctx.ast.expression_from_identifier_reference(object_ident);
let object = Expression::Identifier(ctx.alloc(object_ident));
let property = ctx.ast.identifier_name(SPAN, property_name);
ctx.ast.member_expression_static(SPAN, object, property, false).into()
}

View file

@ -166,7 +166,7 @@ impl<'a, 'ctx> Traverse<'a> for ReactRefresh<'a, 'ctx> {
let callee = self.refresh_reg.to_expression(ctx);
let mut arguments = ctx.ast.vec_with_capacity(2);
arguments.push(Argument::from(binding.create_read_expression(ctx)));
arguments.push(ctx.ast.argument_expression(
arguments.push(Argument::from(
ctx.ast.expression_string_literal(SPAN, ctx.ast.atom(&persistent_id)),
));
new_statements.push(ctx.ast.statement_expression(
@ -345,7 +345,7 @@ impl<'a, 'ctx> Traverse<'a> for ReactRefresh<'a, 'ctx> {
symbol_id,
ReferenceFlags::Read,
);
let mut expr = ctx.ast.expression_from_identifier_reference(ident);
let mut expr = Expression::Identifier(ctx.alloc(ident));
if is_member_expression {
// binding_name.hook_name
@ -505,7 +505,7 @@ impl<'a, 'ctx> ReactRefresh<'a, 'ctx> {
id.symbol_id.get().unwrap(),
ReferenceFlags::Read,
);
let right = ctx.ast.expression_from_identifier_reference(right);
let right = Expression::Identifier(ctx.alloc(right));
let expr = ctx.ast.expression_assignment(SPAN, AssignmentOperator::Assign, left, right);
ctx.ast.statement_expression(SPAN, expr)
}
@ -538,23 +538,16 @@ impl<'a, 'ctx> ReactRefresh<'a, 'ctx> {
let callee_list = self.non_builtin_hooks_callee.remove(&scope_id).unwrap_or_default();
let callee_len = callee_list.len();
let custom_hooks_in_scope = ctx.ast.vec_from_iter(
callee_list
.into_iter()
.filter_map(|e| e.map(|e| ctx.ast.array_expression_element_expression(e))),
callee_list.into_iter().filter_map(|e| e.map(ArrayExpressionElement::from)),
);
let force_reset = custom_hooks_in_scope.len() != callee_len;
let mut arguments = ctx.ast.vec();
arguments.push(
ctx.ast
.argument_expression(ctx.ast.expression_string_literal(SPAN, ctx.ast.atom(&key))),
);
arguments.push(Argument::from(ctx.ast.expression_string_literal(SPAN, ctx.ast.atom(&key))));
if force_reset || !custom_hooks_in_scope.is_empty() {
arguments.push(
ctx.ast.argument_expression(ctx.ast.expression_boolean_literal(SPAN, force_reset)),
);
arguments.push(Argument::from(ctx.ast.expression_boolean_literal(SPAN, force_reset)));
}
if !custom_hooks_in_scope.is_empty() {

View file

@ -200,7 +200,7 @@ impl<'a> InjectGlobalVariables<'a> {
let import_decl = self
.ast
.module_declaration_import_declaration(SPAN, specifiers, source, NONE, kind);
self.ast.statement_module_declaration(import_decl)
Statement::from(import_decl)
});
program.body.splice(0..0, imports);
}

View file

@ -186,17 +186,14 @@ impl<'a, 'ctx> Traverse<'a> for RegExp<'a, 'ctx> {
symbol_id,
ReferenceFlags::read(),
);
ctx.ast.expression_from_identifier_reference(ident)
Expression::Identifier(ctx.alloc(ident))
};
let mut arguments = ctx.ast.vec_with_capacity(2);
arguments.push(
ctx.ast.argument_expression(ctx.ast.expression_string_literal(SPAN, pattern_source)),
);
arguments.push(Argument::from(ctx.ast.expression_string_literal(SPAN, pattern_source)));
let flags_str = flags.to_string();
let flags_str =
ctx.ast.argument_expression(ctx.ast.expression_string_literal(SPAN, flags_str));
let flags_str = Argument::from(ctx.ast.expression_string_literal(SPAN, flags_str));
arguments.push(flags_str);
*expr = ctx.ast.expression_new(regexp.span, callee, arguments, NONE);

View file

@ -151,10 +151,10 @@ impl<'a, 'ctx> Traverse<'a> for TypeScriptAnnotations<'a, 'ctx> {
// need to inject an empty statement (`export {}`) so that the file is
// still considered a module
if no_modules_remaining && some_modules_deleted && self.ctx.module_imports.is_empty() {
let export_decl = ModuleDeclaration::ExportNamedDeclaration(
let export_decl = Statement::ExportNamedDeclaration(
ctx.ast.plain_export_named_declaration(SPAN, ctx.ast.vec(), None),
);
program.body.push(ctx.ast.statement_module_declaration(export_decl));
program.body.push(export_decl);
}
}
@ -629,15 +629,14 @@ impl<'a> Assignment<'a> {
ctx.ast.expression_assignment(
SPAN,
AssignmentOperator::Assign,
ctx.ast
.simple_assignment_target_member_expression(ctx.ast.member_expression_static(
SPAN,
ctx.ast.expression_this(SPAN),
ctx.ast.identifier_name(self.span, &self.name),
false,
))
.into(),
ctx.ast.expression_from_identifier_reference(id),
SimpleAssignmentTarget::from(ctx.ast.member_expression_static(
SPAN,
ctx.ast.expression_this(SPAN),
ctx.ast.identifier_name(self.span, &self.name),
false,
))
.into(),
Expression::Identifier(ctx.alloc(id)),
),
)
}

View file

@ -10,7 +10,7 @@ use oxc_syntax::{
reference::ReferenceFlags,
symbol::SymbolFlags,
};
use oxc_traverse::{Traverse, TraverseCtx};
use oxc_traverse::{BoundIdentifier, Traverse, TraverseCtx};
pub struct TypeScriptEnum<'a> {
enums: FxHashMap<Atom<'a>, FxHashMap<Atom<'a>, ConstantValue>>,
@ -76,15 +76,13 @@ impl<'a> TypeScriptEnum<'a> {
let enum_name = decl.id.name.clone();
let func_scope_id = decl.scope_id.get().unwrap();
let param_ident = ctx.generate_binding(
let param_binding = ctx.generate_binding(
enum_name.clone(),
func_scope_id,
SymbolFlags::FunctionScopedVariable,
);
let ident = param_ident.create_binding_identifier(ctx);
let kind = ast.binding_pattern_kind_from_binding_identifier(ident.clone());
let id = ast.binding_pattern(kind, NONE, false);
let id = param_binding.create_binding_pattern(ctx);
// ((Foo) => {
let params = ast.formal_parameter(SPAN, ast.vec(), id, None, false, false);
@ -99,7 +97,7 @@ impl<'a> TypeScriptEnum<'a> {
// Foo[Foo["X"] = 0] = "X";
let is_already_declared = self.enums.contains_key(&enum_name);
let statements = self.transform_ts_enum_members(&mut decl.members, &ident, ctx);
let statements = self.transform_ts_enum_members(&mut decl.members, &param_binding, ctx);
let body = ast.alloc_function_body(decl.span, ast.vec(), statements);
let callee = Expression::FunctionExpression(ctx.ast.alloc_function_with_scope_id(
FunctionType::FunctionExpression,
@ -130,7 +128,7 @@ impl<'a> TypeScriptEnum<'a> {
var_symbol_id,
ReferenceFlags::Read,
);
let left = ast.expression_from_identifier_reference(left);
let left = Expression::Identifier(ctx.alloc(left));
let right = ast.expression_object(SPAN, ast.vec(), None);
let expression = ast.expression_logical(SPAN, left, op, right);
ast.vec1(Argument::from(expression))
@ -146,8 +144,8 @@ impl<'a> TypeScriptEnum<'a> {
var_symbol_id,
ReferenceFlags::Write,
);
let left = ast.simple_assignment_target_from_identifier_reference(left);
let expr = ast.expression_assignment(SPAN, op, left.into(), call_expression);
let left = AssignmentTarget::AssignmentTargetIdentifier(ctx.alloc(left));
let expr = ast.expression_assignment(SPAN, op, left, call_expression);
return Some(ast.statement_expression(decl.span, expr));
}
@ -159,7 +157,7 @@ impl<'a> TypeScriptEnum<'a> {
let decls = {
let binding_identifier = decl.id.clone();
let binding_pattern_kind =
ast.binding_pattern_kind_from_binding_identifier(binding_identifier);
BindingPatternKind::BindingIdentifier(ctx.alloc(binding_identifier));
let binding = ast.binding_pattern(binding_pattern_kind, NONE, false);
let decl = ast.variable_declarator(SPAN, kind, binding, Some(call_expression), false);
ast.vec1(decl)
@ -181,24 +179,15 @@ impl<'a> TypeScriptEnum<'a> {
fn transform_ts_enum_members(
&mut self,
members: &mut ArenaVec<'a, TSEnumMember<'a>>,
param: &BindingIdentifier<'a>,
param_binding: &BoundIdentifier<'a>,
ctx: &mut TraverseCtx<'a>,
) -> ArenaVec<'a, Statement<'a>> {
let create_identifier_reference = |ctx: &mut TraverseCtx<'a>| {
let ident = ctx.create_bound_reference_id(
param.span,
param.name.clone(),
param.symbol_id.get().unwrap(),
ReferenceFlags::Read,
);
ctx.ast.expression_from_identifier_reference(ident)
};
let ast = ctx.ast;
let mut statements = ast.vec();
let mut prev_constant_value = Some(ConstantValue::Number(-1.0));
let mut previous_enum_members = self.enums.entry(param.name.clone()).or_default().clone();
let mut previous_enum_members =
self.enums.entry(param_binding.name.clone()).or_default().clone();
let mut prev_member_name: Option<Atom<'a>> = None;
@ -238,7 +227,7 @@ impl<'a> TypeScriptEnum<'a> {
);
if !has_binding {
IdentifierReferenceRename::new(
param.name.clone(),
param_binding.name.clone(),
previous_enum_members.clone(),
ctx,
)
@ -276,7 +265,7 @@ impl<'a> TypeScriptEnum<'a> {
}
} else if let Some(prev_member_name) = prev_member_name {
let self_ref = {
let obj = create_identifier_reference(ctx);
let obj = param_binding.create_read_expression(ctx);
let expr = ctx.ast.expression_string_literal(SPAN, prev_member_name);
ast.member_expression_computed(SPAN, obj, expr, false).into()
};
@ -292,22 +281,22 @@ impl<'a> TypeScriptEnum<'a> {
// Foo["x"] = init
let member_expr = {
let obj = create_identifier_reference(ctx);
let obj = param_binding.create_read_expression(ctx);
let expr = ast.expression_string_literal(SPAN, member_name);
ast.member_expression_computed(SPAN, obj, expr, false)
};
let left = ast.simple_assignment_target_member_expression(member_expr);
let left = SimpleAssignmentTarget::from(member_expr);
let mut expr =
ast.expression_assignment(SPAN, AssignmentOperator::Assign, left.into(), init);
// Foo[Foo["x"] = init] = "x"
if !is_str {
let member_expr = {
let obj = create_identifier_reference(ctx);
let obj = param_binding.create_read_expression(ctx);
ast.member_expression_computed(SPAN, obj, expr, false)
};
let left = ast.simple_assignment_target_member_expression(member_expr);
let left = SimpleAssignmentTarget::from(member_expr);
let right = ast.expression_string_literal(SPAN, member_name);
expr =
ast.expression_assignment(SPAN, AssignmentOperator::Assign, left.into(), right);
@ -317,9 +306,9 @@ impl<'a> TypeScriptEnum<'a> {
statements.push(ast.statement_expression(member.span, expr));
}
self.enums.insert(param.name.clone(), previous_enum_members.clone());
self.enums.insert(param_binding.name.clone(), previous_enum_members.clone());
let enum_ref = create_identifier_reference(ctx);
let enum_ref = param_binding.create_read_expression(ctx);
// return Foo;
let return_stmt = ast.statement_return(SPAN, Some(enum_ref));
statements.push(return_stmt);

View file

@ -72,9 +72,9 @@ impl<'a, 'ctx> TypeScriptModule<'a, 'ctx> {
}
let callee = ctx.ast.expression_identifier_reference(SPAN, "require");
let arguments = ctx.ast.vec1(Argument::from(
ctx.ast.expression_from_string_literal(reference.expression.clone()),
));
let arguments = ctx
.ast
.vec1(Argument::StringLiteral(ctx.alloc(reference.expression.clone())));
ctx.ast.expression_call(SPAN, callee, NONE, arguments, false)
}
};
@ -96,7 +96,7 @@ impl<'a, 'ctx> TypeScriptModule<'a, 'ctx> {
let reference_id = ident.reference_id.get().unwrap();
let reference = ctx.symbols_mut().get_reference_mut(reference_id);
*reference.flags_mut() = ReferenceFlags::Read;
ctx.ast.expression_from_identifier_reference(ident)
Expression::Identifier(ctx.alloc(ident))
}
TSTypeName::QualifiedName(qualified_name) => ctx
.ast

View file

@ -363,27 +363,24 @@ impl<'a, 'ctx> TypeScriptNamespace<'a, 'ctx> {
// SAFETY: `ast.copy` is unsound! We need to fix.
let parent_export = unsafe { ctx.ast.copy(&parent_export) };
let assign_left = if let Some(parent_export) = parent_export {
ctx.ast.simple_assignment_target_member_expression(
ctx.ast.member_expression_static(
SPAN,
parent_export,
ctx.ast.identifier_name(SPAN, real_name.clone()),
false,
),
)
AssignmentTarget::from(ctx.ast.member_expression_static(
SPAN,
parent_export,
ctx.ast.identifier_name(SPAN, real_name.clone()),
false,
))
} else {
// _N
ctx.ast.simple_assignment_target_identifier_reference(SPAN, real_name.clone())
AssignmentTarget::from(
ctx.ast
.simple_assignment_target_identifier_reference(SPAN, real_name.clone()),
)
};
let assign_right = ctx.ast.expression_object(SPAN, ctx.ast.vec(), None);
let op = AssignmentOperator::Assign;
let assign_expr = ctx.ast.expression_assignment(
SPAN,
op,
ctx.ast.assignment_target_simple(assign_left),
assign_right,
);
let assign_expr =
ctx.ast.expression_assignment(SPAN, op, assign_left, assign_right);
ctx.ast.expression_parenthesized(SPAN, assign_expr)
};
@ -404,9 +401,9 @@ impl<'a, 'ctx> TypeScriptNamespace<'a, 'ctx> {
logical_right = ctx.ast.expression_parenthesized(SPAN, logical_right);
}
let op = LogicalOperator::Or;
let expr = ctx.ast.expression_logical(SPAN, logical_left, op, logical_right);
ctx.ast.vec1(ctx.ast.argument_expression(expr))
let expr =
ctx.ast.expression_logical(SPAN, logical_left, LogicalOperator::Or, logical_right);
ctx.ast.vec1(Argument::from(expr))
};
let expr = ctx.ast.expression_call(SPAN, callee, NONE, arguments, false);
@ -472,16 +469,13 @@ impl<'a, 'ctx> TypeScriptNamespace<'a, 'ctx> {
ctx.ast.expression_assignment(
SPAN,
AssignmentOperator::Assign,
ctx.ast
.simple_assignment_target_member_expression(
ctx.ast.member_expression_static(
SPAN,
ctx.ast.expression_identifier_reference(SPAN, &name),
ctx.ast.identifier_name(SPAN, property_name),
false,
),
)
.into(),
SimpleAssignmentTarget::from(ctx.ast.member_expression_static(
SPAN,
ctx.ast.expression_identifier_reference(SPAN, &name),
ctx.ast.identifier_name(SPAN, property_name),
false,
))
.into(),
ctx.ast.move_expression(init),
),
);