# HG changeset patch # User jlahoda # Date 1393615524 -3600 # Node ID a58476887b3d019360eeb8413c9d8eab2a28e65e # Parent 00a059740d873ab26317d47447df4a7a22ff4001 8031383: Error recovery in JavacParser could be improved Summary: Improving error recovery in JavacParser by avoiding artificial nextToken in JavacParser.reportSyntaxError. Reviewed-by: jjg, jfranck Contributed-by: dusan.balek@oracle.com, jan.lahoda@oracle.com diff -r 00a059740d87 -r a58476887b3d langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Fri Feb 28 20:25:24 2014 +0100 @@ -431,7 +431,9 @@ return toP(err); } + private static final int RECOVERY_THRESHOLD = 50; private int errorPos = Position.NOPOS; + private int count = 0; /** * Report a syntax using the given the position parameter and arguments, @@ -456,9 +458,13 @@ } } S.errPos(pos); - if (token.pos == errorPos) - nextToken(); // guarantee progress - errorPos = token.pos; + if (token.pos == errorPos) { + //check for a possible infinite loop in parsing: + Assert.check(count++ < RECOVERY_THRESHOLD); + } else { + count = 0; + errorPos = token.pos; + } } @@ -2288,14 +2294,19 @@ @SuppressWarnings("fallthrough") List blockStatements() { //todo: skip to anchor on error(?) + int lastErrPos = -1; ListBuffer stats = new ListBuffer<>(); while (true) { List stat = blockStatement(); if (stat.isEmpty()) { return stats.toList(); } else { + // error recovery + if (token.pos == lastErrPos) + return stats.toList(); if (token.pos <= endPosTable.errorEndPos) { skip(false, true, true, true); + lastErrPos = token.pos; } stats.addAll(stat); } @@ -3424,9 +3435,12 @@ token.kind == INTERFACE || allowEnums && token.kind == ENUM) { return List.of(classOrInterfaceOrEnumDeclaration(mods, dc)); - } else if (token.kind == LBRACE && !isInterface && + } else if (token.kind == LBRACE && (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 && mods.annotations.isEmpty()) { + if (isInterface) { + error(token.pos, "initializer.not.allowed"); + } return List.of(block(pos, mods.flags)); } else { pos = token.pos; diff -r 00a059740d87 -r a58476887b3d langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Feb 28 20:25:24 2014 +0100 @@ -1039,6 +1039,9 @@ compiler.err.initializer.must.be.able.to.complete.normally=\ initializer must be able to complete normally +compiler.err.initializer.not.allowed=\ + initializers not allowed in interfaces + # 0: type compiler.err.unreported.exception.need.to.catch.or.throw=\ unreported exception {0}; must be caught or declared to be thrown diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/TryWithResources/BadTwrSyntax.out --- a/langtools/test/tools/javac/TryWithResources/BadTwrSyntax.out Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/TryWithResources/BadTwrSyntax.out Fri Feb 28 20:25:24 2014 +0100 @@ -1,7 +1,2 @@ BadTwrSyntax.java:14:43: compiler.err.illegal.start.of.type -BadTwrSyntax.java:14:44: compiler.err.expected: = -BadTwrSyntax.java:14:45: compiler.err.expected: ')' -BadTwrSyntax.java:14:47: compiler.err.expected: '{' -BadTwrSyntax.java:15:19: compiler.err.illegal.start.of.expr -BadTwrSyntax.java:15:23: compiler.err.expected: ';' -6 errors +1 error diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.out --- a/langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.out Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.out Fri Feb 28 20:25:24 2014 +0100 @@ -1,8 +1,2 @@ T6967002.java:33:22: compiler.err.expected: ')' -T6967002.java:33:25: compiler.err.illegal.start.of.expr -T6967002.java:33:28: compiler.err.illegal.start.of.expr -T6967002.java:33:29: compiler.err.illegal.start.of.expr -T6967002.java:33:27: compiler.err.not.stmt -T6967002.java:33:30: compiler.err.expected: ';' -T6967002.java:35:2: compiler.err.premature.eof -7 errors +1 error diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.out --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.out Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedPackage2.out Fri Feb 28 20:25:24 2014 +0100 @@ -1,3 +1,3 @@ AnnotatedPackage2.java:9:8: compiler.err.expected: token.identifier -AnnotatedPackage2.java:9:10: compiler.err.expected3: class, interface, enum +AnnotatedPackage2.java:9:12: compiler.err.expected3: class, interface, enum 2 errors diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.out --- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.out Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/OldArray.out Fri Feb 28 20:25:24 2014 +0100 @@ -1,10 +1,4 @@ OldArray.java:12:11: compiler.err.expected: ']' OldArray.java:12:13: compiler.err.expected: token.identifier -OldArray.java:12:14: compiler.err.expected: ';' -OldArray.java:12:17: compiler.err.illegal.start.of.type -OldArray.java:12:18: compiler.err.expected: token.identifier -OldArray.java:12:19: compiler.err.expected: ';' -OldArray.java:12:22: compiler.err.illegal.start.of.type -OldArray.java:12:28: compiler.err.expected: token.identifier -OldArray.java:13:1: compiler.err.expected3: class, interface, enum -9 errors +OldArray.java:12:16: compiler.err.invalid.meth.decl.ret.type.req +3 errors diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/diags/examples/ArrayAndReceiver.java --- a/langtools/test/tools/javac/diags/examples/ArrayAndReceiver.java Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/diags/examples/ArrayAndReceiver.java Fri Feb 28 20:25:24 2014 +0100 @@ -22,9 +22,6 @@ */ // key: compiler.err.array.and.receiver -// key: compiler.err.expected -// key: compiler.err.expected3 -// key: compiler.err.illegal.start.of.type class ArrayAndReceiver { void m(ArrayAndReceiver this[]) { } diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/diags/examples/EmptyCharLiteral.java --- a/langtools/test/tools/javac/diags/examples/EmptyCharLiteral.java Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/diags/examples/EmptyCharLiteral.java Fri Feb 28 20:25:24 2014 +0100 @@ -23,7 +23,6 @@ // key: compiler.err.empty.char.lit // key: compiler.err.unclosed.char.lit -// key: compiler.err.premature.eof class X { char c = ''; diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/diags/examples/IllegalDot.java --- a/langtools/test/tools/javac/diags/examples/IllegalDot.java Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/diags/examples/IllegalDot.java Fri Feb 28 20:25:24 2014 +0100 @@ -22,8 +22,6 @@ */ // key: compiler.err.illegal.dot -// key: compiler.err.expected -// key: compiler.err.illegal.start.of.type class X { void m(Object.. args) { } diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/diags/examples/IllegalStartOfType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/IllegalStartOfType.java Fri Feb 28 20:25:24 2014 +0100 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2014, 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. + */ + +// key: compiler.err.illegal.start.of.type + +class IllegalStartOfType { + public void test(int i,) { } +} diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/diags/examples/InitializerNotAllowed.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/InitializerNotAllowed.java Fri Feb 28 20:25:24 2014 +0100 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2014, 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. + */ + +// key: compiler.err.initializer.not.allowed + +interface InitializerNotAllowed { + { + System.out.println(); + } +} diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/diags/examples/InvalidBinaryNumber.java --- a/langtools/test/tools/javac/diags/examples/InvalidBinaryNumber.java Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/diags/examples/InvalidBinaryNumber.java Fri Feb 28 20:25:24 2014 +0100 @@ -22,9 +22,6 @@ */ // key: compiler.err.invalid.binary.number -// key: compiler.err.illegal.start.of.type -// key: compiler.err.expected -// key: compiler.err.premature.eof class InvalidBinaryNumber { int i = 0b201000010; diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/diags/examples/VarargsMustBeLast.java --- a/langtools/test/tools/javac/diags/examples/VarargsMustBeLast.java Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/diags/examples/VarargsMustBeLast.java Fri Feb 28 20:25:24 2014 +0100 @@ -23,6 +23,6 @@ // key: compiler.err.varargs.must.be.last -class VarargMustBeFinal { +class VarargMustBeLast { public void invalidVarArg(String... invalidVarArg, String extra) { } } diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/enum/EnumMembersOrder.out --- a/langtools/test/tools/javac/enum/EnumMembersOrder.out Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/enum/EnumMembersOrder.out Fri Feb 28 20:25:24 2014 +0100 @@ -1,6 +1,6 @@ EnumMembersOrder.java:11:16: compiler.err.expected: ')' EnumMembersOrder.java:11:17: compiler.err.expected3: ',', '}', ';' -EnumMembersOrder.java:11:19: compiler.err.expected: '}' +EnumMembersOrder.java:11:18: compiler.err.expected: '}' EnumMembersOrder.java:11:31: compiler.err.expected3: class, interface, enum EnumMembersOrder.java:17:13: compiler.err.expected3: class, interface, enum EnumMembersOrder.java:19:1: compiler.err.expected3: class, interface, enum diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/parser/7157165/T7157165.out --- a/langtools/test/tools/javac/parser/7157165/T7157165.out Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/parser/7157165/T7157165.out Fri Feb 28 20:25:24 2014 +0100 @@ -1,4 +1,4 @@ T7157165.java:11:20: compiler.err.expected: > -T7157165.java:11:21: compiler.err.expected: ';' -T7157165.java:11:22: compiler.err.illegal.start.of.type +T7157165.java:11:22: compiler.err.expected: token.identifier +T7157165.java:11:28: compiler.err.expected: token.identifier 3 errors diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/parser/ErroneousParameters.java --- a/langtools/test/tools/javac/parser/ErroneousParameters.java Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/parser/ErroneousParameters.java Fri Feb 28 20:25:24 2014 +0100 @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8030091 + * @bug 8030091 8031383 * @summary Producing reasonable errors for unexpected tokens in method parameters * @compile/fail/ref=ErroneousParameters.out -XDrawDiagnostics ErroneousParameters.java */ diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/parser/ErroneousParameters.out --- a/langtools/test/tools/javac/parser/ErroneousParameters.out Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/parser/ErroneousParameters.out Fri Feb 28 20:25:24 2014 +0100 @@ -1,14 +1,6 @@ ErroneousParameters.java:10:36: compiler.err.varargs.must.be.last ErroneousParameters.java:11:39: compiler.err.expected3: ',', ')', '[' -ErroneousParameters.java:11:42: compiler.err.illegal.start.of.type -ErroneousParameters.java:11:43: compiler.err.expected: token.identifier -ErroneousParameters.java:11:45: compiler.err.expected: ';' ErroneousParameters.java:12:40: compiler.err.illegal.start.of.type -ErroneousParameters.java:12:41: compiler.err.expected3: ',', ')', '[' -ErroneousParameters.java:12:43: compiler.err.expected: ';' ErroneousParameters.java:13:41: compiler.err.expected: ']' ErroneousParameters.java:14:38: compiler.err.expected3: ',', ')', '[' -ErroneousParameters.java:14:39: compiler.err.illegal.start.of.type -ErroneousParameters.java:14:40: compiler.err.expected: token.identifier -ErroneousParameters.java:14:42: compiler.err.expected: ';' -13 errors +5 errors diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/parser/MissingClosingBrace.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/parser/MissingClosingBrace.java Fri Feb 28 20:25:24 2014 +0100 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8031383 + * @summary Verify that the parser handles a missing closing brace of a block gracefully. + * @compile/fail/ref=MissingClosingBrace.out -XDrawDiagnostics MissingClosingBrace.java + */ + +public class MissingClosingBrace { + private void test(int i) { + if (i > 0) { + + private int i; +} diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/parser/MissingClosingBrace.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/parser/MissingClosingBrace.out Fri Feb 28 20:25:24 2014 +0100 @@ -0,0 +1,2 @@ +MissingClosingBrace.java:12:5: compiler.err.illegal.start.of.expr +1 error diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/parser/SingleCommaAnnotationValueFail.out --- a/langtools/test/tools/javac/parser/SingleCommaAnnotationValueFail.out Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/parser/SingleCommaAnnotationValueFail.out Fri Feb 28 20:25:24 2014 +0100 @@ -1,6 +1,3 @@ SingleCommaAnnotationValueFail.java:34:12: compiler.err.expected: '}' -SingleCommaAnnotationValueFail.java:34:13: compiler.err.illegal.start.of.type -SingleCommaAnnotationValueFail.java:34:14: compiler.err.expected: token.identifier -SingleCommaAnnotationValueFail.java:34:15: compiler.err.expected: ';' -SingleCommaAnnotationValueFail.java:34:21: compiler.err.invalid.meth.decl.ret.type.req -5 errors +SingleCommaAnnotationValueFail.java:34:14: compiler.err.expected3: class, interface, enum +2 errors diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/parser/T4881269.out --- a/langtools/test/tools/javac/parser/T4881269.out Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/parser/T4881269.out Fri Feb 28 20:25:24 2014 +0100 @@ -2,8 +2,4 @@ T4881269.java:33:27: compiler.err.illegal.dot T4881269.java:33:22: compiler.err.not.stmt T4881269.java:34:19: compiler.err.illegal.dot -T4881269.java:34:20: compiler.err.expected: ';' -T4881269.java:34:22: compiler.err.illegal.start.of.type -T4881269.java:34:23: compiler.err.expected: token.identifier -T4881269.java:34:25: compiler.err.expected: ';' -8 errors +4 errors diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/processing/TestWarnErrorCount.java --- a/langtools/test/tools/javac/processing/TestWarnErrorCount.java Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/processing/TestWarnErrorCount.java Fri Feb 28 20:25:24 2014 +0100 @@ -214,7 +214,7 @@ javaWarnsExpected = 0; break; case JAVA: - errsExpected = 2; + errsExpected = 1; msgrWarnsExpected = mwk.count(1, ERROR_ROUND + 1); javaWarnsExpected = 0; break; diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/processing/errors/TestParseErrors/TestParseErrors.out --- a/langtools/test/tools/javac/processing/errors/TestParseErrors/TestParseErrors.out Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/processing/errors/TestParseErrors/TestParseErrors.out Fri Feb 28 20:25:24 2014 +0100 @@ -1,8 +1,3 @@ ParseErrors.java:37:37: compiler.err.expected: token.identifier ParseErrors.java:38:1: compiler.err.illegal.start.of.type -ParseErrors.java:38:2: compiler.err.expected3: ',', ')', '[' -ParseErrors.java:40:6: compiler.err.expected: ';' -ParseErrors.java:40:20: compiler.err.illegal.start.of.type -ParseErrors.java:41:5: compiler.err.expected: '(' -ParseErrors.java:41:8: compiler.err.expected: token.identifier -7 errors +2 errors diff -r 00a059740d87 -r a58476887b3d langtools/test/tools/javac/quid/T6999438.out --- a/langtools/test/tools/javac/quid/T6999438.out Fri Feb 28 18:27:14 2014 +0000 +++ b/langtools/test/tools/javac/quid/T6999438.out Fri Feb 28 20:25:24 2014 +0100 @@ -1,6 +1,2 @@ T6999438.java:8:9: compiler.err.illegal.char: # -T6999438.java:8:10: compiler.err.illegal.start.of.type -T6999438.java:8:25: compiler.err.expected: token.identifier -T6999438.java:8:26: compiler.err.expected: ';' -T6999438.java:9:2: compiler.err.premature.eof -5 errors +1 error