Skip to content

Commit

Permalink
fix:bug in isSubtypeOf (broken contract X.isSubtypeOf(X)==true) (#1157)
Browse files Browse the repository at this point in the history
* test X.isSubtypeOf(X)==true

* Change implementation of isSubtypeOf for different implementations to use method defined in CtTypeReferenceImpl.

* Add one more test to check isSubtypeOf for TypeParameters.

* fix checkstyle

* comment test of not yet supported isSubTypeOf TypedParameter

* added comment typeX.isSubtypeOf(typeX) is true
  • Loading branch information
pvojtechovsky authored and surli committed Feb 2, 2017
1 parent 8c35c98 commit ce2856d
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public interface CtTypeInformation {

/**
* Returns true if the referenced type is a sub-type of the given type.
* Returns true is type is self, it means: typeX.isSubtypeOf(typeX) is true too
*/
boolean isSubtypeOf(CtTypeReference<?> type);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public <C extends CtType<T>> C setSuperInterfaces(Set<CtTypeReference<?>> interf

@Override
public boolean isSubtypeOf(CtTypeReference<?> type) {
return false;
return getReference().isSubtypeOf(type);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,15 +176,7 @@ public boolean isAnonymous() {

@Override
public boolean isSubtypeOf(CtTypeReference<?> type) {
if ((getSuperclass() != null) && getSuperclass().isSubtypeOf(type)) {
return true;
}
for (CtTypeReference<?> ref : getSuperInterfaces()) {
if (ref.isSubtypeOf(type)) {
return true;
}
}
return false;
return getReference().isSubtypeOf(type);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,7 @@ public Set<CtMethod<?>> getAllMethods() {

@Override
public boolean isSubtypeOf(CtTypeReference<?> type) {
for (CtTypeReference<?> ref : getSuperInterfaces()) {
if (ref.isSubtypeOf(type)) {
return true;
}
}
return getSuperclass().isSubtypeOf(type);
return getReference().isSubtypeOf(type);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,7 @@ public void accept(CtVisitor visitor) {

@Override
public boolean isSubtypeOf(CtTypeReference<?> type) {
for (CtTypeReference<?> ref : getSuperInterfaces()) {
if (ref.isSubtypeOf(type)) {
return true;
}
}
return false;
return getReference().isSubtypeOf(type);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ public List<CtFieldReference<?>> getDeclaredFields() {

@Override
public boolean isSubtypeOf(CtTypeReference<?> type) {
return false;
return getReference().isSubtypeOf(type);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,6 @@ public boolean isGenerics() {
return true;
}

@Override
public boolean isSubtypeOf(CtTypeReference<?> type) {
return false;
}

@Override
public boolean isPrimitive() {
return false;
Expand Down
38 changes: 36 additions & 2 deletions src/test/java/spoon/test/ctType/CtTypeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@
import spoon.reflect.declaration.CtInterface;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.CtTypeMember;
import spoon.reflect.declaration.CtTypeParameter;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtTypeReference;
import spoon.test.ctType.testclasses.X;

import java.util.List;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static spoon.testing.utils.ModelUtils.buildClass;
Expand Down Expand Up @@ -69,8 +74,37 @@ public void testHasMethodInDefaultMethod() throws Exception {
@Test
public void testIsSubTypeOf() throws Exception {
CtType<X> xCtType = buildClass(X.class);
CtType<?> yCtType = xCtType.getFactory().Type().get("spoon.test.ctType.testclasses.Y");

assertFalse(xCtType.isSubtypeOf(yCtType.getReference()));
assertTrue(yCtType.isSubtypeOf(xCtType.getReference()));
//contract: x isSubtypeOf x
//using CtTypeReference implementation
assertTrue(xCtType.getReference().isSubtypeOf(xCtType.getReference()));
//using CtType implementation
assertTrue(xCtType.isSubtypeOf(xCtType.getReference()));
}

@Test
public void testIsSubTypeOfonTypeParameters() throws Exception {
CtType<X> xCtType = buildClass(X.class);

CtType<?> oCtType = xCtType.getFactory().Type().get("spoon.test.ctType.testclasses.O");

List<CtTypeParameter> typeParameters = oCtType.getFormalCtTypeParameters();
assertTrue(typeParameters.size() == 1);

CtType<?> aCtType = typeParameters.get(0);

List<CtMethod<?>> methods = oCtType.getMethodsByName("foo");

assertTrue(methods.size() == 1);

CtMethod<?> fooMethod = methods.get(0);
CtType<?> bCtType = fooMethod.getType().getDeclaration();

assertFalse(xCtType.isSubtypeOf(xCtType.getFactory().Type().createReference("spoon.test.ctType.testclasses.Y")));
assertTrue(xCtType.getFactory().Type().get("spoon.test.ctType.testclasses.Y").isSubtypeOf(xCtType.getReference()));
//The TypeParameters are not supported yet
// assertTrue(bCtType.isSubtypeOf(xCtType.getReference()));
// assertTrue(bCtType.isSubtypeOf(aCtType.getReference()));
}
}
6 changes: 6 additions & 0 deletions src/test/java/spoon/test/ctType/testclasses/X.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ interface Z {
abstract class W implements Z {
}

class O<A extends X> {
<B extends A> B foo() {
return null;
}
}

0 comments on commit ce2856d

Please sign in to comment.