diff --git a/crates/oxc_ast/src/ast_kind.rs b/crates/oxc_ast/src/ast_kind.rs index bb0078a8a..753c4c9c3 100644 --- a/crates/oxc_ast/src/ast_kind.rs +++ b/crates/oxc_ast/src/ast_kind.rs @@ -3,9 +3,22 @@ use oxc_span::{Atom, GetSpan, Span}; #[allow(clippy::wildcard_imports)] use crate::ast::*; -/// Untyped AST Node Kind -#[derive(Debug, Clone, Copy)] -pub enum AstKind<'a> { +macro_rules! ast_kinds { + { $($ident:ident($type:ty),)* } => ( + #[derive(Debug, Clone, Copy)] + pub enum AstType { + $($ident,)* + } + + /// Untyped AST Node Kind + #[derive(Debug, Clone, Copy)] + pub enum AstKind<'a> { + $($ident($type),)* + } + ) +} + +ast_kinds! { Program(&'a Program<'a>), Directive(&'a Directive<'a>), Hashbang(&'a Hashbang<'a>), diff --git a/crates/oxc_ast/src/lib.rs b/crates/oxc_ast/src/lib.rs index c1e84fd21..332ebd83e 100644 --- a/crates/oxc_ast/src/lib.rs +++ b/crates/oxc_ast/src/lib.rs @@ -20,13 +20,13 @@ mod span; pub mod syntax_directed_operations; mod trivia; mod visit; -mod visit_mut; +pub mod visit_mut; pub use num_bigint::BigUint; pub use crate::{ ast_builder::AstBuilder, - ast_kind::AstKind, + ast_kind::{AstKind, AstType}, trivia::{Comment, CommentKind, Trivias, TriviasMap}, visit::Visit, visit_mut::VisitMut, diff --git a/crates/oxc_ast/src/visit_mut.rs b/crates/oxc_ast/src/visit_mut.rs index f19a0b016..6ac3dcd2c 100644 --- a/crates/oxc_ast/src/visit_mut.rs +++ b/crates/oxc_ast/src/visit_mut.rs @@ -4,25 +4,18 @@ use oxc_allocator::Vec; use oxc_span::Span; use oxc_syntax::scope::ScopeFlags; -use crate::{ast::*, AstKind}; +use crate::{ast::*, AstType}; /// Syntax tree traversal to mutate an exclusive borrow of a syntax tree in place. pub trait VisitMut<'a>: Sized { - fn enter_node(&mut self, _kind: AstKind<'a>) {} - fn leave_node(&mut self, _kind: AstKind<'a>) {} + fn enter_node(&mut self, _kind: AstType) {} + fn leave_node(&mut self, _kind: AstType) {} fn enter_scope(&mut self, _flags: ScopeFlags) {} fn leave_scope(&mut self) {} - fn alloc(&self, t: &T) -> &'a T { - // SAFETY: - // This should be safe as long as `src` is an reference from the allocator. - // But honestly, I'm not really sure if this is safe. - unsafe { std::mem::transmute(t) } - } - fn visit_program(&mut self, program: &mut Program<'a>) { - let kind = AstKind::Program(self.alloc(program)); + let kind = AstType::Program; self.enter_scope({ let mut flags = ScopeFlags::Top; if program.is_strict() { @@ -79,7 +72,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_block_statement(&mut self, stmt: &mut BlockStatement<'a>) { - let kind = AstKind::BlockStatement(self.alloc(stmt)); + let kind = AstType::BlockStatement; self.enter_scope(ScopeFlags::empty()); self.enter_node(kind); self.visit_statements(&mut stmt.body); @@ -88,7 +81,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_break_statement(&mut self, stmt: &mut BreakStatement<'a>) { - let kind = AstKind::BreakStatement(self.alloc(stmt)); + let kind = AstType::BreakStatement; self.enter_node(kind); if let Some(break_target) = &mut stmt.label { self.visit_label_identifier(break_target); @@ -97,7 +90,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_continue_statement(&mut self, stmt: &mut ContinueStatement<'a>) { - let kind = AstKind::ContinueStatement(self.alloc(stmt)); + let kind = AstType::ContinueStatement; self.enter_node(kind); if let Some(continue_target) = &mut stmt.label { self.visit_label_identifier(continue_target); @@ -105,35 +98,35 @@ pub trait VisitMut<'a>: Sized { self.leave_node(kind); } - fn visit_debugger_statement(&mut self, stmt: &mut DebuggerStatement) { - let kind = AstKind::DebuggerStatement(self.alloc(stmt)); + fn visit_debugger_statement(&mut self, _stmt: &mut DebuggerStatement) { + let kind = AstType::DebuggerStatement; self.enter_node(kind); self.leave_node(kind); } fn visit_do_while_statement(&mut self, stmt: &mut DoWhileStatement<'a>) { - let kind = AstKind::DoWhileStatement(self.alloc(stmt)); + let kind = AstType::DoWhileStatement; self.enter_node(kind); self.visit_statement(&mut stmt.body); self.visit_expression(&mut stmt.test); self.leave_node(kind); } - fn visit_empty_statement(&mut self, stmt: &mut EmptyStatement) { - let kind = AstKind::EmptyStatement(self.alloc(stmt)); + fn visit_empty_statement(&mut self, _stmt: &mut EmptyStatement) { + let kind = AstType::EmptyStatement; self.enter_node(kind); self.leave_node(kind); } fn visit_expression_statement(&mut self, stmt: &mut ExpressionStatement<'a>) { - let kind = AstKind::ExpressionStatement(self.alloc(stmt)); + let kind = AstType::ExpressionStatement; self.enter_node(kind); self.visit_expression(&mut stmt.expression); self.leave_node(kind); } fn visit_for_statement(&mut self, stmt: &mut ForStatement<'a>) { - let kind = AstKind::ForStatement(self.alloc(stmt)); + let kind = AstType::ForStatement; let is_lexical_declaration = stmt.init.as_ref().is_some_and(ForStatementInit::is_lexical_declaration); if is_lexical_declaration { @@ -157,7 +150,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_for_statement_init(&mut self, init: &mut ForStatementInit<'a>) { - let kind = AstKind::ForStatementInit(self.alloc(init)); + let kind = AstType::ForStatementInit; self.enter_node(kind); match init { ForStatementInit::VariableDeclaration(decl) => { @@ -172,7 +165,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_for_in_statement(&mut self, stmt: &mut ForInStatement<'a>) { - let kind = AstKind::ForInStatement(self.alloc(stmt)); + let kind = AstType::ForInStatement; let is_lexical_declaration = stmt.left.is_lexical_declaration(); if is_lexical_declaration { self.enter_scope(ScopeFlags::empty()); @@ -188,7 +181,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_for_of_statement(&mut self, stmt: &mut ForOfStatement<'a>) { - let kind = AstKind::ForOfStatement(self.alloc(stmt)); + let kind = AstType::ForOfStatement; let is_lexical_declaration = stmt.left.is_lexical_declaration(); if is_lexical_declaration { self.enter_scope(ScopeFlags::empty()); @@ -216,7 +209,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_if_statement(&mut self, stmt: &mut IfStatement<'a>) { - let kind = AstKind::IfStatement(self.alloc(stmt)); + let kind = AstType::IfStatement; self.enter_node(kind); self.visit_expression(&mut stmt.test); self.visit_statement(&mut stmt.consequent); @@ -227,7 +220,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_labeled_statement(&mut self, stmt: &mut LabeledStatement<'a>) { - let kind = AstKind::LabeledStatement(self.alloc(stmt)); + let kind = AstType::LabeledStatement; self.enter_node(kind); self.visit_label_identifier(&mut stmt.label); self.visit_statement(&mut stmt.body); @@ -235,7 +228,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_return_statement(&mut self, stmt: &mut ReturnStatement<'a>) { - let kind = AstKind::ReturnStatement(self.alloc(stmt)); + let kind = AstType::ReturnStatement; self.enter_node(kind); if let Some(arg) = &mut stmt.argument { self.visit_expression(arg); @@ -244,7 +237,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_switch_statement(&mut self, stmt: &mut SwitchStatement<'a>) { - let kind = AstKind::SwitchStatement(self.alloc(stmt)); + let kind = AstType::SwitchStatement; self.enter_node(kind); self.visit_expression(&mut stmt.discriminant); self.enter_scope(ScopeFlags::empty()); @@ -256,7 +249,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_switch_case(&mut self, case: &mut SwitchCase<'a>) { - let kind = AstKind::SwitchCase(self.alloc(case)); + let kind = AstType::SwitchCase; self.enter_node(kind); if let Some(expr) = &mut case.test { self.visit_expression(expr); @@ -266,14 +259,14 @@ pub trait VisitMut<'a>: Sized { } fn visit_throw_statement(&mut self, stmt: &mut ThrowStatement<'a>) { - let kind = AstKind::ThrowStatement(self.alloc(stmt)); + let kind = AstType::ThrowStatement; self.enter_node(kind); self.visit_expression(&mut stmt.argument); self.leave_node(kind); } fn visit_try_statement(&mut self, stmt: &mut TryStatement<'a>) { - let kind = AstKind::TryStatement(self.alloc(stmt)); + let kind = AstType::TryStatement; self.enter_node(kind); self.visit_block_statement(&mut stmt.block); if let Some(handler) = &mut stmt.handler { @@ -286,7 +279,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_catch_clause(&mut self, clause: &mut CatchClause<'a>) { - let kind = AstKind::CatchClause(self.alloc(clause)); + let kind = AstType::CatchClause; self.enter_scope(ScopeFlags::empty()); self.enter_node(kind); if let Some(param) = &mut clause.param { @@ -298,14 +291,14 @@ pub trait VisitMut<'a>: Sized { } fn visit_finally_clause(&mut self, clause: &mut BlockStatement<'a>) { - let kind = AstKind::FinallyClause(self.alloc(clause)); + let kind = AstType::FinallyClause; self.enter_node(kind); self.visit_block_statement(clause); self.leave_node(kind); } fn visit_while_statement(&mut self, stmt: &mut WhileStatement<'a>) { - let kind = AstKind::WhileStatement(self.alloc(stmt)); + let kind = AstType::WhileStatement; self.enter_node(kind); self.visit_expression(&mut stmt.test); self.visit_statement(&mut stmt.body); @@ -313,7 +306,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_with_statement(&mut self, stmt: &mut WithStatement<'a>) { - let kind = AstKind::WithStatement(self.alloc(stmt)); + let kind = AstType::WithStatement; self.enter_node(kind); self.visit_expression(&mut stmt.object); self.visit_statement(&mut stmt.body); @@ -321,7 +314,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_directive(&mut self, directive: &mut Directive<'a>) { - let kind = AstKind::Directive(self.alloc(directive)); + let kind = AstType::Directive; self.enter_node(kind); self.visit_string_literal(&mut directive.expression); self.leave_node(kind); @@ -330,7 +323,7 @@ pub trait VisitMut<'a>: Sized { /* ---------- Declaration ---------- */ fn visit_variable_declaration(&mut self, decl: &mut VariableDeclaration<'a>) { - let kind = AstKind::VariableDeclaration(self.alloc(decl)); + let kind = AstType::VariableDeclaration; self.enter_node(kind); for declarator in decl.declarations.iter_mut() { self.visit_variable_declarator(declarator); @@ -339,7 +332,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_variable_declarator(&mut self, declarator: &mut VariableDeclarator<'a>) { - let kind = AstKind::VariableDeclarator(self.alloc(declarator)); + let kind = AstType::VariableDeclarator; self.enter_node(kind); self.visit_binding_pattern(&mut declarator.id); if let Some(init) = &mut declarator.init { @@ -349,7 +342,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_using_declaration(&mut self, declaration: &mut UsingDeclaration<'a>) { - let kind = AstKind::UsingDeclaration(self.alloc(declaration)); + let kind = AstType::UsingDeclaration; self.enter_node(kind); for decl in declaration.declarations.iter_mut() { self.visit_variable_declarator(decl); @@ -360,34 +353,11 @@ pub trait VisitMut<'a>: Sized { /* ---------- Function ---------- */ fn visit_function(&mut self, func: &mut Function<'a>, flags: Option) { - let kind = AstKind::Function(self.alloc(func)); - self.enter_scope({ - let mut flags = flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function; - if func.is_strict() { - flags |= ScopeFlags::StrictMode; - } - flags - }); - self.enter_node(kind); - if let Some(ident) = &mut func.id { - self.visit_binding_identifier(ident); - } - self.visit_formal_parameters(&mut func.params); - if let Some(body) = &mut func.body { - self.visit_function_body(body); - } - if let Some(parameters) = &mut func.type_parameters { - self.visit_ts_type_parameter_declaration(parameters); - } - if let Some(annotation) = &mut func.return_type { - self.visit_ts_type_annotation(annotation); - } - self.leave_node(kind); - self.leave_scope(); + walk_function_mut(self, func, flags); } fn visit_function_body(&mut self, body: &mut FunctionBody<'a>) { - let kind = AstKind::FunctionBody(self.alloc(body)); + let kind = AstType::FunctionBody; self.enter_node(kind); for directive in body.directives.iter_mut() { self.visit_directive(directive); @@ -397,7 +367,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_formal_parameters(&mut self, params: &mut FormalParameters<'a>) { - let kind = AstKind::FormalParameters(self.alloc(params)); + let kind = AstType::FormalParameters; self.enter_node(kind); for param in params.items.iter_mut() { self.visit_formal_parameter(param); @@ -409,7 +379,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_formal_parameter(&mut self, param: &mut FormalParameter<'a>) { - let kind = AstKind::FormalParameter(self.alloc(param)); + let kind = AstType::FormalParameter; self.enter_node(kind); for decorator in param.decorators.iter_mut() { self.visit_decorator(decorator); @@ -421,7 +391,7 @@ pub trait VisitMut<'a>: Sized { /* ---------- Class ---------- */ fn visit_decorator(&mut self, decorator: &mut Decorator<'a>) { - let kind = AstKind::Decorator(self.alloc(decorator)); + let kind = AstType::Decorator; self.enter_node(kind); self.visit_expression(&mut decorator.expression); self.leave_node(kind); @@ -432,7 +402,7 @@ pub trait VisitMut<'a>: Sized { self.visit_decorator(decorator); } - let kind = AstKind::Class(self.alloc(class)); + let kind = AstType::Class; // FIXME(don): Should we enter a scope when visiting class declarations? let is_class_expr = class.r#type == ClassType::ClassExpression; @@ -464,7 +434,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_class_heritage(&mut self, expr: &mut Expression<'a>) { - let kind = AstKind::ClassHeritage(self.alloc(expr)); + let kind = AstType::ClassHeritage; self.enter_node(kind); self.visit_expression(expr); self.leave_node(kind); @@ -487,7 +457,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_static_block(&mut self, block: &mut StaticBlock<'a>) { - let kind = AstKind::StaticBlock(self.alloc(block)); + let kind = AstType::StaticBlock; self.enter_scope(ScopeFlags::ClassStaticBlock); self.enter_node(kind); self.visit_statements(&mut block.body); @@ -496,25 +466,11 @@ pub trait VisitMut<'a>: Sized { } fn visit_method_definition(&mut self, def: &mut MethodDefinition<'a>) { - let kind = AstKind::MethodDefinition(self.alloc(def)); - self.enter_node(kind); - for decorator in def.decorators.iter_mut() { - self.visit_decorator(decorator); - } - - let flags = match def.kind { - MethodDefinitionKind::Get => ScopeFlags::GetAccessor, - MethodDefinitionKind::Set => ScopeFlags::SetAccessor, - MethodDefinitionKind::Constructor => ScopeFlags::Constructor, - MethodDefinitionKind::Method => ScopeFlags::empty(), - }; - self.visit_property_key(&mut def.key); - self.visit_function(&mut def.value, Some(flags)); - self.leave_node(kind); + walk_method_definition_mut(self, def); } fn visit_property_definition(&mut self, def: &mut PropertyDefinition<'a>) { - let kind = AstKind::PropertyDefinition(self.alloc(def)); + let kind = AstType::PropertyDefinition; self.enter_node(kind); for decorator in def.decorators.iter_mut() { self.visit_decorator(decorator); @@ -589,14 +545,14 @@ pub trait VisitMut<'a>: Sized { } } - fn visit_meta_property(&mut self, meta: &mut MetaProperty<'a>) { - let kind = AstKind::MetaProperty(self.alloc(meta)); + fn visit_meta_property(&mut self, _meta: &mut MetaProperty<'a>) { + let kind = AstType::MetaProperty; self.enter_node(kind); self.leave_node(kind); } fn visit_array_expression(&mut self, expr: &mut ArrayExpression<'a>) { - let kind = AstKind::ArrayExpression(self.alloc(expr)); + let kind = AstType::ArrayExpression; self.enter_node(kind); for elem in expr.elements.iter_mut() { self.visit_array_expression_element(elem); @@ -605,7 +561,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_array_expression_element(&mut self, arg: &mut ArrayExpressionElement<'a>) { - let kind = AstKind::ArrayExpressionElement(self.alloc(arg)); + let kind = AstType::ArrayExpressionElement; self.enter_node(kind); match arg { ArrayExpressionElement::SpreadElement(spread) => self.visit_spread_element(spread), @@ -616,7 +572,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_argument(&mut self, arg: &mut Argument<'a>) { - let kind = AstKind::Argument(self.alloc(arg)); + let kind = AstType::Argument; self.enter_node(kind); match arg { Argument::SpreadElement(spread) => self.visit_spread_element(spread), @@ -626,27 +582,27 @@ pub trait VisitMut<'a>: Sized { } fn visit_spread_element(&mut self, elem: &mut SpreadElement<'a>) { - let kind = AstKind::SpreadElement(self.alloc(elem)); + let kind = AstType::SpreadElement; self.enter_node(kind); self.visit_expression(&mut elem.argument); self.leave_node(kind); } fn visit_expression_array_element(&mut self, expr: &mut Expression<'a>) { - let kind = AstKind::ExpressionArrayElement(self.alloc(expr)); + let kind = AstType::ExpressionArrayElement; self.enter_node(kind); self.visit_expression(expr); self.leave_node(kind); } - fn visit_elision(&mut self, span: Span) { - let kind = AstKind::Elision(span); + fn visit_elision(&mut self, _span: Span) { + let kind = AstType::Elision; self.enter_node(kind); self.leave_node(kind); } fn visit_assignment_expression(&mut self, expr: &mut AssignmentExpression<'a>) { - let kind = AstKind::AssignmentExpression(self.alloc(expr)); + let kind = AstType::AssignmentExpression; self.enter_node(kind); self.visit_assignment_target(&mut expr.left); self.visit_expression(&mut expr.right); @@ -654,7 +610,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_arrow_expression(&mut self, expr: &mut ArrowFunctionExpression<'a>) { - let kind = AstKind::ArrowFunctionExpression(self.alloc(expr)); + let kind = AstType::ArrowFunctionExpression; self.enter_scope(ScopeFlags::Function | ScopeFlags::Arrow); self.enter_node(kind); self.visit_formal_parameters(&mut expr.params); @@ -667,14 +623,14 @@ pub trait VisitMut<'a>: Sized { } fn visit_await_expression(&mut self, expr: &mut AwaitExpression<'a>) { - let kind = AstKind::AwaitExpression(self.alloc(expr)); + let kind = AstType::AwaitExpression; self.enter_node(kind); self.visit_expression(&mut expr.argument); self.leave_node(kind); } fn visit_binary_expression(&mut self, expr: &mut BinaryExpression<'a>) { - let kind = AstKind::BinaryExpression(self.alloc(expr)); + let kind = AstType::BinaryExpression; self.enter_node(kind); self.visit_expression(&mut expr.left); self.visit_expression(&mut expr.right); @@ -682,7 +638,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_call_expression(&mut self, expr: &mut CallExpression<'a>) { - let kind = AstKind::CallExpression(self.alloc(expr)); + let kind = AstType::CallExpression; self.enter_node(kind); for arg in expr.arguments.iter_mut() { self.visit_argument(arg); @@ -695,7 +651,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_chain_expression(&mut self, expr: &mut ChainExpression<'a>) { - let kind = AstKind::ChainExpression(self.alloc(expr)); + let kind = AstType::ChainExpression; self.enter_node(kind); self.visit_chain_element(&mut expr.expression); self.leave_node(kind); @@ -709,7 +665,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_conditional_expression(&mut self, expr: &mut ConditionalExpression<'a>) { - let kind = AstKind::ConditionalExpression(self.alloc(expr)); + let kind = AstType::ConditionalExpression; self.enter_node(kind); self.visit_expression(&mut expr.test); self.visit_expression(&mut expr.consequent); @@ -725,7 +681,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_logical_expression(&mut self, expr: &mut LogicalExpression<'a>) { - let kind = AstKind::LogicalExpression(self.alloc(expr)); + let kind = AstType::LogicalExpression; self.enter_node(kind); self.visit_expression(&mut expr.left); self.visit_expression(&mut expr.right); @@ -733,7 +689,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_member_expression(&mut self, expr: &mut MemberExpression<'a>) { - let kind = AstKind::MemberExpression(self.alloc(expr)); + let kind = AstType::MemberExpression; self.enter_node(kind); match expr { MemberExpression::ComputedMemberExpression(expr) => { @@ -765,7 +721,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_new_expression(&mut self, expr: &mut NewExpression<'a>) { - let kind = AstKind::NewExpression(self.alloc(expr)); + let kind = AstType::NewExpression; self.enter_node(kind); self.visit_expression(&mut expr.callee); if let Some(parameters) = &mut expr.type_parameters { @@ -778,7 +734,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_object_expression(&mut self, expr: &mut ObjectExpression<'a>) { - let kind = AstKind::ObjectExpression(self.alloc(expr)); + let kind = AstType::ObjectExpression; self.enter_node(kind); for prop in expr.properties.iter_mut() { self.visit_object_property_kind(prop); @@ -794,18 +750,11 @@ pub trait VisitMut<'a>: Sized { } fn visit_object_property(&mut self, prop: &mut ObjectProperty<'a>) { - let kind = AstKind::ObjectProperty(self.alloc(prop)); - self.enter_node(kind); - self.visit_property_key(&mut prop.key); - self.visit_expression(&mut prop.value); - if let Some(init) = &mut prop.init { - self.visit_expression(init); - } - self.leave_node(kind); + walk_object_property_mut(self, prop); } fn visit_property_key(&mut self, key: &mut PropertyKey<'a>) { - let kind = AstKind::PropertyKey(self.alloc(key)); + let kind = AstType::PropertyKey; self.enter_node(kind); match key { PropertyKey::Identifier(ident) => self.visit_identifier_name(ident), @@ -816,7 +765,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_parenthesized_expression(&mut self, expr: &mut ParenthesizedExpression<'a>) { - let kind = AstKind::ParenthesizedExpression(self.alloc(expr)); + let kind = AstType::ParenthesizedExpression; self.enter_node(kind); self.visit_expression(&mut expr.expression); self.leave_node(kind); @@ -828,7 +777,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_sequence_expression(&mut self, expr: &mut SequenceExpression<'a>) { - let kind = AstKind::SequenceExpression(self.alloc(expr)); + let kind = AstType::SequenceExpression; self.enter_node(kind); for expr in expr.expressions.iter_mut() { self.visit_expression(expr); @@ -837,35 +786,35 @@ pub trait VisitMut<'a>: Sized { } fn visit_tagged_template_expression(&mut self, expr: &mut TaggedTemplateExpression<'a>) { - let kind = AstKind::TaggedTemplateExpression(self.alloc(expr)); + let kind = AstType::TaggedTemplateExpression; self.enter_node(kind); self.visit_expression(&mut expr.tag); self.visit_template_literal(&mut expr.quasi); self.leave_node(kind); } - fn visit_this_expression(&mut self, expr: &mut ThisExpression) { - let kind = AstKind::ThisExpression(self.alloc(expr)); + fn visit_this_expression(&mut self, _expr: &mut ThisExpression) { + let kind = AstType::ThisExpression; self.enter_node(kind); self.leave_node(kind); } fn visit_unary_expression(&mut self, expr: &mut UnaryExpression<'a>) { - let kind = AstKind::UnaryExpression(self.alloc(expr)); + let kind = AstType::UnaryExpression; self.enter_node(kind); self.visit_expression(&mut expr.argument); self.leave_node(kind); } fn visit_update_expression(&mut self, expr: &mut UpdateExpression<'a>) { - let kind = AstKind::UpdateExpression(self.alloc(expr)); + let kind = AstType::UpdateExpression; self.enter_node(kind); self.visit_simple_assignment_target(&mut expr.argument); self.leave_node(kind); } fn visit_yield_expression(&mut self, expr: &mut YieldExpression<'a>) { - let kind = AstKind::YieldExpression(self.alloc(expr)); + let kind = AstType::YieldExpression; self.enter_node(kind); if let Some(argument) = &mut expr.argument { self.visit_expression(argument); @@ -873,14 +822,14 @@ pub trait VisitMut<'a>: Sized { self.leave_node(kind); } - fn visit_super(&mut self, expr: &mut Super) { - let kind = AstKind::Super(self.alloc(expr)); + fn visit_super(&mut self, _expr: &mut Super) { + let kind = AstType::Super; self.enter_node(kind); self.leave_node(kind); } fn visit_assignment_target(&mut self, target: &mut AssignmentTarget<'a>) { - let kind = AstKind::AssignmentTarget(self.alloc(target)); + let kind = AstType::AssignmentTarget; self.enter_node(kind); match target { AssignmentTarget::SimpleAssignmentTarget(target) => { @@ -894,7 +843,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_simple_assignment_target(&mut self, target: &mut SimpleAssignmentTarget<'a>) { - let kind = AstKind::SimpleAssignmentTarget(self.alloc(target)); + let kind = AstType::SimpleAssignmentTarget; self.enter_node(kind); match target { SimpleAssignmentTarget::AssignmentTargetIdentifier(ident) => { @@ -957,7 +906,7 @@ pub trait VisitMut<'a>: Sized { &mut self, target: &mut AssignmentTargetWithDefault<'a>, ) { - let kind = AstKind::AssignmentTargetWithDefault(self.alloc(target)); + let kind = AstType::AssignmentTargetWithDefault; self.enter_node(kind); self.visit_assignment_target(&mut target.binding); self.visit_expression(&mut target.init); @@ -1009,7 +958,7 @@ pub trait VisitMut<'a>: Sized { /* ---------- Expression ---------- */ fn visit_jsx_element(&mut self, elem: &mut JSXElement<'a>) { - let kind = AstKind::JSXElement(self.alloc(elem)); + let kind = AstType::JSXElement; self.enter_node(kind); self.visit_jsx_opening_element(&mut elem.opening_element); for child in elem.children.iter_mut() { @@ -1022,7 +971,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) { - let kind = AstKind::JSXOpeningElement(self.alloc(elem)); + let kind = AstType::JSXOpeningElement; self.enter_node(kind); self.visit_jsx_element_name(&mut elem.name); @@ -1033,14 +982,14 @@ pub trait VisitMut<'a>: Sized { } fn visit_jsx_closing_element(&mut self, elem: &mut JSXClosingElement<'a>) { - let kind = AstKind::JSXClosingElement(self.alloc(elem)); + let kind = AstType::JSXClosingElement; self.enter_node(kind); self.visit_jsx_element_name(&mut elem.name); self.leave_node(kind); } fn visit_jsx_element_name(&mut self, name: &mut JSXElementName<'a>) { - let kind = AstKind::JSXElementName(self.alloc(name)); + let kind = AstType::JSXElementName; self.enter_node(kind); match name { JSXElementName::Identifier(ident) => self.visit_jsx_identifier(ident), @@ -1050,14 +999,14 @@ pub trait VisitMut<'a>: Sized { self.leave_node(kind); } - fn visit_jsx_identifier(&mut self, ident: &mut JSXIdentifier<'a>) { - let kind = AstKind::JSXIdentifier(self.alloc(ident)); + fn visit_jsx_identifier(&mut self, _ident: &mut JSXIdentifier<'a>) { + let kind = AstType::JSXIdentifier; self.enter_node(kind); self.leave_node(kind); } fn visit_jsx_member_expression(&mut self, expr: &mut JSXMemberExpression<'a>) { - let kind = AstKind::JSXMemberExpression(self.alloc(expr)); + let kind = AstType::JSXMemberExpression; self.enter_node(kind); self.visit_jsx_member_expression_object(&mut expr.object); self.visit_jsx_identifier(&mut expr.property); @@ -1065,7 +1014,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_jsx_member_expression_object(&mut self, expr: &mut JSXMemberExpressionObject<'a>) { - let kind = AstKind::JSXMemberExpressionObject(self.alloc(expr)); + let kind = AstType::JSXMemberExpressionObject; self.enter_node(kind); match expr { JSXMemberExpressionObject::Identifier(ident) => self.visit_jsx_identifier(ident), @@ -1077,7 +1026,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_jsx_namespaced_name(&mut self, name: &mut JSXNamespacedName<'a>) { - let kind = AstKind::JSXNamespacedName(self.alloc(name)); + let kind = AstType::JSXNamespacedName; self.enter_node(kind); self.visit_jsx_identifier(&mut name.namespace); self.visit_jsx_identifier(&mut name.property); @@ -1085,7 +1034,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_jsx_attribute_item(&mut self, item: &mut JSXAttributeItem<'a>) { - let kind = AstKind::JSXAttributeItem(self.alloc(item)); + let kind = AstType::JSXAttributeItem; self.enter_node(kind); match item { JSXAttributeItem::Attribute(attribute) => self.visit_jsx_attribute(attribute), @@ -1118,7 +1067,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_jsx_expression_container(&mut self, expr: &mut JSXExpressionContainer<'a>) { - let kind = AstKind::JSXExpressionContainer(self.alloc(expr)); + let kind = AstType::JSXExpressionContainer; self.enter_node(kind); self.visit_jsx_expression(&mut expr.expression); self.leave_node(kind); @@ -1132,7 +1081,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_jsx_fragment(&mut self, elem: &mut JSXFragment<'a>) { - let kind = AstKind::JSXFragment(self.alloc(elem)); + let kind = AstType::JSXFragment; self.enter_node(kind); for child in elem.children.iter_mut() { self.visit_jsx_child(child); @@ -1154,8 +1103,8 @@ pub trait VisitMut<'a>: Sized { self.visit_expression(&mut child.expression); } - fn visit_jsx_text(&mut self, child: &JSXText<'a>) { - let kind = AstKind::JSXText(self.alloc(child)); + fn visit_jsx_text(&mut self, _child: &JSXText<'a>) { + let kind = AstType::JSXText; self.enter_node(kind); self.leave_node(kind); } @@ -1176,14 +1125,14 @@ pub trait VisitMut<'a>: Sized { } } - fn visit_binding_identifier(&mut self, ident: &mut BindingIdentifier<'a>) { - let kind = AstKind::BindingIdentifier(self.alloc(ident)); + fn visit_binding_identifier(&mut self, _ident: &mut BindingIdentifier<'a>) { + let kind = AstType::BindingIdentifier; self.enter_node(kind); self.leave_node(kind); } fn visit_object_pattern(&mut self, pat: &mut ObjectPattern<'a>) { - let kind = AstKind::ObjectPattern(self.alloc(pat)); + let kind = AstType::ObjectPattern; self.enter_node(kind); for prop in pat.properties.iter_mut() { self.visit_binding_property(prop); @@ -1200,7 +1149,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_array_pattern(&mut self, pat: &mut ArrayPattern<'a>) { - let kind = AstKind::ArrayPattern(self.alloc(pat)); + let kind = AstType::ArrayPattern; self.enter_node(kind); for pat in pat.elements.iter_mut().flatten() { self.visit_binding_pattern(pat); @@ -1212,14 +1161,14 @@ pub trait VisitMut<'a>: Sized { } fn visit_rest_element(&mut self, pat: &mut BindingRestElement<'a>) { - let kind = AstKind::BindingRestElement(self.alloc(pat)); + let kind = AstType::BindingRestElement; self.enter_node(kind); self.visit_binding_pattern(&mut pat.argument); self.leave_node(kind); } fn visit_assignment_pattern(&mut self, pat: &mut AssignmentPattern<'a>) { - let kind = AstKind::AssignmentPattern(self.alloc(pat)); + let kind = AstType::AssignmentPattern; self.enter_node(kind); self.visit_binding_pattern(&mut pat.left); self.visit_expression(&mut pat.right); @@ -1228,64 +1177,64 @@ pub trait VisitMut<'a>: Sized { /* ---------- Identifier ---------- */ - fn visit_identifier_reference(&mut self, ident: &mut IdentifierReference<'a>) { - let kind = AstKind::IdentifierReference(self.alloc(ident)); + fn visit_identifier_reference(&mut self, _ident: &mut IdentifierReference<'a>) { + let kind = AstType::IdentifierReference; self.enter_node(kind); self.leave_node(kind); } - fn visit_private_identifier(&mut self, ident: &mut PrivateIdentifier<'a>) { - let kind = AstKind::PrivateIdentifier(self.alloc(ident)); + fn visit_private_identifier(&mut self, _ident: &mut PrivateIdentifier<'a>) { + let kind = AstType::PrivateIdentifier; self.enter_node(kind); self.leave_node(kind); } - fn visit_label_identifier(&mut self, ident: &mut LabelIdentifier<'a>) { - let kind = AstKind::LabelIdentifier(self.alloc(ident)); + fn visit_label_identifier(&mut self, _ident: &mut LabelIdentifier<'a>) { + let kind = AstType::LabelIdentifier; self.enter_node(kind); self.leave_node(kind); } - fn visit_identifier_name(&mut self, ident: &mut IdentifierName<'a>) { - let kind = AstKind::IdentifierName(self.alloc(ident)); + fn visit_identifier_name(&mut self, _ident: &mut IdentifierName<'a>) { + let kind = AstType::IdentifierName; self.enter_node(kind); self.leave_node(kind); } /* ---------- Literal ---------- */ - fn visit_number_literal(&mut self, lit: &mut NumericLiteral<'a>) { - let kind = AstKind::NumericLiteral(self.alloc(lit)); + fn visit_number_literal(&mut self, _lit: &mut NumericLiteral<'a>) { + let kind = AstType::NumericLiteral; self.enter_node(kind); self.leave_node(kind); } - fn visit_boolean_literal(&mut self, lit: &mut BooleanLiteral) { - let kind = AstKind::BooleanLiteral(self.alloc(lit)); + fn visit_boolean_literal(&mut self, _lit: &mut BooleanLiteral) { + let kind = AstType::BooleanLiteral; self.enter_node(kind); self.leave_node(kind); } - fn visit_null_literal(&mut self, lit: &mut NullLiteral) { - let kind = AstKind::NullLiteral(self.alloc(lit)); + fn visit_null_literal(&mut self, _lit: &mut NullLiteral) { + let kind = AstType::NullLiteral; self.enter_node(kind); self.leave_node(kind); } - fn visit_bigint_literal(&mut self, lit: &mut BigIntLiteral<'a>) { - let kind = AstKind::BigintLiteral(self.alloc(lit)); + fn visit_bigint_literal(&mut self, _lit: &mut BigIntLiteral<'a>) { + let kind = AstType::BigintLiteral; self.enter_node(kind); self.leave_node(kind); } - fn visit_string_literal(&mut self, lit: &mut StringLiteral<'a>) { - let kind = AstKind::StringLiteral(self.alloc(lit)); + fn visit_string_literal(&mut self, _lit: &mut StringLiteral<'a>) { + let kind = AstType::StringLiteral; self.enter_node(kind); self.leave_node(kind); } fn visit_template_literal(&mut self, lit: &mut TemplateLiteral<'a>) { - let kind = AstKind::TemplateLiteral(self.alloc(lit)); + let kind = AstType::TemplateLiteral; self.enter_node(kind); for elem in lit.quasis.iter_mut() { self.visit_template_element(elem); @@ -1296,8 +1245,8 @@ pub trait VisitMut<'a>: Sized { self.leave_node(kind); } - fn visit_reg_expr_literal(&mut self, lit: &mut RegExpLiteral<'a>) { - let kind = AstKind::RegExpLiteral(self.alloc(lit)); + fn visit_reg_expr_literal(&mut self, _lit: &mut RegExpLiteral<'a>) { + let kind = AstType::RegExpLiteral; self.enter_node(kind); self.leave_node(kind); } @@ -1307,7 +1256,7 @@ pub trait VisitMut<'a>: Sized { /* ---------- Module ---------- */ fn visit_module_declaration(&mut self, decl: &mut ModuleDeclaration<'a>) { - let kind = AstKind::ModuleDeclaration(self.alloc(decl)); + let kind = AstType::ModuleDeclaration; self.enter_node(kind); match decl { ModuleDeclaration::ImportDeclaration(decl) => { @@ -1331,7 +1280,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_import_declaration(&mut self, decl: &mut ImportDeclaration<'a>) { - let kind = AstKind::ImportDeclaration(self.alloc(decl)); + let kind = AstType::ImportDeclaration; self.enter_node(kind); if let Some(specifiers) = &mut decl.specifiers { for specifier in specifiers.iter_mut() { @@ -1381,7 +1330,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_import_specifier(&mut self, specifier: &mut ImportSpecifier<'a>) { - let kind = AstKind::ImportSpecifier(self.alloc(specifier)); + let kind = AstType::ImportSpecifier; self.enter_node(kind); // TODO: imported self.visit_binding_identifier(&mut specifier.local); @@ -1389,28 +1338,28 @@ pub trait VisitMut<'a>: Sized { } fn visit_import_default_specifier(&mut self, specifier: &mut ImportDefaultSpecifier<'a>) { - let kind = AstKind::ImportDefaultSpecifier(self.alloc(specifier)); + let kind = AstType::ImportDefaultSpecifier; self.enter_node(kind); self.visit_binding_identifier(&mut specifier.local); self.leave_node(kind); } fn visit_import_name_specifier(&mut self, specifier: &mut ImportNamespaceSpecifier<'a>) { - let kind = AstKind::ImportNamespaceSpecifier(self.alloc(specifier)); + let kind = AstType::ImportNamespaceSpecifier; self.enter_node(kind); self.visit_binding_identifier(&mut specifier.local); self.leave_node(kind); } fn visit_export_all_declaration(&mut self, decl: &mut ExportAllDeclaration<'a>) { - let kind = AstKind::ExportAllDeclaration(self.alloc(decl)); + let kind = AstType::ExportAllDeclaration; self.enter_node(kind); self.visit_string_literal(&mut decl.source); self.leave_node(kind); } fn visit_export_default_declaration(&mut self, decl: &mut ExportDefaultDeclaration<'a>) { - let kind = AstKind::ExportDefaultDeclaration(self.alloc(decl)); + let kind = AstType::ExportDefaultDeclaration; self.enter_node(kind); match &mut decl.declaration { ExportDefaultDeclarationKind::Expression(expr) => self.visit_expression(expr), @@ -1424,7 +1373,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_export_named_declaration(&mut self, decl: &mut ExportNamedDeclaration<'a>) { - let kind = AstKind::ExportNamedDeclaration(self.alloc(decl)); + let kind = AstType::ExportNamedDeclaration; self.enter_node(kind); if let Some(decl) = &mut decl.declaration { self.visit_declaration(decl); @@ -1436,7 +1385,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_enum_member(&mut self, member: &mut TSEnumMember<'a>) { - let kind = AstKind::TSEnumMember(self.alloc(member)); + let kind = AstType::TSEnumMember; self.enter_node(kind); if let Some(initializer) = &mut member.initializer { self.visit_expression(initializer); @@ -1445,7 +1394,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_enum(&mut self, decl: &mut TSEnumDeclaration<'a>) { - let kind = AstKind::TSEnumDeclaration(self.alloc(decl)); + let kind = AstType::TSEnumDeclaration; self.enter_node(kind); self.visit_binding_identifier(&mut decl.id); self.enter_scope(ScopeFlags::empty()); @@ -1483,7 +1432,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_import_equals_declaration(&mut self, decl: &mut TSImportEqualsDeclaration<'a>) { - let kind = AstKind::TSImportEqualsDeclaration(self.alloc(decl)); + let kind = AstType::TSImportEqualsDeclaration; self.enter_node(kind); self.visit_binding_identifier(&mut decl.id); self.visit_ts_module_reference(&mut decl.module_reference); @@ -1500,7 +1449,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_type_name(&mut self, name: &mut TSTypeName<'a>) { - let kind = AstKind::TSTypeName(self.alloc(name)); + let kind = AstType::TSTypeName; self.enter_node(kind); match name { TSTypeName::IdentifierReference(ident) => self.visit_identifier_reference(ident), @@ -1513,14 +1462,14 @@ pub trait VisitMut<'a>: Sized { &mut self, reference: &mut TSExternalModuleReference<'a>, ) { - let kind = AstKind::TSExternalModuleReference(self.alloc(reference)); + let kind = AstType::TSExternalModuleReference; self.enter_node(kind); self.visit_string_literal(&mut reference.expression); self.leave_node(kind); } fn visit_ts_qualified_name(&mut self, name: &mut TSQualifiedName<'a>) { - let kind = AstKind::TSQualifiedName(self.alloc(name)); + let kind = AstType::TSQualifiedName; self.enter_node(kind); self.visit_ts_type_name(&mut name.left); self.visit_identifier_name(&mut name.right); @@ -1528,7 +1477,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_module_declaration(&mut self, decl: &mut TSModuleDeclaration<'a>) { - let kind = AstKind::TSModuleDeclaration(self.alloc(decl)); + let kind = AstType::TSModuleDeclaration; self.enter_node(kind); match &mut decl.id { TSModuleDeclarationName::Identifier(ident) => self.visit_identifier_name(ident), @@ -1544,7 +1493,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_module_block(&mut self, block: &mut TSModuleBlock<'a>) { - let kind = AstKind::TSModuleBlock(self.alloc(block)); + let kind = AstType::TSModuleBlock; self.enter_scope(ScopeFlags::TsModuleBlock); self.enter_node(kind); self.visit_statements(&mut block.body); @@ -1553,7 +1502,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_type_alias_declaration(&mut self, decl: &mut TSTypeAliasDeclaration<'a>) { - let kind = AstKind::TSTypeAliasDeclaration(self.alloc(decl)); + let kind = AstType::TSTypeAliasDeclaration; self.enter_node(kind); self.visit_binding_identifier(&mut decl.id); if let Some(parameters) = &mut decl.type_parameters { @@ -1564,7 +1513,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_interface_declaration(&mut self, decl: &mut TSInterfaceDeclaration<'a>) { - let kind = AstKind::TSInterfaceDeclaration(self.alloc(decl)); + let kind = AstType::TSInterfaceDeclaration; self.enter_node(kind); self.visit_binding_identifier(&mut decl.id); if let Some(parameters) = &mut decl.type_parameters { @@ -1577,7 +1526,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_as_expression(&mut self, expr: &mut TSAsExpression<'a>) { - let kind = AstKind::TSAsExpression(self.alloc(expr)); + let kind = AstType::TSAsExpression; self.enter_node(kind); self.visit_expression(&mut expr.expression); self.visit_ts_type(&mut expr.type_annotation); @@ -1585,7 +1534,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_satisfies_expression(&mut self, expr: &mut TSSatisfiesExpression<'a>) { - let kind = AstKind::TSSatisfiesExpression(self.alloc(expr)); + let kind = AstType::TSSatisfiesExpression; self.enter_node(kind); self.visit_expression(&mut expr.expression); self.visit_ts_type(&mut expr.type_annotation); @@ -1593,14 +1542,14 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_non_null_expression(&mut self, expr: &mut TSNonNullExpression<'a>) { - let kind = AstKind::TSNonNullExpression(self.alloc(expr)); + let kind = AstType::TSNonNullExpression; self.enter_node(kind); self.visit_expression(&mut expr.expression); self.leave_node(kind); } fn visit_ts_type_assertion(&mut self, expr: &mut TSTypeAssertion<'a>) { - let kind = AstKind::TSTypeAssertion(self.alloc(expr)); + let kind = AstType::TSTypeAssertion; self.enter_node(kind); self.visit_expression(&mut expr.expression); self.visit_ts_type(&mut expr.type_annotation); @@ -1613,7 +1562,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_type_annotation(&mut self, annotation: &mut TSTypeAnnotation<'a>) { - let kind = AstKind::TSTypeAnnotation(self.alloc(annotation)); + let kind = AstType::TSTypeAnnotation; self.enter_node(kind); self.visit_ts_type(&mut annotation.type_annotation); self.leave_node(kind); @@ -1644,7 +1593,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_type_literal(&mut self, ty: &mut TSTypeLiteral<'a>) { - let kind = AstKind::TSTypeLiteral(self.alloc(ty)); + let kind = AstType::TSTypeLiteral; self.enter_node(kind); for signature in ty.members.iter_mut() { self.visit_ts_signature(signature); @@ -1653,7 +1602,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_indexed_access_type(&mut self, ty: &mut TSIndexedAccessType<'a>) { - let kind = AstKind::TSIndexedAccessType(self.alloc(ty)); + let kind = AstType::TSIndexedAccessType; self.enter_node(kind); self.visit_ts_type(&mut ty.object_type); self.visit_ts_type(&mut ty.index_type); @@ -1704,7 +1653,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_type_parameter(&mut self, ty: &mut TSTypeParameter<'a>) { - let kind = AstKind::TSTypeParameter(self.alloc(ty)); + let kind = AstType::TSTypeParameter; self.enter_scope(ScopeFlags::empty()); self.enter_node(kind); if let Some(constraint) = &mut ty.constraint { @@ -1719,7 +1668,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_type_parameter_instantiation(&mut self, ty: &mut TSTypeParameterInstantiation<'a>) { - let kind = AstKind::TSTypeParameterInstantiation(self.alloc(ty)); + let kind = AstType::TSTypeParameterInstantiation; self.enter_node(kind); for ts_parameter in ty.params.iter_mut() { self.visit_ts_type(ts_parameter); @@ -1728,7 +1677,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_type_parameter_declaration(&mut self, ty: &mut TSTypeParameterDeclaration<'a>) { - let kind = AstKind::TSTypeParameterDeclaration(self.alloc(ty)); + let kind = AstType::TSTypeParameterDeclaration; self.enter_node(kind); for ts_parameter in ty.params.iter_mut() { self.visit_ts_type_parameter(ts_parameter); @@ -1755,26 +1704,26 @@ pub trait VisitMut<'a>: Sized { self.visit_ts_type(&mut ty.element_type); } - fn visit_ts_null_keyword(&mut self, ty: &mut TSNullKeyword) { - let kind = AstKind::TSNullKeyword(self.alloc(ty)); + fn visit_ts_null_keyword(&mut self, _ty: &mut TSNullKeyword) { + let kind = AstType::TSNullKeyword; self.enter_node(kind); self.leave_node(kind); } - fn visit_ts_any_keyword(&mut self, ty: &mut TSAnyKeyword) { - let kind = AstKind::TSAnyKeyword(self.alloc(ty)); + fn visit_ts_any_keyword(&mut self, _ty: &mut TSAnyKeyword) { + let kind = AstType::TSAnyKeyword; self.enter_node(kind); self.leave_node(kind); } - fn visit_ts_void_keyword(&mut self, ty: &mut TSVoidKeyword) { - let kind = AstKind::TSVoidKeyword(self.alloc(ty)); + fn visit_ts_void_keyword(&mut self, _ty: &mut TSVoidKeyword) { + let kind = AstType::TSVoidKeyword; self.enter_node(kind); self.leave_node(kind); } fn visit_ts_intersection_type(&mut self, ty: &mut TSIntersectionType<'a>) { - let kind = AstKind::TSIntersectionType(self.alloc(ty)); + let kind = AstType::TSIntersectionType; self.enter_node(kind); for ty in ty.types.iter_mut() { self.visit_ts_type(ty); @@ -1783,7 +1732,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_type_reference(&mut self, ty: &mut TSTypeReference<'a>) { - let kind = AstKind::TSTypeReference(self.alloc(ty)); + let kind = AstType::TSTypeReference; self.enter_node(kind); self.visit_ts_type_name(&mut ty.type_name); if let Some(parameters) = &mut ty.type_parameters { @@ -1793,7 +1742,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_union_type(&mut self, ty: &mut TSUnionType<'a>) { - let kind = AstKind::TSUnionType(self.alloc(ty)); + let kind = AstType::TSUnionType; self.enter_node(kind); for ty in ty.types.iter_mut() { self.visit_ts_type(ty); @@ -1802,7 +1751,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_literal_type(&mut self, ty: &mut TSLiteralType<'a>) { - let kind = AstKind::TSLiteralType(self.alloc(ty)); + let kind = AstType::TSLiteralType; self.enter_node(kind); match &mut ty.literal { TSLiteral::BigintLiteral(lit) => self.visit_bigint_literal(lit), @@ -1845,7 +1794,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_method_signature(&mut self, signature: &mut TSMethodSignature<'a>) { - let kind = AstKind::TSMethodSignature(self.alloc(signature)); + let kind = AstType::TSMethodSignature; self.enter_node(kind); self.visit_formal_parameters(&mut signature.params); if let Some(parameters) = &mut signature.type_parameters { @@ -1870,7 +1819,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_property_signature(&mut self, signature: &mut TSPropertySignature<'a>) { - let kind = AstKind::TSPropertySignature(self.alloc(signature)); + let kind = AstType::TSPropertySignature; self.enter_node(kind); self.visit_property_key(&mut signature.key); if let Some(annotation) = &mut signature.type_annotation { @@ -1894,7 +1843,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_type_query(&mut self, ty: &mut TSTypeQuery<'a>) { - let kind = AstKind::TSTypeQuery(self.alloc(ty)); + let kind = AstType::TSTypeQuery; self.enter_node(kind); match &mut ty.expr_name { TSTypeQueryExprName::TSTypeName(name) => self.visit_ts_type_name(name), @@ -1907,7 +1856,7 @@ pub trait VisitMut<'a>: Sized { } fn visit_ts_import_type(&mut self, ty: &mut TSImportType<'a>) { - let kind = AstKind::TSImportType(self.alloc(ty)); + let kind = AstType::TSImportType; self.enter_node(kind); self.visit_ts_type(&mut ty.argument); if let Some(name) = &mut ty.qualifier { @@ -1940,3 +1889,69 @@ pub trait VisitMut<'a>: Sized { } } } + +pub fn walk_method_definition_mut<'a, V: VisitMut<'a>>( + visitor: &mut V, + def: &mut MethodDefinition<'a>, +) { + let kind = AstType::MethodDefinition; + visitor.enter_node(kind); + for decorator in def.decorators.iter_mut() { + visitor.visit_decorator(decorator); + } + + let flags = match def.kind { + MethodDefinitionKind::Get => ScopeFlags::GetAccessor, + MethodDefinitionKind::Set => ScopeFlags::SetAccessor, + MethodDefinitionKind::Constructor => ScopeFlags::Constructor, + MethodDefinitionKind::Method => ScopeFlags::empty(), + }; + visitor.visit_property_key(&mut def.key); + visitor.visit_function(&mut def.value, Some(flags)); + visitor.leave_node(kind); +} + +pub fn walk_object_property_mut<'a, V: VisitMut<'a>>( + visitor: &mut V, + prop: &mut ObjectProperty<'a>, +) { + let kind = AstType::ObjectProperty; + visitor.enter_node(kind); + visitor.visit_property_key(&mut prop.key); + visitor.visit_expression(&mut prop.value); + if let Some(init) = &mut prop.init { + visitor.visit_expression(init); + } + visitor.leave_node(kind); +} + +pub fn walk_function_mut<'a, V: VisitMut<'a>>( + visitor: &mut V, + func: &mut Function<'a>, + flags: Option, +) { + let kind = AstType::Function; + visitor.enter_scope({ + let mut flags = flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function; + if func.is_strict() { + flags |= ScopeFlags::StrictMode; + } + flags + }); + visitor.enter_node(kind); + if let Some(ident) = &mut func.id { + visitor.visit_binding_identifier(ident); + } + visitor.visit_formal_parameters(&mut func.params); + if let Some(body) = &mut func.body { + visitor.visit_function_body(body); + } + if let Some(parameters) = &mut func.type_parameters { + visitor.visit_ts_type_parameter_declaration(parameters); + } + if let Some(annotation) = &mut func.return_type { + visitor.visit_ts_type_annotation(annotation); + } + visitor.leave_node(kind); + visitor.leave_scope(); +} diff --git a/crates/oxc_transformer/src/es2015/arrow_functions.rs b/crates/oxc_transformer/src/es2015/arrow_functions.rs index e41eb282c..0d5c62227 100644 --- a/crates/oxc_transformer/src/es2015/arrow_functions.rs +++ b/crates/oxc_transformer/src/es2015/arrow_functions.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use oxc_allocator::Vec; -use oxc_ast::{ast::*, AstBuilder, AstKind, VisitMut}; +use oxc_ast::{ast::*, AstBuilder, AstType, VisitMut}; use oxc_span::{Atom, SPAN}; use serde::Deserialize; @@ -16,7 +16,7 @@ use crate::TransformTarget; /// * pub struct ArrowFunctions<'a> { ast: Rc>, - nodes: Vec<'a, AstKind<'a>>, + nodes: Vec<'a, AstType>, uid: usize, has_this: bool, /// Insert a variable declaration at the top of the BlockStatement @@ -33,11 +33,11 @@ pub struct ArrowFunctionsOptions { } impl<'a> VisitMut<'a> for ArrowFunctions<'a> { - fn enter_node(&mut self, kind: AstKind<'a>) { + fn enter_node(&mut self, kind: AstType) { self.nodes.push(kind); } - fn leave_node(&mut self, _kind: AstKind<'a>) { + fn leave_node(&mut self, _kind: AstType) { self.nodes.pop(); } @@ -45,8 +45,8 @@ impl<'a> VisitMut<'a> for ArrowFunctions<'a> { let parent_kind = self.nodes.last().unwrap(); let parent_parent_kind = self.nodes[self.nodes.len() - 2]; if ident.name == "this" - && (matches!(parent_kind, AstKind::JSXElementName(_)) - || matches!(parent_parent_kind, AstKind::JSXMemberExpression(_))) + && (matches!(parent_kind, AstType::JSXElementName) + || matches!(parent_parent_kind, AstType::JSXMemberExpression)) { if !self.has_this { self.has_this = true; diff --git a/crates/oxc_transformer/src/es2015/new_target.rs b/crates/oxc_transformer/src/es2015/new_target.rs index 1d6027cae..a9341826f 100644 --- a/crates/oxc_transformer/src/es2015/new_target.rs +++ b/crates/oxc_transformer/src/es2015/new_target.rs @@ -1,6 +1,6 @@ use crate::{context::TransformerCtx, TransformOptions, TransformTarget}; use oxc_allocator::Vec; -use oxc_ast::{ast::*, AstBuilder, AstKind, VisitMut}; +use oxc_ast::{ast::*, AstBuilder}; use oxc_diagnostics::miette; use oxc_span::{Atom, Span, SPAN}; use oxc_syntax::operator::BinaryOperator; @@ -24,18 +24,54 @@ enum NewTargetKind<'a> { Function(Option>), } -impl<'a> VisitMut<'a> for NewTarget<'a> { - fn enter_node(&mut self, kind: AstKind<'a>) { - if let Some(kind) = self.get_kind(kind) { - self.kinds.push(kind); +impl<'a> NewTarget<'a> { + pub(crate) fn enter_method_definition(&mut self, def: &MethodDefinition<'a>) { + let kind = match def.kind { + MethodDefinitionKind::Get + | MethodDefinitionKind::Set + | MethodDefinitionKind::Method => NewTargetKind::Method, + MethodDefinitionKind::Constructor => NewTargetKind::Constructor, + }; + self.push(kind); + } + + pub(crate) fn leave_method_definition(&mut self, _: &MethodDefinition) { + self.pop(); + } + + pub(crate) fn enter_object_property(&mut self, prop: &ObjectProperty<'a>) { + if prop.method { + self.push(NewTargetKind::Method); } } - fn leave_node(&mut self, kind: AstKind<'a>) { - if self.get_kind(kind).is_some() { - self.kinds.pop(); + pub(crate) fn leave_object_property(&mut self, prop: &ObjectProperty<'a>) { + if prop.method { + self.pop(); } } + + pub(crate) fn enter_function(&mut self, func: &Function<'a>) { + if let Some(kind) = self.function_new_target_kind(func) { + self.push(kind); + } + } + + pub(crate) fn leave_function(&mut self, func: &Function<'a>) { + if self.function_new_target_kind(func).is_some() { + self.pop(); + } + } + + fn function_new_target_kind(&self, func: &Function<'a>) -> Option> { + // oxc visitor `MethodDefinitionKind` will enter `Function` node, here need to exclude it + if let Some(kind) = self.kinds.last() { + if !matches!(kind, NewTargetKind::Function(_)) { + return None; + } + } + func.id.as_ref().map(|id| NewTargetKind::Function(Some(id.name.clone()))) + } } impl<'a> NewTarget<'a> { @@ -52,26 +88,12 @@ impl<'a> NewTarget<'a> { }) } - fn get_kind(&self, kind: AstKind<'a>) -> Option> { - match kind { - AstKind::MethodDefinition(def) => match def.kind { - MethodDefinitionKind::Get - | MethodDefinitionKind::Set - | MethodDefinitionKind::Method => Some(NewTargetKind::Method), - MethodDefinitionKind::Constructor => Some(NewTargetKind::Constructor), - }, - AstKind::ObjectProperty(property) => property.method.then_some(NewTargetKind::Method), - AstKind::Function(function) => { - // oxc visitor `MethodDefinitionKind` will enter `Function` node, here need to exclude it - if let Some(kind) = self.kinds.last() { - if !matches!(kind, NewTargetKind::Function(_)) { - return None; - } - } - function.id.as_ref().map(|id| NewTargetKind::Function(Some(id.name.clone()))) - } - _ => None, - } + fn push(&mut self, kind: NewTargetKind<'a>) { + self.kinds.push(kind); + } + + fn pop(&mut self) { + self.kinds.pop(); } fn create_constructor_expr(&self, span: Span) -> Expression<'a> { diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index 5d50d5e09..82e3d204f 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -28,7 +28,7 @@ use std::{cell::RefCell, rc::Rc, sync::Arc}; use es2015::TemplateLiterals; use oxc_allocator::Allocator; -use oxc_ast::{ast::*, AstBuilder, AstKind, VisitMut}; +use oxc_ast::{ast::*, visit_mut::walk_function_mut, AstBuilder, AstType, VisitMut}; use oxc_diagnostics::Error; use oxc_semantic::{ScopeFlags, Semantic}; use oxc_span::SourceType; @@ -152,16 +152,8 @@ impl<'a> Transformer<'a> { } impl<'a> VisitMut<'a> for Transformer<'a> { - fn enter_node(&mut self, kind: oxc_ast::AstKind<'a>) { - self.es2015_new_target.as_mut().map(|t| t.enter_node(kind)); - } - - fn leave_node(&mut self, kind: oxc_ast::AstKind<'a>) { - self.es2015_new_target.as_mut().map(|t| t.leave_node(kind)); - } - fn visit_program(&mut self, program: &mut Program<'a>) { - let kind = AstKind::Program(self.alloc(program)); + let kind = AstType::Program; self.enter_scope({ let mut flags = ScopeFlags::Top; if program.is_strict() { @@ -185,7 +177,7 @@ impl<'a> VisitMut<'a> for Transformer<'a> { } fn visit_assignment_expression(&mut self, expr: &mut AssignmentExpression<'a>) { - let kind = AstKind::AssignmentExpression(self.alloc(expr)); + let kind = AstType::AssignmentExpression; self.enter_node(kind); self.es2015_function_name.as_mut().map(|t| t.transform_assignment_expression(expr)); @@ -238,7 +230,7 @@ impl<'a> VisitMut<'a> for Transformer<'a> { } fn visit_catch_clause(&mut self, clause: &mut CatchClause<'a>) { - let kind = AstKind::CatchClause(self.alloc(clause)); + let kind = AstType::CatchClause; self.enter_scope(ScopeFlags::empty()); self.enter_node(kind); @@ -253,7 +245,7 @@ impl<'a> VisitMut<'a> for Transformer<'a> { } fn visit_object_expression(&mut self, expr: &mut ObjectExpression<'a>) { - let kind = AstKind::ObjectExpression(self.alloc(expr)); + let kind = AstType::ObjectExpression; self.enter_node(kind); self.es2015_function_name.as_mut().map(|t| t.transform_object_expression(expr)); self.es2015_duplicate_keys.as_mut().map(|t| t.transform_object_expression(expr)); @@ -265,8 +257,9 @@ impl<'a> VisitMut<'a> for Transformer<'a> { } fn visit_object_property(&mut self, prop: &mut ObjectProperty<'a>) { - let kind = AstKind::ObjectProperty(self.alloc(prop)); + let kind = AstType::ObjectProperty; self.enter_node(kind); + self.es2015_new_target.as_mut().map(|t| t.enter_object_property(prop)); self.es2015_shorthand_properties.as_mut().map(|t| t.transform_object_property(prop)); self.es3_property_literal.as_mut().map(|t| t.transform_object_property(prop)); @@ -276,6 +269,8 @@ impl<'a> VisitMut<'a> for Transformer<'a> { if let Some(init) = &mut prop.init { self.visit_expression(init); } + + self.es2015_new_target.as_mut().map(|t| t.leave_object_property(prop)); self.leave_node(kind); } @@ -288,7 +283,7 @@ impl<'a> VisitMut<'a> for Transformer<'a> { } fn visit_variable_declarator(&mut self, declarator: &mut VariableDeclarator<'a>) { - let kind = AstKind::VariableDeclarator(self.alloc(declarator)); + let kind = AstType::VariableDeclarator; self.enter_node(kind); self.es2015_function_name.as_mut().map(|t| t.transform_variable_declarator(declarator)); @@ -315,8 +310,9 @@ impl<'a> VisitMut<'a> for Transformer<'a> { } fn visit_method_definition(&mut self, def: &mut MethodDefinition<'a>) { - let kind = AstKind::MethodDefinition(self.alloc(def)); + let kind = AstType::MethodDefinition; self.enter_node(kind); + self.es2015_new_target.as_mut().map(|t| t.enter_method_definition(def)); self.typescript.as_mut().map(|t| t.transform_method_definition(def)); @@ -332,6 +328,13 @@ impl<'a> VisitMut<'a> for Transformer<'a> { }; self.visit_property_key(&mut def.key); self.visit_function(&mut def.value, Some(flags)); + self.es2015_new_target.as_mut().map(|t| t.leave_method_definition(def)); self.leave_node(kind); } + + fn visit_function(&mut self, func: &mut Function<'a>, flags: Option) { + self.es2015_new_target.as_mut().map(|t| t.enter_function(func)); + walk_function_mut(self, func, flags); + self.es2015_new_target.as_mut().map(|t| t.leave_function(func)); + } }