8020437: Wrong handling of line numbers with multiline string literals
Reviewed-by: attila, lagergren
--- a/nashorn/src/jdk/nashorn/internal/parser/Lexer.java Thu Jul 11 22:01:55 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/parser/Lexer.java Fri Jul 12 15:01:33 2013 +0530
@@ -546,14 +546,27 @@
}
/**
+ * interface to receive line information for multi-line literals.
+ */
+ protected interface LineInfoReceiver {
+ /**
+ * Receives line information
+ * @param line last line number
+ * @param linePosition position of last line
+ */
+ public void lineInfo(int line, int linePosition);
+ }
+
+ /**
* Check whether the given token represents the beginning of a literal. If so scan
* the literal and return <tt>true</tt>, otherwise return false.
*
* @param token the token.
* @param startTokenType the token type.
+ * @parasm lir LineInfoReceiver that receives line info for multi-line string literals.
* @return True if a literal beginning with startToken was found and scanned.
*/
- protected boolean scanLiteral(final long token, final TokenType startTokenType) {
+ protected boolean scanLiteral(final long token, final TokenType startTokenType, final LineInfoReceiver lir) {
// Check if it can be a literal.
if (!canStartLiteral(startTokenType)) {
return false;
@@ -569,7 +582,7 @@
return scanRegEx();
} else if (ch0 == '<') {
if (ch1 == '<') {
- return scanHereString();
+ return scanHereString(lir);
} else if (Character.isJavaIdentifierStart(ch1)) {
return scanXMLLiteral();
}
@@ -1417,7 +1430,7 @@
*
* @return TRUE if is a here string.
*/
- private boolean scanHereString() {
+ private boolean scanHereString(final LineInfoReceiver lir) {
assert ch0 == '<' && ch1 == '<';
if (scripting) {
// Record beginning of here string.
@@ -1446,7 +1459,13 @@
// Record rest of line.
final State restState = saveState();
+ // keep line number updated
+ int lastLine = line;
+ int lastLinePosition = linePosition;
+
skipLine(false);
+ lastLine++;
+ lastLinePosition = position;
restState.setLimit(position);
// Record beginning of string.
@@ -1463,9 +1482,14 @@
}
skipLine(false);
+ lastLine++;
+ lastLinePosition = position;
stringEnd = position;
}
+ // notify last line information
+ lir.lineInfo(lastLine, lastLinePosition);
+
// Record end of string.
stringState.setLimit(stringEnd);
--- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java Thu Jul 11 22:01:55 2013 +0200
+++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java Fri Jul 12 15:01:33 2013 +0530
@@ -130,6 +130,9 @@
private static final DebugLogger LOG = new DebugLogger("parser");
+ /** to receive line information from Lexer when scanning multine literals. */
+ protected final Lexer.LineInfoReceiver lineInfoReceiver;
+
/**
* Constructor
*
@@ -154,6 +157,19 @@
this.env = env;
this.namespace = new Namespace(env.getNamespace());
this.scripting = env._scripting;
+ if (this.scripting) {
+ this.lineInfoReceiver = new Lexer.LineInfoReceiver() {
+ @Override
+ public void lineInfo(final int line, final int linePosition) {
+ // update the parser maintained line information
+ Parser.this.line = line;
+ Parser.this.linePosition = linePosition;
+ }
+ };
+ } else {
+ // non-scripting mode script can't have multi-line literals
+ this.lineInfoReceiver = null;
+ }
}
/**
@@ -1802,7 +1818,7 @@
default:
// In this context some operator tokens mark the start of a literal.
- if (lexer.scanLiteral(primaryToken, type)) {
+ if (lexer.scanLiteral(primaryToken, type, lineInfoReceiver)) {
next();
return getLiteral();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8020437.js Fri Jul 12 15:01:33 2013 +0530
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020437: Wrong handling of line numbers with multiline string literals
+ *
+ * @test
+ * @option -scripting
+ * @run
+ */
+
+print({
+ text: <<EOF
+This is a multiple line
+text inside a sting literal.
+Run this with -scripting option.
+EOF}); f();
+
+function f() {
+ try {
+ func();
+ } catch (e) {
+ print(e.stack.replace(/\\/g, '/'));
+ }
+}
+
+function func() {
+ throw new Error();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8020437.js.EXPECTED Fri Jul 12 15:01:33 2013 +0530
@@ -0,0 +1,5 @@
+[object Object]
+Error
+ at func (test/script/basic/JDK-8020437.js:48)
+ at f (test/script/basic/JDK-8020437.js:41)
+ at <program> (test/script/basic/JDK-8020437.js:37)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/error/JDK-8020437-2.js Fri Jul 12 15:01:33 2013 +0530
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020437: Wrong handling of line numbers with multiline string literals
+ *
+ * @test/compile-error
+ * @option -scripting
+ */
+
+print({
+ text: <<EOF
+This is a multiple line
+text inside a sting literal.
+Run this with -scripting option.
+EOF}); var x++; // syntax error in same line
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/error/JDK-8020437-2.js.EXPECTED Fri Jul 12 15:01:33 2013 +0530
@@ -0,0 +1,3 @@
+test/script/error/JDK-8020437-2.js:36:12 Expected ; but found ++
+EOF}); var x++; // syntax error in same line
+ ^
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/error/JDK-8020437.js Fri Jul 12 15:01:33 2013 +0530
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8020437: Wrong handling of line numbers with multiline string literals
+ *
+ * @test/compile-error
+ * @option -scripting
+ */
+
+print({
+ text: <<EOF
+This is a multiple line
+text inside a sting literal.
+Run this with -scripting option.
+EOF); // missing "}" to end object literal
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/error/JDK-8020437.js.EXPECTED Fri Jul 12 15:01:33 2013 +0530
@@ -0,0 +1,3 @@
+test/script/error/JDK-8020437.js:36:3 Expected comma but found )
+EOF); // missing "}" to end object literal
+ ^