LibJS: "-->" preceded by token on same line isn't start of HTML-like comment

B.1.3 HTML-like Comments

The syntax and semantics of 11.4 is extended as follows except that this
extension is not allowed when parsing source code using the goal symbol
Module:

Syntax (only relevant part included)

    SingleLineHTMLCloseComment ::
        LineTerminatorSequence HTMLCloseComment

    HTMLCloseComment ::
        WhiteSpaceSequence[opt] SingleLineDelimitedCommentSequence[opt] --> SingleLineCommentChars[opt]

Fixes #3810.
This commit is contained in:
Linus Groh 2020-10-29 17:55:24 +00:00 committed by Andreas Kling
parent a10d09faba
commit 69845ae460
Notes: sideshowbarker 2024-07-19 01:39:12 +09:00
3 changed files with 27 additions and 12 deletions

View file

@ -321,9 +321,14 @@ bool Lexer::is_identifier_middle() const
return is_identifier_start() || isdigit(m_current_char);
}
bool Lexer::is_line_comment_start() const
bool Lexer::is_line_comment_start(bool line_has_token_yet) const
{
return match('/', '/') || match('<', '!', '-', '-') || match('-', '-', '>');
return match('/', '/')
|| match('<', '!', '-', '-')
// "-->" is considered a line comment start if the current line is only whitespace and/or
// other block comment(s); or in other words: the current line does not have a token or
// ongoing line comment yet
|| (match('-', '-', '>') && !line_has_token_yet);
}
bool Lexer::is_block_comment_start() const
@ -362,16 +367,22 @@ Token Lexer::next()
{
size_t trivia_start = m_position;
auto in_template = !m_template_states.is_empty();
bool line_has_token_yet = m_line_column > 1;
bool unterminated_comment = false;
if (!in_template || m_template_states.last().in_expr) {
// consume whitespace and comments
while (true) {
if (isspace(m_current_char) || is_line_terminator()) {
if (is_line_terminator()) {
line_has_token_yet = false;
do {
consume();
} while (isspace(m_current_char) || is_line_terminator());
} else if (is_line_comment_start()) {
} while (is_line_terminator());
} else if (isspace(m_current_char)) {
do {
consume();
} while (isspace(m_current_char));
} else if (is_line_comment_start(line_has_token_yet)) {
consume();
do {
consume();

View file

@ -50,7 +50,7 @@ private:
bool is_line_terminator() const;
bool is_identifier_start() const;
bool is_identifier_middle() const;
bool is_line_comment_start() const;
bool is_line_comment_start(bool line_has_token_yet) const;
bool is_block_comment_start() const;
bool is_block_comment_end() const;
bool is_numeric_literal_start() const;

View file

@ -1,25 +1,29 @@
test("regular comments", () => {
const source = `var i = 0;
const source = `
var i = 0;
// i++;
/* i++; */
/*
i++;
*/
/**/ i++;
return i;`;
expect(source).toEvalTo(0);
expect(source).toEvalTo(1);
});
test("html comments", () => {
const source = `var i = 0;
const source = `
var i = 0;
var j = 0;
<!-- i++; --> i++;
<!-- i++;
i++;
--> i++;
/**/ --> i++;
j --> i++;
return i;`;
expect(source).toEvalTo(1);
expect(source).toEvalTo(2);
});
test("unterminated multi-line comment", () => {