refactor(transformer): use AstBuilder instead of using struct constructor (#5778)

This commit is contained in:
Boshen 2024-09-15 14:58:56 +00:00
parent 148c7a8b82
commit 1c1353bed5
14 changed files with 87 additions and 128 deletions

View file

@ -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()
}

View file

@ -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);

View file

@ -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))
})
}

View file

@ -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.

View file

@ -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);

View file

@ -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);

View file

@ -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 =

View file

@ -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);

View file

@ -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`

View file

@ -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,

View file

@ -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(

View file

@ -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));
}
}

View file

@ -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 {

View file

@ -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`.