Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManoj Palat2015-08-27 05:02:25 +0000
committerManoj Palat2015-08-27 05:03:13 +0000
commit74bb5893666ff64fec3acee561b65f591ab9aed2 (patch)
tree8c54d9328a693cd6afb3f21c14ed599f5cb175c3
parentc4d165337c4f39b38e6e47bd68ace1aa106b0673 (diff)
downloadeclipse.jdt.core-74bb5893666ff64fec3acee561b65f591ab9aed2.tar.gz
eclipse.jdt.core-74bb5893666ff64fec3acee561b65f591ab9aed2.tar.xz
eclipse.jdt.core-74bb5893666ff64fec3acee561b65f591ab9aed2.zip
Fix for Bug 470794 Missing support for Intersection types in
ITypeBinding
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java75
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java29
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java7
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java23
4 files changed, 131 insertions, 3 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
index c13eec8962..daa0e280a0 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java
@@ -5192,4 +5192,79 @@ public void test429813a() throws JavaModelException {
assertTrue("Should be a varargs", binding.isVarargs());
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=399792
+public void testBug470794_001() throws JavaModelException {
+ String content =
+ "public class X {\n" +
+ " Object o = (I & J) () -> {};" +
+ " public K main(Object o) {\n" +
+ " K oo = (I & J & K) o;\n" +
+ " return oo;\n" +
+ " }\n" +
+ "}\n" +
+ "interface I {\n" +
+ " public void foo();\n" +
+ "}\n" +
+ "interface J {\n" +
+ " public void foo();\n" +
+ " public void bar();\n" +
+ "}\n" +
+ "interface K {\n" +
+ " public void foo();\n" +
+ " public void bar();\n" +
+ "}\n";
+
+ this.workingCopy = getWorkingCopy("/Converter18/src/X.java", true);
+ ASTNode node = buildAST(content, this.workingCopy, true);
+ assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
+ CompilationUnit unit = (CompilationUnit) node;
+ TypeDeclaration type = (TypeDeclaration) unit.types().get(0);
+ node = (ASTNode) type.bodyDeclarations().get(0);
+ assertEquals("Not a field Declaration", ASTNode.FIELD_DECLARATION, node.getNodeType());
+ FieldDeclaration field = (FieldDeclaration) node;
+ assertEquals("Field should not be malformed", 0, (field.getFlags() & ASTNode.MALFORMED));
+
+ List fragments = field.fragments();
+ assertEquals("Incorrect no of fragments", 1, fragments.size());
+ VariableDeclarationFragment fragment = (VariableDeclarationFragment) fragments.get(0);
+ CastExpression cast = (CastExpression) fragment.getInitializer();
+ Type castType = cast.getType();
+ assertEquals("Not an intersection cast type", ASTNode.INTERSECTION_TYPE, castType.getNodeType());
+ assertTrue("Not an intersection cast type", castType.isIntersectionType());
+ assertEquals("Type should not be malformed", 0, (castType.getFlags() & ASTNode.MALFORMED));
+ ITypeBinding binding = castType.resolveBinding();
+ assertNotNull("binding is null", binding);
+ assertTrue("Not an intersection type binding", binding.isIntersectionType());
+ {
+ ITypeBinding [] intersectionBindings = binding.getTypeBounds();
+ String[] expectedTypes = new String[]{"I", "J"};
+ assertTrue("Incorrect number of intersection bindings", intersectionBindings.length == expectedTypes.length);
+ for (int i = 0, l = intersectionBindings.length; i < l; ++i) {
+ assertTrue("Unexpected Intersection Type", expectedTypes[i].equals(intersectionBindings[i].getName()));
+ }
+ }
+
+ node = (ASTNode) type.bodyDeclarations().get(1);
+ assertEquals("Not a method Declaration", ASTNode.METHOD_DECLARATION, node.getNodeType());
+ MethodDeclaration method = (MethodDeclaration) node;
+ assertEquals("Method should not be malformed", 0, (method.getFlags() & ASTNode.MALFORMED));
+
+ List statements = method.getBody().statements();
+ VariableDeclarationStatement statement = (VariableDeclarationStatement) statements.get(0);
+ fragment = (VariableDeclarationFragment) statement.fragments().get(0);
+ cast = (CastExpression) fragment.getInitializer();
+ castType = cast.getType();
+ binding = castType.resolveBinding();
+ assertNotNull("binding is null", binding);
+ assertTrue("Not an intersection type binding", binding.isIntersectionType());
+ {
+ ITypeBinding [] intersectionBindings = binding.getTypeBounds();
+ String[] expectedTypes = new String[]{"I", "J", "K"};
+ assertTrue("Incorrect number of intersection bindings", intersectionBindings.length == expectedTypes.length);
+ for (int i = 0, l = intersectionBindings.length; i < l; ++i) {
+ assertTrue("Unexpected Intersection Type", expectedTypes[i].equals(intersectionBindings[i].getName()));
+ }
+ }
+}
+
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
index 4786097b39..64d8f26256 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
@@ -584,8 +584,8 @@ public interface ITypeBinding extends IBinding {
public ITypeBinding[] getTypeArguments();
/**
- * Returns the upper type bounds of this type variable, wildcard, or capture. If the
- * variable, wildcard, or capture had no explicit bound, then it returns an empty list.
+ * Returns the upper type bounds of this type variable, wildcard, capture, or intersectionType.
+ * If the variable, wildcard, or capture had no explicit bound, then it returns an empty list.
* <p>
* Note that per construction, it can only contain one class or array type,
* at most, and then it is located in first position.
@@ -595,11 +595,12 @@ public interface ITypeBinding extends IBinding {
* binding, e.g. <code>capture-of ? extends Object[]</code>
* </p>
*
- * @return the list of upper bounds for this type variable, wildcard, or capture,
+ * @return the list of upper bounds for this type variable, wildcard, capture, or intersection type
* or otherwise the empty list
* @see #isTypeVariable()
* @see #isWildcardType()
* @see #isCapture()
+ * @see #isIntersectionType()
* @since 3.1
*/
public ITypeBinding[] getTypeBounds();
@@ -819,6 +820,28 @@ public interface ITypeBinding extends IBinding {
public boolean isInterface();
/**
+ * Returns whether this type binding represents an intersection binding.
+ * <p>
+ * Intersection types can be derived from type parameter bounds and cast
+ * expressions; they also arise in the processes of capture conversion
+ * and least upper bound computation as specified in section 4.9 of
+ * <em>The Java Language Specification, Java SE 8 Edition</em> (JLS8).
+ * </p>
+ * <p>
+ * All the types in the intersection type can be accessed using
+ * {@link #getTypeBounds()}. Wildcard types with more than one
+ * bound will also be reported as intersection type. To check whether this
+ * is a wildcard type, use {@link #isWildcardType()}.
+ * </p>
+ * @return <code>true</code> if this type binding is an intersecting type,
+ * and <code>false</code> otherwise
+ * @see #getTypeBounds()
+ * @see ITypeBinding#isWildcardType()
+ * @since 3.12
+ */
+ public boolean isIntersectionType();
+
+ /**
* Returns whether this type binding represents a local class.
* <p>
* A local class is any nested class or enum type not declared as a member
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java
index c126584ef8..76c9bc70cc 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java
@@ -467,6 +467,13 @@ class RecoveredTypeBinding implements ITypeBinding {
}
/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.dom.ITypeBinding#isIntersectionType18()
+ */
+ public boolean isIntersectionType() {
+ return false;
+ }
+
+ /* (non-Javadoc)
* @see org.eclipse.jdt.core.dom.ITypeBinding#isLocal()
*/
public boolean isLocal() {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
index 1fdc50969d..1fd7224cf0 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
@@ -554,6 +554,19 @@ class TypeBinding implements ITypeBinding {
return this.interfaces = NO_TYPE_BINDINGS;
}
+ private ITypeBinding[] getIntersectingTypes() {
+ ITypeBinding[] intersectionBindings = TypeBinding.NO_TYPE_BINDINGS;
+ if (this.binding instanceof IntersectionTypeBinding18) {
+ ReferenceBinding[] intersectingTypes = this.binding.getIntersectingTypes();
+ int l = intersectingTypes.length;
+ intersectionBindings = new ITypeBinding[l];
+ for (int i = 0; i < l; ++i) {
+ intersectionBindings[i] = this.resolver.getTypeBinding(intersectingTypes[i]);
+ }
+ }
+ return intersectionBindings;
+ }
+
public IJavaElement getJavaElement() {
JavaElement element = getUnresolvedJavaElement();
if (element != null)
@@ -926,6 +939,8 @@ class TypeBinding implements ITypeBinding {
} else if (this.binding instanceof WildcardBinding) {
WildcardBinding wildcardBinding = (WildcardBinding) this.binding;
typeVariableBinding = wildcardBinding.typeVariable();
+ } else if (this.binding instanceof IntersectionTypeBinding18) {
+ return this.bounds = getIntersectingTypes();
}
if (typeVariableBinding != null) {
ReferenceBinding varSuperclass = typeVariableBinding.superclass();
@@ -1214,6 +1229,14 @@ class TypeBinding implements ITypeBinding {
}
/*
+ * @see ITypeBinding#isIntersectionType18
+ */
+ public boolean isIntersectionType() {
+ int kind = this.binding.kind();
+ return kind == Binding.INTERSECTION_TYPE18 || kind == Binding.INTERSECTION_TYPE;
+ }
+
+ /*
* @see ITypeBinding#isLocal()
*/
public boolean isLocal() {

Back to the top