Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 65 additions & 8 deletions crates/oxc_ast/src/ast/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ pub enum CommentAnnotation {
CoverageIgnore = 7,
}

/// State of newlines around a comment.
#[ast]
#[generate_derive(CloneIn, ContentEq)]
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
pub enum CommentNewlines {
/// No newlines before or after
#[default]
None = 0,
/// Preceded by a newline
Leading = 1,
/// Followed by a newline
Trailing = 2,
/// Preceded and followed by a newline
LeadingAndTrailing = 3,
}

/// A comment in source code.
#[ast]
#[generate_derive(CloneIn, ContentEq, ESTree)]
Expand All @@ -105,14 +121,10 @@ pub struct Comment {
#[estree(skip)]
pub position: CommentPosition,

/// Whether this comment has a preceding newline.
/// Whether this comment has newlines around it.
/// Used to avoid becoming a trailing comment in codegen.
#[estree(skip)]
pub preceded_by_newline: bool,

/// Whether this comment has a tailing newline.
#[estree(skip)]
pub followed_by_newline: bool,
pub newlines: CommentNewlines,

/// Comment Annotation
#[estree(skip)]
Expand All @@ -129,8 +141,7 @@ impl Comment {
attached_to: 0,
kind,
position: CommentPosition::Trailing,
preceded_by_newline: false,
followed_by_newline: false,
newlines: CommentNewlines::None,
annotation: CommentAnnotation::None,
}
}
Expand Down Expand Up @@ -219,4 +230,50 @@ impl Comment {
pub fn is_coverage_ignore(self) -> bool {
self.annotation == CommentAnnotation::CoverageIgnore && self.is_leading()
}

/// Sets the state of `newlines` to include/exclude a newline after the comment.
pub fn set_followed_by_newline(&mut self, followed_by_newline: bool) {
if followed_by_newline {
self.newlines = match self.newlines {
CommentNewlines::None => CommentNewlines::Trailing,
CommentNewlines::Leading => CommentNewlines::LeadingAndTrailing,
_ => self.newlines,
}
} else {
self.newlines = match self.newlines {
CommentNewlines::Trailing => CommentNewlines::None,
CommentNewlines::LeadingAndTrailing => CommentNewlines::Leading,
_ => self.newlines,
}
}
}

/// Sets the state of `newlines` to include/exclude a newline before the comment.
pub fn set_preceded_by_newline(&mut self, preceded_by_newline: bool) {
if preceded_by_newline {
self.newlines = match self.newlines {
CommentNewlines::None => CommentNewlines::Leading,
CommentNewlines::Trailing => CommentNewlines::LeadingAndTrailing,
_ => self.newlines,
}
} else {
self.newlines = match self.newlines {
CommentNewlines::Leading => CommentNewlines::None,
CommentNewlines::LeadingAndTrailing => CommentNewlines::Trailing,
_ => self.newlines,
}
}
}

/// Returns `true` if this comment is preceded by a newline.
#[inline]
pub fn preceded_by_newline(self) -> bool {
matches!(self.newlines, CommentNewlines::Leading | CommentNewlines::LeadingAndTrailing)
}

/// Returns `true` if this comment is followed by a newline.
#[inline]
pub fn followed_by_newline(self) -> bool {
matches!(self.newlines, CommentNewlines::Trailing | CommentNewlines::LeadingAndTrailing)
}
}
24 changes: 14 additions & 10 deletions crates/oxc_ast/src/generated/assert_layouts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1581,16 +1581,18 @@ const _: () = {
assert!(size_of::<CommentAnnotation>() == 1);
assert!(align_of::<CommentAnnotation>() == 1);

// Padding: 7 bytes
assert!(size_of::<Comment>() == 24);
assert!(size_of::<CommentNewlines>() == 1);
assert!(align_of::<CommentNewlines>() == 1);

// Padding: 0 bytes
assert!(size_of::<Comment>() == 16);
assert!(align_of::<Comment>() == 8);
assert!(offset_of!(Comment, span) == 0);
assert!(offset_of!(Comment, attached_to) == 8);
assert!(offset_of!(Comment, kind) == 12);
assert!(offset_of!(Comment, position) == 13);
assert!(offset_of!(Comment, preceded_by_newline) == 14);
assert!(offset_of!(Comment, followed_by_newline) == 15);
assert!(offset_of!(Comment, annotation) == 16);
assert!(offset_of!(Comment, newlines) == 14);
assert!(offset_of!(Comment, annotation) == 15);
};

#[cfg(target_pointer_width = "32")]
Expand Down Expand Up @@ -3167,16 +3169,18 @@ const _: () = {
assert!(size_of::<CommentAnnotation>() == 1);
assert!(align_of::<CommentAnnotation>() == 1);

// Padding: 3 bytes
assert!(size_of::<Comment>() == 20);
assert!(size_of::<CommentNewlines>() == 1);
assert!(align_of::<CommentNewlines>() == 1);

// Padding: 0 bytes
assert!(size_of::<Comment>() == 16);
assert!(align_of::<Comment>() == 4);
assert!(offset_of!(Comment, span) == 0);
assert!(offset_of!(Comment, attached_to) == 8);
assert!(offset_of!(Comment, kind) == 12);
assert!(offset_of!(Comment, position) == 13);
assert!(offset_of!(Comment, preceded_by_newline) == 14);
assert!(offset_of!(Comment, followed_by_newline) == 15);
assert!(offset_of!(Comment, annotation) == 16);
assert!(offset_of!(Comment, newlines) == 14);
assert!(offset_of!(Comment, annotation) == 15);
};

#[cfg(not(any(target_pointer_width = "64", target_pointer_width = "32")))]
Expand Down
26 changes: 16 additions & 10 deletions crates/oxc_ast/src/generated/derive_clone_in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7866,6 +7866,20 @@ impl<'new_alloc> CloneIn<'new_alloc> for CommentAnnotation {
}
}

impl<'new_alloc> CloneIn<'new_alloc> for CommentNewlines {
type Cloned = CommentNewlines;

#[inline(always)]
fn clone_in(&self, allocator: &'new_alloc Allocator) -> Self::Cloned {
*self
}

#[inline(always)]
fn clone_in_with_semantic_ids(&self, allocator: &'new_alloc Allocator) -> Self::Cloned {
*self
}
}

impl<'new_alloc> CloneIn<'new_alloc> for Comment {
type Cloned = Comment;

Expand All @@ -7875,8 +7889,7 @@ impl<'new_alloc> CloneIn<'new_alloc> for Comment {
attached_to: CloneIn::clone_in(&self.attached_to, allocator),
kind: CloneIn::clone_in(&self.kind, allocator),
position: CloneIn::clone_in(&self.position, allocator),
preceded_by_newline: CloneIn::clone_in(&self.preceded_by_newline, allocator),
followed_by_newline: CloneIn::clone_in(&self.followed_by_newline, allocator),
newlines: CloneIn::clone_in(&self.newlines, allocator),
annotation: CloneIn::clone_in(&self.annotation, allocator),
}
}
Expand All @@ -7887,14 +7900,7 @@ impl<'new_alloc> CloneIn<'new_alloc> for Comment {
attached_to: CloneIn::clone_in_with_semantic_ids(&self.attached_to, allocator),
kind: CloneIn::clone_in_with_semantic_ids(&self.kind, allocator),
position: CloneIn::clone_in_with_semantic_ids(&self.position, allocator),
preceded_by_newline: CloneIn::clone_in_with_semantic_ids(
&self.preceded_by_newline,
allocator,
),
followed_by_newline: CloneIn::clone_in_with_semantic_ids(
&self.followed_by_newline,
allocator,
),
newlines: CloneIn::clone_in_with_semantic_ids(&self.newlines, allocator),
annotation: CloneIn::clone_in_with_semantic_ids(&self.annotation, allocator),
}
}
Expand Down
9 changes: 7 additions & 2 deletions crates/oxc_ast/src/generated/derive_content_eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2482,13 +2482,18 @@ impl ContentEq for CommentAnnotation {
}
}

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

impl ContentEq for Comment {
fn content_eq(&self, other: &Self) -> bool {
ContentEq::content_eq(&self.attached_to, &other.attached_to)
&& ContentEq::content_eq(&self.kind, &other.kind)
&& ContentEq::content_eq(&self.position, &other.position)
&& ContentEq::content_eq(&self.preceded_by_newline, &other.preceded_by_newline)
&& ContentEq::content_eq(&self.followed_by_newline, &other.followed_by_newline)
&& ContentEq::content_eq(&self.newlines, &other.newlines)
&& ContentEq::content_eq(&self.annotation, &other.annotation)
}
}
6 changes: 3 additions & 3 deletions crates/oxc_codegen/src/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl Codegen<'_> {
pub(crate) fn print_comments(&mut self, comments: &[Comment]) {
for (i, comment) in comments.iter().enumerate() {
if i == 0 {
if comment.preceded_by_newline {
if comment.preceded_by_newline() {
// Skip printing newline if this comment is already on a newline.
if let Some(b) = self.last_byte() {
match b {
Expand All @@ -113,7 +113,7 @@ impl Codegen<'_> {
}
}
if i >= 1 {
if comment.preceded_by_newline {
if comment.preceded_by_newline() {
self.print_hard_newline();
self.print_indent();
} else if comment.is_legal() {
Expand All @@ -122,7 +122,7 @@ impl Codegen<'_> {
}
self.print_comment(comment);
if i == comments.len() - 1 {
if comment.is_line() || comment.followed_by_newline {
if comment.is_line() || comment.followed_by_newline() {
self.print_hard_newline();
} else {
self.print_next_indent_as_space = true;
Expand Down
Loading
Loading