mirror of
https://github.com/aphrody-labs/oxc.git
synced 2026-10-14 22:29:17 +00:00
fix(parser): handle HTML comment values (#22933)
Strip full HTML comment markers while preserving comment ranges, and keep closing annotations valid when emitted mid-line. Fixes #22803. AI-assisted with Codex.
This commit is contained in:
22 files changed
+197
-32
No files matched your search
@@ -344,16 +344,18 @@ function deserializeCommentIfNeeded(index: number): Comment | null {
|
||||
// Deserialize comment into a cached `Comment` object
|
||||
const comment = cachedComments[index];
|
||||
|
||||
const isBlock = commentsUint8[pos + COMMENT_KIND_OFFSET] !== COMMENT_LINE_KIND;
|
||||
// HTML comment discriminants equal their delimiter lengths (3 or 4).
|
||||
const kind = commentsUint8[pos + COMMENT_KIND_OFFSET];
|
||||
const isBlock = kind !== COMMENT_LINE_KIND && kind < 3;
|
||||
|
||||
const pos32 = pos >> 2,
|
||||
start = commentsInt32[pos32],
|
||||
end = commentsInt32[pos32 + 1];
|
||||
|
||||
comment.type = isBlock ? "Block" : "Line";
|
||||
// Line comments: `// text` -> slice `start + 2..end`
|
||||
// Line comments: skip `//`, `-->`, or `<!--`
|
||||
// Block comments: `/* text */` -> slice `start + 2..end - 2`
|
||||
comment.value = sourceText.slice(start + 2, end - (+isBlock << 1));
|
||||
comment.value = sourceText.slice(start + (kind < 3 ? 2 : kind), end - (+isBlock << 1));
|
||||
comment.range[0] = comment.start = start;
|
||||
comment.range[1] = comment.end = end;
|
||||
|
||||
|
||||
@@ -96,6 +96,23 @@ const CallExpression = { range: [48, 54] } as Node;
|
||||
|
||||
// https://github.com/eslint/eslint/blob/v9.39.1/tests/lib/languages/js/source-code/token-store.js#L62-L155
|
||||
describe("when calling getTokens", () => {
|
||||
it("should strip HTML comment markers and preserve comment ranges", () => {
|
||||
const source = "<!--a\n-->\n<!--\n//b\n/*c*/\nfoo;";
|
||||
setup(source);
|
||||
const program = { range: [0, source.length] } as Node;
|
||||
const comments = getTokens(program, {
|
||||
includeComments: true,
|
||||
filter: (token) => token.type === "Line" || token.type === "Block",
|
||||
});
|
||||
expect(comments.map(({ type, value, range }) => ({ type, value, range }))).toEqual([
|
||||
{ type: "Line", value: "a", range: [0, 5] },
|
||||
{ type: "Line", value: "", range: [6, 9] },
|
||||
{ type: "Line", value: "", range: [10, 14] },
|
||||
{ type: "Line", value: "b", range: [15, 18] },
|
||||
{ type: "Block", value: "c", range: [19, 24] },
|
||||
]);
|
||||
});
|
||||
|
||||
it("should retrieve all tokens for root node", () => {
|
||||
expect(getTokens(Program).map((token) => token.value)).toEqual([
|
||||
"var",
|
||||
|
||||
@@ -20,6 +20,12 @@ pub enum CommentKind {
|
||||
/// Multi-line block comment (contains line breaks)
|
||||
#[estree(rename = "Block")]
|
||||
MultiLineBlock = 2,
|
||||
/// HTML opening line comment (`<!--`). The discriminant is the delimiter length.
|
||||
#[estree(rename = "Line")]
|
||||
HtmlOpen = 4,
|
||||
/// HTML closing line comment (`-->`). The discriminant is the delimiter length.
|
||||
#[estree(rename = "Line")]
|
||||
HtmlClose = 3,
|
||||
}
|
||||
|
||||
/// Information about a comment's position relative to a token.
|
||||
@@ -212,6 +218,9 @@ impl Comment {
|
||||
pub fn content_span(&self) -> Span {
|
||||
match self.kind {
|
||||
CommentKind::Line => Span::new(self.span.start + 2, self.span.end),
|
||||
CommentKind::HtmlOpen | CommentKind::HtmlClose => {
|
||||
Span::new(self.span.start + self.kind as u32, self.span.end)
|
||||
}
|
||||
CommentKind::SingleLineBlock | CommentKind::MultiLineBlock => {
|
||||
Span::new(self.span.start + 2, self.span.end - 2)
|
||||
}
|
||||
@@ -221,7 +230,7 @@ impl Comment {
|
||||
/// Returns `true` if this is a line comment.
|
||||
#[inline]
|
||||
pub fn is_line(self) -> bool {
|
||||
self.kind == CommentKind::Line
|
||||
matches!(self.kind, CommentKind::Line | CommentKind::HtmlOpen | CommentKind::HtmlClose)
|
||||
}
|
||||
|
||||
/// Returns `true` if this is a block comment (either single-line or multi-line).
|
||||
|
||||
@@ -3368,6 +3368,8 @@ impl ESTree for CommentKind {
|
||||
Self::Line => JsonSafeString("Line").serialize(serializer),
|
||||
Self::SingleLineBlock => JsonSafeString("Block").serialize(serializer),
|
||||
Self::MultiLineBlock => JsonSafeString("Block").serialize(serializer),
|
||||
Self::HtmlOpen => JsonSafeString("Line").serialize(serializer),
|
||||
Self::HtmlClose => JsonSafeString("Line").serialize(serializer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +218,11 @@ fn get_ts_start_span(program: &Program<'_>) -> u32 {
|
||||
#[ast_meta]
|
||||
#[estree(
|
||||
ts_type = "string",
|
||||
raw_deser = "SOURCE_TEXT.slice(THIS.start + 2, THIS.end - (THIS.type === 'Line' ? 0 : 2))",
|
||||
raw_deser = "
|
||||
// HTML comment discriminants equal their delimiter lengths (3 or 4).
|
||||
const kind = DESER[u8](POS_OFFSET.kind);
|
||||
SOURCE_TEXT.slice(THIS.start + (kind < 3 ? 2 : kind), THIS.end - (THIS.type === 'Line' ? 0 : 2))
|
||||
",
|
||||
raw_deser_inline
|
||||
)]
|
||||
pub struct CommentValue<'b>(#[expect(dead_code)] pub &'b Comment);
|
||||
|
||||
@@ -416,9 +416,26 @@ impl Codegen<'_> {
|
||||
};
|
||||
let comment_source = comment.span.source_text(source_text);
|
||||
match comment.kind {
|
||||
CommentKind::Line | CommentKind::SingleLineBlock => {
|
||||
CommentKind::Line | CommentKind::HtmlOpen | CommentKind::SingleLineBlock => {
|
||||
self.print_str_escaping_script_close_tag(comment_source);
|
||||
}
|
||||
CommentKind::HtmlClose => {
|
||||
// `-->` is only a comment at the start of a line, allowing indentation.
|
||||
// Annotation emission can place it after code even without minification.
|
||||
let is_mid_line = self
|
||||
.code()
|
||||
.as_bytes()
|
||||
.iter()
|
||||
.rfind(|&&byte| !matches!(byte, b' ' | b'\t'))
|
||||
.is_some_and(|&byte| byte != b'\n');
|
||||
let text = if is_mid_line {
|
||||
self.print_str("//");
|
||||
comment.content_span().source_text(source_text)
|
||||
} else {
|
||||
comment_source
|
||||
};
|
||||
self.print_str_escaping_script_close_tag(text);
|
||||
}
|
||||
CommentKind::MultiLineBlock => {
|
||||
for line in LineTerminatorSplitter::new(comment_source) {
|
||||
if !line.starts_with("/*") {
|
||||
|
||||
@@ -241,6 +241,38 @@ fn test_comment_at_top_of_file() {
|
||||
assert_eq!(code, "/** comment */ export {};\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_html_closing_annotation_after_code() {
|
||||
use oxc_allocator::Allocator;
|
||||
use oxc_codegen::{Codegen, CodegenOptions};
|
||||
use oxc_parser::Parser;
|
||||
use oxc_span::SourceType;
|
||||
|
||||
let allocator = Allocator::default();
|
||||
let source_type = SourceType::script();
|
||||
for (source, pretty_delimiter, minified_delimiter) in [
|
||||
("foo();\n--> @__NO_SIDE_EFFECTS__\nfunction f() {}", "-->", "//"),
|
||||
("if (true)\n--> @__NO_SIDE_EFFECTS__\nfunction f() {}", "//", "//"),
|
||||
("label:\n--> @__NO_SIDE_EFFECTS__\nfunction f() {}", "//", "//"),
|
||||
("--> @__NO_SIDE_EFFECTS__\nfunction f() {}", "-->", "-->"),
|
||||
("{\n--> @__NO_SIDE_EFFECTS__\nfunction f() {}\n}", "-->", "//"),
|
||||
] {
|
||||
let ret = Parser::new(&allocator, source, source_type).parse();
|
||||
assert!(ret.diagnostics.is_empty(), "Invalid source: {source}");
|
||||
|
||||
for minify in [false, true] {
|
||||
let options = CodegenOptions { minify, ..CodegenOptions::default() };
|
||||
let code = Codegen::new().with_options(options.clone()).build(&ret.program).code;
|
||||
let reparsed = Parser::new(&allocator, &code, source_type).parse();
|
||||
assert!(reparsed.diagnostics.is_empty(), "Invalid output: {code}");
|
||||
let expected_comment = if minify { minified_delimiter } else { pretty_delimiter };
|
||||
assert!(code.contains(&format!("{expected_comment} @__NO_SIDE_EFFECTS__\n")));
|
||||
let second = Codegen::new().with_options(options).build(&reparsed.program).code;
|
||||
assert_eq!(code, second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit() {
|
||||
test_same("<div>{/* Hello */}</div>;\n");
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use oxc_ast::CommentKind;
|
||||
|
||||
use crate::{comment_meta, error::DiagCode, lanes::Lanes, token::tk};
|
||||
|
||||
use crate::pipeline::{
|
||||
@@ -290,6 +292,7 @@ pub(super) unsafe fn lex_html_open_comment(
|
||||
let m = comment_meta::meta_byte_exact(&srcs[..n], (s + 2) as u32, end as u32, false);
|
||||
lanes.comment_meta.push(m);
|
||||
lanes.push_comment_record(srcs, n, s as u32, end as u32, false, m);
|
||||
lanes.comments.last_mut().unwrap().kind = CommentKind::HtmlOpen;
|
||||
end
|
||||
}
|
||||
|
||||
@@ -334,6 +337,7 @@ pub(super) unsafe fn lex_html_close_comment(
|
||||
let m = comment_meta::meta_byte_exact(&srcs[..n], (start + 1) as u32, end as u32, false);
|
||||
lanes.comment_meta.push(m);
|
||||
lanes.push_comment_record(srcs, n, start as u32, end as u32, false, m);
|
||||
lanes.comments.last_mut().unwrap().kind = CommentKind::HtmlClose;
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,22 @@ fn script_html_open_comment_anywhere() {
|
||||
assert!(diag_codes("x <!-- y\nz;", false).is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn html_comment_content() {
|
||||
let source = "<!--a\n-->\n<!--";
|
||||
let mut buf = source.as_bytes().to_vec();
|
||||
buf.resize(buf.len() + PAD, 0);
|
||||
let options = LexOptions { source_type_module: false, ..Default::default() };
|
||||
let (result, arena) = lex_utf8(&buf, source.len() as u32, options);
|
||||
assert!(result.diagnostics().is_empty());
|
||||
let comments = result.comments(&arena);
|
||||
assert_eq!(comments.len(), 3);
|
||||
for (comment, content) in comments.iter().zip(["a", "", ""]) {
|
||||
assert!(comment.is_line());
|
||||
assert_eq!(comment.content_span().source_text(source), content);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn module_html_open_comment_mid_expression_is_lt() {
|
||||
let ks = kinds_of("x <!-- y;", true);
|
||||
|
||||
@@ -34,7 +34,9 @@ pub fn convert_utf8_to_utf16(
|
||||
}
|
||||
Comment {
|
||||
r#type: match comment.kind {
|
||||
CommentKind::Line => String::from("Line"),
|
||||
CommentKind::Line | CommentKind::HtmlOpen | CommentKind::HtmlClose => {
|
||||
String::from("Line")
|
||||
}
|
||||
CommentKind::SingleLineBlock | CommentKind::MultiLineBlock => {
|
||||
String::from("Block")
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use oxc_ast::CommentKind;
|
||||
use oxc_data_structures::assert_unchecked;
|
||||
|
||||
use crate::{
|
||||
@@ -304,7 +305,7 @@ ascii_byte_handler!(COM(lexer) {
|
||||
// -
|
||||
ascii_byte_handler!(MIN(lexer) {
|
||||
lexer.consume_char();
|
||||
lexer.read_minus().unwrap_or_else(|| lexer.skip_single_line_comment())
|
||||
lexer.read_minus().unwrap_or_else(|| lexer.skip_single_line_comment(CommentKind::HtmlClose))
|
||||
});
|
||||
|
||||
// .
|
||||
@@ -319,7 +320,7 @@ ascii_byte_handler!(SLH(lexer) {
|
||||
match lexer.peek_byte() {
|
||||
Some(b'/') => {
|
||||
lexer.consume_char();
|
||||
lexer.skip_single_line_comment()
|
||||
lexer.skip_single_line_comment(CommentKind::Line)
|
||||
}
|
||||
Some(b'*') => {
|
||||
lexer.consume_char();
|
||||
@@ -363,7 +364,7 @@ ascii_byte_handler!(SEM(lexer) {
|
||||
// <
|
||||
ascii_byte_handler!(LSS(lexer) {
|
||||
lexer.consume_char();
|
||||
lexer.read_left_angle().unwrap_or_else(|| lexer.skip_single_line_comment())
|
||||
lexer.read_left_angle().unwrap_or_else(|| lexer.skip_single_line_comment(CommentKind::HtmlOpen))
|
||||
});
|
||||
|
||||
// =
|
||||
|
||||
@@ -25,7 +25,7 @@ static MULTILINE_COMMENT_START_TABLE: SafeByteMatchTable =
|
||||
|
||||
impl<'a, C: Config> Lexer<'a, C> {
|
||||
/// Section 12.4 Single Line Comment
|
||||
pub(super) fn skip_single_line_comment(&mut self) -> Kind {
|
||||
pub(super) fn skip_single_line_comment(&mut self, kind: CommentKind) -> Kind {
|
||||
byte_search! {
|
||||
lexer: self,
|
||||
table: LINE_BREAK_TABLE,
|
||||
@@ -38,7 +38,7 @@ impl<'a, C: Config> Lexer<'a, C> {
|
||||
if next_byte != LS_OR_PS_FIRST {
|
||||
// `\r` or `\n`
|
||||
self.trivia_builder
|
||||
.add_line_comment(self.token.start(), self.source.offset_of(pos), self.source.whole());
|
||||
.add_line_comment(self.token.start(), self.source.offset_of(pos), kind, self.source.whole());
|
||||
// SAFETY: Safe to consume `\r` or `\n` as both are ASCII
|
||||
pos = unsafe { pos.add(1) };
|
||||
// We've found the end. Do not continue searching.
|
||||
@@ -53,7 +53,7 @@ impl<'a, C: Config> Lexer<'a, C> {
|
||||
if matches!(next2, LS_BYTES_2_AND_3 | PS_BYTES_2_AND_3) {
|
||||
// Irregular line break
|
||||
self.trivia_builder
|
||||
.add_line_comment(self.token.start(), self.source.offset_of(pos), self.source.whole());
|
||||
.add_line_comment(self.token.start(), self.source.offset_of(pos), kind, self.source.whole());
|
||||
// Advance `pos` to after this char.
|
||||
// SAFETY: `0xE2` is always 1st byte of a 3-byte UTF-8 char,
|
||||
// so consuming 3 bytes will place `pos` on next UTF-8 char boundary.
|
||||
@@ -71,7 +71,7 @@ impl<'a, C: Config> Lexer<'a, C> {
|
||||
}
|
||||
},
|
||||
handle_eof: {
|
||||
self.trivia_builder.add_line_comment(self.token.start(), self.offset(), self.source.whole());
|
||||
self.trivia_builder.add_line_comment(self.token.start(), self.offset(), kind, self.source.whole());
|
||||
return Kind::Skip;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -114,8 +114,8 @@ impl<'a> TriviaBuilder<'a> {
|
||||
self.irregular_whitespaces.push(Span::new(start, end));
|
||||
}
|
||||
|
||||
pub fn add_line_comment(&mut self, start: u32, end: u32, source_text: &str) {
|
||||
self.add_comment(Comment::new(start, end, CommentKind::Line), source_text);
|
||||
pub fn add_line_comment(&mut self, start: u32, end: u32, kind: CommentKind, source_text: &str) {
|
||||
self.add_comment(Comment::new(start, end, kind), source_text);
|
||||
}
|
||||
|
||||
pub fn add_block_comment(
|
||||
@@ -666,6 +666,21 @@ token /* Trailing 1 */
|
||||
assert_eq!(comments, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn html_comment_content() {
|
||||
let allocator = Allocator::default();
|
||||
let source = "<!--a\n-->\n<!--";
|
||||
let ret = Parser::new(&allocator, source, SourceType::script()).parse();
|
||||
assert!(ret.diagnostics.is_empty());
|
||||
assert_eq!(ret.program.comments.len(), 3);
|
||||
let expected = [(Span::new(0, 5), "a"), (Span::new(6, 9), ""), (Span::new(10, 14), "")];
|
||||
for (comment, (span, content)) in ret.program.comments.iter().zip(expected) {
|
||||
assert!(comment.is_line());
|
||||
assert_eq!(comment.span, span);
|
||||
assert_eq!(comment.content_span().source_text(source), content);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn html_close_comments_after_irregular_line_terminators_are_leading() {
|
||||
for line_terminator in ['\u{2028}', '\u{2029}'] {
|
||||
|
||||
@@ -4330,6 +4330,10 @@ function deserializeCommentKind(pos) {
|
||||
return "Block";
|
||||
case 2:
|
||||
return "Block";
|
||||
case 3:
|
||||
return "Line";
|
||||
case 4:
|
||||
return "Line";
|
||||
default:
|
||||
throw Error(`Unexpected discriminant ${uint8[pos]} for CommentKind`);
|
||||
}
|
||||
@@ -4338,10 +4342,11 @@ function deserializeCommentKind(pos) {
|
||||
function deserializeComment(pos) {
|
||||
let type = deserializeCommentKind(pos + 12),
|
||||
start = deserializeI32(pos),
|
||||
end = deserializeI32(pos + 4);
|
||||
end = deserializeI32(pos + 4),
|
||||
kind = deserializeU8(pos + 12);
|
||||
return {
|
||||
type,
|
||||
value: sourceText.slice(start + 2, end - (type === "Line" ? 0 : 2)),
|
||||
value: sourceText.slice(start + (kind < 3 ? 2 : kind), end - (type === "Line" ? 0 : 2)),
|
||||
start,
|
||||
end,
|
||||
};
|
||||
|
||||
@@ -4864,6 +4864,10 @@ function deserializeCommentKind(pos) {
|
||||
return "Block";
|
||||
case 2:
|
||||
return "Block";
|
||||
case 3:
|
||||
return "Line";
|
||||
case 4:
|
||||
return "Line";
|
||||
default:
|
||||
throw Error(`Unexpected discriminant ${uint8[pos]} for CommentKind`);
|
||||
}
|
||||
@@ -4872,10 +4876,11 @@ function deserializeCommentKind(pos) {
|
||||
function deserializeComment(pos) {
|
||||
let type = deserializeCommentKind(pos + 12),
|
||||
start = deserializeI32(pos),
|
||||
end = deserializeI32(pos + 4);
|
||||
end = deserializeI32(pos + 4),
|
||||
kind = deserializeU8(pos + 12);
|
||||
return {
|
||||
type,
|
||||
value: sourceText.slice(start + 2, end - (type === "Line" ? 0 : 2)),
|
||||
value: sourceText.slice(start + (kind < 3 ? 2 : kind), end - (type === "Line" ? 0 : 2)),
|
||||
start,
|
||||
end,
|
||||
};
|
||||
|
||||
@@ -4866,6 +4866,10 @@ function deserializeCommentKind(pos) {
|
||||
return "Block";
|
||||
case 2:
|
||||
return "Block";
|
||||
case 3:
|
||||
return "Line";
|
||||
case 4:
|
||||
return "Line";
|
||||
default:
|
||||
throw Error(`Unexpected discriminant ${uint8[pos]} for CommentKind`);
|
||||
}
|
||||
@@ -4874,10 +4878,11 @@ function deserializeCommentKind(pos) {
|
||||
function deserializeComment(pos) {
|
||||
let type = deserializeCommentKind(pos + 12),
|
||||
start = deserializeI32(pos),
|
||||
end = deserializeI32(pos + 4);
|
||||
end = deserializeI32(pos + 4),
|
||||
kind = deserializeU8(pos + 12);
|
||||
return {
|
||||
type,
|
||||
value: sourceText.slice(start + 2, end - (type === "Line" ? 0 : 2)),
|
||||
value: sourceText.slice(start + (kind < 3 ? 2 : kind), end - (type === "Line" ? 0 : 2)),
|
||||
start,
|
||||
end,
|
||||
range: [start, end],
|
||||
|
||||
@@ -5399,6 +5399,10 @@ function deserializeCommentKind(pos) {
|
||||
return "Block";
|
||||
case 2:
|
||||
return "Block";
|
||||
case 3:
|
||||
return "Line";
|
||||
case 4:
|
||||
return "Line";
|
||||
default:
|
||||
throw Error(`Unexpected discriminant ${uint8[pos]} for CommentKind`);
|
||||
}
|
||||
@@ -5407,10 +5411,11 @@ function deserializeCommentKind(pos) {
|
||||
function deserializeComment(pos) {
|
||||
let type = deserializeCommentKind(pos + 12),
|
||||
start = deserializeI32(pos),
|
||||
end = deserializeI32(pos + 4);
|
||||
end = deserializeI32(pos + 4),
|
||||
kind = deserializeU8(pos + 12);
|
||||
return {
|
||||
type,
|
||||
value: sourceText.slice(start + 2, end - (type === "Line" ? 0 : 2)),
|
||||
value: sourceText.slice(start + (kind < 3 ? 2 : kind), end - (type === "Line" ? 0 : 2)),
|
||||
start,
|
||||
end,
|
||||
range: [start, end],
|
||||
|
||||
@@ -4632,6 +4632,10 @@ function deserializeCommentKind(pos) {
|
||||
return "Block";
|
||||
case 2:
|
||||
return "Block";
|
||||
case 3:
|
||||
return "Line";
|
||||
case 4:
|
||||
return "Line";
|
||||
default:
|
||||
throw Error(`Unexpected discriminant ${uint8[pos]} for CommentKind`);
|
||||
}
|
||||
@@ -4640,10 +4644,11 @@ function deserializeCommentKind(pos) {
|
||||
function deserializeComment(pos) {
|
||||
let type = deserializeCommentKind(pos + 12),
|
||||
start = deserializeI32(pos),
|
||||
end = deserializeI32(pos + 4);
|
||||
end = deserializeI32(pos + 4),
|
||||
kind = deserializeU8(pos + 12);
|
||||
return {
|
||||
type,
|
||||
value: sourceText.slice(start + 2, end - (type === "Line" ? 0 : 2)),
|
||||
value: sourceText.slice(start + (kind < 3 ? 2 : kind), end - (type === "Line" ? 0 : 2)),
|
||||
start,
|
||||
end,
|
||||
};
|
||||
|
||||
@@ -5196,6 +5196,10 @@ function deserializeCommentKind(pos) {
|
||||
return "Block";
|
||||
case 2:
|
||||
return "Block";
|
||||
case 3:
|
||||
return "Line";
|
||||
case 4:
|
||||
return "Line";
|
||||
default:
|
||||
throw Error(`Unexpected discriminant ${uint8[pos]} for CommentKind`);
|
||||
}
|
||||
@@ -5204,10 +5208,11 @@ function deserializeCommentKind(pos) {
|
||||
function deserializeComment(pos) {
|
||||
let type = deserializeCommentKind(pos + 12),
|
||||
start = deserializeI32(pos),
|
||||
end = deserializeI32(pos + 4);
|
||||
end = deserializeI32(pos + 4),
|
||||
kind = deserializeU8(pos + 12);
|
||||
return {
|
||||
type,
|
||||
value: sourceText.slice(start + 2, end - (type === "Line" ? 0 : 2)),
|
||||
value: sourceText.slice(start + (kind < 3 ? 2 : kind), end - (type === "Line" ? 0 : 2)),
|
||||
start,
|
||||
end,
|
||||
};
|
||||
|
||||
@@ -5195,6 +5195,10 @@ function deserializeCommentKind(pos) {
|
||||
return "Block";
|
||||
case 2:
|
||||
return "Block";
|
||||
case 3:
|
||||
return "Line";
|
||||
case 4:
|
||||
return "Line";
|
||||
default:
|
||||
throw Error(`Unexpected discriminant ${uint8[pos]} for CommentKind`);
|
||||
}
|
||||
@@ -5203,10 +5207,11 @@ function deserializeCommentKind(pos) {
|
||||
function deserializeComment(pos) {
|
||||
let type = deserializeCommentKind(pos + 12),
|
||||
start = deserializeI32(pos),
|
||||
end = deserializeI32(pos + 4);
|
||||
end = deserializeI32(pos + 4),
|
||||
kind = deserializeU8(pos + 12);
|
||||
return {
|
||||
type,
|
||||
value: sourceText.slice(start + 2, end - (type === "Line" ? 0 : 2)),
|
||||
value: sourceText.slice(start + (kind < 3 ? 2 : kind), end - (type === "Line" ? 0 : 2)),
|
||||
start,
|
||||
end,
|
||||
range: [start, end],
|
||||
|
||||
@@ -5758,6 +5758,10 @@ function deserializeCommentKind(pos) {
|
||||
return "Block";
|
||||
case 2:
|
||||
return "Block";
|
||||
case 3:
|
||||
return "Line";
|
||||
case 4:
|
||||
return "Line";
|
||||
default:
|
||||
throw Error(`Unexpected discriminant ${uint8[pos]} for CommentKind`);
|
||||
}
|
||||
@@ -5766,10 +5770,11 @@ function deserializeCommentKind(pos) {
|
||||
function deserializeComment(pos) {
|
||||
let type = deserializeCommentKind(pos + 12),
|
||||
start = deserializeI32(pos),
|
||||
end = deserializeI32(pos + 4);
|
||||
end = deserializeI32(pos + 4),
|
||||
kind = deserializeU8(pos + 12);
|
||||
return {
|
||||
type,
|
||||
value: sourceText.slice(start + 2, end - (type === "Line" ? 0 : 2)),
|
||||
value: sourceText.slice(start + (kind < 3 ? 2 : kind), end - (type === "Line" ? 0 : 2)),
|
||||
start,
|
||||
end,
|
||||
range: [start, end],
|
||||
|
||||
@@ -12022,6 +12022,10 @@ function constructCommentKind(pos, ast) {
|
||||
return "Block";
|
||||
case 2:
|
||||
return "Block";
|
||||
case 3:
|
||||
return "Line";
|
||||
case 4:
|
||||
return "Line";
|
||||
default:
|
||||
throw new Error(`Unexpected discriminant ${ast.buffer[pos]} for CommentKind`);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user