Skip to content

Commit 6f67bf0

Browse files
committed
feat(ast, parser, codegen): add CommentKind::MultineBlock
1 parent d90ef9f commit 6f67bf0

File tree

18 files changed

+79
-35
lines changed

18 files changed

+79
-35
lines changed

apps/oxlint/src-js/generated/deserialize.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5651,6 +5651,8 @@ function deserializeCommentKind(pos) {
56515651
return "Line";
56525652
case 1:
56535653
return "Block";
5654+
case 2:
5655+
return "MultiLineBlock";
56545656
default:
56555657
throw Error(`Unexpected discriminant ${uint8[pos]} for CommentKind`);
56565658
}

crates/oxc_ast/src/ast/comment.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ pub enum CommentKind {
1717
Line = 0,
1818
/// Block comment
1919
Block = 1,
20+
/// Multiline block comment (contains line breaks)
21+
MultilineBlock = 2,
2022
}
2123

2224
/// Information about a comment's position relative to a token.
@@ -172,7 +174,9 @@ impl Comment {
172174
pub fn content_span(&self) -> Span {
173175
match self.kind {
174176
CommentKind::Line => Span::new(self.span.start + 2, self.span.end),
175-
CommentKind::Block => Span::new(self.span.start + 2, self.span.end - 2),
177+
CommentKind::Block | CommentKind::MultilineBlock => {
178+
Span::new(self.span.start + 2, self.span.end - 2)
179+
}
176180
}
177181
}
178182

@@ -185,7 +189,13 @@ impl Comment {
185189
/// Returns `true` if this is a block comment.
186190
#[inline]
187191
pub fn is_block(self) -> bool {
188-
self.kind == CommentKind::Block
192+
matches!(self.kind, CommentKind::Block | CommentKind::MultilineBlock)
193+
}
194+
195+
/// Returns `true` if this is a multi-line block comment.
196+
#[inline]
197+
pub fn is_multiline_block(self) -> bool {
198+
self.kind == CommentKind::MultilineBlock
189199
}
190200

191201
/// Returns `true` if this comment is before a token.

crates/oxc_ast/src/generated/derive_estree.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3234,6 +3234,7 @@ impl ESTree for CommentKind {
32343234
match self {
32353235
Self::Line => JsonSafeString("Line").serialize(serializer),
32363236
Self::Block => JsonSafeString("Block").serialize(serializer),
3237+
Self::MultilineBlock => JsonSafeString("MultiLineBlock").serialize(serializer),
32373238
}
32383239
}
32393240
}

crates/oxc_codegen/src/comment.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::{borrow::Cow, iter::FusedIterator};
33
use rustc_hash::{FxHashMap, FxHashSet};
44

55
use oxc_ast::{Comment, CommentKind, ast::Program};
6-
use oxc_syntax::identifier::is_line_terminator;
76

87
use crate::{
98
Codegen, LegalComment,
@@ -214,10 +213,10 @@ impl Codegen<'_> {
214213
};
215214
let comment_source = comment.span.source_text(source_text);
216215
match comment.kind {
217-
CommentKind::Line => {
216+
CommentKind::Line | CommentKind::Block => {
218217
self.print_str_escaping_script_close_tag(comment_source);
219218
}
220-
CommentKind::Block => {
219+
CommentKind::MultilineBlock => {
221220
for line in LineTerminatorSplitter::new(comment_source) {
222221
if !line.starts_with("/*") {
223222
self.print_indent();
@@ -249,7 +248,7 @@ impl Codegen<'_> {
249248
let source_text = program.source_text;
250249
for comment in program.comments.iter().filter(|c| c.is_legal()) {
251250
let mut text = Cow::Borrowed(comment.span.source_text(source_text));
252-
if comment.is_block() && text.contains(is_line_terminator) {
251+
if comment.is_multiline_block() {
253252
let mut buffer = String::with_capacity(text.len());
254253
// Print block comments with our own indentation.
255254
for line in LineTerminatorSplitter::new(&text) {

crates/oxc_formatter/src/formatter/trivia.rs

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -114,28 +114,31 @@ impl<'a> Format<'a> for FormatLeadingComments<'a> {
114114
write!(f, comment);
115115

116116
match comment.kind {
117-
CommentKind::Block => match f.source_text().lines_after(comment.span.end) {
118-
0 => {
119-
let should_nestle =
120-
leading_comments_iter.peek().is_some_and(|next_comment| {
121-
should_nestle_adjacent_doc_comments(
122-
comment,
123-
next_comment,
124-
f.source_text(),
125-
)
126-
});
127-
128-
write!(f, [maybe_space(!should_nestle)]);
129-
}
130-
1 => {
131-
if f.source_text().get_lines_before(comment.span, f.comments()) == 0 {
132-
write!(f, [soft_line_break_or_space()]);
133-
} else {
134-
write!(f, [hard_line_break()]);
117+
CommentKind::Block | CommentKind::MultilineBlock => {
118+
match f.source_text().lines_after(comment.span.end) {
119+
0 => {
120+
let should_nestle =
121+
leading_comments_iter.peek().is_some_and(|next_comment| {
122+
should_nestle_adjacent_doc_comments(
123+
comment,
124+
next_comment,
125+
f.source_text(),
126+
)
127+
});
128+
129+
write!(f, [maybe_space(!should_nestle)]);
130+
}
131+
1 => {
132+
if f.source_text().get_lines_before(comment.span, f.comments()) == 0
133+
{
134+
write!(f, [soft_line_break_or_space()]);
135+
} else {
136+
write!(f, [hard_line_break()]);
137+
}
135138
}
139+
_ => write!(f, [empty_line()]),
136140
}
137-
_ => write!(f, [empty_line()]),
138-
},
141+
}
139142
CommentKind::Line => match f.source_text().lines_after(comment.span.end) {
140143
0 | 1 => write!(f, [hard_line_break()]),
141144
_ => write!(f, [empty_line()]),

crates/oxc_linter/src/rules/typescript/prefer_function_type.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ fn check_member(member: &TSSignature, node: &AstNode<'_>, ctx: &LintContext<'_>)
159159

160160
let has_comments = ctx.has_comments_between(interface_decl.span);
161161

162+
// TODO:
162163
if has_comments {
163164
let comments = ctx
164165
.comments_range(node_start..node_end)
@@ -174,7 +175,7 @@ fn check_member(member: &TSSignature, node: &AstNode<'_>, ctx: &LintContext<'_>)
174175
let single_line_comment: String = format!("//{comment}\n");
175176
comments_vec.push(single_line_comment);
176177
}
177-
CommentKind::Block => {
178+
CommentKind::Block | CommentKind::MultilineBlock => {
178179
let multi_line_comment: String = format!("/*{comment}*/\n");
179180
comments_vec.push(multi_line_comment);
180181
}

crates/oxc_napi/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub fn convert_utf8_to_utf16(
3333
Comment {
3434
r#type: match comment.kind {
3535
CommentKind::Line => String::from("Line"),
36-
CommentKind::Block => String::from("Block"),
36+
CommentKind::Block | CommentKind::MultilineBlock => String::from("Block"),
3737
},
3838
value,
3939
start: span.start,

crates/oxc_parser/src/lexer/comment.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use memchr::memmem::Finder;
22

3+
use oxc_ast::CommentKind;
34
use oxc_syntax::identifier::is_line_terminator;
45

56
use crate::diagnostics;
@@ -82,9 +83,10 @@ impl<'a> Lexer<'a> {
8283
/// Section 12.4 Multi Line Comment
8384
pub(super) fn skip_multi_line_comment(&mut self) -> Kind {
8485
// If `is_on_new_line` is already set, go directly to faster search which only looks for `*/`
85-
if self.token.is_on_new_line() {
86-
return self.skip_multi_line_comment_after_line_break(self.source.position());
87-
}
86+
// TODO(FIXME): commented out since it doesn't means there is a line break in the comment, while it means the line break is before the comment
87+
// if self.token.is_on_new_line() {
88+
// return self.skip_multi_line_comment_after_line_break(self.source.position());
89+
// }
8890

8991
byte_search! {
9092
lexer: self,
@@ -149,6 +151,7 @@ impl<'a> Lexer<'a> {
149151
self.trivia_builder.add_block_comment(
150152
self.token.start(),
151153
self.offset(),
154+
CommentKind::Block,
152155
self.source.whole(),
153156
);
154157
Kind::Skip
@@ -170,6 +173,7 @@ impl<'a> Lexer<'a> {
170173
self.trivia_builder.add_block_comment(
171174
self.token.start(),
172175
self.offset(),
176+
CommentKind::MultilineBlock,
173177
self.source.whole(),
174178
);
175179
Kind::Skip

crates/oxc_parser/src/lexer/trivia_builder.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,14 @@ impl TriviaBuilder {
5959
self.add_comment(Comment::new(start, end, CommentKind::Line), source_text);
6060
}
6161

62-
pub fn add_block_comment(&mut self, start: u32, end: u32, source_text: &str) {
63-
self.add_comment(Comment::new(start, end, CommentKind::Block), source_text);
62+
pub fn add_block_comment(
63+
&mut self,
64+
start: u32,
65+
end: u32,
66+
kind: CommentKind,
67+
source_text: &str,
68+
) {
69+
self.add_comment(Comment::new(start, end, kind), source_text);
6470
}
6571

6672
// For block comments only. This function is not called after line comments because the lexer skips
@@ -425,15 +431,15 @@ token /* Trailing 1 */
425431
let expected = vec![
426432
Comment {
427433
span: Span::new(1, 13),
428-
kind: CommentKind::Block,
434+
kind: CommentKind::MultilineBlock,
429435
position: CommentPosition::Leading,
430436
attached_to: 28,
431437
newlines: CommentNewlines::Leading | CommentNewlines::Trailing,
432438
content: CommentContent::None,
433439
},
434440
Comment {
435441
span: Span::new(14, 26),
436-
kind: CommentKind::Block,
442+
kind: CommentKind::MultilineBlock,
437443
position: CommentPosition::Leading,
438444
attached_to: 28,
439445
newlines: CommentNewlines::Leading | CommentNewlines::Trailing,

napi/parser/generated/deserialize/js.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4210,6 +4210,8 @@ function deserializeCommentKind(pos) {
42104210
return "Line";
42114211
case 1:
42124212
return "Block";
4213+
case 2:
4214+
return "MultiLineBlock";
42134215
default:
42144216
throw Error(`Unexpected discriminant ${uint8[pos]} for CommentKind`);
42154217
}

0 commit comments

Comments
 (0)