Skip to content

Commit

Permalink
feat(ast)!: add Program::comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen committed Oct 11, 2024
1 parent 2b7be08 commit 5c2b551
Show file tree
Hide file tree
Showing 17 changed files with 294 additions and 119 deletions.
1 change: 1 addition & 0 deletions .github/.generated_ast_watch_list.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ src:
- 'crates/oxc_ast/src/ast/js.rs'
- 'crates/oxc_ast/src/ast/ts.rs'
- 'crates/oxc_ast/src/ast/jsx.rs'
- 'crates/oxc_ast/src/ast/comment.rs'
- 'crates/oxc_syntax/src/number.rs'
- 'crates/oxc_syntax/src/operator.rs'
- 'crates/oxc_span/src/span/types.rs'
Expand Down
112 changes: 112 additions & 0 deletions crates/oxc_ast/src/ast/comment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use oxc_allocator::CloneIn;
use oxc_ast_macros::ast;
use oxc_span::{cmp::ContentEq, hash::ContentHash, Span};

#[ast]
#[generate_derive(CloneIn, ContentEq, ContentHash)]
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
pub enum CommentKind {
#[default]
Line = 0,
Block = 1,
}

#[ast]
#[generate_derive(CloneIn, ContentEq, ContentHash)]
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
pub enum CommentPosition {
/// Comments prior to a token until another token or trailing comment.
///
/// e.g.
///
/// ```
/// /* leading */ token;
/// /* leading */
/// // leading
/// token;
/// ```
#[default]
Leading = 0,

/// Comments tailing a token until a newline.
/// e.g. `token /* trailing */ // trailing`
Trailing = 1,
}

#[ast]
#[generate_derive(CloneIn, ContentEq, ContentHash)]
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
pub struct Comment {
/// The span of the comment text (without leading/trailing delimiters).
pub span: Span,

/// Line or block comment
pub kind: CommentKind,

/// Leading or trailing comment
pub position: CommentPosition,

/// Start of token this leading comment is attached to.
/// `/* Leading */ token`
/// ^ This start
/// NOTE: Trailing comment attachment is not computed yet.
pub attached_to: u32,

/// Whether this comment has a preceding newline.
/// Used to avoid becoming a trailing comment in codegen.
pub preceded_by_newline: bool,

/// Whether this comment has a tailing newline.
pub followed_by_newline: bool,
}

impl Comment {
#[inline]
pub fn new(start: u32, end: u32, kind: CommentKind) -> Self {
let span = Span::new(start, end);
Self {
span,
kind,
position: CommentPosition::Trailing,
attached_to: 0,
preceded_by_newline: false,
followed_by_newline: false,
}
}

pub fn is_line(self) -> bool {
self.kind == CommentKind::Line
}

pub fn is_block(self) -> bool {
self.kind == CommentKind::Block
}

pub fn is_leading(self) -> bool {
self.position == CommentPosition::Leading
}

pub fn is_trailing(self) -> bool {
self.position == CommentPosition::Trailing
}

pub fn real_span(&self) -> Span {
Span::new(self.real_span_start(), self.real_span_end())
}

pub fn real_span_end(&self) -> u32 {
match self.kind {
CommentKind::Line => self.span.end,
// length of `*/`
CommentKind::Block => self.span.end + 2,
}
}

pub fn real_span_start(&self) -> u32 {
self.span.start - 2
}

pub fn is_jsdoc(&self, source_text: &str) -> bool {
self.is_leading() && self.is_block() && self.span.source_text(source_text).starts_with('*')
}
}
3 changes: 3 additions & 0 deletions crates/oxc_ast/src/ast/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ pub struct Program<'a> {
pub source_type: SourceType,
#[serde(skip)]
pub source_text: &'a str,
/// Sorted comments
#[serde(skip)]
pub comments: Vec<'a, Comment>,
pub hashbang: Option<Hashbang<'a>>,
pub directives: Vec<'a, Directive<'a>>,
pub body: Vec<'a, Statement<'a>>,
Expand Down
3 changes: 2 additions & 1 deletion crates/oxc_ast/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
//!
//! If you are seeing compile-time errors in `src/ast/macros.rs`, this will be the cause.

pub(crate) mod comment;
pub(crate) mod js;
pub(crate) mod jsx;
pub(crate) mod literal;
Expand All @@ -191,4 +192,4 @@ pub use oxc_syntax::{
},
};

pub use self::{js::*, jsx::*, literal::*, ts::*};
pub use self::{comment::*, js::*, jsx::*, literal::*, ts::*};
52 changes: 42 additions & 10 deletions crates/oxc_ast/src/generated/assert_layouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,16 @@ const _: () = {
assert!(offset_of!(StringLiteral, span) == 0usize);
assert!(offset_of!(StringLiteral, value) == 8usize);

assert!(size_of::<Program>() == 128usize);
assert!(size_of::<Program>() == 160usize);
assert!(align_of::<Program>() == 8usize);
assert!(offset_of!(Program, span) == 0usize);
assert!(offset_of!(Program, source_type) == 8usize);
assert!(offset_of!(Program, source_text) == 16usize);
assert!(offset_of!(Program, hashbang) == 32usize);
assert!(offset_of!(Program, directives) == 56usize);
assert!(offset_of!(Program, body) == 88usize);
assert!(offset_of!(Program, scope_id) == 120usize);
assert!(offset_of!(Program, comments) == 32usize);
assert!(offset_of!(Program, hashbang) == 64usize);
assert!(offset_of!(Program, directives) == 88usize);
assert!(offset_of!(Program, body) == 120usize);
assert!(offset_of!(Program, scope_id) == 152usize);

assert!(size_of::<Expression>() == 16usize);
assert!(align_of::<Expression>() == 8usize);
Expand Down Expand Up @@ -1375,6 +1376,21 @@ const _: () = {
assert!(offset_of!(JSXText, span) == 0usize);
assert!(offset_of!(JSXText, value) == 8usize);

assert!(size_of::<CommentKind>() == 1usize);
assert!(align_of::<CommentKind>() == 1usize);

assert!(size_of::<CommentPosition>() == 1usize);
assert!(align_of::<CommentPosition>() == 1usize);

assert!(size_of::<Comment>() == 20usize);
assert!(align_of::<Comment>() == 4usize);
assert!(offset_of!(Comment, span) == 0usize);
assert!(offset_of!(Comment, kind) == 8usize);
assert!(offset_of!(Comment, position) == 9usize);
assert!(offset_of!(Comment, attached_to) == 12usize);
assert!(offset_of!(Comment, preceded_by_newline) == 16usize);
assert!(offset_of!(Comment, followed_by_newline) == 17usize);

assert!(size_of::<NumberBase>() == 1usize);
assert!(align_of::<NumberBase>() == 1usize);

Expand Down Expand Up @@ -1598,15 +1614,16 @@ const _: () = {
assert!(offset_of!(StringLiteral, span) == 0usize);
assert!(offset_of!(StringLiteral, value) == 8usize);

assert!(size_of::<Program>() == 72usize);
assert!(size_of::<Program>() == 88usize);
assert!(align_of::<Program>() == 4usize);
assert!(offset_of!(Program, span) == 0usize);
assert!(offset_of!(Program, source_type) == 8usize);
assert!(offset_of!(Program, source_text) == 12usize);
assert!(offset_of!(Program, hashbang) == 20usize);
assert!(offset_of!(Program, directives) == 36usize);
assert!(offset_of!(Program, body) == 52usize);
assert!(offset_of!(Program, scope_id) == 68usize);
assert!(offset_of!(Program, comments) == 20usize);
assert!(offset_of!(Program, hashbang) == 36usize);
assert!(offset_of!(Program, directives) == 52usize);
assert!(offset_of!(Program, body) == 68usize);
assert!(offset_of!(Program, scope_id) == 84usize);

assert!(size_of::<Expression>() == 8usize);
assert!(align_of::<Expression>() == 4usize);
Expand Down Expand Up @@ -2918,6 +2935,21 @@ const _: () = {
assert!(offset_of!(JSXText, span) == 0usize);
assert!(offset_of!(JSXText, value) == 8usize);

assert!(size_of::<CommentKind>() == 1usize);
assert!(align_of::<CommentKind>() == 1usize);

assert!(size_of::<CommentPosition>() == 1usize);
assert!(align_of::<CommentPosition>() == 1usize);

assert!(size_of::<Comment>() == 20usize);
assert!(align_of::<Comment>() == 4usize);
assert!(offset_of!(Comment, span) == 0usize);
assert!(offset_of!(Comment, kind) == 8usize);
assert!(offset_of!(Comment, position) == 9usize);
assert!(offset_of!(Comment, attached_to) == 12usize);
assert!(offset_of!(Comment, preceded_by_newline) == 16usize);
assert!(offset_of!(Comment, followed_by_newline) == 17usize);

assert!(size_of::<NumberBase>() == 1usize);
assert!(align_of::<NumberBase>() == 1usize);

Expand Down
7 changes: 6 additions & 1 deletion crates/oxc_ast/src/generated/ast_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ impl<'a> AstBuilder<'a> {
/// - span: The [`Span`] covering this node
/// - source_type
/// - source_text
/// - comments: Sorted comments
/// - hashbang
/// - directives
/// - body
Expand All @@ -231,6 +232,7 @@ impl<'a> AstBuilder<'a> {
span: Span,
source_type: SourceType,
source_text: S,
comments: Vec<'a, Comment>,
hashbang: Option<Hashbang<'a>>,
directives: Vec<'a, Directive<'a>>,
body: Vec<'a, Statement<'a>>,
Expand All @@ -242,6 +244,7 @@ impl<'a> AstBuilder<'a> {
span,
source_type,
source_text: source_text.into_in(self.allocator),
comments,
hashbang,
directives,
body,
Expand All @@ -257,6 +260,7 @@ impl<'a> AstBuilder<'a> {
/// - span: The [`Span`] covering this node
/// - source_type
/// - source_text
/// - comments: Sorted comments
/// - hashbang
/// - directives
/// - body
Expand All @@ -266,6 +270,7 @@ impl<'a> AstBuilder<'a> {
span: Span,
source_type: SourceType,
source_text: S,
comments: Vec<'a, Comment>,
hashbang: Option<Hashbang<'a>>,
directives: Vec<'a, Directive<'a>>,
body: Vec<'a, Statement<'a>>,
Expand All @@ -274,7 +279,7 @@ impl<'a> AstBuilder<'a> {
S: IntoIn<'a, &'a str>,
{
Box::new_in(
self.program(span, source_type, source_text, hashbang, directives, body),
self.program(span, source_type, source_text, comments, hashbang, directives, body),
self.allocator,
)
}
Expand Down
38 changes: 38 additions & 0 deletions crates/oxc_ast/src/generated/derive_clone_in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

use oxc_allocator::{Allocator, CloneIn};

#[allow(clippy::wildcard_imports)]
use crate::ast::comment::*;

#[allow(clippy::wildcard_imports)]
use crate::ast::js::*;

Expand Down Expand Up @@ -113,6 +116,7 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for Program<'old_alloc> {
span: CloneIn::clone_in(&self.span, allocator),
source_type: CloneIn::clone_in(&self.source_type, allocator),
source_text: CloneIn::clone_in(&self.source_text, allocator),
comments: CloneIn::clone_in(&self.comments, allocator),
hashbang: CloneIn::clone_in(&self.hashbang, allocator),
directives: CloneIn::clone_in(&self.directives, allocator),
body: CloneIn::clone_in(&self.body, allocator),
Expand Down Expand Up @@ -4231,3 +4235,37 @@ impl<'old_alloc, 'new_alloc> CloneIn<'new_alloc> for JSXText<'old_alloc> {
}
}
}

impl<'alloc> CloneIn<'alloc> for CommentKind {
type Cloned = CommentKind;
fn clone_in(&self, _: &'alloc Allocator) -> Self::Cloned {
match self {
Self::Line => CommentKind::Line,
Self::Block => CommentKind::Block,
}
}
}

impl<'alloc> CloneIn<'alloc> for CommentPosition {
type Cloned = CommentPosition;
fn clone_in(&self, _: &'alloc Allocator) -> Self::Cloned {
match self {
Self::Leading => CommentPosition::Leading,
Self::Trailing => CommentPosition::Trailing,
}
}
}

impl<'alloc> CloneIn<'alloc> for Comment {
type Cloned = Comment;
fn clone_in(&self, allocator: &'alloc Allocator) -> Self::Cloned {
Comment {
span: CloneIn::clone_in(&self.span, allocator),
kind: CloneIn::clone_in(&self.kind, allocator),
position: CloneIn::clone_in(&self.position, allocator),
attached_to: CloneIn::clone_in(&self.attached_to, allocator),
preceded_by_newline: CloneIn::clone_in(&self.preceded_by_newline, allocator),
followed_by_newline: CloneIn::clone_in(&self.followed_by_newline, allocator),
}
}
}
26 changes: 26 additions & 0 deletions crates/oxc_ast/src/generated/derive_content_eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

use oxc_span::cmp::ContentEq;

#[allow(clippy::wildcard_imports)]
use crate::ast::comment::*;

#[allow(clippy::wildcard_imports)]
use crate::ast::js::*;

Expand Down Expand Up @@ -93,6 +96,7 @@ impl<'a> ContentEq for Program<'a> {
fn content_eq(&self, other: &Self) -> bool {
ContentEq::content_eq(&self.source_type, &other.source_type)
&& ContentEq::content_eq(&self.source_text, &other.source_text)
&& ContentEq::content_eq(&self.comments, &other.comments)
&& ContentEq::content_eq(&self.hashbang, &other.hashbang)
&& ContentEq::content_eq(&self.directives, &other.directives)
&& ContentEq::content_eq(&self.body, &other.body)
Expand Down Expand Up @@ -4212,3 +4216,25 @@ impl<'a> ContentEq for JSXText<'a> {
ContentEq::content_eq(&self.value, &other.value)
}
}

impl ContentEq for CommentKind {
fn content_eq(&self, other: &Self) -> bool {
self == other
}
}

impl ContentEq for CommentPosition {
fn content_eq(&self, other: &Self) -> bool {
self == other
}
}

impl ContentEq for Comment {
fn content_eq(&self, other: &Self) -> bool {
ContentEq::content_eq(&self.kind, &other.kind)
&& ContentEq::content_eq(&self.position, &other.position)
&& ContentEq::content_eq(&self.attached_to, &other.attached_to)
&& ContentEq::content_eq(&self.preceded_by_newline, &other.preceded_by_newline)
&& ContentEq::content_eq(&self.followed_by_newline, &other.followed_by_newline)
}
}
Loading

0 comments on commit 5c2b551

Please sign in to comment.