Skip to content

Commit

Permalink
Added more sorts for bridge methods to better reflect Java 8 properti…
Browse files Browse the repository at this point in the history
…es and specific bridge methods. Fixed implementation accordingly and added further tests.
  • Loading branch information
Rafael Winterhalter committed Jul 23, 2015
1 parent adb17e0 commit 53f115f
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 49 deletions.
Expand Up @@ -1154,12 +1154,8 @@ public static <T extends MethodDescription> ElementMatcher.Junction<T> isTypeIni
return new MethodSortMatcher<T>(MethodSortMatcher.Sort.TYPE_INITIALIZER); return new MethodSortMatcher<T>(MethodSortMatcher.Sort.TYPE_INITIALIZER);
} }


public static <T extends MethodDescription> ElementMatcher.Junction<T> isReturnTypeBridge() { public static <T extends MethodDescription> ElementMatcher.Junction<T> isTypeBridge() {
return new MethodSortMatcher<T>(MethodSortMatcher.Sort.RETURN_TYPE_BRIDGE); return new MethodSortMatcher<T>(MethodSortMatcher.Sort.TYPE_BRIDGE);
}

public static <T extends MethodDescription> ElementMatcher.Junction<T> isTypeVariableBridge() {
return new MethodSortMatcher<T>(MethodSortMatcher.Sort.TYPE_VARIABLE_BRIDGE);
} }


/** /**
Expand Down
Expand Up @@ -101,19 +101,22 @@ protected boolean isSort(MethodDescription target) {
VISIBILITY_BRIDGE("isVisibilityBridge()") { VISIBILITY_BRIDGE("isVisibilityBridge()") {
@Override @Override
protected boolean isSort(MethodDescription target) { protected boolean isSort(MethodDescription target) {
return target.isBridge() return target.isBridge() && !TYPE_BRIDGE.isSort(target);
&& !TYPE_VARIABLE_BRIDGE.isSort(target)
&& !RETURN_TYPE_BRIDGE.isSort(target);
} }
}, },


TYPE_VARIABLE_BRIDGE("isTypeVariableBridge()") { TYPE_BRIDGE("isTypeBridge()") {
@Override @Override
protected boolean isSort(MethodDescription target) { protected boolean isSort(MethodDescription target) {
if (target.isBridge() && !RETURN_TYPE_BRIDGE.isSort(target)) { if (target.isBridge()) {
if (target.getDeclaringType().asRawType().isInterface()) { if (target.getDeclaringType().asRawType().isInterface()) {
return true; return true;
} }
if (!target.getDeclaringType().getDeclaredMethods().filter(not(is(target))
.and(hasMethodName(target.getInternalName()))
.and(takesArguments(target.getParameters().asTypeList().asRawTypes()))).isEmpty()) {
return true;
}
GenericTypeDescription currentType = target.getDeclaringType().getSuperType(); GenericTypeDescription currentType = target.getDeclaringType().getSuperType();
while (currentType != null) { while (currentType != null) {
for (MethodDescription methodDescription : currentType.getDeclaredMethods()) { for (MethodDescription methodDescription : currentType.getDeclaredMethods()) {
Expand All @@ -128,16 +131,6 @@ protected boolean isSort(MethodDescription target) {
} }
}, },


RETURN_TYPE_BRIDGE("isReturnTypeBridge()") {
@Override
protected boolean isSort(MethodDescription target) {
return target.isBridge() && !target.getDeclaringType().getDeclaredMethods()
.filter(not(is(target))
.and(hasMethodName(target.getInternalName()))
.and(takesArguments(target.getParameters().asTypeList().asRawTypes()))).isEmpty();
}
},

/** /**
* Matches method descriptions that represent Java 8 default methods. * Matches method descriptions that represent Java 8 default methods.
*/ */
Expand Down
Expand Up @@ -8,6 +8,8 @@
import net.bytebuddy.description.method.ParameterDescription; import net.bytebuddy.description.method.ParameterDescription;
import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.description.type.generic.GenericTypeDescription; import net.bytebuddy.description.type.generic.GenericTypeDescription;
import net.bytebuddy.test.precompiled.ReturnTypeInterfaceBridge;
import net.bytebuddy.test.precompiled.TypeVariableInterfaceBridge;
import net.bytebuddy.test.utility.JavaVersionRule; import net.bytebuddy.test.utility.JavaVersionRule;
import net.bytebuddy.test.utility.PrecompiledTypeClassLoader; import net.bytebuddy.test.utility.PrecompiledTypeClassLoader;
import org.junit.Before; import org.junit.Before;
Expand All @@ -30,6 +32,7 @@
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Collections; import java.util.Collections;


import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
Expand All @@ -43,6 +46,10 @@ public class ElementMatchersTest {


private static final String PARAMETER_NAMES = "net.bytebuddy.test.precompiled.ParameterNames"; private static final String PARAMETER_NAMES = "net.bytebuddy.test.precompiled.ParameterNames";


private static final String RETURN_TYPE_INTERFACE_BRIDGE = "net.bytebuddy.test.precompiled.ReturnTypeInterfaceBridge";

private static final String TYPE_VARIABLE_INTERFACE_BRIDGE = "net.bytebuddy.test.precompiled.TypeVariableInterfaceBridge";

@Rule @Rule
public MethodRule javaVersionRule = new JavaVersionRule(); public MethodRule javaVersionRule = new JavaVersionRule();


Expand Down Expand Up @@ -259,17 +266,17 @@ public void testRawTypes() throws Exception {
public void testMethodName() throws Exception { public void testMethodName() throws Exception {
assertThat(ElementMatchers.hasMethodName(MethodDescription.TYPE_INITIALIZER_INTERNAL_NAME), is(ElementMatchers.isTypeInitializer())); assertThat(ElementMatchers.hasMethodName(MethodDescription.TYPE_INITIALIZER_INTERNAL_NAME), is(ElementMatchers.isTypeInitializer()));
assertThat(ElementMatchers.hasMethodName(MethodDescription.CONSTRUCTOR_INTERNAL_NAME), is(ElementMatchers.isConstructor())); assertThat(ElementMatchers.hasMethodName(MethodDescription.CONSTRUCTOR_INTERNAL_NAME), is(ElementMatchers.isConstructor()));
ElementMatcher<MethodDescription> nameMatcher = ElementMatchers.named(FOO); ElementMatcher<MethodDescription> nameMatcher = named(FOO);
assertThat(ElementMatchers.hasMethodName(FOO), is(nameMatcher)); assertThat(ElementMatchers.hasMethodName(FOO), is(nameMatcher));
} }


@Test @Test
public void testNamed() throws Exception { public void testNamed() throws Exception {
ByteCodeElement byteCodeElement = mock(ByteCodeElement.class); ByteCodeElement byteCodeElement = mock(ByteCodeElement.class);
when(byteCodeElement.getSourceCodeName()).thenReturn(FOO); when(byteCodeElement.getSourceCodeName()).thenReturn(FOO);
assertThat(ElementMatchers.named(FOO).matches(byteCodeElement), is(true)); assertThat(named(FOO).matches(byteCodeElement), is(true));
assertThat(ElementMatchers.named(FOO.toUpperCase()).matches(byteCodeElement), is(false)); assertThat(named(FOO.toUpperCase()).matches(byteCodeElement), is(false));
assertThat(ElementMatchers.named(BAR).matches(byteCodeElement), is(false)); assertThat(named(BAR).matches(byteCodeElement), is(false));
} }


@Test @Test
Expand Down Expand Up @@ -562,8 +569,8 @@ public void testTakesArgumentsLength() throws Exception {
public void testHasParameter() throws Exception { public void testHasParameter() throws Exception {
MethodDescription methodDescription = new MethodDescription.ForLoadedMethod(classLoader.loadClass(PARAMETER_NAMES) MethodDescription methodDescription = new MethodDescription.ForLoadedMethod(classLoader.loadClass(PARAMETER_NAMES)
.getDeclaredMethod(FOO, String.class, long.class, int.class)); .getDeclaredMethod(FOO, String.class, long.class, int.class));
assertThat(ElementMatchers.hasParameter(ElementMatchers.named(FOO)).matches(methodDescription), is(false)); assertThat(ElementMatchers.hasParameter(named(FOO)).matches(methodDescription), is(false));
assertThat(ElementMatchers.hasParameter(ElementMatchers.named("first")).matches(methodDescription), is(true)); assertThat(ElementMatchers.hasParameter(named("first")).matches(methodDescription), is(true));
} }


@Test @Test
Expand Down Expand Up @@ -660,28 +667,18 @@ public void testSortIsTypeInitializer() throws Exception {
} }


@Test @Test
public void testSortIsTypeVariableBridge() throws Exception { public void testSortIsTypeBridge() throws Exception {
assertThat(ElementMatchers.isTypeVariableBridge() assertThat(ElementMatchers.isTypeBridge()
.matches(new MethodDescription.ForLoadedMethod(IsVisibilityBridge.class.getDeclaredMethod(FOO))), is(false)); .matches(new MethodDescription.ForLoadedMethod(IsVisibilityBridge.class.getDeclaredMethod(FOO))), is(false));
assertThat(ElementMatchers.isTypeVariableBridge() assertThat(ElementMatchers.isTypeBridge()
.matches(new MethodDescription.ForLoadedMethod(IsTypeVariableBridge.class.getDeclaredMethod(FOO, Object.class))), is(true)); .matches(new MethodDescription.ForLoadedMethod(IsTypeVariableBridge.class.getDeclaredMethod(FOO, Object.class))), is(true));
assertThat(ElementMatchers.isTypeVariableBridge().matches(new TypeDescription.ForLoadedType(IsReturnTypeBridge.class) assertThat(ElementMatchers.isTypeBridge().matches(new TypeDescription.ForLoadedType(IsReturnTypeBridge.class)
.getDeclaredMethods().filter(ElementMatchers.named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(false)); .getDeclaredMethods().filter(named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(true));
assertThat(ElementMatchers.isTypeVariableBridge() assertThat(ElementMatchers.isTypeBridge().matches(new TypeDescription.ForLoadedType(IsTypeVariableReturnTypeBridge.class)
.matches(new MethodDescription.ForLoadedMethod(Object.class.getDeclaredMethod("toString"))), is(false)); .getDeclaredMethods().filter(named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(true));
} assertThat(ElementMatchers.isTypeBridge().matches(new TypeDescription.ForLoadedType(IsTypeVariableReturnTypeOverrideBridge.class)

.getDeclaredMethods().filter(named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(true));
@Test assertThat(ElementMatchers.isTypeBridge()
public void testSortIsReturnTypeBridge() throws Exception {
assertThat(ElementMatchers.isReturnTypeBridge()
.matches(new MethodDescription.ForLoadedMethod(IsVisibilityBridge.class.getDeclaredMethod(FOO))), is(false));
assertThat(ElementMatchers.isReturnTypeBridge()
.matches(new MethodDescription.ForLoadedMethod(IsTypeVariableBridge.class.getDeclaredMethod(FOO, Object.class))), is(false));
assertThat(ElementMatchers.isReturnTypeBridge().matches(new TypeDescription.ForLoadedType(IsReturnTypeBridge.class)
.getDeclaredMethods().filter(ElementMatchers.named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(true));
assertThat(ElementMatchers.isReturnTypeBridge().matches(new TypeDescription.ForLoadedType(IsReturnTypeBridge.class)
.getDeclaredMethods().filter(ElementMatchers.named(FOO).and(ElementMatchers.returns(String.class))).getOnly()), is(false));
assertThat(ElementMatchers.isReturnTypeBridge()
.matches(new MethodDescription.ForLoadedMethod(Object.class.getDeclaredMethod("toString"))), is(false)); .matches(new MethodDescription.ForLoadedMethod(Object.class.getDeclaredMethod("toString"))), is(false));
} }


Expand All @@ -692,19 +689,36 @@ public void testSortIsVisibilityBridge() throws Exception {
assertThat(ElementMatchers.isVisibilityBridge() assertThat(ElementMatchers.isVisibilityBridge()
.matches(new MethodDescription.ForLoadedMethod(IsTypeVariableBridge.class.getDeclaredMethod(FOO, Object.class))), is(false)); .matches(new MethodDescription.ForLoadedMethod(IsTypeVariableBridge.class.getDeclaredMethod(FOO, Object.class))), is(false));
assertThat(ElementMatchers.isVisibilityBridge().matches(new TypeDescription.ForLoadedType(IsReturnTypeBridge.class) assertThat(ElementMatchers.isVisibilityBridge().matches(new TypeDescription.ForLoadedType(IsReturnTypeBridge.class)
.getDeclaredMethods().filter(ElementMatchers.named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(false)); .getDeclaredMethods().filter(named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(false));
assertThat(ElementMatchers.isVisibilityBridge().matches(new TypeDescription.ForLoadedType(IsTypeVariableReturnTypeBridge.class)
.getDeclaredMethods().filter(named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(false));
assertThat(ElementMatchers.isVisibilityBridge().matches(new TypeDescription.ForLoadedType(IsTypeVariableReturnTypeOverrideBridge.class)
.getDeclaredMethods().filter(named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(false));
assertThat(ElementMatchers.isVisibilityBridge() assertThat(ElementMatchers.isVisibilityBridge()
.matches(new MethodDescription.ForLoadedMethod(Object.class.getDeclaredMethod("toString"))), is(false)); .matches(new MethodDescription.ForLoadedMethod(Object.class.getDeclaredMethod("toString"))), is(false));
} }


@Test
@JavaVersionRule.Enforce(8)
public void testSortInterfaceBridgeType() throws Exception {
assertThat(ElementMatchers.isTypeBridge().matches(new TypeDescription.ForLoadedType(classLoader.loadClass(RETURN_TYPE_INTERFACE_BRIDGE))
.getDeclaredMethods().filter(ElementMatchers.named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(true));
assertThat(ElementMatchers.isTypeBridge().matches(new MethodDescription.ForLoadedMethod(classLoader.loadClass(TYPE_VARIABLE_INTERFACE_BRIDGE)
.getDeclaredMethod(FOO, Object.class))), is(true));
assertThat(ElementMatchers.isVisibilityBridge().matches(new TypeDescription.ForLoadedType(classLoader.loadClass(RETURN_TYPE_INTERFACE_BRIDGE))
.getDeclaredMethods().filter(ElementMatchers.named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(false));
assertThat(ElementMatchers.isVisibilityBridge().matches(new MethodDescription.ForLoadedMethod(classLoader.loadClass(TYPE_VARIABLE_INTERFACE_BRIDGE)
.getDeclaredMethod(FOO, Object.class))), is(false));
}

@Test @Test
public void testSortIsBridge() throws Exception { public void testSortIsBridge() throws Exception {
assertThat(ElementMatchers.isBridge() assertThat(ElementMatchers.isBridge()
.matches(new MethodDescription.ForLoadedMethod(IsVisibilityBridge.class.getDeclaredMethod(FOO))), is(true)); .matches(new MethodDescription.ForLoadedMethod(IsVisibilityBridge.class.getDeclaredMethod(FOO))), is(true));
assertThat(ElementMatchers.isBridge() assertThat(ElementMatchers.isBridge()
.matches(new MethodDescription.ForLoadedMethod(IsTypeVariableBridge.class.getDeclaredMethod(FOO, Object.class))), is(true)); .matches(new MethodDescription.ForLoadedMethod(IsTypeVariableBridge.class.getDeclaredMethod(FOO, Object.class))), is(true));
assertThat(ElementMatchers.isBridge().matches(new TypeDescription.ForLoadedType(IsReturnTypeBridge.class) assertThat(ElementMatchers.isBridge().matches(new TypeDescription.ForLoadedType(IsReturnTypeBridge.class)
.getDeclaredMethods().filter(ElementMatchers.named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(true)); .getDeclaredMethods().filter(named(FOO).and(ElementMatchers.returns(Object.class))).getOnly()), is(true));
assertThat(ElementMatchers.isBridge() assertThat(ElementMatchers.isBridge()
.matches(new MethodDescription.ForLoadedMethod(Object.class.getDeclaredMethod("toString"))), is(false)); .matches(new MethodDescription.ForLoadedMethod(Object.class.getDeclaredMethod("toString"))), is(false));
} }
Expand Down Expand Up @@ -1046,6 +1060,36 @@ public String foo() {
} }
} }


public static class TypeVariableReturnTypeBridgeBase<T> {

public T foo() {
return null;
}
}

public static class IsTypeVariableReturnTypeBridge extends TypeVariableReturnTypeBridgeBase<String> {

@Override
public String foo() {
return null;
}
}

public static class TypeVariableReturnTypeOverrideBridgeBase<T, S extends T> {

public T foo() {
return null;
}
}

public static class IsTypeVariableReturnTypeOverrideBridge<S extends Number> extends TypeVariableReturnTypeOverrideBridgeBase<Number, S> {

@Override
public S foo() {
return null;
}
}

private static class ObjectMethods { private static class ObjectMethods {


@Override @Override
Expand Down
Binary file not shown.
@@ -0,0 +1,11 @@
package net.bytebuddy.test.precompiled;

public interface ReturnTypeInterfaceBridge extends ReturnTypeInterfaceBridgeBase {

String BAR = "bar";

@Override
default String foo() {
return BAR;
}
}
Binary file not shown.
@@ -0,0 +1,10 @@
package net.bytebuddy.test.precompiled;

public interface ReturnTypeInterfaceBridgeBase {

String FOO = "foo";

default Object foo() {
return FOO;
}
}
Binary file not shown.
@@ -0,0 +1,11 @@
package net.bytebuddy.test.precompiled;

public interface TypeVariableInterfaceBridge extends TypeVariableInterfaceBridgeBase<String> {

String FOO = "foo";

@Override
default String foo(String s) {
return FOO;
}
}
Binary file not shown.
@@ -0,0 +1,8 @@
package net.bytebuddy.test.precompiled;

public interface TypeVariableInterfaceBridgeBase<T> {

default T foo(T t) {
return t;
}
}

0 comments on commit 53f115f

Please sign in to comment.