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
30 changes: 8 additions & 22 deletions crates/oxc_formatter/src/formatter/trivia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ use oxc_syntax::line_terminator::LineTerminatorSplitter;

use crate::write;

use super::{SourceText, prelude::*};
use super::prelude::*;

/// Returns true if:
/// - `next_comment` is Some, and
Expand All @@ -78,18 +78,12 @@ use super::{SourceText, prelude::*};
/// There isn't much documentation about this behavior, but it is mentioned on the JSDoc repo
/// for documentation: <https://github.com/jsdoc/jsdoc.github.io/issues/40>. Prettier also
/// implements the same behavior: <https://github.com/prettier/prettier/pull/13445/files#diff-3d5eaa2a1593372823589e6e55e7ca905f7c64203ecada0aa4b3b0cdddd5c3ddR160-R178>
#[expect(clippy::suspicious_operation_groupings)]
// `current.span.end == next.span.start` is correct, which checks whether the next comment starts exactly where the current comment ends.
fn should_nestle_adjacent_doc_comments(
current: &Comment,
next: &Comment,
source_text: SourceText,
) -> bool {
fn should_nestle_adjacent_doc_comments(current: &Comment, next: &Comment) -> bool {
matches!(current.content, CommentContent::Jsdoc)
&& matches!(next.content, CommentContent::Jsdoc)
&& current.is_multiline_block()
&& next.is_multiline_block()
&& current.span.end == next.span.start
&& source_text.contains_newline(current.span)
&& source_text.contains_newline(next.span)
}

/// Formats the leading comments of `node`
Expand Down Expand Up @@ -122,11 +116,7 @@ impl<'a> Format<'a> for FormatLeadingComments<'a> {
0 => {
let should_nestle =
leading_comments_iter.peek().is_some_and(|next_comment| {
should_nestle_adjacent_doc_comments(
comment,
next_comment,
f.source_text(),
)
should_nestle_adjacent_doc_comments(comment, next_comment)
});

write!(f, [maybe_space(!should_nestle)]);
Expand Down Expand Up @@ -202,7 +192,7 @@ impl<'a> Format<'a> for FormatTrailingComments<'a> {
total_lines_before += lines_before;

let should_nestle = previous_comment.is_some_and(|previous_comment| {
should_nestle_adjacent_doc_comments(previous_comment, comment, f.source_text())
should_nestle_adjacent_doc_comments(previous_comment, comment)
});

// This allows comments at the end of nested structures:
Expand Down Expand Up @@ -373,11 +363,7 @@ impl<'a> Format<'a> for FormatDanglingComments<'a> {
f.context_mut().comments_mut().increment_printed_count();

let should_nestle = previous_comment.is_some_and(|previous_comment| {
should_nestle_adjacent_doc_comments(
previous_comment,
comment,
f.source_text(),
)
should_nestle_adjacent_doc_comments(previous_comment, comment)
});

write!(
Expand Down Expand Up @@ -433,7 +419,7 @@ impl<'a> Format<'a> for FormatDanglingComments<'a> {
impl<'a> Format<'a> for Comment {
fn fmt(&self, f: &mut Formatter<'_, 'a>) {
let content = f.source_text().text_for(&self.span);
if content.bytes().any(|b| b == b'\n' || b == b'\r') {
if self.is_multiline_block() {
let mut lines = LineTerminatorSplitter::new(content);
if is_alignable_comment(content) {
// `unwrap` is safe because `content` contains at least one line.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ fn format_as_or_satisfies_expression<'a>(
// https://github.com/prettier/prettier/blob/fdfa6701767f5140a85902ecc9fb6444f5b4e3f8/src/language-js/comments/handle-comments.js#L1131
// See also https://github.com/prettier/prettier/blob/3.7.3/tests/format/typescript/as/comments/18160.ts
let comments = f.context().comments().comments_in_range(expression.span().end, type_start);
let multiline_comment_position =
comments.iter().position(|c| c.is_block() && f.source_text().contains_newline(c.span));
let multiline_comment_position = comments.iter().position(|c| c.is_multiline_block());
let block_comments =
if let Some(pos) = multiline_comment_position { &comments[..pos] } else { comments };

Expand Down
17 changes: 7 additions & 10 deletions crates/oxc_formatter/src/write/return_or_throw_statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,25 +114,22 @@ impl<'a> Format<'a> for FormatAdjacentArgument<'a, '_> {
/// Traversing the left nodes is necessary in case the first node is parenthesized because
/// parentheses will be removed (and be re-added by the return statement, but only if the argument breaks)
fn has_argument_leading_comments(argument: &AstNode<Expression>, f: &Formatter<'_, '_>) -> bool {
let source_text = f.source_text();

for left_side in ExpressionLeftSide::from(argument).iter() {
let start = left_side.span().start;
let comments = f.context().comments();
let leading_comments = comments.comments_before(start);

if leading_comments.iter().any(|comment| {
(comment.is_block() && source_text.contains_newline(comment.span))
|| comment.followed_by_newline()
}) {
if leading_comments
.iter()
.any(|comment| comment.is_multiline_block() || comment.followed_by_newline())
{
return true;
}

let is_own_line_comment_or_multi_line_comment = |leading_comments: &[Comment]| {
leading_comments.iter().any(|comment| {
comment.preceded_by_newline()
|| (comment.is_block() && source_text.contains_newline(comment.span))
})
leading_comments
.iter()
.any(|comment| comment.is_multiline_block() || comment.preceded_by_newline())
};

// Yield expressions only need to check the leading comments on the left side.
Expand Down
Loading