Forráskód Böngészése

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.
Linus Groh 4 éve
szülő
commit
69845ae460

+ 16 - 5
Libraries/LibJS/Lexer.cpp

@@ -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();

+ 1 - 1
Libraries/LibJS/Lexer.h

@@ -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;

+ 10 - 6
Libraries/LibJS/Tests/comments-basic.js

@@ -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", () => {