mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
refactor(transformer): use AstBuilder instead of using struct constructor (#5778)
This commit is contained in:
parent
148c7a8b82
commit
1c1353bed5
14 changed files with 87 additions and 128 deletions
|
|
@ -3,7 +3,10 @@ use std::{borrow::Cow, cell::Cell, fmt};
|
|||
use oxc_allocator::{Box, FromIn, Vec};
|
||||
use oxc_span::{Atom, GetSpan, SourceType, Span};
|
||||
use oxc_syntax::{
|
||||
operator::UnaryOperator, reference::ReferenceId, scope::ScopeFlags, symbol::SymbolId,
|
||||
operator::UnaryOperator,
|
||||
reference::ReferenceId,
|
||||
scope::{ScopeFlags, ScopeId},
|
||||
symbol::SymbolId,
|
||||
};
|
||||
|
||||
use crate::ast::*;
|
||||
|
|
@ -356,6 +359,10 @@ impl<'a> BindingIdentifier<'a> {
|
|||
pub fn new(span: Span, name: Atom<'a>) -> Self {
|
||||
Self { span, name, symbol_id: Cell::default() }
|
||||
}
|
||||
|
||||
pub fn new_with_symbol_id(span: Span, name: Atom<'a>, symbol_id: SymbolId) -> Self {
|
||||
Self { span, name, symbol_id: Cell::new(Some(symbol_id)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for BindingIdentifier<'a> {
|
||||
|
|
@ -753,6 +760,10 @@ impl<'a> BlockStatement<'a> {
|
|||
pub fn new(span: Span, body: Vec<'a, Statement<'a>>) -> Self {
|
||||
Self { span, body, scope_id: Cell::default() }
|
||||
}
|
||||
|
||||
pub fn new_with_scope_id(span: Span, body: Vec<'a, Statement<'a>>, scope_id: ScopeId) -> Self {
|
||||
Self { span, body, scope_id: Cell::new(Some(scope_id)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Declaration<'a> {
|
||||
|
|
@ -910,10 +921,6 @@ impl<'a> CatchClause<'a> {
|
|||
}
|
||||
|
||||
impl<'a> BindingPattern<'a> {
|
||||
pub fn new_with_kind(kind: BindingPatternKind<'a>) -> Self {
|
||||
Self { kind, type_annotation: None, optional: false }
|
||||
}
|
||||
|
||||
pub fn get_identifier(&self) -> Option<Atom<'a>> {
|
||||
self.kind.get_identifier()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -546,7 +546,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
kind: BindingPatternKind<'a>,
|
||||
type_annotation: Option<Box<'a, TSTypeAnnotation<'a>>>,
|
||||
) -> Box<'a, FormalParameters<'a>> {
|
||||
let pattern = BindingPattern { kind, type_annotation, optional: false };
|
||||
let pattern = self.ast.binding_pattern(kind, type_annotation, false);
|
||||
let parameter =
|
||||
self.ast.formal_parameter(SPAN, self.ast.vec(), pattern, None, false, false);
|
||||
let items = self.ast.vec1(parameter);
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
) -> Option<ExportNamedDeclaration<'a>> {
|
||||
let decl = self.transform_declaration(decl.declaration.as_ref()?, false)?;
|
||||
|
||||
Some(ExportNamedDeclaration {
|
||||
span: decl.span(),
|
||||
declaration: Some(decl),
|
||||
specifiers: self.ast.vec(),
|
||||
source: None,
|
||||
export_kind: ImportOrExportKind::Value,
|
||||
with_clause: None,
|
||||
})
|
||||
Some(self.ast.export_named_declaration(
|
||||
decl.span(),
|
||||
Some(decl),
|
||||
self.ast.vec(),
|
||||
None,
|
||||
ImportOrExportKind::Value,
|
||||
None::<WithClause>,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn create_unique_name(&mut self, name: &str) -> Atom<'a> {
|
||||
|
|
@ -69,12 +69,12 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
self.ast.vec1(self.ast.variable_declarator(SPAN, kind, id, None, true));
|
||||
|
||||
Some((
|
||||
Some(VariableDeclaration {
|
||||
span: SPAN,
|
||||
Some(self.ast.variable_declaration(
|
||||
SPAN,
|
||||
kind,
|
||||
declarations,
|
||||
declare: self.is_declare(),
|
||||
}),
|
||||
self.is_declare(),
|
||||
)),
|
||||
ExportDefaultDeclarationKind::from(
|
||||
self.ast.expression_identifier_reference(SPAN, &name),
|
||||
),
|
||||
|
|
@ -86,7 +86,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
|||
declaration.map(|(var_decl, declaration)| {
|
||||
let exported =
|
||||
ModuleExportName::IdentifierName(self.ast.identifier_name(SPAN, "default"));
|
||||
(var_decl, ExportDefaultDeclaration { span: decl.span, declaration, exported })
|
||||
(var_decl, self.ast.export_default_declaration(decl.span, declaration, exported))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,8 +59,6 @@
|
|||
//! * Babel plugin implementation: <https://github.com/babel/babel/blob/main/packages/babel-plugin-transform-arrow-functions>
|
||||
//! * Arrow function specification: <https://tc39.es/ecma262/#sec-arrow-function-definitions>
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
use oxc_allocator::Vec;
|
||||
use oxc_ast::{ast::*, NONE};
|
||||
use oxc_span::SPAN;
|
||||
|
|
@ -290,23 +288,23 @@ impl<'a> ArrowFunctions<'a> {
|
|||
*flags &= !ScopeFlags::Arrow;
|
||||
}
|
||||
|
||||
let new_function = Function {
|
||||
r#type: FunctionType::FunctionExpression,
|
||||
span: arrow_function_expr.span,
|
||||
id: None,
|
||||
generator: false,
|
||||
r#async: arrow_function_expr.r#async,
|
||||
declare: false,
|
||||
this_param: None,
|
||||
let new_function = ctx.ast.function(
|
||||
FunctionType::FunctionExpression,
|
||||
arrow_function_expr.span,
|
||||
None,
|
||||
false,
|
||||
arrow_function_expr.r#async,
|
||||
false,
|
||||
// SAFETY: `ast.copy` is unsound! We need to fix.
|
||||
params: unsafe { self.ctx.ast.copy(&arrow_function_expr.params) },
|
||||
body: Some(body),
|
||||
unsafe { self.ctx.ast.copy(&arrow_function_expr.type_parameters) },
|
||||
None::<TSThisParameter<'a>>,
|
||||
// SAFETY: `ast.copy` is unsound! We need to fix.
|
||||
type_parameters: unsafe { self.ctx.ast.copy(&arrow_function_expr.type_parameters) },
|
||||
unsafe { self.ctx.ast.copy(&arrow_function_expr.params) },
|
||||
// SAFETY: `ast.copy` is unsound! We need to fix.
|
||||
return_type: unsafe { self.ctx.ast.copy(&arrow_function_expr.return_type) },
|
||||
scope_id: Cell::new(scope_id),
|
||||
};
|
||||
unsafe { self.ctx.ast.copy(&arrow_function_expr.return_type) },
|
||||
Some(body),
|
||||
);
|
||||
new_function.scope_id.set(scope_id);
|
||||
|
||||
let expr = Expression::FunctionExpression(self.ctx.ast.alloc(new_function));
|
||||
// Avoid creating a function declaration.
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@
|
|||
//! * Exponentiation operator TC39 proposal: <https://github.com/tc39/proposal-exponentiation-operator>
|
||||
//! * Exponentiation operator specification: <https://tc39.es/ecma262/#sec-exp-operator>
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
use oxc_allocator::{CloneIn, Vec};
|
||||
use oxc_ast::{ast::*, NONE};
|
||||
use oxc_semantic::{ReferenceFlags, SymbolFlags};
|
||||
|
|
@ -314,11 +312,8 @@ impl<'a> ExponentiationOperator<'a> {
|
|||
|
||||
{
|
||||
// var _name;
|
||||
let binding_identifier = BindingIdentifier {
|
||||
span: SPAN,
|
||||
name: symbol_name.clone(),
|
||||
symbol_id: Cell::new(Some(symbol_id)),
|
||||
};
|
||||
let binding_identifier =
|
||||
BindingIdentifier::new_with_symbol_id(SPAN, symbol_name.clone(), symbol_id);
|
||||
let kind = VariableDeclarationKind::Var;
|
||||
let id = ctx.ast.binding_pattern_kind_from_binding_identifier(binding_identifier);
|
||||
let id = ctx.ast.binding_pattern(id, NONE, false);
|
||||
|
|
|
|||
|
|
@ -32,8 +32,6 @@
|
|||
//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-optional-catch-binding>
|
||||
//! * Optional catch binding TC39 proposal: <https://github.com/tc39/proposal-optional-catch-binding>
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
use oxc_ast::{ast::*, NONE};
|
||||
use oxc_semantic::SymbolFlags;
|
||||
use oxc_span::SPAN;
|
||||
|
|
@ -66,8 +64,7 @@ impl<'a> Traverse<'a> for OptionalCatchBinding<'a> {
|
|||
SymbolFlags::CatchVariable | SymbolFlags::FunctionScopedVariable,
|
||||
);
|
||||
let name = ctx.ast.atom(ctx.symbols().get_name(symbol_id));
|
||||
let binding_identifier =
|
||||
BindingIdentifier { span: SPAN, symbol_id: Cell::new(Some(symbol_id)), name };
|
||||
let binding_identifier = BindingIdentifier::new_with_symbol_id(SPAN, name, symbol_id);
|
||||
let binding_pattern_kind =
|
||||
ctx.ast.binding_pattern_kind_from_binding_identifier(binding_identifier);
|
||||
let binding_pattern = ctx.ast.binding_pattern(binding_pattern_kind, NONE, false);
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-nullish-coalescing-operator>
|
||||
//! * Nullish coalescing TC39 proposal: <https://github.com/tc39-transfer/proposal-nullish-coalescing>
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
use oxc_allocator::{CloneIn, Vec};
|
||||
use oxc_ast::{ast::*, NONE};
|
||||
use oxc_semantic::{ReferenceFlags, ScopeFlags, ScopeId, SymbolFlags};
|
||||
|
|
@ -186,11 +184,8 @@ impl<'a> NullishCoalescingOperator<'a> {
|
|||
let symbol_name = ctx.ast.atom(ctx.symbols().get_name(symbol_id));
|
||||
|
||||
// var _name;
|
||||
let binding_identifier = BindingIdentifier {
|
||||
span: SPAN,
|
||||
name: symbol_name.clone(),
|
||||
symbol_id: Cell::new(Some(symbol_id)),
|
||||
};
|
||||
let binding_identifier =
|
||||
BindingIdentifier::new_with_symbol_id(SPAN, symbol_name.clone(), symbol_id);
|
||||
let id = ctx.ast.binding_pattern_kind_from_binding_identifier(binding_identifier);
|
||||
let id = ctx.ast.binding_pattern(id, NONE, false);
|
||||
let reference =
|
||||
|
|
|
|||
|
|
@ -53,8 +53,6 @@
|
|||
//! * Babel plugin implementation: <https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-logical-assignment-operators>
|
||||
//! * Logical Assignment TC39 proposal: <https://github.com/tc39/proposal-logical-assignment>
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
use oxc_allocator::{CloneIn, Vec};
|
||||
use oxc_ast::{ast::*, NONE};
|
||||
use oxc_semantic::{ReferenceFlags, SymbolFlags};
|
||||
|
|
@ -360,11 +358,9 @@ impl<'a> LogicalAssignmentOperators<'a> {
|
|||
let symbol_name = ctx.ast.atom(ctx.symbols().get_name(symbol_id));
|
||||
|
||||
// var _name;
|
||||
let binding_identifier = BindingIdentifier {
|
||||
span: SPAN,
|
||||
name: symbol_name.clone(),
|
||||
symbol_id: Cell::new(Some(symbol_id)),
|
||||
};
|
||||
let binding_identifier =
|
||||
BindingIdentifier::new_with_symbol_id(SPAN, symbol_name.clone(), symbol_id);
|
||||
|
||||
let kind = VariableDeclarationKind::Var;
|
||||
let id = ctx.ast.binding_pattern_kind_from_binding_identifier(binding_identifier);
|
||||
let id = ctx.ast.binding_pattern(id, NONE, false);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
use std::cell::Cell;
|
||||
|
||||
use oxc_ast::ast::{BindingIdentifier, IdentifierReference};
|
||||
use oxc_span::{Atom, Span, SPAN};
|
||||
use oxc_syntax::{
|
||||
|
|
@ -78,11 +76,7 @@ impl<'a> BoundIdentifier<'a> {
|
|||
|
||||
/// Create `BindingIdentifier` for this binding
|
||||
pub fn create_binding_identifier(&self) -> BindingIdentifier<'a> {
|
||||
BindingIdentifier {
|
||||
span: SPAN,
|
||||
name: self.name.clone(),
|
||||
symbol_id: Cell::new(Some(self.symbol_id)),
|
||||
}
|
||||
BindingIdentifier::new_with_symbol_id(SPAN, self.name.clone(), self.symbol_id)
|
||||
}
|
||||
|
||||
/// Create `IdentifierReference` referencing this binding, which is read from, with dummy `Span`
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::cell::RefCell;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use oxc_allocator::{Allocator, Vec};
|
||||
|
|
@ -90,19 +90,12 @@ impl<'a> ModuleImports<'a> {
|
|||
) -> Statement<'a> {
|
||||
let specifiers = self.ast.vec_from_iter(names.into_iter().map(|name| {
|
||||
let local = name.local.unwrap_or_else(|| name.imported.clone());
|
||||
ImportDeclarationSpecifier::ImportSpecifier(self.ast.alloc(ImportSpecifier {
|
||||
span: SPAN,
|
||||
imported: ModuleExportName::IdentifierName(IdentifierName::new(
|
||||
SPAN,
|
||||
name.imported,
|
||||
)),
|
||||
local: BindingIdentifier {
|
||||
span: SPAN,
|
||||
name: local,
|
||||
symbol_id: Cell::new(Some(name.symbol_id)),
|
||||
},
|
||||
import_kind: ImportOrExportKind::Value,
|
||||
}))
|
||||
ImportDeclarationSpecifier::ImportSpecifier(self.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(
|
||||
SPAN,
|
||||
|
|
@ -132,11 +125,7 @@ impl<'a> ModuleImports<'a> {
|
|||
};
|
||||
let name = names.into_iter().next().unwrap();
|
||||
let id = {
|
||||
let ident = BindingIdentifier {
|
||||
span: SPAN,
|
||||
name: name.imported,
|
||||
symbol_id: Cell::new(Some(name.symbol_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),
|
||||
NONE,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{cell::Cell, iter::once};
|
||||
use std::iter::once;
|
||||
|
||||
use base64::prelude::{Engine, BASE64_STANDARD};
|
||||
use oxc_allocator::CloneIn;
|
||||
|
|
@ -150,12 +150,7 @@ impl<'a> Traverse<'a> for ReactRefresh<'a> {
|
|||
let mut new_statements = ctx.ast.vec_with_capacity(self.registrations.len() + 1);
|
||||
for (symbol_id, persistent_id) in self.registrations.drain(..) {
|
||||
let name = ctx.ast.atom(ctx.symbols().get_name(symbol_id));
|
||||
let binding_identifier = BindingIdentifier {
|
||||
name: name.clone(),
|
||||
symbol_id: Cell::new(Some(symbol_id)),
|
||||
span: SPAN,
|
||||
};
|
||||
|
||||
let binding_identifier = BindingIdentifier::new_with_symbol_id(SPAN, name, symbol_id);
|
||||
variable_declarator_items.push(
|
||||
ctx.ast.variable_declarator(
|
||||
SPAN,
|
||||
|
|
@ -690,11 +685,8 @@ impl<'a> ReactRefresh<'a> {
|
|||
|
||||
let symbol_name = ctx.ast.atom(ctx.symbols().get_name(symbol_id));
|
||||
|
||||
let binding_identifier = BindingIdentifier {
|
||||
span: SPAN,
|
||||
name: symbol_name.clone(),
|
||||
symbol_id: Cell::new(Some(symbol_id)),
|
||||
};
|
||||
let binding_identifier =
|
||||
BindingIdentifier::new_with_symbol_id(SPAN, symbol_name.clone(), symbol_id);
|
||||
|
||||
// _s();
|
||||
let call_expression = ctx.ast.statement_expression(
|
||||
|
|
|
|||
|
|
@ -554,8 +554,8 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
ctx: &mut TraverseCtx<'a>,
|
||||
) -> Statement<'a> {
|
||||
let scope_id = ctx.insert_scope_below_statement(&stmt, ScopeFlags::empty());
|
||||
let block =
|
||||
BlockStatement { span, body: ctx.ast.vec1(stmt), scope_id: Cell::new(Some(scope_id)) };
|
||||
let block = BlockStatement::new_with_scope_id(span, ctx.ast.vec1(stmt), scope_id);
|
||||
block.scope_id.set(Some(scope_id));
|
||||
Statement::BlockStatement(ctx.ast.alloc(block))
|
||||
}
|
||||
|
||||
|
|
@ -575,11 +575,7 @@ impl<'a> TypeScriptAnnotations<'a> {
|
|||
) {
|
||||
if stmt.is_typescript_syntax() {
|
||||
let scope_id = ctx.create_child_scope(parent_scope_id, ScopeFlags::empty());
|
||||
let block = BlockStatement {
|
||||
span: stmt.span(),
|
||||
body: ctx.ast.vec(),
|
||||
scope_id: Cell::new(Some(scope_id)),
|
||||
};
|
||||
let block = BlockStatement::new_with_scope_id(stmt.span(), ctx.ast.vec(), scope_id);
|
||||
*stmt = Statement::BlockStatement(ctx.ast.alloc(block));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
use std::cell::Cell;
|
||||
|
||||
use oxc_allocator::Vec;
|
||||
use oxc_ast::{ast::*, visit::walk_mut, VisitMut, NONE};
|
||||
use oxc_span::{Atom, Span, SPAN};
|
||||
|
|
@ -88,11 +86,12 @@ impl<'a> TypeScriptEnum<'a> {
|
|||
NodeId::DUMMY,
|
||||
);
|
||||
ctx.scopes_mut().add_binding(func_scope_id, enum_name.to_compact_str(), param_symbol_id);
|
||||
let ident = BindingIdentifier {
|
||||
span: decl.id.span,
|
||||
name: decl.id.name.clone(),
|
||||
symbol_id: Cell::new(Some(param_symbol_id)),
|
||||
};
|
||||
|
||||
let ident = BindingIdentifier::new_with_symbol_id(
|
||||
decl.id.span,
|
||||
decl.id.name.clone(),
|
||||
param_symbol_id,
|
||||
);
|
||||
let kind = ast.binding_pattern_kind_from_binding_identifier(ident.clone());
|
||||
let id = ast.binding_pattern(kind, NONE, false);
|
||||
|
||||
|
|
@ -111,20 +110,21 @@ impl<'a> TypeScriptEnum<'a> {
|
|||
|
||||
let statements = self.transform_ts_enum_members(&mut decl.members, &ident, ctx);
|
||||
let body = ast.alloc_function_body(decl.span, ast.vec(), statements);
|
||||
let callee = Expression::FunctionExpression(ctx.alloc(Function {
|
||||
r#type: FunctionType::FunctionExpression,
|
||||
span: SPAN,
|
||||
id: None,
|
||||
generator: false,
|
||||
r#async: false,
|
||||
declare: false,
|
||||
this_param: None,
|
||||
let function = ctx.ast.function(
|
||||
FunctionType::FunctionExpression,
|
||||
SPAN,
|
||||
None,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
None::<TSTypeParameterDeclaration>,
|
||||
None::<TSThisParameter>,
|
||||
params,
|
||||
body: Some(body),
|
||||
type_parameters: None,
|
||||
return_type: None,
|
||||
scope_id: Cell::new(Some(func_scope_id)),
|
||||
}));
|
||||
None::<TSTypeAnnotation>,
|
||||
Some(body),
|
||||
);
|
||||
function.scope_id.set(Some(func_scope_id));
|
||||
let callee = ctx.ast.expression_from_function(function);
|
||||
|
||||
let var_symbol_id = decl.id.symbol_id.get().unwrap();
|
||||
let arguments = if (is_export || is_not_top_scope) && !is_already_declared {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{cell::Cell, str};
|
||||
use std::str;
|
||||
|
||||
use compact_str::CompactString;
|
||||
use itoa::Buffer as ItoaBuffer;
|
||||
|
|
@ -296,7 +296,7 @@ impl TraverseScoping {
|
|||
flags: ReferenceFlags,
|
||||
) -> IdentifierReference<'a> {
|
||||
let reference_id = self.create_bound_reference(symbol_id, flags);
|
||||
IdentifierReference { span, name, reference_id: Cell::new(Some(reference_id)) }
|
||||
IdentifierReference::new_with_reference_id(span, name, Some(reference_id))
|
||||
}
|
||||
|
||||
/// Create an unbound reference
|
||||
|
|
@ -319,7 +319,7 @@ impl TraverseScoping {
|
|||
flags: ReferenceFlags,
|
||||
) -> IdentifierReference<'a> {
|
||||
let reference_id = self.create_unbound_reference(name.to_compact_str(), flags);
|
||||
IdentifierReference { span, name, reference_id: Cell::new(Some(reference_id)) }
|
||||
IdentifierReference::new_with_reference_id(span, name, Some(reference_id))
|
||||
}
|
||||
|
||||
/// Create a reference optionally bound to a `SymbolId`.
|
||||
|
|
|
|||
Loading…
Reference in a new issue