Skip to content

Commit

Permalink
Added further tests to showcase some remaining weaknesses of the curr…
Browse files Browse the repository at this point in the history
…ent method graph implementation.
  • Loading branch information
Rafael Winterhalter committed Jul 31, 2015
1 parent eab5f19 commit 8a61ea5
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 16 deletions.
Expand Up @@ -390,13 +390,13 @@ public int hashCode() {

protected static class Detached extends Key<MethodDescription.Token> {

public static Detached of(MethodDescription.Token methodToken) {
protected static Detached of(MethodDescription.Token methodToken) {
return new Detached(methodToken.getInternalName(), Collections.singleton(methodToken));
}

private final Set<MethodDescription.Token> identifiers;

public Detached(String internalName, Set<MethodDescription.Token> identifiers) {
protected Detached(String internalName, Set<MethodDescription.Token> identifiers) {
super(internalName);
this.identifiers = identifiers;
}
Expand All @@ -423,7 +423,7 @@ public String toString() {

protected static class Harmonized<V> extends Key<V> {

public static <Q> Harmonized<Q> of(MethodDescription methodDescription, Harmonizer<Q> factory) {
protected static <Q> Harmonized<Q> of(MethodDescription methodDescription, Harmonizer<Q> factory) {
MethodDescription.Token methodToken = methodDescription.asToken();
return new Harmonized<Q>(methodDescription.getInternalName(),
Collections.singletonMap(factory.wrap(methodToken), Collections.singleton(methodToken)));
Expand Down Expand Up @@ -792,7 +792,7 @@ class Ambiguous<U> implements Entry<U> {
protected static <Q> Entry<Q> of(Harmonized<Q> key, MethodDescription left, MethodDescription right) {
return left.isBridge() ^ right.isBridge()
? new ForMethod<Q>(key, left.isBridge() ? right : left, false)
: new Ambiguous<Q>(key, left.getDeclaringType().asRawType(), right.asToken());
: new Ambiguous<Q>(key, left.getDeclaringType().asRawType(), merge(left.asToken(), right.asToken()));
}

protected Ambiguous(Harmonized<U> key, TypeDescription declaringType, MethodDescription.Token methodToken) {
Expand All @@ -810,9 +810,13 @@ public Harmonized<U> getKey() {
public Entry<U> expandWith(MethodDescription methodDescription, Harmonizer<U> harmonizer) {
Harmonized<U> key = this.key.expandWith(methodDescription.asDefined(), harmonizer);
if (methodDescription.getDeclaringType().asRawType().equals(declaringType)) {
return methodToken.isBridge() ^ methodDescription.isBridge()
? methodToken.isBridge() ? new ForMethod<U>(key, methodDescription, false) : new Ambiguous<U>(key, declaringType, methodToken)
: new Ambiguous<U>(key, declaringType, methodDescription.asToken());
if (methodToken.isBridge() ^ methodDescription.isBridge()) {
return methodToken.isBridge()
? new ForMethod<U>(key, methodDescription, false)
: new Ambiguous<U>(key, declaringType, methodToken);
} else {
return new Ambiguous<U>(key, declaringType, merge(methodToken, methodDescription.asToken()));
}
} else {
return methodDescription.isBridge()
? new Ambiguous<U>(key, declaringType, methodToken)
Expand Down Expand Up @@ -857,6 +861,10 @@ public String toString() {
'}';
}

private static MethodDescription.Token merge(MethodDescription.Token left, MethodDescription.Token right) {
return right; // TODO!
}

protected static class Node implements MethodGraph.Node {

private final Detached key;
Expand Down
Expand Up @@ -15,7 +15,7 @@
public class MethodGraphCompilerDefaultTest {

@Test
public void testTrivial() throws Exception {
public void testObjectType() throws Exception {
MethodGraph.Linked methodGraph = MethodGraph.Compiler.Default.forJavaHierarchy().make(TypeDescription.OBJECT);
assertThat(methodGraph.listNodes().size(), is(TypeDescription.OBJECT.getDeclaredMethods().size()));
assertThat(methodGraph.getSuperGraph().listNodes().size(), is(0));
Expand Down Expand Up @@ -107,7 +107,7 @@ public void testInterfaceExtension() throws Exception {
}

@Test
public void testMultipleInheritance() throws Exception {
public void testInterfaceClassMultipleInheritance() throws Exception {
TypeDescription typeDescription = new TypeDescription.ForLoadedType(MultipleInheritance.class);
MethodGraph.Linked methodGraph = MethodGraph.Compiler.Default.forJavaHierarchy().make(typeDescription);
assertThat(methodGraph.listNodes().size(), is(TypeDescription.OBJECT.getDeclaredMethods().filter(isVirtual()).size() + 2));
Expand Down Expand Up @@ -163,8 +163,8 @@ public void testReturnTypeClassSingleEvolution() throws Exception {
TypeDescription typeDescription = new TypeDescription.ForLoadedType(ReturnTypeClassBase.Inner.class);
MethodGraph.Linked methodGraph = MethodGraph.Compiler.Default.forJavaHierarchy().make(typeDescription);
assertThat(methodGraph.listNodes().size(), is(TypeDescription.OBJECT.getDeclaredMethods().filter(isVirtual()).size() + 2));
MethodGraph.Node methodNode = methodGraph.locate(typeDescription.getSuperType().getDeclaredMethods()
.filter(isMethod()).getOnly().asToken());
MethodGraph.Node methodNode = methodGraph.locate(typeDescription.getDeclaredMethods()
.filter(isMethod().and(ElementMatchers.not(isBridge()))).getOnly().asToken());
MethodDescription.Token bridgeToken = typeDescription.getSuperType().getDeclaredMethods().filter(isMethod()).getOnly().asToken();
assertThat(methodNode, is(methodGraph.locate(bridgeToken)));
assertThat(methodNode.getSort(), is(MethodGraph.Node.Sort.RESOLVED));
Expand Down Expand Up @@ -233,36 +233,96 @@ public void testReturnTypeInterfaceSingleEvolution() throws Exception {
TypeDescription typeDescription = new TypeDescription.ForLoadedType(ReturnTypeInterfaceBase.Inner.class);
MethodGraph.Linked methodGraph = MethodGraph.Compiler.Default.forJavaHierarchy().make(typeDescription);
assertThat(methodGraph.listNodes().size(), is(1));
MethodGraph.Node methodNode = methodGraph.locate(typeDescription.getDeclaredMethods().getOnly().asToken());
MethodDescription.Token bridgeToken = typeDescription.getInterfaces().getOnly().getDeclaredMethods().getOnly().asToken();
assertThat(methodNode, is(methodGraph.locate(bridgeToken)));
assertThat(methodNode.getSort(), is(MethodGraph.Node.Sort.RESOLVED));
assertThat(methodNode.isMadeVisible(), is(false));
assertThat(methodNode.getBridges().size(), is(1));
assertThat(methodNode.getBridges().contains(bridgeToken), is(true));
}

@Test
public void testReturnTypeInterfaceMultipleEvolution() throws Exception {
TypeDescription typeDescription = new TypeDescription.ForLoadedType(ReturnTypeInterfaceBase.Intermediate.Inner.class);
MethodGraph.Linked methodGraph = MethodGraph.Compiler.Default.forJavaHierarchy().make(typeDescription);
assertThat(methodGraph.listNodes().size(), is(1));
MethodGraph.Node methodNode = methodGraph.locate(typeDescription.getDeclaredMethods().getOnly().asToken());
MethodDescription.Token firstBridgeToken = typeDescription.getInterfaces().getOnly()
.getDeclaredMethods().getOnly().asToken();
MethodDescription.Token secondBridgeToken = typeDescription.getInterfaces().getOnly().getInterfaces().getOnly()
.getDeclaredMethods().getOnly().asToken();
assertThat(methodNode, is(methodGraph.locate(firstBridgeToken)));
assertThat(methodNode.getSort(), is(MethodGraph.Node.Sort.RESOLVED));
assertThat(methodNode.isMadeVisible(), is(false));
assertThat(methodNode.getBridges().size(), is(2));
assertThat(methodNode.getBridges().contains(firstBridgeToken), is(true));
assertThat(methodNode.getBridges().contains(secondBridgeToken), is(true));
}

@Test
public void testVisibilityBridge() throws Exception {
TypeDescription typeDescription = new TypeDescription.ForLoadedType(VisibilityBridgeTarget.class);
MethodGraph.Linked methodGraph = MethodGraph.Compiler.Default.forJavaHierarchy().make(typeDescription);
assertThat(methodGraph.listNodes().size(), is(TypeDescription.OBJECT.getDeclaredMethods().filter(isVirtual()).size() + 2));
MethodDescription methodDescription = typeDescription.getDeclaredMethods().filter(isMethod()).getOnly();
MethodGraph.Node methodNode = methodGraph.locate(methodDescription.asToken());
assertThat(methodNode.getSort(), is(MethodGraph.Node.Sort.RESOLVED));
assertThat(methodNode.isMadeVisible(), is(true));
assertThat(methodNode.getBridges().size(), is(0));
assertThat(methodNode.getRepresentative(), is(methodDescription));
}

@Test
public void testGenericVisibilityBridge() throws Exception {
TypeDescription typeDescription = new TypeDescription.ForLoadedType(GenericVisibilityBridgeTarget.class);
MethodGraph.Linked methodGraph = MethodGraph.Compiler.Default.forJavaHierarchy().make(typeDescription);
assertThat(methodGraph.listNodes().size(), is(TypeDescription.OBJECT.getDeclaredMethods().filter(isVirtual()).size() + 2));
MethodDescription methodDescription = typeDescription.getSuperType()
.getDeclaredMethods().filter(isMethod().and(ElementMatchers.not(isBridge()))).getOnly();
MethodDescription.Token bridgeToken = typeDescription.getSuperType().getSuperType()
.getDeclaredMethods().filter(isMethod()).getOnly().asToken();
MethodGraph.Node methodNode = methodGraph.locate(methodDescription.asToken());
assertThat(methodNode.getSort(), is(MethodGraph.Node.Sort.RESOLVED));
assertThat(methodNode, is(methodGraph.locate(bridgeToken)));
assertThat(methodNode.isMadeVisible(), is(true));
assertThat(methodNode.getBridges().size(), is(1));
assertThat(methodNode.getRepresentative(), is(methodDescription));
}

@Test
public void testMethodConvergence() throws Exception {
TypeDescription typeDescription = new TypeDescription.ForLoadedType(MethodConvergence.Inner.class);
public void testMethodClassConvergence() throws Exception {
TypeDescription typeDescription = new TypeDescription.ForLoadedType(MethodClassConvergence.Inner.class);
MethodGraph.Linked methodGraph = MethodGraph.Compiler.Default.forJavaHierarchy().make(typeDescription);
assertThat(methodGraph.listNodes().size(), is(TypeDescription.OBJECT.getDeclaredMethods().filter(isVirtual()).size() + 2));
MethodDescription methodDescription = typeDescription.getDeclaredMethods().filter(isMethod().and(ElementMatchers.not(isBridge()))).getOnly();
MethodDescription originalMethod = typeDescription.getSuperType().getDeclaredMethods()
.filter(isMethod().and(definedMethod(takesArguments(Object.class)))).getOnly();
MethodGraph.Node methodNode = methodGraph.locate(methodDescription.asToken());
assertThat(methodNode.getSort(), is(MethodGraph.Node.Sort.RESOLVED));
assertThat(methodNode, is(methodGraph.locate(originalMethod.asDefined().asToken())));
assertThat(methodNode.isMadeVisible(), is(false));
assertThat(methodNode.getBridges().size(), is(1));
assertThat(methodNode.getRepresentative(), is(methodDescription));
MethodGraph superGraph = methodGraph.getSuperGraph();
MethodGraph.Node superNode = superGraph.locate(methodDescription.asToken());
assertThat(superNode.getSort(), is(MethodGraph.Node.Sort.AMBIGUOUS));
assertThat(superNode.isMadeVisible(), is(false));
assertThat(superNode.getBridges().size(), is(1));
assertThat(superNode.getRepresentative(), is(originalMethod)); // TODO
}

// TODO: method convergance, generic

@Test
public void testAmbiguousInterface() throws Exception {
TypeDescription typeDescription = new TypeDescription.ForLoadedType(MethodInterfaceConvergenceTarget.class);
MethodGraph.Linked methodGraph = MethodGraph.Compiler.Default.forJavaHierarchy().make(typeDescription);
assertThat(methodGraph.listNodes().size(), is(1));
}

// TODO: ambigous interfaces are not properly merged

@Test
public void testObjectProperties() throws Exception {
ObjectPropertyAssertion.of(MethodGraph.Compiler.Default.class).apply();
Expand Down Expand Up @@ -427,7 +487,7 @@ public static class VisibilityBridgeTarget extends VisibilityBridgeBase {
/* empty */
}

static class GenericVisibilityBridgeBase<T> {
public static class GenericVisibilityBridgeBase<T> {

public void foo(T t) {
/* empty */
Expand All @@ -446,7 +506,7 @@ public static class GenericVisibilityBridgeTarget extends GenericVisibilityBridg
/* empty */
}

public static class MethodConvergence<T> {
public static class MethodClassConvergence<T> {

public T foo(T arg) {
return null;
Expand All @@ -456,12 +516,45 @@ public Void foo(Void arg) {
return null;
}

public static class Inner extends MethodConvergence<Void> {
public static class Inner extends MethodClassConvergence<Void> {

@Override
public Void foo(Void arg) {
return null;
}
}
}

public interface MethodInterfaceConvergenceFirstBase<T> {

T foo();
}

public interface MethodInterfaceConvergenceSecondBase {

Void foo();
}

public interface MethodInterfaceConvergenceTarget extends MethodInterfaceConvergenceFirstBase<Void>, MethodInterfaceConvergenceSecondBase {
/* empty */
}

static class MethodConvergenceVisibilityBridgeBase<T> {

public T foo(T arg) {
return null;
}

public Void foo(Void arg) {
return null;
}
}

public static class MethodConvergenceVisibilityBridgeTarget extends MethodConvergenceVisibilityBridgeBase<Void> {

@Override
public Void foo(Void arg) {
return null;
}
}
}

0 comments on commit 8a61ea5

Please sign in to comment.