diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index dbf2d1e1163d2..101ff788ec644 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -39,8 +39,8 @@ pub struct Program<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub source_type: SourceType, - pub directives: Vec<'a, Directive<'a>>, pub hashbang: Option>, + pub directives: Vec<'a, Directive<'a>>, pub body: Vec<'a, Statement<'a>>, pub scope_id: Cell>, } diff --git a/crates/oxc_ast/src/generated/ast_builder.rs b/crates/oxc_ast/src/generated/ast_builder.rs index 86cac8b2bddfd..076cc5b3ed316 100644 --- a/crates/oxc_ast/src/generated/ast_builder.rs +++ b/crates/oxc_ast/src/generated/ast_builder.rs @@ -136,11 +136,11 @@ impl<'a> AstBuilder<'a> { self, span: Span, source_type: SourceType, - directives: Vec<'a, Directive<'a>>, hashbang: Option>, + directives: Vec<'a, Directive<'a>>, body: Vec<'a, Statement<'a>>, ) -> Program<'a> { - Program { span, source_type, directives, hashbang, body, scope_id: Default::default() } + Program { span, source_type, hashbang, directives, body, scope_id: Default::default() } } #[inline] @@ -148,11 +148,11 @@ impl<'a> AstBuilder<'a> { self, span: Span, source_type: SourceType, - directives: Vec<'a, Directive<'a>>, hashbang: Option>, + directives: Vec<'a, Directive<'a>>, body: Vec<'a, Statement<'a>>, ) -> Box<'a, Program<'a>> { - self.program(span, source_type, directives, hashbang, body).into_in(self.allocator) + self.program(span, source_type, hashbang, directives, body).into_in(self.allocator) } #[inline] diff --git a/crates/oxc_ast/src/generated/visit.rs b/crates/oxc_ast/src/generated/visit.rs index d7bf71dae1e6b..3953493e781eb 100644 --- a/crates/oxc_ast/src/generated/visit.rs +++ b/crates/oxc_ast/src/generated/visit.rs @@ -50,6 +50,11 @@ pub trait Visit<'a>: Sized { walk_program(self, it); } + #[inline] + fn visit_hashbang(&mut self, it: &Hashbang<'a>) { + walk_hashbang(self, it); + } + #[inline] fn visit_directives(&mut self, it: &Vec<'a, Directive<'a>>) { walk_directives(self, it); @@ -65,11 +70,6 @@ pub trait Visit<'a>: Sized { walk_string_literal(self, it); } - #[inline] - fn visit_hashbang(&mut self, it: &Hashbang<'a>) { - walk_hashbang(self, it); - } - #[inline] fn visit_statements(&mut self, it: &Vec<'a, Statement<'a>>) { walk_statements(self, it); @@ -1366,15 +1366,22 @@ pub mod walk { }, &it.scope_id, ); - visitor.visit_directives(&it.directives); if let Some(hashbang) = &it.hashbang { visitor.visit_hashbang(hashbang); } + visitor.visit_directives(&it.directives); visitor.visit_statements(&it.body); visitor.leave_scope(); visitor.leave_node(kind); } + #[inline] + pub fn walk_hashbang<'a, V: Visit<'a>>(visitor: &mut V, it: &Hashbang<'a>) { + let kind = AstKind::Hashbang(visitor.alloc(it)); + visitor.enter_node(kind); + visitor.leave_node(kind); + } + #[inline] pub fn walk_directives<'a, V: Visit<'a>>(visitor: &mut V, it: &Vec<'a, Directive<'a>>) { for el in it.iter() { @@ -1397,13 +1404,6 @@ pub mod walk { visitor.leave_node(kind); } - #[inline] - pub fn walk_hashbang<'a, V: Visit<'a>>(visitor: &mut V, it: &Hashbang<'a>) { - let kind = AstKind::Hashbang(visitor.alloc(it)); - visitor.enter_node(kind); - visitor.leave_node(kind); - } - #[inline] pub fn walk_statements<'a, V: Visit<'a>>(visitor: &mut V, it: &Vec<'a, Statement<'a>>) { for el in it.iter() { diff --git a/crates/oxc_ast/src/generated/visit_mut.rs b/crates/oxc_ast/src/generated/visit_mut.rs index 345da83274595..73aa5d0dd0ec6 100644 --- a/crates/oxc_ast/src/generated/visit_mut.rs +++ b/crates/oxc_ast/src/generated/visit_mut.rs @@ -42,6 +42,11 @@ pub trait VisitMut<'a>: Sized { walk_program(self, it); } + #[inline] + fn visit_hashbang(&mut self, it: &mut Hashbang<'a>) { + walk_hashbang(self, it); + } + #[inline] fn visit_directives(&mut self, it: &mut Vec<'a, Directive<'a>>) { walk_directives(self, it); @@ -57,11 +62,6 @@ pub trait VisitMut<'a>: Sized { walk_string_literal(self, it); } - #[inline] - fn visit_hashbang(&mut self, it: &mut Hashbang<'a>) { - walk_hashbang(self, it); - } - #[inline] fn visit_statements(&mut self, it: &mut Vec<'a, Statement<'a>>) { walk_statements(self, it); @@ -1361,15 +1361,22 @@ pub mod walk_mut { }, &it.scope_id, ); - visitor.visit_directives(&mut it.directives); if let Some(hashbang) = &mut it.hashbang { visitor.visit_hashbang(hashbang); } + visitor.visit_directives(&mut it.directives); visitor.visit_statements(&mut it.body); visitor.leave_scope(); visitor.leave_node(kind); } + #[inline] + pub fn walk_hashbang<'a, V: VisitMut<'a>>(visitor: &mut V, it: &mut Hashbang<'a>) { + let kind = AstType::Hashbang; + visitor.enter_node(kind); + visitor.leave_node(kind); + } + #[inline] pub fn walk_directives<'a, V: VisitMut<'a>>(visitor: &mut V, it: &mut Vec<'a, Directive<'a>>) { for el in it.iter_mut() { @@ -1392,13 +1399,6 @@ pub mod walk_mut { visitor.leave_node(kind); } - #[inline] - pub fn walk_hashbang<'a, V: VisitMut<'a>>(visitor: &mut V, it: &mut Hashbang<'a>) { - let kind = AstType::Hashbang; - visitor.enter_node(kind); - visitor.leave_node(kind); - } - #[inline] pub fn walk_statements<'a, V: VisitMut<'a>>(visitor: &mut V, it: &mut Vec<'a, Statement<'a>>) { for el in it.iter_mut() { diff --git a/crates/oxc_isolated_declarations/src/lib.rs b/crates/oxc_isolated_declarations/src/lib.rs index ea3830adaed83..8485e01d03833 100644 --- a/crates/oxc_isolated_declarations/src/lib.rs +++ b/crates/oxc_isolated_declarations/src/lib.rs @@ -58,7 +58,7 @@ impl<'a> IsolatedDeclarations<'a> { let source_type = SourceType::default().with_module(true).with_typescript_definition(true); let directives = self.ast.vec(); let stmts = self.transform_program(program); - let program = self.ast.program(SPAN, source_type, directives, None, stmts); + let program = self.ast.program(SPAN, source_type, None, directives, stmts); IsolatedDeclarationsReturn { program, errors: self.take_errors() } } diff --git a/crates/oxc_parser/src/lib.rs b/crates/oxc_parser/src/lib.rs index bb83000f3e8af..531a38fa39acf 100644 --- a/crates/oxc_parser/src/lib.rs +++ b/crates/oxc_parser/src/lib.rs @@ -328,9 +328,9 @@ impl<'a> ParserImpl<'a> { let program = self.ast.program( Span::default(), self.source_type, - self.ast.vec(), None, self.ast.vec(), + self.ast.vec(), ); (program, true) } @@ -361,7 +361,7 @@ impl<'a> ParserImpl<'a> { self.parse_directives_and_statements(/* is_top_level */ true)?; let span = Span::new(0, self.source_text.len() as u32); - Ok(self.ast.program(span, self.source_type, directives, hashbang, statements)) + Ok(self.ast.program(span, self.source_type, hashbang, directives, statements)) } fn default_context(source_type: SourceType, options: ParserOptions) -> Context { diff --git a/crates/oxc_traverse/src/ancestor.rs b/crates/oxc_traverse/src/ancestor.rs index 292c26992eb5c..12796bfbc428d 100644 --- a/crates/oxc_traverse/src/ancestor.rs +++ b/crates/oxc_traverse/src/ancestor.rs @@ -30,8 +30,8 @@ use oxc_syntax::{ #[allow(dead_code)] pub(crate) enum AncestorType { None = 0, - ProgramDirectives = 1, - ProgramHashbang = 2, + ProgramHashbang = 1, + ProgramDirectives = 2, ProgramBody = 3, ArrayExpressionElements = 4, ObjectExpressionProperties = 5, @@ -343,8 +343,8 @@ pub(crate) enum AncestorType { #[derive(Debug)] pub enum Ancestor<'a> { None = AncestorType::None as u16, - ProgramDirectives(ProgramWithoutDirectives<'a>) = AncestorType::ProgramDirectives as u16, ProgramHashbang(ProgramWithoutHashbang<'a>) = AncestorType::ProgramHashbang as u16, + ProgramDirectives(ProgramWithoutDirectives<'a>) = AncestorType::ProgramDirectives as u16, ProgramBody(ProgramWithoutBody<'a>) = AncestorType::ProgramBody as u16, ArrayExpressionElements(ArrayExpressionWithoutElements<'a>) = AncestorType::ArrayExpressionElements as u16, @@ -872,7 +872,7 @@ pub enum Ancestor<'a> { impl<'a> Ancestor<'a> { #[inline] pub fn is_program(&self) -> bool { - matches!(self, Self::ProgramDirectives(_) | Self::ProgramHashbang(_) | Self::ProgramBody(_)) + matches!(self, Self::ProgramHashbang(_) | Self::ProgramDirectives(_) | Self::ProgramBody(_)) } #[inline] @@ -2178,16 +2178,16 @@ impl<'a> Ancestor<'a> { pub(crate) const OFFSET_PROGRAM_SPAN: usize = offset_of!(Program, span); pub(crate) const OFFSET_PROGRAM_SOURCE_TYPE: usize = offset_of!(Program, source_type); -pub(crate) const OFFSET_PROGRAM_DIRECTIVES: usize = offset_of!(Program, directives); pub(crate) const OFFSET_PROGRAM_HASHBANG: usize = offset_of!(Program, hashbang); +pub(crate) const OFFSET_PROGRAM_DIRECTIVES: usize = offset_of!(Program, directives); pub(crate) const OFFSET_PROGRAM_BODY: usize = offset_of!(Program, body); pub(crate) const OFFSET_PROGRAM_SCOPE_ID: usize = offset_of!(Program, scope_id); #[repr(transparent)] #[derive(Debug)] -pub struct ProgramWithoutDirectives<'a>(pub(crate) *const Program<'a>); +pub struct ProgramWithoutHashbang<'a>(pub(crate) *const Program<'a>); -impl<'a> ProgramWithoutDirectives<'a> { +impl<'a> ProgramWithoutHashbang<'a> { #[inline] pub fn span(&self) -> &Span { unsafe { &*((self.0 as *const u8).add(OFFSET_PROGRAM_SPAN) as *const Span) } @@ -2199,9 +2199,10 @@ impl<'a> ProgramWithoutDirectives<'a> { } #[inline] - pub fn hashbang(&self) -> &Option> { + pub fn directives(&self) -> &Vec<'a, Directive<'a>> { unsafe { - &*((self.0 as *const u8).add(OFFSET_PROGRAM_HASHBANG) as *const Option>) + &*((self.0 as *const u8).add(OFFSET_PROGRAM_DIRECTIVES) + as *const Vec<'a, Directive<'a>>) } } @@ -2222,9 +2223,9 @@ impl<'a> ProgramWithoutDirectives<'a> { #[repr(transparent)] #[derive(Debug)] -pub struct ProgramWithoutHashbang<'a>(pub(crate) *const Program<'a>); +pub struct ProgramWithoutDirectives<'a>(pub(crate) *const Program<'a>); -impl<'a> ProgramWithoutHashbang<'a> { +impl<'a> ProgramWithoutDirectives<'a> { #[inline] pub fn span(&self) -> &Span { unsafe { &*((self.0 as *const u8).add(OFFSET_PROGRAM_SPAN) as *const Span) } @@ -2236,10 +2237,9 @@ impl<'a> ProgramWithoutHashbang<'a> { } #[inline] - pub fn directives(&self) -> &Vec<'a, Directive<'a>> { + pub fn hashbang(&self) -> &Option> { unsafe { - &*((self.0 as *const u8).add(OFFSET_PROGRAM_DIRECTIVES) - as *const Vec<'a, Directive<'a>>) + &*((self.0 as *const u8).add(OFFSET_PROGRAM_HASHBANG) as *const Option>) } } @@ -2274,17 +2274,17 @@ impl<'a> ProgramWithoutBody<'a> { } #[inline] - pub fn directives(&self) -> &Vec<'a, Directive<'a>> { + pub fn hashbang(&self) -> &Option> { unsafe { - &*((self.0 as *const u8).add(OFFSET_PROGRAM_DIRECTIVES) - as *const Vec<'a, Directive<'a>>) + &*((self.0 as *const u8).add(OFFSET_PROGRAM_HASHBANG) as *const Option>) } } #[inline] - pub fn hashbang(&self) -> &Option> { + pub fn directives(&self) -> &Vec<'a, Directive<'a>> { unsafe { - &*((self.0 as *const u8).add(OFFSET_PROGRAM_HASHBANG) as *const Option>) + &*((self.0 as *const u8).add(OFFSET_PROGRAM_DIRECTIVES) + as *const Vec<'a, Directive<'a>>) } } diff --git a/crates/oxc_traverse/src/walk.rs b/crates/oxc_traverse/src/walk.rs index 86a377fe07104..c4873f7d34d62 100644 --- a/crates/oxc_traverse/src/walk.rs +++ b/crates/oxc_traverse/src/walk.rs @@ -37,19 +37,19 @@ pub(crate) unsafe fn walk_program<'a, Tr: Traverse<'a>>( ctx.set_current_scope_id(scope_id); } traverser.enter_program(&mut *node, ctx); - ctx.push_stack(Ancestor::ProgramDirectives(ancestor::ProgramWithoutDirectives(node))); + ctx.push_stack(Ancestor::ProgramHashbang(ancestor::ProgramWithoutHashbang(node))); + if let Some(field) = + &mut *((node as *mut u8).add(ancestor::OFFSET_PROGRAM_HASHBANG) as *mut Option) + { + walk_hashbang(traverser, field as *mut _, ctx); + } + ctx.retag_stack(AncestorType::ProgramDirectives); for item in (*((node as *mut u8).add(ancestor::OFFSET_PROGRAM_DIRECTIVES) as *mut Vec)) .iter_mut() { walk_directive(traverser, item as *mut _, ctx); } - if let Some(field) = - &mut *((node as *mut u8).add(ancestor::OFFSET_PROGRAM_HASHBANG) as *mut Option) - { - ctx.retag_stack(AncestorType::ProgramHashbang); - walk_hashbang(traverser, field as *mut _, ctx); - } ctx.retag_stack(AncestorType::ProgramBody); walk_statements( traverser,