Bug 1066331 - Fix for multi-line template strings reflecting incorrect debugger line numbers r=jorendorff
authorGuptha Rajagopal <gupta.rajagopal@gmail.com>
Wed, 08 Oct 2014 21:23:00 +0200
changeset 209539 a24b22bc3fe5672634b841e7f0f08800d7d7a4f4
parent 209538 ccde95bd3c7e76a10ce5f192bbead2646463a847
child 209540 963d24ebf03b282bbf7b7fa0eabf20f71aefee8b
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersjorendorff
bugs1066331
milestone35.0a1
Bug 1066331 - Fix for multi-line template strings reflecting incorrect debugger line numbers r=jorendorff
js/src/frontend/TokenStream.cpp
js/src/tests/ecma_6/TemplateStrings/debugLineNumber.js
js/src/tests/js1_8_5/extensions/reflect-parse.js
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -1732,16 +1732,18 @@ bool TokenStream::getStringOrTemplateTok
                     reportError(JSMSG_UNTERMINATED_STRING);
                     return false;
                 }
                 if (c == '\r') {
                     c = '\n';
                     if (userbuf.peekRawChar() == '\n')
                         skipChars(1);
                 }
+                updateLineInfoForEOL();
+                updateFlagsForEOL();
             } else if (qc == '`' && c == '$') {
                 if ((nc = getCharIgnoreEOL()) == '{')
                     break;
                 ungetCharIgnoreEOL(nc);
             }
         }
         if (!tokenbuf.append(c))
             return false;
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TemplateStrings/debugLineNumber.js
@@ -0,0 +1,50 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// TEST BEGIN
+
+// verify debugger line numbers are accurate
+try {
+    `
+    a
+    b
+    c
+    `;
+    throw Error("error");
+} catch (e) {
+    assertEq(e.lineNumber, 14);
+}
+
+try {
+    function tagThatThrows(...args) { throw new Error(); }
+
+    tagThatThrows`
+        multi-line
+        template
+        string`;
+} catch (e) {
+    var stackLines = e.stack.split('\n');
+    var firstLine = stackLines[0].split(':');
+    var secondLine = stackLines[1].split(':');
+    var firstLineSize = firstLine.length;
+    var secondLineSize = secondLine.length;
+    assertEq(firstLine[firstLineSize - 2], "20");
+    assertEq(firstLine[firstLineSize - 1], "45");
+    assertEq(secondLine[secondLineSize - 2], "22");
+    assertEq(secondLine[secondLineSize - 1], "5");
+}
+
+try {
+    ` multi-line
+        template
+        with
+        ${substitutionThatThrows()}`
+
+} catch (e) {
+    assertEq(e.lineNumber, 42);
+}
+
+
+
+reportCompare(0, 0, "ok");
--- a/js/src/tests/js1_8_5/extensions/reflect-parse.js
+++ b/js/src/tests/js1_8_5/extensions/reflect-parse.js
@@ -464,16 +464,27 @@ assertExpr("func`hey${\"4\"}there${5}`",
                   lit("4"), lit(5))));
 assertExpr("func`hey\r\n`", taggedTemplate(ident("func"), template(["hey\n"], ["hey\n"])));
 assertExpr("func`hey${4}``${5}there``mine`",
            taggedTemplate(taggedTemplate(taggedTemplate(
                ident("func"), template(["hey", ""], ["hey", ""], lit(4))),
                template(["", "there"], ["", "there"], lit(5))),
                template(["mine"], ["mine"])));
 
+// multi-line template string - line numbers
+var node = Reflect.parse("`\n\n   ${2}\n\n\n`");
+Pattern({loc:{start:{line:1, column:0}, end:{line:6, column:1}, source:null}, type:"Program",
+body:[{loc:{start:{line:1, column:0}, end:{line:6, column:1}, source:null},
+type:"ExpressionStatement", expression:{loc:{start:{line:1, column:0}, end:{line:6, column:1},
+source:null}, type:"TemplateLiteral", elements:[{loc:{start:{line:1, column:0}, end:{line:3,
+column:5}, source:null}, type:"Literal", value:"\n\n   "}, {loc:{start:{line:3, column:5},
+end:{line:3, column:6}, source:null}, type:"Literal", value:2}, {loc:{start:{line:3, column:6},
+end:{line:6, column:1}, source:null}, type:"Literal", value:"\n\n\n"}]}}]}).match(node);
+
+
 assertStringExpr("\"hey there\"", literal("hey there"));
 
 assertStmt("foo: for(;;) break foo;", labStmt(ident("foo"), forStmt(null, null, null, breakStmt(ident("foo")))));
 assertStmt("foo: for(;;) continue foo;", labStmt(ident("foo"), forStmt(null, null, null, continueStmt(ident("foo")))));
 assertStmt("with (obj) { }", withStmt(ident("obj"), blockStmt([])));
 assertStmt("with (obj) { obj; }", withStmt(ident("obj"), blockStmt([exprStmt(ident("obj"))])));
 assertStmt("while (foo) { }", whileStmt(ident("foo"), blockStmt([])));
 assertStmt("while (foo) { foo; }", whileStmt(ident("foo"), blockStmt([exprStmt(ident("foo"))])));