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
2 changes: 1 addition & 1 deletion crates/oxc_transformer/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl<'a> TransformCtx<'a> {
source_type,
source_text,
trivias,
module_imports: ModuleImports::new(allocator),
module_imports: ModuleImports::new(),
var_declarations: VarDeclarationsStore::new(),
}
}
Expand Down
48 changes: 22 additions & 26 deletions crates/oxc_transformer/src/helpers/module_imports.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::cell::RefCell;

use indexmap::IndexMap;
use oxc_allocator::{Allocator, Vec};
use oxc_ast::{ast::*, AstBuilder, NONE};
use oxc_allocator::Vec;
use oxc_ast::{ast::*, NONE};
use oxc_semantic::ReferenceFlags;
use oxc_span::{Atom, SPAN};
use oxc_syntax::symbol::SymbolId;
Expand Down Expand Up @@ -41,15 +41,12 @@ impl<'a> ImportType<'a> {
/// Manage import statement globally
/// <https://github.com/nicolo-ribaudo/babel/tree/main/packages/babel-helper-module-imports>
pub struct ModuleImports<'a> {
ast: AstBuilder<'a>,

imports: RefCell<IndexMap<ImportType<'a>, std::vec::Vec<NamedImport<'a>>>>,
}

impl<'a> ModuleImports<'a> {
pub fn new(allocator: &'a Allocator) -> ModuleImports<'a> {
let ast = AstBuilder::new(allocator);
Self { ast, imports: RefCell::new(IndexMap::default()) }
pub fn new() -> ModuleImports<'a> {
Self { imports: RefCell::new(IndexMap::default()) }
}

/// Add `import { named_import } from 'source'`
Expand All @@ -75,40 +72,39 @@ impl<'a> ModuleImports<'a> {
}

pub fn get_import_statements(&self, ctx: &mut TraverseCtx<'a>) -> Vec<'a, Statement<'a>> {
self.ast.vec_from_iter(self.imports.borrow_mut().drain(..).map(|(import_type, names)| {
ctx.ast.vec_from_iter(self.imports.borrow_mut().drain(..).map(|(import_type, names)| {
match import_type.kind {
ImportKind::Import => self.get_named_import(import_type.source, names),
ImportKind::Require => self.get_require(import_type.source, names, ctx),
ImportKind::Import => Self::get_named_import(import_type.source, names, ctx),
ImportKind::Require => Self::get_require(import_type.source, names, ctx),
}
}))
}

fn get_named_import(
&self,
source: Atom<'a>,
names: std::vec::Vec<NamedImport<'a>>,
ctx: &mut TraverseCtx<'a>,
) -> Statement<'a> {
let specifiers = self.ast.vec_from_iter(names.into_iter().map(|name| {
let specifiers = ctx.ast.vec_from_iter(names.into_iter().map(|name| {
let local = name.local.unwrap_or_else(|| name.imported.clone());
ImportDeclarationSpecifier::ImportSpecifier(self.ast.alloc_import_specifier(
ImportDeclarationSpecifier::ImportSpecifier(ctx.ast.alloc_import_specifier(
SPAN,
ModuleExportName::IdentifierName(IdentifierName::new(SPAN, name.imported)),
BindingIdentifier::new_with_symbol_id(SPAN, local, name.symbol_id),
ImportOrExportKind::Value,
))
}));
let import_stmt = self.ast.module_declaration_import_declaration(
let import_stmt = ctx.ast.module_declaration_import_declaration(
SPAN,
Some(specifiers),
StringLiteral::new(SPAN, source),
NONE,
ImportOrExportKind::Value,
);
self.ast.statement_module_declaration(import_stmt)
ctx.ast.statement_module_declaration(import_stmt)
}

fn get_require(
&self,
source: Atom<'a>,
names: std::vec::Vec<NamedImport<'a>>,
ctx: &mut TraverseCtx<'a>,
Expand All @@ -117,27 +113,27 @@ impl<'a> ModuleImports<'a> {
let symbol_id = ctx.scopes().get_root_binding("require");
let ident =
ctx.create_reference_id(SPAN, Atom::from("require"), symbol_id, ReferenceFlags::read());
let callee = self.ast.expression_from_identifier_reference(ident);
let callee = ctx.ast.expression_from_identifier_reference(ident);

let args = {
let arg = Argument::from(self.ast.expression_string_literal(SPAN, source));
self.ast.vec1(arg)
let arg = Argument::from(ctx.ast.expression_string_literal(SPAN, source));
ctx.ast.vec1(arg)
};
let name = names.into_iter().next().unwrap();
let id = {
let ident = BindingIdentifier::new_with_symbol_id(SPAN, name.imported, name.symbol_id);
self.ast.binding_pattern(
self.ast.binding_pattern_kind_from_binding_identifier(ident),
ctx.ast.binding_pattern(
ctx.ast.binding_pattern_kind_from_binding_identifier(ident),
NONE,
false,
)
};
let decl = {
let init = self.ast.expression_call(SPAN, callee, NONE, args, false);
let decl = self.ast.variable_declarator(SPAN, var_kind, id, Some(init), false);
self.ast.vec1(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);
ctx.ast.vec1(decl)
};
let var_decl = self.ast.declaration_variable(SPAN, var_kind, decl, false);
self.ast.statement_declaration(var_decl)
let var_decl = ctx.ast.declaration_variable(SPAN, var_kind, decl, false);
ctx.ast.statement_declaration(var_decl)
}
}