Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2018-04-20 21:46:06 +0000
committerStephan Herrmann2018-04-20 21:46:06 +0000
commitea689a4af26390201617f298fb17b50a48435f21 (patch)
tree786506aea2e5394f4674a1e036f40e9f0314e405
parentee7589441b1c0b24e13063921c3a2241305813d2 (diff)
downloadeclipse.jdt.core-ea689a4af26390201617f298fb17b50a48435f21.tar.gz
eclipse.jdt.core-ea689a4af26390201617f298fb17b50a48435f21.tar.xz
eclipse.jdt.core-ea689a4af26390201617f298fb17b50a48435f21.zip
Bug 533884 - [10] var type in an enhanced for loop is not resolved
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java56
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnLocalName.java22
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java9
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java1
4 files changed, 83 insertions, 5 deletions
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 bd66ea49e2..9480c8a582 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
@@ -1418,5 +1418,61 @@ public void test531046h() throws CoreException, IOException {
deleteProject("P");
}
}
+public void testBug533884a() throws Exception {
+ if (!isJRE9) return;
+ try {
+ createJava10Project("P", new String[] {"src"});
+ String source = "package p;\n" +
+ "public class X {\n" +
+ " void bar() {\n" +
+ " String[] x = {\"a\", \"b\"};\n" +
+ " for (var y : x) { \n" + // <= select this occurrence of 'y'
+ " System.err.println(y.toUpperCase());\n" +
+ " }\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 = "y";
+ IJavaElement[] elements = unit.codeSelect(source.indexOf(select), select.length());
+ assertEquals("should not be empty", 1, elements.length);
+ ILocalVariable variable = (ILocalVariable) elements[0];
+ assertEquals("incorrect type", "Ljava.lang.String;", variable.getTypeSignature());
+ } finally {
+ deleteProject("P");
+ }
+}
+// disabled: SelectionParser drops the ForeachStatement :(
+public void _testBug533884b() throws Exception {
+ if (!isJRE9) return;
+ try {
+ createJava10Project("P", new String[] {"src"});
+ String source = "package p;\n" +
+ "public class X {\n" +
+ " void bar() {\n" +
+ " String[] x = {\"a\", \"b\"};\n" +
+ " for (var y : x) { \n" +
+ " System.err.println(y.toUpperCase());\n" + // <= select this occurrence of 'y'
+ " }\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 = "y";
+ 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.lang.String;", variable.getTypeSignature());
+ } finally {
+ deleteProject("P");
+ }
+}
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnLocalName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnLocalName.java
index 79ec1e3fe5..a2e5d58074 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnLocalName.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnLocalName.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 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
@@ -10,8 +10,11 @@
*******************************************************************************/
package org.eclipse.jdt.internal.codeassist.select;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
public class SelectionOnLocalName extends LocalDeclaration{
@@ -24,6 +27,23 @@ public class SelectionOnLocalName extends LocalDeclaration{
public void resolve(BlockScope scope) {
super.resolve(scope);
+ if (isTypeNameVar(scope)) {
+ if ((this.bits & ASTNode.IsForeachElementVariable) != 0 && scope.blockStatement instanceof ForeachStatement) {
+ // small version extracted from ForeachStatement.resolve():
+
+ ForeachStatement stat = (ForeachStatement) scope.blockStatement;
+ TypeBinding collectionType = stat.collection == null ? null : stat.collection.resolveType((BlockScope) scope.parent);
+
+ // Patch the resolved type
+ if (!TypeBinding.equalsEquals(TypeBinding.NULL, collectionType)
+ && !TypeBinding.equalsEquals(TypeBinding.VOID, collectionType)) {
+ TypeBinding elementType = ForeachStatement.getCollectionElementType(scope, collectionType);
+ if (elementType != null) {
+ this.patchType(elementType);
+ }
+ }
+ }
+ }
throw new SelectionNodeFound(this.binding);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
index 42a5ebd0f9..5088c8be5b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
@@ -418,10 +418,10 @@ public class ForeachStatement extends Statement {
return output;
}
- private TypeBinding getCollectionElementType(TypeBinding collectionType) {
+ public static TypeBinding getCollectionElementType(BlockScope scope, TypeBinding collectionType) {
if (collectionType == null) return null;
- boolean isTargetJsr14 = this.scope.compilerOptions().targetJDK == ClassFileConstants.JDK1_4;
+ boolean isTargetJsr14 = scope.compilerOptions().targetJDK == ClassFileConstants.JDK1_4;
if (collectionType.isCapture()) {
TypeBinding upperBound = ((CaptureBinding)collectionType).firstBound;
if (upperBound != null && upperBound.isArrayType())
@@ -439,7 +439,7 @@ public class ForeachStatement extends Statement {
TypeBinding[] arguments = null;
switch (iterableType.kind()) {
case Binding.RAW_TYPE : // for(Object o : Iterable)
- return this.scope.getJavaLangObject();
+ return scope.getJavaLangObject();
case Binding.GENERIC_TYPE : // for (T t : Iterable<T>) - in case used inside Iterable itself
arguments = iterableType.typeVariables();
@@ -462,6 +462,7 @@ public class ForeachStatement extends Statement {
public void resolve(BlockScope upperScope) {
// use the scope that will hold the init declarations
this.scope = new BlockScope(upperScope);
+ this.scope.blockStatement = this;
this.elementVariable.resolve(this.scope); // collection expression can see itemVariable
TypeBinding elementType = this.elementVariable.type.resolvedType;
TypeBinding collectionType = this.collection == null ? null : this.collection.resolveType(upperScope);
@@ -478,7 +479,7 @@ public class ForeachStatement extends Statement {
upperScope.problemReporter().varLocalInitializedToVoid(this.elementVariable);
elementType = collectionType;
}
- if ((elementType = getCollectionElementType(collectionType)) == null) {
+ if ((elementType = getCollectionElementType(this.scope, collectionType)) == null) {
elementType = collectionType;
} else {
elementType = this.elementVariable.patchType(elementType);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
index 34fe9d5f1f..ccac4716a1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
@@ -67,6 +67,7 @@ public class BlockScope extends Scope {
// annotation support
public boolean insideTypeAnnotation = false;
+ public Statement blockStatement;
public BlockScope(BlockScope parent) {
this(parent, true);

Back to the top