diff --git a/nashorn/src/jdk/nashorn/internal/parser/Lexer.java b/nashorn/src/jdk/nashorn/internal/parser/Lexer.java
index ecf67962015..adb1445c9a4 100644
--- a/nashorn/src/jdk/nashorn/internal/parser/Lexer.java
+++ b/nashorn/src/jdk/nashorn/internal/parser/Lexer.java
@@ -545,15 +545,28 @@ public class Lexer extends Scanner {
return token.startsWith('/') || ((scripting || XML_LITERALS) && token.startsWith('<'));
}
+ /**
+ * 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 true, 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 @@ public class Lexer extends Scanner {
return scanRegEx();
} else if (ch0 == '<') {
if (ch1 == '<') {
- return scanHereString();
+ return scanHereString(lir);
} else if (Character.isJavaIdentifierStart(ch1)) {
return scanXMLLiteral();
}
@@ -1417,7 +1430,7 @@ public class Lexer extends Scanner {
*
* @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 @@ public class Lexer extends Scanner {
// 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 @@ public class Lexer extends Scanner {
}
skipLine(false);
+ lastLine++;
+ lastLinePosition = position;
stringEnd = position;
}
+ // notify last line information
+ lir.lineInfo(lastLine, lastLinePosition);
+
// Record end of string.
stringState.setLimit(stringEnd);
diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java
index c7f437cd8bb..b19f62d0a8a 100644
--- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java
+++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java
@@ -130,6 +130,9 @@ public class Parser extends AbstractParser {
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 @@ public class Parser extends AbstractParser {
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 @@ loop:
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();
}
diff --git a/nashorn/test/script/basic/JDK-8020437.js b/nashorn/test/script/basic/JDK-8020437.js
new file mode 100644
index 00000000000..d758355c909
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8020437.js
@@ -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: < (test/script/basic/JDK-8020437.js:37)
diff --git a/nashorn/test/script/error/JDK-8020437-2.js b/nashorn/test/script/error/JDK-8020437-2.js
new file mode 100644
index 00000000000..dcd1e173d36
--- /dev/null
+++ b/nashorn/test/script/error/JDK-8020437-2.js
@@ -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: <