Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions crates/oxc_transformer/src/common/helper_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,13 +277,8 @@ impl<'a> HelperLoaderStore<'a> {
static HELPER_VAR: &str = "babelHelpers";

let symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), HELPER_VAR);
let ident = ctx.create_ident_reference(
SPAN,
Atom::from(HELPER_VAR),
symbol_id,
ReferenceFlags::Read,
);
let object = Expression::Identifier(ctx.alloc(ident));
let object =
ctx.create_ident_expr(SPAN, Atom::from(HELPER_VAR), symbol_id, ReferenceFlags::Read);
let property = ctx.ast.identifier_name(SPAN, Atom::from(helper.name()));
Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false))
}
Expand Down
5 changes: 2 additions & 3 deletions crates/oxc_transformer/src/common/module_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,21 +226,20 @@ impl<'a> ModuleImportsStore<'a> {
require_symbol_id: Option<SymbolId>,
ctx: &mut TraverseCtx<'a>,
) -> Statement<'a> {
let var_kind = VariableDeclarationKind::Var;
let ident = ctx.create_ident_reference(
let callee = ctx.create_ident_expr(
SPAN,
Atom::from("require"),
require_symbol_id,
ReferenceFlags::read(),
);
let callee = Expression::Identifier(ctx.alloc(ident));

let args = {
let arg = Argument::from(ctx.ast.expression_string_literal(SPAN, source));
ctx.ast.vec1(arg)
};
let Some(Import::Default(local)) = names.into_iter().next() else { unreachable!() };
let id = local.create_binding_pattern(ctx);
let var_kind = VariableDeclarationKind::Var;
let decl = {
let init = ctx.ast.expression_call(SPAN, callee, NONE, args, false);
let decl = ctx.ast.variable_declarator(SPAN, var_kind, id, Some(init), false);
Expand Down
35 changes: 11 additions & 24 deletions crates/oxc_transformer/src/es2016/exponentiation_operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,18 +164,12 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
*reference.flags_mut() = ReferenceFlags::Write;
}

Expression::Identifier(ctx.ast.alloc(ctx.create_bound_ident_reference(
SPAN,
ident.name.clone(),
symbol_id,
ReferenceFlags::Read,
)))
ctx.create_bound_ident_expr(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_ident_reference(SPAN, ident.name.clone(), ReferenceFlags::Read),
));
let reference =
ctx.create_unbound_ident_expr(SPAN, ident.name.clone(), ReferenceFlags::Read);
let binding = self.create_temp_var(reference, &mut temp_var_inits, ctx);
binding.create_read_expression(ctx)
};
Expand Down Expand Up @@ -495,14 +489,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 Expression::Identifier(ctx.ast.alloc(
ctx.create_bound_ident_reference(
SPAN,
ident.name.clone(),
symbol_id,
ReferenceFlags::Read,
),
));
return ctx.create_bound_ident_expr(
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.
Expand Down Expand Up @@ -548,13 +540,8 @@ impl<'a, 'ctx> ExponentiationOperator<'a, 'ctx> {
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let math_symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), "Math");
let ident_math = ctx.create_ident_reference(
SPAN,
Atom::from("Math"),
math_symbol_id,
ReferenceFlags::Read,
);
let object = Expression::Identifier(ctx.alloc(ident_math));
let object =
ctx.create_ident_expr(SPAN, Atom::from("Math"), math_symbol_id, ReferenceFlags::Read);
let property = ctx.ast.identifier_name(SPAN, "pow");
let callee =
Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false));
Expand Down
10 changes: 4 additions & 6 deletions crates/oxc_transformer/src/es2017/async_to_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,16 +310,15 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> {
let id = caller_function.id.as_ref().unwrap();
// If the function has an id, then we need to return the id.
// `function foo() { ... }` -> `function foo() {} return foo;`
let reference = ctx.create_bound_ident_reference(
let reference = ctx.create_bound_ident_expr(
SPAN,
id.name.clone(),
id.symbol_id(),
ReferenceFlags::Read,
);
let statement = Statement::FunctionDeclaration(caller_function);
statements.push(statement);
let argument = Some(Expression::Identifier(ctx.alloc(reference)));
statements.push(ctx.ast.statement_return(SPAN, argument));
statements.push(ctx.ast.statement_return(SPAN, Some(reference)));
} else {
// If the function doesn't have an id, then we need to return the function itself.
// `function() { ... }` -> `return function() { ... };`
Expand Down Expand Up @@ -597,13 +596,12 @@ impl<'a, 'ctx> AsyncGeneratorExecutor<'a, 'ctx> {
ctx: &mut TraverseCtx<'a>,
) -> Statement<'a> {
let symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), "arguments");
let arguments_ident = ctx.create_ident_reference(
let arguments_ident = Argument::from(ctx.create_ident_expr(
SPAN,
Atom::from("arguments"),
symbol_id,
ReferenceFlags::Read,
);
let arguments_ident = Argument::Identifier(ctx.alloc(arguments_ident));
));

// (this, arguments)
let mut arguments = ctx.ast.vec_with_capacity(2);
Expand Down
5 changes: 2 additions & 3 deletions crates/oxc_transformer/src/es2018/object_rest_spread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,8 @@ impl<'a, 'ctx> ObjectRestSpread<'a, 'ctx> {
}

fn object_assign(symbol_id: Option<SymbolId>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
let ident =
ctx.create_ident_reference(SPAN, Atom::from("Object"), symbol_id, ReferenceFlags::Read);
let object = Expression::Identifier(ctx.alloc(ident));
let object =
ctx.create_ident_expr(SPAN, Atom::from("Object"), symbol_id, ReferenceFlags::Read);
let property = ctx.ast.identifier_name(SPAN, Atom::from("assign"));
Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false))
}
Expand Down
6 changes: 2 additions & 4 deletions crates/oxc_transformer/src/jsx/refresh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,13 +336,12 @@ impl<'a, 'ctx> Traverse<'a> for ReactRefresh<'a, 'ctx> {
binding_name.as_str(),
)
.map(|symbol_id| {
let ident = ctx.create_bound_ident_reference(
let mut expr = ctx.create_bound_ident_expr(
SPAN,
binding_name,
symbol_id,
ReferenceFlags::Read,
);
let mut expr = Expression::Identifier(ctx.alloc(ident));

if is_member_expression {
// binding_name.hook_name
Expand Down Expand Up @@ -496,13 +495,12 @@ impl<'a, 'ctx> ReactRefresh<'a, 'ctx> {
ctx: &mut TraverseCtx<'a>,
) -> Statement<'a> {
let left = self.create_registration(id.name.clone(), ReferenceFlags::Write, ctx);
let right = ctx.create_bound_ident_reference(
let right = ctx.create_bound_ident_expr(
SPAN,
id.name.clone(),
id.symbol_id(),
ReferenceFlags::Read,
);
let right = Expression::Identifier(ctx.alloc(right));
let expr = ctx.ast.expression_assignment(SPAN, AssignmentOperator::Assign, left, right);
ctx.ast.statement_expression(SPAN, expr)
}
Expand Down
8 changes: 1 addition & 7 deletions crates/oxc_transformer/src/regexp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,7 @@ impl<'a, 'ctx> Traverse<'a> for RegExp<'a, 'ctx> {

let callee = {
let symbol_id = ctx.scopes().find_binding(ctx.current_scope_id(), "RegExp");
let ident = ctx.create_ident_reference(
SPAN,
Atom::from("RegExp"),
symbol_id,
ReferenceFlags::read(),
);
Expression::Identifier(ctx.alloc(ident))
ctx.create_ident_expr(SPAN, Atom::from("RegExp"), symbol_id, ReferenceFlags::read())
};

let mut arguments = ctx.ast.vec_with_capacity(2);
Expand Down
3 changes: 1 addition & 2 deletions crates/oxc_transformer/src/typescript/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,12 @@ impl<'a> TypeScriptEnum<'a> {
} else {
// }(Foo || {});
let op = LogicalOperator::Or;
let left = ctx.create_bound_ident_reference(
let left = ctx.create_bound_ident_expr(
decl.id.span,
enum_name.clone(),
var_symbol_id,
ReferenceFlags::Read,
);
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))
Expand Down
41 changes: 41 additions & 0 deletions crates/oxc_traverse/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,18 @@ impl<'a> TraverseCtx<'a> {
self.ast.identifier_reference_with_reference_id(span, name, reference_id)
}

/// Create an `Expression::Identifier` bound to a `SymbolId`.
pub fn create_bound_ident_expr(
&mut self,
span: Span,
name: Atom<'a>,
symbol_id: SymbolId,
flags: ReferenceFlags,
) -> Expression<'a> {
let ident = self.create_bound_ident_reference(span, name, symbol_id, flags);
Expression::Identifier(self.ast.alloc(ident))
}

/// Create an unbound reference.
///
/// This is a shortcut for `ctx.scoping.create_unbound_reference`.
Expand All @@ -468,6 +480,17 @@ impl<'a> TraverseCtx<'a> {
self.ast.identifier_reference_with_reference_id(span, name, reference_id)
}

/// Create an unbound `Expression::Identifier`.
pub fn create_unbound_ident_expr(
&mut self,
span: Span,
name: Atom<'a>,
flags: ReferenceFlags,
) -> Expression<'a> {
let ident = self.create_unbound_ident_reference(span, name, flags);
Expression::Identifier(self.ast.alloc(ident))
}

/// Create a reference optionally bound to a `SymbolId`.
///
/// If you know if there's a `SymbolId` or not, prefer `TraverseCtx::create_bound_reference`
Expand Down Expand Up @@ -502,6 +525,24 @@ impl<'a> TraverseCtx<'a> {
}
}

/// Create an `Expression::Identifier` optionally bound to a `SymbolId`.
///
/// If you know if there's a `SymbolId` or not, prefer `TraverseCtx::create_bound_ident_expr`
/// or `TraverseCtx::create_unbound_ident_expr`.
pub fn create_ident_expr(
&mut self,
span: Span,
name: Atom<'a>,
symbol_id: Option<SymbolId>,
flags: ReferenceFlags,
) -> Expression<'a> {
if let Some(symbol_id) = symbol_id {
self.create_bound_ident_expr(span, name, symbol_id, flags)
} else {
self.create_unbound_ident_expr(span, name, flags)
}
}

/// Create reference in current scope, looking up binding for `name`,
///
/// This is a shortcut for `ctx.scoping.create_reference_in_current_scope`.
Expand Down