Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(parser): should be treated comments where after ( as leading comments of next token #6588

Merged
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
62 changes: 60 additions & 2 deletions crates/oxc_parser/src/lexer/trivia_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,35 @@ impl TriviaBuilder {
self.saw_newline = false;
}

/// Determines if the current line comment should be treated as a trailing comment.
///
/// A line comment should be treated as trailing when both of the following conditions are met:
///
/// 1. It is not preceded by a newline.
///
/// ```javascript
/// let x = 5; // This should be treated as a trailing comment
/// foo(); // This should also be treated as a trailing comment
///
/// // This should not be treated as trailing (preceded by newline)
/// let x = 5;
/// ```
///
/// 2. It does not immediately follow an `=` [`Kind::Eq`] or `(` [`Kind::LParen`]
/// token.
///
/// ```javascript
/// let y = // This should not be treated as trailing (follows `=`)
/// 10;
///
/// function foo( // This should not be treated as trailing (follows `(`)
/// param
/// ) {}
/// ```
fn should_be_treated_as_trailing_comment(&self) -> bool {
!self.saw_newline && !matches!(self.previous_kind, Kind::Eq | Kind::LParen)
}

fn add_comment(&mut self, comment: Comment) {
// The comments array is an ordered vec, only add the comment if its not added before,
// to avoid situations where the parser needs to rewind and tries to reinsert the comment.
Expand All @@ -93,8 +122,7 @@ impl TriviaBuilder {
if comment.is_line() {
// A line comment is always followed by a newline. This is never set in `handle_newline`.
comment.followed_by_newline = true;
// A line comment is trailing when it is no preceded by a newline and it is not after `=`
if !self.saw_newline && self.previous_kind != Kind::Eq {
if self.should_be_treated_as_trailing_comment() {
self.processed = self.comments.len() + 1; // +1 to include this comment.
}
self.saw_newline = true;
Expand Down Expand Up @@ -275,4 +303,34 @@ token /* Trailing 1 */
];
assert_eq!(comments, expected);
}

#[test]
fn leading_comments_after_left_parenthesis() {
let source_text = "
call(// Leading comment 1
arguments)
(// Leading comment 2
arguments)
";
let comments = get_comments(source_text);
let expected = vec![
Comment {
span: Span::new(20, 38),
kind: CommentKind::Line,
position: CommentPosition::Leading,
attached_to: 55,
preceded_by_newline: false,
followed_by_newline: true,
},
Comment {
span: Span::new(81, 99),
kind: CommentKind::Line,
position: CommentPosition::Leading,
attached_to: 116,
preceded_by_newline: false,
followed_by_newline: true,
},
];
assert_eq!(comments, expected);
}
}
Loading