Skip to content

Commit

Permalink
Fixed bug 383046: [1.8][compiler] Error getting reported on the
Browse files Browse the repository at this point in the history
lambda expression if there is a subsequent parse error
  • Loading branch information
Srikanth committed Jun 20, 2012
1 parent 32f37f4 commit 6a1671a
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ protected int getNextToken0() throws InvalidInputException {
this.data.removedTokenUsed[i] = true;
this.currentPosition = this.data.removedTokensEnd[i] + 1;
this.precededByRemoved = false;
return getNextToken();
return getNextToken0();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
/*******************************************************************************
* 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
*******************************************************************************/
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;
Expand Down Expand Up @@ -193,6 +198,9 @@ public void diagnoseParse(boolean record) {
oldRecord = this.recoveryScanner.record;
this.recoveryScanner.record = record;
}
if (this.options.sourceLevel >= ClassFileConstants.JDK1_8) {
this.parser.scanner.shouldDisambiguate = true;
}
try {
this.lexStream.reset();

Expand Down Expand Up @@ -421,6 +429,7 @@ public void diagnoseParse(boolean record) {
if(this.recoveryScanner != null) {
this.recoveryScanner.record = oldRecord;
}
this.parser.scanner.shouldDisambiguate = false;
}
return;
}
Expand Down Expand Up @@ -2249,10 +2258,13 @@ private void reportPrimaryError(int msgCode, int nameIndex, int token, int scope
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]];
Expand Down Expand Up @@ -2291,6 +2303,13 @@ private void reportPrimaryError(int msgCode, int nameIndex, int token, int scope
}

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,
Expand Down Expand Up @@ -2425,12 +2444,14 @@ private void reportSecondaryError(int msgCode, int nameIndex, int leftToken, int
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]];
Expand Down Expand Up @@ -2466,6 +2487,13 @@ private void reportSecondaryError(int msgCode, int nameIndex, int leftToken, int
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,
Expand Down

0 comments on commit 6a1671a

Please sign in to comment.