8020437: Wrong handling of line numbers with multiline string literals

Reviewed-by: attila, lagergren
This commit is contained in:
Athijegannathan Sundararajan 2013-07-12 15:01:33 +05:30
parent 8603660852
commit 4972fea316
8 changed files with 176 additions and 4 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,3 @@
test/script/error/JDK-8020437-2.js:36:12 Expected ; but found ++
EOF}); var x++; // syntax error in same line
^

View File

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

View File

@ -0,0 +1,3 @@
test/script/error/JDK-8020437.js:36:3 Expected comma but found )
EOF); // missing "}" to end object literal
^