Skip to content

Commit

Permalink
refactor(transformer): HelperLoader common transform: Helper enum
Browse files Browse the repository at this point in the history
  • Loading branch information
overlookmotel committed Oct 15, 2024
1 parent 8c6afe0 commit 5b4dba0
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 21 deletions.
49 changes: 31 additions & 18 deletions crates/oxc_transformer/src/common/helper_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,21 @@ fn default_as_module_name() -> Cow<'static, str> {
Cow::Borrowed("@babel/runtime")
}

/// Available helpers.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Helper {
ObjectSpread2,
}

impl Helper {
fn name(self) -> &'static str {
match self {
Self::ObjectSpread2 => "objectSpread2",
}
}
}

/// Helper loader transform.
pub struct HelperLoader<'a, 'ctx> {
ctx: &'ctx TransformCtx<'a>,
}
Expand All @@ -144,7 +159,7 @@ impl<'a, 'ctx> Traverse<'a> for HelperLoader<'a, 'ctx> {
}
}

struct Helper<'a> {
struct LoadedHelper<'a> {
source: Atom<'a>,
local: BoundIdentifier<'a>,
}
Expand All @@ -154,7 +169,7 @@ pub struct HelperLoaderStore<'a> {
module_name: Cow<'static, str>,
mode: HelperLoaderMode,
/// Loaded helpers, determined what helpers are loaded and what imports should be added.
loaded_helpers: RefCell<FxHashMap<Atom<'a>, Helper<'a>>>,
loaded_helpers: RefCell<FxHashMap<Helper, LoadedHelper<'a>>>,
}

// Public methods
Expand All @@ -171,11 +186,11 @@ impl<'a> HelperLoaderStore<'a> {
#[expect(dead_code)]
pub fn call(
&mut self,
helper_name: Atom<'a>,
helper: Helper,
arguments: Vec<'a, Argument<'a>>,
ctx: &mut TraverseCtx<'a>,
) -> CallExpression<'a> {
let callee = self.load(helper_name, ctx);
let callee = self.load(helper, ctx);
ctx.ast.call_expression(
SPAN,
callee,
Expand All @@ -189,11 +204,11 @@ impl<'a> HelperLoaderStore<'a> {
#[expect(dead_code)]
pub fn call_expr(
&mut self,
helper_name: Atom<'a>,
helper: Helper,
arguments: Vec<'a, Argument<'a>>,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let callee = self.load(helper_name, ctx);
let callee = self.load(helper, ctx);
ctx.ast.expression_call(
SPAN,
callee,
Expand All @@ -204,10 +219,10 @@ impl<'a> HelperLoaderStore<'a> {
}

/// Load a helper function and return the callee expression.
pub fn load(&self, helper_name: Atom<'a>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
pub fn load(&self, helper: Helper, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
match self.mode {
HelperLoaderMode::Runtime => self.transform_for_runtime_helper(helper_name, ctx),
HelperLoaderMode::External => Self::transform_for_external_helper(helper_name, ctx),
HelperLoaderMode::Runtime => self.transform_for_runtime_helper(helper, ctx),
HelperLoaderMode::External => Self::transform_for_external_helper(helper, ctx),
HelperLoaderMode::Inline => {
unreachable!("Inline helpers are not supported yet");
}
Expand All @@ -219,29 +234,27 @@ impl<'a> HelperLoaderStore<'a> {
impl<'a> HelperLoaderStore<'a> {
fn transform_for_runtime_helper(
&self,
helper_name: Atom<'a>,
helper: Helper,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let mut loaded_helpers = self.loaded_helpers.borrow_mut();
let helper = loaded_helpers.entry(helper_name).or_insert_with_key(|helper_name| {
let loaded_helper = loaded_helpers.entry(helper).or_insert_with(|| {
let helper_name = helper.name();
let source = ctx.ast.atom(&format!("{}/helpers/{helper_name}", self.module_name));
let local = ctx.generate_uid_in_root_scope(helper_name, SymbolFlags::Import);
Helper { source, local }
LoadedHelper { source, local }
});
helper.local.create_read_expression(ctx)
loaded_helper.local.create_read_expression(ctx)
}

fn transform_for_external_helper(
helper_name: Atom<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
fn transform_for_external_helper(helper: Helper, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
static HELPER_VAR: &str = "babelHelpers";

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 property = ctx.ast.identifier_name(SPAN, helper_name);
let property = ctx.ast.identifier_name(SPAN, Atom::from(helper.name()));
Expression::from(ctx.ast.member_expression_static(SPAN, object, property, false))
}

Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_transformer/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Utility transforms which are in common between other transforms.
use helper_loader::HelperLoader;
use oxc_allocator::Vec;
use oxc_ast::ast::*;
use oxc_traverse::{Traverse, TraverseCtx};
Expand All @@ -12,6 +11,7 @@ pub mod module_imports;
pub mod top_level_statements;
pub mod var_declarations;

use helper_loader::HelperLoader;
use module_imports::ModuleImports;
use top_level_statements::TopLevelStatements;
use var_declarations::VarDeclarations;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use oxc_semantic::{ReferenceFlags, SymbolId};
use oxc_span::SPAN;
use oxc_traverse::{Traverse, TraverseCtx};

use crate::context::TransformCtx;
use crate::{common::helper_loader::Helper, TransformCtx};

use super::ObjectRestSpreadOptions;

Expand Down Expand Up @@ -132,6 +132,6 @@ impl<'a, 'ctx> ObjectSpread<'a, 'ctx> {
}

fn babel_external_helper(&self, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
self.ctx.helper_loader.load(Atom::from("objectSpread2"), ctx)
self.ctx.helper_loader.load(Helper::ObjectSpread2, ctx)
}
}

0 comments on commit 5b4dba0

Please sign in to comment.