Skip to content

Commit

Permalink
Added further documentation and tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafael Winterhalter committed Mar 31, 2015
1 parent 5c37f15 commit 9a123b9
Show file tree
Hide file tree
Showing 7 changed files with 391 additions and 44 deletions.

Large diffs are not rendered by default.

Expand Up @@ -18,6 +18,7 @@
import net.bytebuddy.instrumentation.type.TypeDescription; import net.bytebuddy.instrumentation.type.TypeDescription;
import net.bytebuddy.instrumentation.type.TypeList; import net.bytebuddy.instrumentation.type.TypeList;
import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.test.utility.DebuggingWrapper;
import org.hamcrest.CoreMatchers; import org.hamcrest.CoreMatchers;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;


Expand Down
Expand Up @@ -75,7 +75,7 @@ public void testMethodHandleConstantPoolValue() throws Exception {
} }


private static Object makeMethodHandle() throws Exception { private static Object makeMethodHandle() throws Exception {
Object lookup = Class.forName("java.lang.invoke.MethodHandles").getDeclaredMethod("lookup").invoke(null); Object lookup = Class.forName("java.lang.invoke.MethodHandles").getDeclaredMethod("publicLookup").invoke(null);
return JavaType.METHOD_HANDLES_LOOKUP.load().getDeclaredMethod("findVirtual", Class.class, String.class, JavaType.METHOD_TYPE.load()) return JavaType.METHOD_HANDLES_LOOKUP.load().getDeclaredMethod("findVirtual", Class.class, String.class, JavaType.METHOD_TYPE.load())
.invoke(lookup, Qux.class, BAR, makeMethodType(Object.class)); .invoke(lookup, Qux.class, BAR, makeMethodType(Object.class));
} }
Expand Down
Expand Up @@ -5,8 +5,9 @@
import net.bytebuddy.test.utility.JavaVersionRule; import net.bytebuddy.test.utility.JavaVersionRule;
import net.bytebuddy.test.utility.ObjectPropertyAssertion; import net.bytebuddy.test.utility.ObjectPropertyAssertion;
import net.bytebuddy.test.utility.PrecompiledTypeClassLoader; import net.bytebuddy.test.utility.PrecompiledTypeClassLoader;
import net.bytebuddy.utility.JavaInstance;
import net.bytebuddy.utility.JavaType;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.MethodRule; import org.junit.rules.MethodRule;
Expand Down Expand Up @@ -120,19 +121,21 @@ public void testBootstrapWithArrayArgumentsWithArguments() throws Exception {
TypeDescription typeDescription = new TypeDescription.ForLoadedType(type); TypeDescription typeDescription = new TypeDescription.ForLoadedType(type);
DynamicType.Loaded<Simple> dynamicType = instrument(Simple.class, DynamicType.Loaded<Simple> dynamicType = instrument(Simple.class,
InvokeDynamic.bootstrap(typeDescription.getDeclaredMethods().filter(named(BOOTSTRAP_ARRAY_ARGUMENTS)).getOnly(), InvokeDynamic.bootstrap(typeDescription.getDeclaredMethods().filter(named(BOOTSTRAP_ARRAY_ARGUMENTS)).getOnly(),
INTEGER, LONG, FLOAT, DOUBLE, FOO, CLASS) INTEGER, LONG, FLOAT, DOUBLE, FOO, CLASS, makeMethodType(CLASS), makeMethodHandle())
.withoutImplicitArguments(), .withoutImplicitArguments(),
classLoader, classLoader,
isDeclaredBy(Simple.class)); isDeclaredBy(Simple.class));
assertThat(dynamicType.getLoaded().newInstance().foo(), is(FOO)); assertThat(dynamicType.getLoaded().newInstance().foo(), is(FOO));
Object[] arguments = (Object[]) field.get(null); Object[] arguments = (Object[]) field.get(null);
assertThat(arguments.length, is(6)); assertThat(arguments.length, is(8));
assertThat(arguments[0], is((Object) INTEGER)); assertThat(arguments[0], is((Object) INTEGER));
assertThat(arguments[1], is((Object) LONG)); assertThat(arguments[1], is((Object) LONG));
assertThat(arguments[2], is((Object) FLOAT)); assertThat(arguments[2], is((Object) FLOAT));
assertThat(arguments[3], is((Object) DOUBLE)); assertThat(arguments[3], is((Object) DOUBLE));
assertThat(arguments[4], is((Object) FOO)); assertThat(arguments[4], is((Object) FOO));
assertThat(arguments[5], is((Object) CLASS)); assertThat(arguments[5], is((Object) CLASS));
assertThat(arguments[6], is(makeMethodType(CLASS)));
assertThat(JavaInstance.MethodHandle.of(arguments[7]), is(JavaInstance.MethodHandle.of(makeMethodHandle())));
} }


@Test @Test
Expand All @@ -144,19 +147,21 @@ public void testBootstrapWithExplicitArgumentsWithArguments() throws Exception {
TypeDescription typeDescription = new TypeDescription.ForLoadedType(type); TypeDescription typeDescription = new TypeDescription.ForLoadedType(type);
DynamicType.Loaded<Simple> dynamicType = instrument(Simple.class, DynamicType.Loaded<Simple> dynamicType = instrument(Simple.class,
InvokeDynamic.bootstrap(typeDescription.getDeclaredMethods().filter(named(BOOTSTRAP_EXPLICIT_ARGUMENTS)).getOnly(), InvokeDynamic.bootstrap(typeDescription.getDeclaredMethods().filter(named(BOOTSTRAP_EXPLICIT_ARGUMENTS)).getOnly(),
INTEGER, LONG, FLOAT, DOUBLE, FOO, CLASS) INTEGER, LONG, FLOAT, DOUBLE, FOO, CLASS, makeMethodType(CLASS), makeMethodHandle())
.withoutImplicitArguments(), .withoutImplicitArguments(),
classLoader, classLoader,
isDeclaredBy(Simple.class)); isDeclaredBy(Simple.class));
assertThat(dynamicType.getLoaded().newInstance().foo(), is(FOO)); assertThat(dynamicType.getLoaded().newInstance().foo(), is(FOO));
Object[] arguments = (Object[]) field.get(null); Object[] arguments = (Object[]) field.get(null);
assertThat(arguments.length, is(6)); assertThat(arguments.length, is(8));
assertThat(arguments[0], is((Object) INTEGER)); assertThat(arguments[0], is((Object) INTEGER));
assertThat(arguments[1], is((Object) LONG)); assertThat(arguments[1], is((Object) LONG));
assertThat(arguments[2], is((Object) FLOAT)); assertThat(arguments[2], is((Object) FLOAT));
assertThat(arguments[3], is((Object) DOUBLE)); assertThat(arguments[3], is((Object) DOUBLE));
assertThat(arguments[4], is((Object) FOO)); assertThat(arguments[4], is((Object) FOO));
assertThat(arguments[5], is((Object) CLASS)); assertThat(arguments[5], is((Object) CLASS));
assertThat(arguments[6], is(makeMethodType(CLASS)));
assertThat(JavaInstance.MethodHandle.of(arguments[7]), is(JavaInstance.MethodHandle.of(makeMethodHandle())));
} }


@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
Expand All @@ -169,8 +174,7 @@ public void testBootstrapWithExplicitArgumentsWithoutArgumentsThrowsException()
@Test @Test
@JavaVersionRule.Enforce(7) @JavaVersionRule.Enforce(7)
public void testBootstrapOfMethodsWithParametersPrimitive() throws Exception { public void testBootstrapOfMethodsWithParametersPrimitive() throws Exception {
Class<?> type = classLoader.loadClass(ARGUMENT_BOOTSTRAP); TypeDescription typeDescription = new TypeDescription.ForLoadedType(classLoader.loadClass(ARGUMENT_BOOTSTRAP));
TypeDescription typeDescription = new TypeDescription.ForLoadedType(type);
Object value = new Object(); Object value = new Object();
DynamicType.Loaded<Simple> dynamicType = instrument(Simple.class, DynamicType.Loaded<Simple> dynamicType = instrument(Simple.class,
InvokeDynamic.bootstrap(typeDescription.getDeclaredMethods().filter(named(BOOTSTRAP)).getOnly()) InvokeDynamic.bootstrap(typeDescription.getDeclaredMethods().filter(named(BOOTSTRAP)).getOnly())
Expand All @@ -184,11 +188,14 @@ public void testBootstrapOfMethodsWithParametersPrimitive() throws Exception {
.withLongValue(LONG) .withLongValue(LONG)
.withFloatValue(FLOAT) .withFloatValue(FLOAT)
.withDoubleValue(DOUBLE) .withDoubleValue(DOUBLE)
.withValue(FOO, CLASS, value), .withType(new TypeDescription.ForLoadedType(CLASS))
.withInstance(JavaInstance.MethodType.of(makeMethodType(CLASS)), JavaInstance.MethodHandle.of(makeMethodHandle()))
.withValue(FOO, CLASS, makeMethodType(CLASS), makeMethodHandle(), value),
classLoader, classLoader,
isDeclaredBy(Simple.class)); isDeclaredBy(Simple.class));
assertThat(dynamicType.getLoaded().newInstance().foo(), assertThat(dynamicType.getLoaded().newInstance().foo(),
is("" + BOOLEAN + BYTE + SHORT + CHARACTER + INTEGER + LONG + FLOAT + DOUBLE + FOO + CLASS + value)); is("" + BOOLEAN + BYTE + SHORT + CHARACTER + INTEGER + LONG + FLOAT + DOUBLE + CLASS + makeMethodType(CLASS)
+ makeMethodHandle() + FOO + CLASS + makeMethodType(CLASS) + makeMethodHandle() + value));
} }


@Test @Test
Expand All @@ -201,12 +208,12 @@ public void testBootstrapOfMethodsWithParametersWrapperConstantPool() throws Exc
InvokeDynamic.bootstrap(typeDescription.getDeclaredMethods().filter(named(BOOTSTRAP)).getOnly()) InvokeDynamic.bootstrap(typeDescription.getDeclaredMethods().filter(named(BOOTSTRAP)).getOnly())
.invoke(BAR, String.class) .invoke(BAR, String.class)
.withoutImplicitArguments() .withoutImplicitArguments()
.withValue(BOOLEAN, BYTE, SHORT, CHARACTER, INTEGER, LONG, FLOAT, DOUBLE, FOO, CLASS, value), .withValue(BOOLEAN, BYTE, SHORT, CHARACTER, INTEGER, LONG, FLOAT, DOUBLE, FOO, CLASS, makeMethodType(CLASS), makeMethodHandle(), value),
classLoader, classLoader,
isDeclaredBy(Simple.class)); isDeclaredBy(Simple.class));
assertThat(dynamicType.getLoaded().getDeclaredFields().length, is(1)); assertThat(dynamicType.getLoaded().getDeclaredFields().length, is(1));
assertThat(dynamicType.getLoaded().newInstance().foo(), assertThat(dynamicType.getLoaded().newInstance().foo(),
is("" + BOOLEAN + BYTE + SHORT + CHARACTER + INTEGER + LONG + FLOAT + DOUBLE + FOO + CLASS + value)); is("" + BOOLEAN + BYTE + SHORT + CHARACTER + INTEGER + LONG + FLOAT + DOUBLE + FOO + CLASS + makeMethodType(CLASS) + makeMethodHandle() + value));
} }


@Test @Test
Expand All @@ -219,12 +226,14 @@ public void testBootstrapOfMethodsWithParametersWrapperReference() throws Except
InvokeDynamic.bootstrap(typeDescription.getDeclaredMethods().filter(named(BOOTSTRAP)).getOnly()) InvokeDynamic.bootstrap(typeDescription.getDeclaredMethods().filter(named(BOOTSTRAP)).getOnly())
.invoke(BAR, String.class) .invoke(BAR, String.class)
.withoutImplicitArguments() .withoutImplicitArguments()
.withReference(BOOLEAN, BYTE, SHORT, CHARACTER, INTEGER, LONG, FLOAT, DOUBLE, FOO, CLASS, value), .withReference(BOOLEAN, BYTE, SHORT, CHARACTER, INTEGER, LONG, FLOAT, DOUBLE, FOO, CLASS, makeMethodType(CLASS))
.withReference(makeMethodHandle()).as(JavaType.METHOD_HANDLE.load()) // avoid direct method handle
.withReference(value),
classLoader, classLoader,
isDeclaredBy(Simple.class)); isDeclaredBy(Simple.class));
assertThat(dynamicType.getLoaded().getDeclaredFields().length, is(11)); assertThat(dynamicType.getLoaded().getDeclaredFields().length, is(13));
assertThat(dynamicType.getLoaded().newInstance().foo(), assertThat(dynamicType.getLoaded().newInstance().foo(),
is("" + BOOLEAN + BYTE + SHORT + CHARACTER + INTEGER + LONG + FLOAT + DOUBLE + FOO + CLASS + value)); is("" + BOOLEAN + BYTE + SHORT + CHARACTER + INTEGER + LONG + FLOAT + DOUBLE + FOO + CLASS + makeMethodType(CLASS) + makeMethodHandle() + value));
} }


@Test @Test
Expand Down Expand Up @@ -415,6 +424,7 @@ public void testObjectProperties() throws Exception {
ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.ForClassValue.class).apply(); ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.ForClassValue.class).apply();
ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.ForStaticField.class).apply(); ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.ForStaticField.class).apply();
ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.ForThisInstance.class).apply(); ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.ForThisInstance.class).apply();
ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.ForJavaInstance.class).apply();
ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.Resolved.Simple.class).apply(); ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.Resolved.Simple.class).apply();
ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.ConstantPoolWrapper.class).apply(); ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.ConstantPoolWrapper.class).apply();
ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.ConstantPoolWrapper.WrappingArgumentProvider.class).apply(); ObjectPropertyAssertion.of(InvokeDynamic.InvocationProvider.ArgumentProvider.ConstantPoolWrapper.WrappingArgumentProvider.class).apply();
Expand All @@ -424,6 +434,16 @@ public void testObjectProperties() throws Exception {
ObjectPropertyAssertion.of(InvokeDynamic.TerminationHandler.ForChainedInvocation.class).apply(); ObjectPropertyAssertion.of(InvokeDynamic.TerminationHandler.ForChainedInvocation.class).apply();
} }


private static Object makeMethodType(Class<?> returnType, Class<?>... parameterType) throws Exception {
return JavaType.METHOD_TYPE.load().getDeclaredMethod("methodType", Class.class, Class[].class).invoke(null, returnType, parameterType);
}

private static Object makeMethodHandle() throws Exception {
Object lookup = Class.forName("java.lang.invoke.MethodHandles").getDeclaredMethod("publicLookup").invoke(null);
return JavaType.METHOD_HANDLES_LOOKUP.load().getDeclaredMethod("findVirtual", Class.class, String.class, JavaType.METHOD_TYPE.load())
.invoke(lookup, Simple.class, FOO, makeMethodType(String.class));
}

public static class Simple { public static class Simple {


public String foo() { public String foo() {
Expand All @@ -433,7 +453,7 @@ public String foo() {


public static class SimpleWithField { public static class SimpleWithField {


protected String foo; public String foo;


public String foo() { public String foo() {
return null; return null;
Expand Down
@@ -1,9 +1,6 @@
package net.bytebuddy.test.precompiled; package net.bytebuddy.test.precompiled;


import java.lang.invoke.CallSite; import java.lang.invoke.*;
import java.lang.invoke.ConstantCallSite;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;


public class ArgumentBootstrap { public class ArgumentBootstrap {


Expand All @@ -20,10 +17,15 @@ public static String foo(boolean arg0,
long arg5, long arg5,
float arg6, float arg6,
double arg7, double arg7,
String arg8, Class<?> arg8,
Class<?> arg9, MethodType arg9,
Object arg10) { MethodHandle arg10,
return "" + arg0 + arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9 + arg10; String arg11,
Class<?> arg12,
MethodType arg13,
MethodHandle arg14,
Object arg15) {
return "" + arg0 + arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9 + arg10 + arg11 + arg12 + arg13 + arg14 + arg15;
} }


public static String bar(Boolean arg0, public static String bar(Boolean arg0,
Expand All @@ -36,8 +38,10 @@ public static String bar(Boolean arg0,
Double arg7, Double arg7,
String arg8, String arg8,
Class<?> arg9, Class<?> arg9,
Object arg10) { MethodType arg10,
return "" + arg0 + arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9 + arg10; MethodHandle arg11,
Object arg12) {
return "" + arg0 + arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9 + arg10 + arg11 + arg12;
} }


public static String qux(String arg) { public static String qux(String arg) {
Expand Down
@@ -1,9 +1,6 @@
package net.bytebuddy.test.precompiled; package net.bytebuddy.test.precompiled;


import java.lang.invoke.CallSite; import java.lang.invoke.*;
import java.lang.invoke.ConstantCallSite;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;


public class ParameterBootstrap { public class ParameterBootstrap {


Expand All @@ -28,9 +25,11 @@ public static CallSite bootstrapExplicitArguments(MethodHandles.Lookup lookup,
float arg2, float arg2,
double arg3, double arg3,
String arg4, String arg4,
Class<?> arg5) Class<?> arg5,
MethodType arg6,
MethodHandle arg7)
throws NoSuchMethodException, IllegalAccessException { throws NoSuchMethodException, IllegalAccessException {
ParameterBootstrap.arguments = new Object[]{arg0, arg1, arg2, arg3, arg4, arg5}; ParameterBootstrap.arguments = new Object[]{arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7};
return new ConstantCallSite(lookup.findStatic(ParameterBootstrap.class, methodName, methodType)); return new ConstantCallSite(lookup.findStatic(ParameterBootstrap.class, methodName, methodType));
} }


Expand Down
@@ -1,5 +1,8 @@
package net.bytebuddy.test.precompiled; package net.bytebuddy.test.precompiled;


/**
* This class must be compiled with enabling {@code -parameters} for the related tests to work!
*/
public abstract class ParameterNames { public abstract class ParameterNames {


public ParameterNames(String first, final int second) { public ParameterNames(String first, final int second) {
Expand Down

0 comments on commit 9a123b9

Please sign in to comment.