diff --git a/crates/oxc_ast/src/ast_impl/js.rs b/crates/oxc_ast/src/ast_impl/js.rs index 15f327b10..cd334f0d9 100644 --- a/crates/oxc_ast/src/ast_impl/js.rs +++ b/crates/oxc_ast/src/ast_impl/js.rs @@ -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> { self.kind.get_identifier() } diff --git a/crates/oxc_isolated_declarations/src/class.rs b/crates/oxc_isolated_declarations/src/class.rs index 75807dbf0..4a8a4f2d3 100644 --- a/crates/oxc_isolated_declarations/src/class.rs +++ b/crates/oxc_isolated_declarations/src/class.rs @@ -546,7 +546,7 @@ impl<'a> IsolatedDeclarations<'a> { kind: BindingPatternKind<'a>, type_annotation: Option>>, ) -> 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); diff --git a/crates/oxc_isolated_declarations/src/module.rs b/crates/oxc_isolated_declarations/src/module.rs index de6fff1b5..e16fb4507 100644 --- a/crates/oxc_isolated_declarations/src/module.rs +++ b/crates/oxc_isolated_declarations/src/module.rs @@ -12,14 +12,14 @@ impl<'a> IsolatedDeclarations<'a> { ) -> Option> { 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::, + )) } 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)) }) } diff --git a/crates/oxc_transformer/src/es2015/arrow_functions.rs b/crates/oxc_transformer/src/es2015/arrow_functions.rs index ed9f9636b..5dc2b055a 100644 --- a/crates/oxc_transformer/src/es2015/arrow_functions.rs +++ b/crates/oxc_transformer/src/es2015/arrow_functions.rs @@ -59,8 +59,6 @@ //! * Babel plugin implementation: //! * Arrow function specification: -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::>, // 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. diff --git a/crates/oxc_transformer/src/es2016/exponentiation_operator.rs b/crates/oxc_transformer/src/es2016/exponentiation_operator.rs index 514b26d38..1f0b3312b 100644 --- a/crates/oxc_transformer/src/es2016/exponentiation_operator.rs +++ b/crates/oxc_transformer/src/es2016/exponentiation_operator.rs @@ -30,8 +30,6 @@ //! * Exponentiation operator TC39 proposal: //! * Exponentiation operator specification: -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); diff --git a/crates/oxc_transformer/src/es2019/optional_catch_binding.rs b/crates/oxc_transformer/src/es2019/optional_catch_binding.rs index 511f0b0ff..b8d2d61e2 100644 --- a/crates/oxc_transformer/src/es2019/optional_catch_binding.rs +++ b/crates/oxc_transformer/src/es2019/optional_catch_binding.rs @@ -32,8 +32,6 @@ //! * Babel plugin implementation: //! * Optional catch binding TC39 proposal: -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); diff --git a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs index 996e2d8ee..b5145e1e7 100644 --- a/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs +++ b/crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs @@ -28,8 +28,6 @@ //! * Babel plugin implementation: //! * Nullish coalescing TC39 proposal: -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 = diff --git a/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs b/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs index 025a6f3ed..c428d1fbf 100644 --- a/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs +++ b/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs @@ -53,8 +53,6 @@ //! * Babel plugin implementation: //! * Logical Assignment TC39 proposal: -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); diff --git a/crates/oxc_transformer/src/helpers/bindings.rs b/crates/oxc_transformer/src/helpers/bindings.rs index f7e9190a2..b954a057f 100644 --- a/crates/oxc_transformer/src/helpers/bindings.rs +++ b/crates/oxc_transformer/src/helpers/bindings.rs @@ -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` diff --git a/crates/oxc_transformer/src/helpers/module_imports.rs b/crates/oxc_transformer/src/helpers/module_imports.rs index b52b289d5..54fe0bbcc 100644 --- a/crates/oxc_transformer/src/helpers/module_imports.rs +++ b/crates/oxc_transformer/src/helpers/module_imports.rs @@ -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, diff --git a/crates/oxc_transformer/src/react/refresh.rs b/crates/oxc_transformer/src/react/refresh.rs index d878e0196..4c1fcebbd 100644 --- a/crates/oxc_transformer/src/react/refresh.rs +++ b/crates/oxc_transformer/src/react/refresh.rs @@ -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( diff --git a/crates/oxc_transformer/src/typescript/annotations.rs b/crates/oxc_transformer/src/typescript/annotations.rs index 9d2d819f4..d113affa3 100644 --- a/crates/oxc_transformer/src/typescript/annotations.rs +++ b/crates/oxc_transformer/src/typescript/annotations.rs @@ -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)); } } diff --git a/crates/oxc_transformer/src/typescript/enum.rs b/crates/oxc_transformer/src/typescript/enum.rs index a3374a81c..9ca940c70 100644 --- a/crates/oxc_transformer/src/typescript/enum.rs +++ b/crates/oxc_transformer/src/typescript/enum.rs @@ -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::, + None::, params, - body: Some(body), - type_parameters: None, - return_type: None, - scope_id: Cell::new(Some(func_scope_id)), - })); + None::, + 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 { diff --git a/crates/oxc_traverse/src/context/scoping.rs b/crates/oxc_traverse/src/context/scoping.rs index cea6a97a5..f0d9d70f4 100644 --- a/crates/oxc_traverse/src/context/scoping.rs +++ b/crates/oxc_traverse/src/context/scoping.rs @@ -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`.