diff options
| author | Srikanth | 2012-06-20 11:54:28 +0000 |
|---|---|---|
| committer | Srikanth | 2012-06-20 11:54:28 +0000 |
| commit | 6a1671aa7ea88fc01c83297c32d40152115e2623 (patch) | |
| tree | b4a877227248bb52a705f748e9991c7fcd8e170b | |
| parent | 32f37f4b1b4681f8d4c2ce5fe64581861184d0f5 (diff) | |
| download | eclipse.jdt.core-6a1671aa7ea88fc01c83297c32d40152115e2623.tar.gz eclipse.jdt.core-6a1671aa7ea88fc01c83297c32d40152115e2623.tar.xz eclipse.jdt.core-6a1671aa7ea88fc01c83297c32d40152115e2623.zip | |
Fixed bug 383046: [1.8][compiler] Error getting reported on the
lambda expression if there is a subsequent parse error
4 files changed, 58 insertions, 3 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsNegativeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsNegativeTest.java index fdd1a59e58..82cc7e5ecf 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsNegativeTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsNegativeTest.java @@ -105,6 +105,26 @@ public void test003() { "Type mismatch: cannot convert from I to int\n" + "----------\n"); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=383046, syntax error reported incorrectly on syntactically valid lambda expression +public void test004() { + this.runNegativeTest( + new String[] { + "X.java", + "interface IX {\n" + + " public void foo();\n" + + "}\n" + + "public class X {\n" + + " IX i = () -> 42;\n" + + " int\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in X.java (at line 6)\n" + + " int\n" + + " ^^^\n" + + "Syntax error on token \"int\", delete this token\n" + + "----------\n"); +} public static Class testClass() { return LambdaExpressionsNegativeTest.class; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java index 8c09fafe1e..8fe5d13129 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java @@ -208,7 +208,7 @@ public class RecoveryScanner extends Scanner { this.data.removedTokenUsed[i] = true; this.currentPosition = this.data.removedTokensEnd[i] + 1; this.precededByRemoved = false; - return getNextToken(); + return getNextToken0(); } } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java index dd76a051c2..cddee87ae5 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java @@ -192,6 +192,7 @@ public class Scanner implements TerminalTokens { private int nextToken = TokenNameNotAToken; // allows for one token push back, only the most recent token can be reliably ungotten. private final boolean scanningJava8Plus; public boolean shouldDisambiguate; // feedback from parser about need to disambiguate -- to lookahead only when absolutely necessary. + public boolean disambiguatedAlready; public static final int RoundBracket = 0; public static final int SquareBracket = 1; @@ -1143,15 +1144,21 @@ public int getNextToken() throws InvalidInputException { } else { token = getNextToken0(); } + if (this.disambiguatedAlready) { + this.disambiguatedAlready = false; + return token; + } if (this.scanningJava8Plus && this.shouldDisambiguate) { if (token == TokenNameLPAREN) { if(atLambdaParameterList()) { this.nextToken = token; + this.disambiguatedAlready = true; return TokenNameBeginLambda; } } else if (token == TokenNameLESS) { if (atReferenceExpression()) { this.nextToken = token; + this.disambiguatedAlready = true; return TokenNameBeginTypeArguments; } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java index a25da20963..95c03fa355 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java @@ -1,9 +1,13 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -11,6 +15,7 @@ package org.eclipse.jdt.internal.compiler.parser.diagnose; import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.parser.Parser; import org.eclipse.jdt.internal.compiler.parser.ParserBasicInformation; @@ -193,6 +198,9 @@ public class DiagnoseParser implements ParserBasicInformation, TerminalTokens { oldRecord = this.recoveryScanner.record; this.recoveryScanner.record = record; } + if (this.options.sourceLevel >= ClassFileConstants.JDK1_8) { + this.parser.scanner.shouldDisambiguate = true; + } try { this.lexStream.reset(); @@ -421,6 +429,7 @@ public class DiagnoseParser implements ParserBasicInformation, TerminalTokens { if(this.recoveryScanner != null) { this.recoveryScanner.record = oldRecord; } + this.parser.scanner.shouldDisambiguate = false; } return; } @@ -2249,10 +2258,13 @@ public class DiagnoseParser implements ParserBasicInformation, TerminalTokens { addedTokens = new int[Parser.scope_rhs.length - Parser.scope_suffix[- nameIndex]]; } + int insertedToken = TokenNameNotAToken; for (int i = Parser.scope_suffix[- nameIndex]; Parser.scope_rhs[i] != 0; i++) { buf.append(Parser.readableName[Parser.scope_rhs[i]]); if (Parser.scope_rhs[i + 1] != 0) // any more symbols to print? buf.append(' '); + else + insertedToken = Parser.reverse_index[Parser.scope_rhs[i]]; if(addedTokens != null) { int tmpAddedToken = Parser.reverse_index[Parser.scope_rhs[i]]; @@ -2291,6 +2303,13 @@ public class DiagnoseParser implements ParserBasicInformation, TerminalTokens { } if (scopeNameIndex != 0) { + if (insertedToken == TokenNameElidedSemicolonAndRightBrace) { + /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=383046, we should never ever report the diagnostic, "Syntax error, insert ElidedSemicolonAndRightBraceto complete LambdaBody" + as it is a synthetic token. Instead we should simply repair and move on. See how the regular Parser behaves at Parser.consumeElidedLeftBraceAndReturn and Parser.consumeExpression. + See also: point (4) in https://bugs.eclipse.org/bugs/show_bug.cgi?id=380194#c15 + */ + break; + } if(this.reportProblem) problemReporter().parseErrorInsertToComplete( errorStart, errorEnd, @@ -2425,12 +2444,14 @@ public class DiagnoseParser implements ParserBasicInformation, TerminalTokens { if(this.recoveryScanner != null) { addedTokens = new int[Parser.scope_rhs.length - Parser.scope_suffix[- nameIndex]]; } - + int insertedToken = TokenNameNotAToken; for (int i = Parser.scope_suffix[- nameIndex]; Parser.scope_rhs[i] != 0; i++) { buf.append(Parser.readableName[Parser.scope_rhs[i]]); if (Parser.scope_rhs[i+1] != 0) buf.append(' '); + else + insertedToken = Parser.reverse_index[Parser.scope_rhs[i]]; if(addedTokens != null) { int tmpAddedToken = Parser.reverse_index[Parser.scope_rhs[i]]; @@ -2466,6 +2487,13 @@ public class DiagnoseParser implements ParserBasicInformation, TerminalTokens { this.recoveryScanner.insertTokens(addedTokens, completedToken, errorEnd); } if (scopeNameIndex != 0) { + if (insertedToken == TokenNameElidedSemicolonAndRightBrace) { + /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=383046, we should never ever report the diagnostic, "Syntax error, insert ElidedSemicolonAndRightBraceto complete LambdaBody" + as it is a synthetic token. Instead we should simply repair and move on. See how the regular Parser behaves at Parser.consumeElidedLeftBraceAndReturn and Parser.consumeExpression. + See also: point (4) in https://bugs.eclipse.org/bugs/show_bug.cgi?id=380194#c15 + */ + break; + } if(this.reportProblem) problemReporter().parseErrorInsertToComplete( errorStart, errorEnd, |
