mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(ast): use atom for Directive and Hashbang (#701)
The main reason is using Atom to remove the lifetime for convenience. And after removing the lifetime of these nodes, the `Program<'a>` doesn't rely on `&'a source` anymore, which allows us to [specify more accurate lifetimes](https://github.com/web-infra-dev/oxc/discussions/700).
This commit is contained in:
parent
f5b8690309
commit
35167599bc
14 changed files with 45 additions and 47 deletions
|
|
@ -17,8 +17,8 @@ pub struct Program<'a> {
|
|||
#[cfg_attr(feature = "serde", 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>,
|
||||
pub hashbang: Option<Hashbang>,
|
||||
pub body: Vec<'a, Statement<'a>>,
|
||||
}
|
||||
|
||||
|
|
@ -918,21 +918,21 @@ pub enum Statement<'a> {
|
|||
/// Directive Prologue
|
||||
#[derive(Debug, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
|
||||
pub struct Directive<'a> {
|
||||
pub struct Directive {
|
||||
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub expression: StringLiteral,
|
||||
// directives should always use the unescaped raw string
|
||||
pub directive: &'a str,
|
||||
pub directive: Atom,
|
||||
}
|
||||
|
||||
/// Hashbang
|
||||
#[derive(Debug, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
|
||||
pub struct Hashbang<'a> {
|
||||
pub struct Hashbang {
|
||||
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub value: &'a str,
|
||||
pub value: Atom,
|
||||
}
|
||||
|
||||
/// Block Statement
|
||||
|
|
@ -1447,7 +1447,7 @@ impl<'a> FormalParameters<'a> {
|
|||
pub struct FunctionBody<'a> {
|
||||
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub directives: Vec<'a, Directive<'a>>,
|
||||
pub directives: Vec<'a, Directive>,
|
||||
pub statements: Vec<'a, Statement<'a>>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ impl<'a> AstBuilder<'a> {
|
|||
span: Span,
|
||||
source_type: SourceType,
|
||||
directives: Vec<'a, Directive>,
|
||||
hashbang: Option<Hashbang<'a>>,
|
||||
hashbang: Option<Hashbang>,
|
||||
body: Vec<'a, Statement<'a>>,
|
||||
) -> Program<'a> {
|
||||
Program { span, source_type, directives, hashbang, body }
|
||||
|
|
@ -109,16 +109,11 @@ impl<'a> AstBuilder<'a> {
|
|||
|
||||
/* ---------- Statements ---------- */
|
||||
|
||||
pub fn directive(
|
||||
&self,
|
||||
span: Span,
|
||||
expression: StringLiteral,
|
||||
directive: &'a str,
|
||||
) -> Directive<'a> {
|
||||
pub fn directive(&self, span: Span, expression: StringLiteral, directive: Atom) -> Directive {
|
||||
Directive { span, expression, directive }
|
||||
}
|
||||
|
||||
pub fn hashbang(&self, span: Span, value: &'a str) -> Hashbang<'a> {
|
||||
pub fn hashbang(&self, span: Span, value: Atom) -> Hashbang {
|
||||
Hashbang { span, value }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ use crate::ast::*;
|
|||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum AstKind<'a> {
|
||||
Program(&'a Program<'a>),
|
||||
Directive(&'a Directive<'a>),
|
||||
Hashbang(&'a Hashbang<'a>),
|
||||
Directive(&'a Directive),
|
||||
Hashbang(&'a Hashbang),
|
||||
|
||||
BlockStatement(&'a BlockStatement<'a>),
|
||||
BreakStatement(&'a BreakStatement),
|
||||
|
|
@ -387,7 +387,7 @@ impl<'a> AstKind<'a> {
|
|||
pub fn debug_name(&self) -> std::borrow::Cow<str> {
|
||||
match self {
|
||||
Self::Program(_) => "Program".into(),
|
||||
Self::Directive(d) => d.directive.into(),
|
||||
Self::Directive(d) => d.directive.as_ref().into(),
|
||||
Self::Hashbang(_) => "Hashbang".into(),
|
||||
|
||||
Self::BlockStatement(_) => "BlockStatement".into(),
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ pub trait Visit<'a>: Sized {
|
|||
self.leave_node(kind);
|
||||
}
|
||||
|
||||
fn visit_directive(&mut self, directive: &'a Directive<'a>) {
|
||||
fn visit_directive(&mut self, directive: &'a Directive) {
|
||||
let kind = AstKind::Directive(directive);
|
||||
self.enter_node(kind);
|
||||
self.visit_string_literal(&directive.expression);
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ pub trait VisitMut<'a, 'b>: Sized {
|
|||
self.visit_statement(&mut stmt.body);
|
||||
}
|
||||
|
||||
fn visit_directive(&mut self, directive: &'b mut Directive<'a>) {
|
||||
fn visit_directive(&mut self, directive: &'b mut Directive) {
|
||||
self.visit_string_literal(&mut directive.expression);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,13 +160,13 @@ impl<'a> AstLower<'a> {
|
|||
self.hir.program(program.span, directives, hashbang, statements)
|
||||
}
|
||||
|
||||
fn lower_hasbang(&mut self, hashbang: &ast::Hashbang<'a>) -> hir::Hashbang<'a> {
|
||||
self.hir.hashbang(hashbang.span, hashbang.value)
|
||||
fn lower_hasbang(&mut self, hashbang: &ast::Hashbang) -> hir::Hashbang {
|
||||
self.hir.hashbang(hashbang.span, hashbang.value.clone())
|
||||
}
|
||||
|
||||
fn lower_directive(&mut self, directive: &ast::Directive<'a>) -> hir::Directive<'a> {
|
||||
fn lower_directive(&mut self, directive: &ast::Directive) -> hir::Directive {
|
||||
let expression = self.lower_string_literal(&directive.expression);
|
||||
self.hir.directive(directive.span, expression, directive.directive)
|
||||
self.hir.directive(directive.span, expression, directive.directive.clone())
|
||||
}
|
||||
|
||||
fn lower_statement(&mut self, statement: &ast::Statement<'a>) -> Option<hir::Statement<'a>> {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ impl<'a> Gen for Program<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Gen for Directive<'a> {
|
||||
impl Gen for Directive {
|
||||
fn gen(&self, p: &mut Formatter) {
|
||||
p.print_indent();
|
||||
p.print(b'"');
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ use crate::HirId;
|
|||
pub struct Program<'a> {
|
||||
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub directives: Vec<'a, Directive<'a>>,
|
||||
pub hashbang: Option<Hashbang<'a>>,
|
||||
pub directives: Vec<'a, Directive>,
|
||||
pub hashbang: Option<Hashbang>,
|
||||
pub body: Vec<'a, Statement<'a>>,
|
||||
}
|
||||
|
||||
|
|
@ -1039,25 +1039,25 @@ pub enum Statement<'a> {
|
|||
/// Directive Prologue
|
||||
#[derive(Debug, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
|
||||
pub struct Directive<'a> {
|
||||
pub struct Directive {
|
||||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
pub hir_id: HirId,
|
||||
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub expression: StringLiteral,
|
||||
// directives should always use the unescaped raw string
|
||||
pub directive: &'a str,
|
||||
pub directive: Atom,
|
||||
}
|
||||
|
||||
/// Hashbang
|
||||
#[derive(Debug, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
|
||||
pub struct Hashbang<'a> {
|
||||
pub struct Hashbang {
|
||||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
pub hir_id: HirId,
|
||||
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub value: &'a str,
|
||||
pub value: Atom,
|
||||
}
|
||||
|
||||
/// Block Statement
|
||||
|
|
@ -1501,7 +1501,7 @@ impl<'a> FormalParameters<'a> {
|
|||
pub struct FunctionBody<'a> {
|
||||
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub directives: Vec<'a, Directive<'a>>,
|
||||
pub directives: Vec<'a, Directive>,
|
||||
pub statements: Vec<'a, Statement<'a>>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ impl<'a> HirBuilder<'a> {
|
|||
&mut self,
|
||||
span: Span,
|
||||
directives: Vec<'a, Directive>,
|
||||
hashbang: Option<Hashbang<'a>>,
|
||||
hashbang: Option<Hashbang>,
|
||||
body: Vec<'a, Statement<'a>>,
|
||||
) -> Program<'a> {
|
||||
Program { span, directives, hashbang, body }
|
||||
|
|
@ -209,12 +209,12 @@ impl<'a> HirBuilder<'a> {
|
|||
&mut self,
|
||||
span: Span,
|
||||
expression: StringLiteral,
|
||||
directive: &'a str,
|
||||
) -> Directive<'a> {
|
||||
directive: Atom,
|
||||
) -> Directive {
|
||||
Directive { hir_id: self.next_id(), span, expression, directive }
|
||||
}
|
||||
|
||||
pub fn hashbang(&mut self, span: Span, value: &'a str) -> Hashbang<'a> {
|
||||
pub fn hashbang(&mut self, span: Span, value: Atom) -> Hashbang {
|
||||
Hashbang { hir_id: self.next_id(), span, value }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ pub enum HirKind<'a> {
|
|||
Root,
|
||||
|
||||
Program(&'a Program<'a>),
|
||||
Directive(&'a Directive<'a>),
|
||||
Directive(&'a Directive),
|
||||
|
||||
BlockStatement(&'a BlockStatement<'a>),
|
||||
BreakStatement(&'a BreakStatement),
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ pub trait Visit<'a>: Sized {
|
|||
self.leave_node(kind);
|
||||
}
|
||||
|
||||
fn visit_directive(&mut self, directive: &'a Directive<'a>) {
|
||||
fn visit_directive(&mut self, directive: &'a Directive) {
|
||||
let kind = HirKind::Directive(directive);
|
||||
self.enter_node(kind);
|
||||
self.visit_string_literal(&directive.expression);
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ pub trait VisitMut<'a, 'b>: Sized {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_directive(&mut self, directive: &'b mut Directive<'a>) {
|
||||
fn visit_directive(&mut self, directive: &'b mut Directive) {
|
||||
self.visit_string_literal(&mut directive.expression);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,14 +53,14 @@ impl<'a> Gen for Program<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Gen for Hashbang<'a> {
|
||||
impl Gen for Hashbang {
|
||||
fn gen(&self, p: &mut Printer, ctx: Context) {
|
||||
p.print_str(b"#!");
|
||||
p.print_str(self.value.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Gen for Directive<'a> {
|
||||
impl Gen for Directive {
|
||||
fn gen(&self, p: &mut Printer, ctx: Context) {
|
||||
p.print(b'"');
|
||||
p.print_str(self.directive.as_bytes());
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use oxc_allocator::{Box, Vec};
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_diagnostics::Result;
|
||||
use oxc_span::Span;
|
||||
use oxc_span::{Atom, Span};
|
||||
|
||||
use super::{
|
||||
declaration::{VariableDeclarationContext, VariableDeclarationParent},
|
||||
|
|
@ -14,13 +14,13 @@ impl<'a> Parser<'a> {
|
|||
// Section 12
|
||||
// The InputElementHashbangOrRegExp goal is used at the start of a Script
|
||||
// or Module.
|
||||
pub(crate) fn parse_hashbang(&mut self) -> Option<Hashbang<'a>> {
|
||||
pub(crate) fn parse_hashbang(&mut self) -> Option<Hashbang> {
|
||||
if self.cur_kind() == Kind::HashbangComment {
|
||||
let span = self.start_span();
|
||||
self.bump_any();
|
||||
let span = self.end_span(span);
|
||||
let src = &self.source_text[span.start as usize + 2..span.end as usize];
|
||||
Some(self.ast.hashbang(span, src))
|
||||
Some(self.ast.hashbang(span, Atom::from(src)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ impl<'a> Parser<'a> {
|
|||
pub(crate) fn parse_directives_and_statements(
|
||||
&mut self,
|
||||
is_top_level: bool,
|
||||
) -> Result<(Vec<'a, Directive<'a>>, Vec<'a, Statement<'a>>)> {
|
||||
) -> Result<(Vec<'a, Directive>, Vec<'a, Statement<'a>>)> {
|
||||
let mut directives = self.ast.new_vec();
|
||||
let mut statements = self.ast.new_vec();
|
||||
|
||||
|
|
@ -64,8 +64,11 @@ impl<'a> Parser<'a> {
|
|||
if let Expression::StringLiteral(string) = &expr.expression {
|
||||
let src = &self.source_text
|
||||
[string.span.start as usize + 1..string.span.end as usize - 1];
|
||||
let directive =
|
||||
self.ast.directive(expr.span, (*string).clone(), src);
|
||||
let directive = self.ast.directive(
|
||||
expr.span,
|
||||
(*string).clone(),
|
||||
Atom::from(src),
|
||||
);
|
||||
directives.push(directive);
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue