Skip to content

Commit

Permalink
fix(ast): visit Programs hashbang field first (#4368)
Browse files Browse the repository at this point in the history
Visit `hashbang` before `directives` for `Program`.
  • Loading branch information
overlookmotel committed Jul 19, 2024
1 parent 6ffce86 commit aece1df
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 60 deletions.
2 changes: 1 addition & 1 deletion crates/oxc_ast/src/ast/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Hashbang<'a>>,
pub directives: Vec<'a, Directive<'a>>,
pub body: Vec<'a, Statement<'a>>,
pub scope_id: Cell<Option<ScopeId>>,
}
Expand Down
8 changes: 4 additions & 4 deletions crates/oxc_ast/src/generated/ast_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,23 +136,23 @@ impl<'a> AstBuilder<'a> {
self,
span: Span,
source_type: SourceType,
directives: Vec<'a, Directive<'a>>,
hashbang: Option<Hashbang<'a>>,
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]
pub fn alloc_program(
self,
span: Span,
source_type: SourceType,
directives: Vec<'a, Directive<'a>>,
hashbang: Option<Hashbang<'a>>,
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]
Expand Down
26 changes: 13 additions & 13 deletions crates/oxc_ast/src/generated/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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() {
Expand All @@ -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() {
Expand Down
26 changes: 13 additions & 13 deletions crates/oxc_ast/src/generated/visit_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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() {
Expand All @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_isolated_declarations/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() }
}

Expand Down
4 changes: 2 additions & 2 deletions crates/oxc_parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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 {
Expand Down
38 changes: 19 additions & 19 deletions crates/oxc_traverse/src/ancestor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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) }
Expand All @@ -2199,9 +2199,10 @@ impl<'a> ProgramWithoutDirectives<'a> {
}

#[inline]
pub fn hashbang(&self) -> &Option<Hashbang<'a>> {
pub fn directives(&self) -> &Vec<'a, Directive<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_PROGRAM_HASHBANG) as *const Option<Hashbang<'a>>)
&*((self.0 as *const u8).add(OFFSET_PROGRAM_DIRECTIVES)
as *const Vec<'a, Directive<'a>>)
}
}

Expand All @@ -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) }
Expand All @@ -2236,10 +2237,9 @@ impl<'a> ProgramWithoutHashbang<'a> {
}

#[inline]
pub fn directives(&self) -> &Vec<'a, Directive<'a>> {
pub fn hashbang(&self) -> &Option<Hashbang<'a>> {
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<Hashbang<'a>>)
}
}

Expand Down Expand Up @@ -2274,17 +2274,17 @@ impl<'a> ProgramWithoutBody<'a> {
}

#[inline]
pub fn directives(&self) -> &Vec<'a, Directive<'a>> {
pub fn hashbang(&self) -> &Option<Hashbang<'a>> {
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<Hashbang<'a>>)
}
}

#[inline]
pub fn hashbang(&self) -> &Option<Hashbang<'a>> {
pub fn directives(&self) -> &Vec<'a, Directive<'a>> {
unsafe {
&*((self.0 as *const u8).add(OFFSET_PROGRAM_HASHBANG) as *const Option<Hashbang<'a>>)
&*((self.0 as *const u8).add(OFFSET_PROGRAM_DIRECTIVES)
as *const Vec<'a, Directive<'a>>)
}
}

Expand Down
14 changes: 7 additions & 7 deletions crates/oxc_traverse/src/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Hashbang>)
{
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<Directive>))
.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<Hashbang>)
{
ctx.retag_stack(AncestorType::ProgramHashbang);
walk_hashbang(traverser, field as *mut _, ctx);
}
ctx.retag_stack(AncestorType::ProgramBody);
walk_statements(
traverser,
Expand Down

0 comments on commit aece1df

Please sign in to comment.