Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2018-04-21 13:05:32 +0000
committerStephan Herrmann2018-04-21 15:26:07 +0000
commit345e42a611307a2681fbe3027e3d89a313222e16 (patch)
treefd9c47575f0042513a034128652a569c8dd832d0
parentea689a4af26390201617f298fb17b50a48435f21 (diff)
downloadeclipse.jdt.core-345e42a611307a2681fbe3027e3d89a313222e16.tar.gz
eclipse.jdt.core-345e42a611307a2681fbe3027e3d89a313222e16.tar.xz
eclipse.jdt.core-345e42a611307a2681fbe3027e3d89a313222e16.zip
Bug 533884 - [10] var type in an enhanced for loop is not resolvedI20180421-1500
properly - recovery for the block of a ForeachStatement Change-Id: I0fb553f21eaf48ca02e3b003849a0cf6f59873b0
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/GenericsCompletionParserTest.java24
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests10.java2
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java30
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java6
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java10
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java37
6 files changed, 90 insertions, 19 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/GenericsCompletionParserTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/GenericsCompletionParserTest.java
index 37256a874c..b22cfb90ec 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/GenericsCompletionParserTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/GenericsCompletionParserTest.java
@@ -8111,10 +8111,10 @@ public void test0167_Method(){
" }\n" +
" void foo() {\n" +
" List<Integer> cont;\n" +
- " Integer i;\n" +
- " {\n" +
- " <CompleteOnName:i.>;\n" +
- " }\n" +
+ " for (Integer i : cont) \n" +
+ " {\n" +
+ " <CompleteOnName:i.>;\n" +
+ " }\n" +
" }\n" +
"}\n";
@@ -10086,10 +10086,10 @@ public void test0202_Method(){
" public Test() {\n" +
" }\n" +
" void bar() {\n" +
- " Entry entry;\n" +
- " {\n" +
- " <CompleteOnName:entry.>;\n" +
- " }\n" +
+ " for (Entry entry : (Set<Entry>) var) \n" +
+ " {\n" +
+ " <CompleteOnName:entry.>;\n" +
+ " }\n" +
" }\n" +
"}\n";
@@ -10164,10 +10164,10 @@ public void test0203_Method(){
" public Test() {\n" +
" }\n" +
" void bar() {\n" +
- " Entry entry;\n" +
- " {\n" +
- " <CompleteOnName:entry.>;\n" +
- " }\n" +
+ " for (Entry entry : (ZZZ<YYY>.Set<Entry>) var) \n" +
+ " {\n" +
+ " <CompleteOnName:entry.>;\n" +
+ " }\n" +
" }\n" +
"}\n";
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests10.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests10.java
index 8ff3ac113e..d82b172282 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests10.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests10.java
@@ -291,7 +291,7 @@ public void testBug532476b() throws JavaModelException {
"}",
"i_");
assertResults(
- "i_jkl[LOCAL_VARIABLE_REF]{i_jkl, null, Ljava.lang.Object;, i_jkl, null, " + (R_DEFAULT + 22) + "}",
+ "i_jkl[LOCAL_VARIABLE_REF]{i_jkl, null, Ljava.lang.String;, i_jkl, null, " + (R_DEFAULT + 22) + "}",
result.proposals);
}
public void testBug532476c() throws JavaModelException {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java
index 9480c8a582..80f3795f92 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java
@@ -1446,8 +1446,7 @@ public void testBug533884a() throws Exception {
deleteProject("P");
}
}
-// disabled: SelectionParser drops the ForeachStatement :(
-public void _testBug533884b() throws Exception {
+public void testBug533884b() throws Exception {
if (!isJRE9) return;
try {
createJava10Project("P", new String[] {"src"});
@@ -1475,4 +1474,31 @@ public void _testBug533884b() throws Exception {
deleteProject("P");
}
}
+public void testBug533884c() throws Exception {
+ try {
+ createJava10Project("P", new String[] {"src"});
+ String source = "package p;\n" +
+ "import java.io.*;\n" +
+ "public class X {\n" +
+ " void bar(File file) {\n" +
+ " try (var rc = new FileInputStream(file)) { \n" +
+ " System.err.println(rc.read());\n" + // <= select this occurrence of 'rc'
+ " }\n" +
+ " }\n" +
+ "\n"
+ + "}\n";
+ createFolder("/P/src/p");
+ createFile("/P/src/p/X.java", source);
+ waitForAutoBuild();
+
+ ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java");
+ String select = "rc";
+ IJavaElement[] elements = unit.codeSelect(source.lastIndexOf(select), select.length());
+ assertEquals("should not be empty", 1, elements.length);
+ ILocalVariable variable = (ILocalVariable) elements[0];
+ assertEquals("incorrect type", "Ljava.io.FileInputStream;", variable.getTypeSignature());
+ } finally {
+ deleteProject("P");
+ }
+}
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
index d6ff6c7bc5..afc4777be5 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
@@ -231,9 +231,6 @@ public RecoveredElement buildInitialRecoveryState(){
ASTNode node = null, lastNode = null;
for (int i = 0; i <= this.astPtr; i++, lastNode = node) {
node = this.astStack[i];
- if(node instanceof ForeachStatement && ((ForeachStatement)node).action == null) {
- node = ((ForeachStatement)node).elementVariable;
- }
/* check for intermediate block creation, so recovery can properly close them afterwards */
int nodeStart = node.sourceStart;
for (int j = blockIndex; j <= this.realBlockPtr; j++){
@@ -334,6 +331,9 @@ public RecoveredElement buildInitialRecoveryState(){
element.add(stmt, 0);
this.lastCheckPoint = stmt.sourceEnd + 1;
this.isOrphanCompletionNode = false;
+ } else if ((stmt instanceof ForeachStatement) && ((ForeachStatement) stmt).action == null) {
+ element = element.add(stmt, 0);
+ this.lastCheckPoint = stmt.sourceEnd + 1;
}
}
continue;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java
index 7f6bd94c62..ea8f2b8022 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java
@@ -18,6 +18,7 @@ import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
@@ -169,9 +170,16 @@ public RecoveredElement add(Statement stmt, int bracketBalanceValue, boolean del
RecoveredStatement element = new RecoveredStatement(stmt, this, bracketBalanceValue);
attach(element);
- if (stmt.sourceEnd == 0) return element;
+ if (!isEndKnown(stmt)) return element;
return this;
}
+boolean isEndKnown(Statement stmt) {
+ if (stmt instanceof ForeachStatement) {
+ if (((ForeachStatement) stmt).action == null)
+ return false;
+ }
+ return stmt.sourceEnd != 0;
+}
/*
* Addition of a type to an initializer (act like inside method body)
*/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java
index 775a88703b..ca5757d728 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java
@@ -17,12 +17,15 @@ import java.util.HashSet;
import java.util.Set;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Block;
+import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
public class RecoveredStatement extends RecoveredElement {
public Statement statement;
+ RecoveredBlock nestedBlock;
public RecoveredStatement(Statement statement, RecoveredElement parent, int bracketBalance){
super(parent, bracketBalance);
@@ -48,6 +51,10 @@ public String toString(int tab){
return tabString(tab) + "Recovered statement:\n" + this.statement.print(tab + 1, new StringBuffer(10)); //$NON-NLS-1$
}
public Statement updatedStatement(int depth, Set<TypeDeclaration> knownTypes){
+ if (this.nestedBlock != null) {
+ this.nestedBlock.updatedStatement(depth, knownTypes);
+ // block has already been assigned in its parent statement
+ }
return this.statement;
}
@Override
@@ -70,4 +77,34 @@ public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
}
return this;
}
+@Override
+public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalanceValue) {
+ if (this.statement instanceof ForeachStatement) {
+ ForeachStatement foreach = (ForeachStatement) this.statement;
+
+ // see RecoveredBlock.add(Block, int):
+ resetPendingModifiers();
+
+ /* do not consider a nested block starting passed the block end (if set)
+ it must be belonging to an enclosing block */
+ if (foreach.sourceEnd != 0
+ && foreach.action != null // if action is unassigned then foreach.sourceEnd is not yet the real end.
+ && nestedBlockDeclaration.sourceStart > foreach.sourceEnd) {
+ return this.parent.add(nestedBlockDeclaration, bracketBalanceValue);
+ }
+ foreach.action = nestedBlockDeclaration;
+
+ RecoveredBlock element = new RecoveredBlock(nestedBlockDeclaration, this, bracketBalanceValue);
+
+ if(parser().statementRecoveryActivated) {
+ addBlockStatement(element);
+ }
+ this.nestedBlock = element;
+
+ if (nestedBlockDeclaration.sourceEnd == 0) return element;
+ return this;
+ } else {
+ return super.add(nestedBlockDeclaration, bracketBalanceValue);
+ }
+}
}

Back to the top