package net.bytebuddy.asm;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.field.FieldList;
import net.bytebuddy.description.method.MethodList;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.bytecode.assign.Assigner;
import net.bytebuddy.pool.TypePool;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Locale;
import static junit.framework.TestCase.fail;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
@RunWith(Parameterized.class)
public class AdviceTypeTest {
private static final String FOO = "foo", BAR = "bar", ENTER = "enter", EXIT = "exit", exception = "exception";
private static final String FIELD = "field", MUTATED = "mutated", STATIC_FIELD = "staticField", MUTATED_STATIC_FIELD = "mutatedStatic";
private static final byte VALUE = 42;
private static final boolean BOOLEAN = true;
private static final byte NUMERIC_DEFAULT = 0;
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{VoidInlineAdvice.class, Void.class, null},
{VoidDelegatingAdvice.class, Void.class, null},
{BooleanInlineAdvice.class, boolean.class, BOOLEAN},
{BooleanDelegationAdvice.class, boolean.class, BOOLEAN},
{ByteInlineAdvice.class, byte.class, VALUE},
{ByteDelegationAdvice.class, byte.class, VALUE},
{ShortInlineAdvice.class, short.class, (short) VALUE},
{ShortDelegationAdvice.class, short.class, (short) VALUE},
{CharacterInlineAdvice.class, char.class, (char) VALUE},
{CharacterDelegationAdvice.class, char.class, (char) VALUE},
{IntegerInlineAdvice.class, int.class, (int) VALUE},
{IntegerDelegationAdvice.class, int.class, (int) VALUE},
{LongInlineAdvice.class, long.class, (long) VALUE},
{LongDelegationAdvice.class, long.class, (long) VALUE},
{FloatInlineAdvice.class, float.class, (float) VALUE},
{FloatDelegationAdvice.class, float.class, (float) VALUE},
{DoubleInlineAdvice.class, double.class, (double) VALUE},
{DoubleDelegationAdvice.class, double.class, (double) VALUE},
{ReferenceInlineAdvice.class, Object.class, FOO},
{ReferenceDelegationAdvice.class, Object.class, FOO}
});
}
private final Class<?> advice;
private final Class<?> type;
private final Serializable value;
public AdviceTypeTest(Class<?> advice, Class<?> type, Serializable value) {
this.advice = advice;
this.type = type;
this.value = value;
}
@Test
public void testAdvice() throws Exception {
Class<?> type = new ByteBuddy()
.redefine(advice)
.visit(new SerializationAssertion())
.visit(Advice.withCustomMapping()
.bind(CustomAnnotation.class, value)
.to(advice)
.on(named(FOO)))
.make()
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertThat(type.getDeclaredMethod(FOO, this.type, this.type).invoke(type.getDeclaredConstructor().newInstance(), value, value), is((Object) value));
assertThat(type.getDeclaredField(ENTER).get(null), is((Object) 1));
assertThat(type.getDeclaredField(EXIT).get(null), is((Object) 1));
}
@Test
public void testAdviceWithException() throws Exception {
Class<?> type = new ByteBuddy()
.redefine(advice)
.visit(new SerializationAssertion())
.visit(Advice.withCustomMapping()
.bind(CustomAnnotation.class, value)
.to(advice)
.on(named(BAR)))
.make()
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
type.getDeclaredField(exception).set(null, true);
try {
assertThat(type.getDeclaredMethod(BAR, this.type, this.type).invoke(type.getDeclaredConstructor().newInstance(), value, value), is((Object) value));
fail();
} catch (InvocationTargetException exception) {
assertThat(exception.getCause(), instanceOf(RuntimeException.class));
}
assertThat(type.getDeclaredField(ENTER).get(null), is((Object) 1));
assertThat(type.getDeclaredField(EXIT).get(null), is((Object) 1));
}
@Test
public void testAdviceWithProperty() throws Exception {
if (type == Void.class) {
return; // No void property on annotations.
}
Class<?> type = new ByteBuddy()
.redefine(advice)
.visit(new SerializationAssertion())
.visit(Advice.withCustomMapping()
.bindProperty(CustomAnnotation.class, this.type.getSimpleName().toLowerCase(Locale.US) + "Value")
.to(advice)
.on(named(FOO)))
.make()
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertThat(type.getDeclaredMethod(FOO, this.type, this.type).invoke(type.getDeclaredConstructor().newInstance(), value, value), is((Object) value));
assertThat(type.getDeclaredField(ENTER).get(null), is((Object) 1));
assertThat(type.getDeclaredField(EXIT).get(null), is((Object) 1));
}
@SuppressWarnings("unused")
public static class VoidInlineAdvice {
public static int enter, exit;
public static boolean exception;
public void foo(Void ignoredArgument, Void ignoredMutableArgument) {
/* empty */
}
public void bar(Void ignoredArgument, Void ignoredMutableArgument) {
throw new RuntimeException();
}
@Advice.OnMethodEnter
public static void enter(@Advice.AllArguments Object[] boxed,
@Advice.StubValue Object stubValue,
@CustomAnnotation Void custom) {
if (boxed.length != 2 || boxed[0] != null || boxed[1] != null) {
throw new AssertionError();
}
if (stubValue != null) {
throw new AssertionError();
}
if (custom != null) {
throw new AssertionError();
}
enter++;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static void exit(@Advice.Thrown Throwable throwable,
@Advice.Return(typing = Assigner.Typing.DYNAMIC) Object boxedReturn,
@Advice.AllArguments Object[] boxed,
@CustomAnnotation Void custom) {
if (!(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (boxedReturn != null) {
throw new AssertionError();
}
if (boxed.length != 2 || boxed[0] != null || boxed[1] != null) {
throw new AssertionError();
}
if (custom != null) {
throw new AssertionError();
}
exit++;
}
}
@SuppressWarnings("unused")
public static class VoidDelegatingAdvice {
public static int enter, exit;
public static boolean exception;
public void foo(Void ignoredArgument, Void ignored) {
/* empty */
}
public void bar(Void ignoredArgument, Void ignored) {
throw new RuntimeException();
}
@Advice.OnMethodEnter(inline = false)
public static void enter(@Advice.AllArguments Object[] boxed,
@Advice.StubValue Object stubValue,
@CustomAnnotation Void custom) {
if (boxed.length != 2 || boxed[0] != null || boxed[1] != null) {
throw new AssertionError();
}
if (stubValue != null) {
throw new AssertionError();
}
if (custom != null) {
throw new AssertionError();
}
enter++;
}
@Advice.OnMethodExit(inline = false, onThrowable = Exception.class)
public static void exit(@Advice.Thrown Throwable throwable,
@Advice.Return(typing = Assigner.Typing.DYNAMIC) Object boxedReturn,
@Advice.AllArguments Object[] boxed,
@CustomAnnotation Void custom) {
if (!(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (boxedReturn != null) {
throw new AssertionError();
}
if (boxed.length != 2 || boxed[0] != null || boxed[1] != null) {
throw new AssertionError();
}
if (custom != null) {
throw new AssertionError();
}
exit++;
}
}
@SuppressWarnings("unused")
public static class BooleanInlineAdvice {
public static int enter, exit;
public static boolean exception;
private boolean field = BOOLEAN, mutated = BOOLEAN;
private static boolean staticField = BOOLEAN, mutatedStatic = BOOLEAN;
public boolean foo(boolean argument, boolean mutableArgument) {
return argument;
}
public boolean bar(boolean argument, boolean mutableArgument) {
throw new RuntimeException();
}
@Advice.OnMethodEnter
public static boolean enter(@Advice.Unused boolean value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) boolean argument,
@Advice.Argument(value = 1, readOnly = false) boolean mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) boolean field,
@Advice.FieldValue(STATIC_FIELD) boolean staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) boolean mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) boolean mutatedStatic,
@CustomAnnotation boolean custom) {
if (value) {
throw new AssertionError();
}
value = BOOLEAN;
if (value) {
throw new AssertionError();
}
if ((Boolean) stubValue) {
throw new AssertionError();
}
if (!argument || !mutableArgument) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(BOOLEAN) || !boxed[1].equals(BOOLEAN)) {
throw new AssertionError();
}
mutableArgument = false;
if (boxed.length != 2 || !boxed[0].equals(BOOLEAN) || !boxed[1].equals(false)) {
throw new AssertionError();
}
if (!field || !mutated || !staticField || !mutatedStatic) {
throw new AssertionError();
}
mutated = mutatedStatic = false;
if (!custom) {
throw new AssertionError();
}
enter++;
return BOOLEAN;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static boolean exit(@Advice.Return boolean result,
@Advice.StubValue Object stubValue,
@Advice.Enter boolean enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) boolean argument,
@Advice.AllArguments Object[] boxed,
@Advice.Argument(value = 1, readOnly = false) boolean mutableArgument,
@Advice.FieldValue(FIELD) boolean field,
@Advice.FieldValue(STATIC_FIELD) boolean staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) boolean mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) boolean mutatedStatic,
@CustomAnnotation boolean custom) {
if (result == exception
|| !enter
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (boxedReturn.equals(exception)) {
throw new AssertionError();
}
if (!argument || mutableArgument) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(BOOLEAN) || !boxed[1].equals(false)) {
throw new AssertionError();
}
if (!field || mutated || !staticField || mutatedStatic) {
throw new AssertionError();
}
if (!custom) {
throw new AssertionError();
}
exit++;
return BOOLEAN;
}
}
@SuppressWarnings("unused")
public static class BooleanDelegationAdvice {
public static int enter, exit;
public static boolean exception;
private boolean field = BOOLEAN;
private static boolean staticField = BOOLEAN;
public boolean foo(boolean argument, boolean ignored) {
return argument;
}
public boolean bar(boolean argument, boolean ignored) {
throw new RuntimeException();
}
@Advice.OnMethodEnter(inline = false)
public static boolean enter(@Advice.Unused boolean value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) boolean argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) boolean field,
@Advice.FieldValue(STATIC_FIELD) boolean staticField,
@CustomAnnotation boolean custom) {
if (value) {
throw new AssertionError();
}
if ((Boolean) stubValue) {
throw new AssertionError();
}
if (!argument) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(BOOLEAN) || !boxed[1].equals(BOOLEAN)) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(BOOLEAN) || !boxed[1].equals(BOOLEAN)) {
throw new AssertionError();
}
if (!field || !staticField) {
throw new AssertionError();
}
if (!custom) {
throw new AssertionError();
}
enter++;
return BOOLEAN;
}
@Advice.OnMethodExit(inline = false, onThrowable = Exception.class)
public static boolean exit(@Advice.Return boolean result,
@Advice.Enter boolean enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) boolean argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) boolean field,
@Advice.FieldValue(STATIC_FIELD) boolean staticField,
@CustomAnnotation boolean custom) {
if (result == exception
|| !enter
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (boxedReturn.equals(exception)) {
throw new AssertionError();
}
if (!argument) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(BOOLEAN) || !boxed[1].equals(BOOLEAN)) {
throw new AssertionError();
}
if (!field || !staticField) {
throw new AssertionError();
}
if (!custom) {
throw new AssertionError();
}
exit++;
return BOOLEAN;
}
}
@SuppressWarnings("unused")
public static class ByteInlineAdvice {
public static int enter, exit;
public static boolean exception;
private byte field = VALUE, mutated = VALUE;
private static byte staticField = VALUE, mutatedStatic = VALUE;
public byte foo(byte argument, byte mutableArgument) {
return argument;
}
public byte bar(byte argument, byte mutableArgument) {
throw new RuntimeException();
}
@Advice.OnMethodEnter
public static byte enter(@Advice.Unused byte value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) byte argument,
@Advice.Argument(value = 1, readOnly = false) byte mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) byte field,
@Advice.FieldValue(STATIC_FIELD) byte staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) byte mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) byte mutatedStatic,
@CustomAnnotation byte custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
value = VALUE;
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Byte) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(VALUE) || !boxed[1].equals(VALUE)) {
throw new AssertionError();
}
mutableArgument = VALUE * 2;
if (boxed.length != 2 || !boxed[0].equals(VALUE) || !boxed[1].equals((byte) (VALUE * 2))) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE || staticField != VALUE || mutatedStatic != VALUE) {
throw new AssertionError();
}
mutated = mutatedStatic = VALUE * 2;
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static byte exit(@Advice.Return byte result,
@Advice.Enter byte enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) byte argument,
@Advice.Argument(value = 1, readOnly = false) byte mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) byte field,
@Advice.FieldValue(STATIC_FIELD) byte staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) byte mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) byte mutatedStatic,
@CustomAnnotation byte custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals(exception ? NUMERIC_DEFAULT : VALUE)) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE * 2) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(VALUE) || !boxed[1].equals((byte) (VALUE * 2))) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE * 2 || staticField != VALUE || mutatedStatic != VALUE * 2) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class ByteDelegationAdvice {
public static int enter, exit;
public static boolean exception;
private byte field = VALUE;
private static byte staticField = VALUE;
public byte foo(byte argument, byte ignored) {
return argument;
}
public byte bar(byte argument, byte ignored) {
throw new RuntimeException();
}
@Advice.OnMethodEnter(inline = false)
public static byte enter(@Advice.Unused byte value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) byte argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) byte field,
@Advice.FieldValue(STATIC_FIELD) byte staticField,
@CustomAnnotation byte custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Byte) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(VALUE) || !boxed[1].equals(VALUE)) {
throw new AssertionError();
}
if (field != VALUE || staticField != VALUE) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(inline = false, onThrowable = Exception.class)
public static byte exit(@Advice.Return byte result,
@Advice.Enter byte enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) byte argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) byte field,
@Advice.FieldValue(STATIC_FIELD) byte staticField,
@CustomAnnotation byte custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals(exception ? NUMERIC_DEFAULT : VALUE)) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(VALUE) || !boxed[1].equals(VALUE)) {
throw new AssertionError();
}
if (field != VALUE || staticField != VALUE) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class ShortInlineAdvice {
public static int enter, exit;
public static boolean exception;
private short field = VALUE, mutated = VALUE;
private static short staticField = VALUE, mutatedStatic = VALUE;
public short foo(short argument, short mutableArgument) {
return argument;
}
public short bar(short argument, short mutableArgument) {
throw new RuntimeException();
}
@Advice.OnMethodEnter
public static short enter(@Advice.Unused short value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) short argument,
@Advice.Argument(value = 1, readOnly = false) short mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) short field,
@Advice.FieldValue(STATIC_FIELD) short staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) short mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) short mutatedStatic,
@CustomAnnotation short custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
value = VALUE;
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Short) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((short) VALUE) || !boxed[1].equals((short) VALUE)) {
throw new AssertionError();
}
mutableArgument = VALUE * 2;
if (boxed.length != 2 || !boxed[0].equals((short) VALUE) || !boxed[1].equals((short) (VALUE * 2))) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE || staticField != VALUE || mutatedStatic != VALUE) {
throw new AssertionError();
}
mutated = mutatedStatic = VALUE * 2;
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static short exit(@Advice.Return short result,
@Advice.Enter short enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) short argument,
@Advice.Argument(value = 1, readOnly = false) short mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) short field,
@Advice.FieldValue(STATIC_FIELD) short staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) short mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) short mutatedStatic,
@CustomAnnotation short custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals((short) (exception ? NUMERIC_DEFAULT : VALUE))) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE * 2) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((short) VALUE) || !boxed[1].equals((short) (VALUE * 2))) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE * 2 || staticField != VALUE || mutatedStatic != VALUE * 2) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class ShortDelegationAdvice {
public static int enter, exit;
public static boolean exception;
private short field = VALUE;
private static short staticField = VALUE;
public short foo(short argument, short ignored) {
return argument;
}
public short bar(short argument, short ignored) {
throw new RuntimeException();
}
@Advice.OnMethodEnter(inline = false)
public static short enter(@Advice.Unused short value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) short argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) short field,
@Advice.FieldValue(STATIC_FIELD) short staticField,
@CustomAnnotation short custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Short) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((short) VALUE) || !boxed[1].equals((short) VALUE)) {
throw new AssertionError();
}
if (field != VALUE || staticField != VALUE) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(inline = false, onThrowable = Exception.class)
public static short exit(@Advice.Return short result,
@Advice.Enter short enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) short argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) short field,
@Advice.FieldValue(STATIC_FIELD) short staticField,
@CustomAnnotation short custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals((short) (exception ? NUMERIC_DEFAULT : VALUE))) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((short) VALUE) || !boxed[1].equals((short) VALUE)) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class CharacterInlineAdvice {
public static int enter, exit;
public static boolean exception;
private char field = VALUE, mutated = VALUE;
private static char staticField = VALUE, mutatedStatic = VALUE;
public char foo(char argument, char mutableArgument) {
return argument;
}
public char bar(char argument, char mutableArgument) {
throw new RuntimeException();
}
@Advice.OnMethodEnter
public static char enter(@Advice.Unused char value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) char argument,
@Advice.Argument(value = 1, readOnly = false) char mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) char field,
@Advice.FieldValue(STATIC_FIELD) char staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) char mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) char mutatedStatic,
@CustomAnnotation char custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
value = VALUE;
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Character) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((char) VALUE) || !boxed[1].equals((char) VALUE)) {
throw new AssertionError();
}
mutableArgument = VALUE * 2;
if (boxed.length != 2 || !boxed[0].equals((char) VALUE) || !boxed[1].equals((char) (VALUE * 2))) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE || staticField != VALUE || mutatedStatic != VALUE) {
throw new AssertionError();
}
mutated = mutatedStatic = VALUE * 2;
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static char exit(@Advice.Return char result,
@Advice.Enter char enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) char argument,
@Advice.Argument(value = 1, readOnly = false) char mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) char field,
@Advice.FieldValue(STATIC_FIELD) char staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) char mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) char mutatedStatic,
@CustomAnnotation char custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals((char) (exception ? NUMERIC_DEFAULT : VALUE))) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE * 2) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((char) VALUE) || !boxed[1].equals((char) (VALUE * 2))) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE * 2 || staticField != VALUE || mutatedStatic != VALUE * 2) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class CharacterDelegationAdvice {
public static int enter, exit;
public static boolean exception;
private char field = VALUE;
private static char staticField = VALUE;
public char foo(char argument, char ignored) {
return argument;
}
public char bar(char argument, char ignored) {
throw new RuntimeException();
}
@Advice.OnMethodEnter(inline = false)
public static char enter(@Advice.Unused char value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) char argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) char field,
@Advice.FieldValue(STATIC_FIELD) char staticField,
@CustomAnnotation char custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Character) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((char) VALUE) || !boxed[1].equals((char) VALUE)) {
throw new AssertionError();
}
if (field != VALUE || staticField != VALUE) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(inline = false, onThrowable = Exception.class)
public static char exit(@Advice.Return char result,
@Advice.Enter char enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) char argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) char field,
@Advice.FieldValue(STATIC_FIELD) char staticField,
@CustomAnnotation char custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals((char) (exception ? NUMERIC_DEFAULT : VALUE))) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((char) VALUE) || !boxed[1].equals((char) VALUE)) {
throw new AssertionError();
}
if (field != VALUE || staticField != VALUE) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class IntegerInlineAdvice {
public static int enter, exit;
public static boolean exception;
private int field = VALUE, mutated = VALUE;
private static int staticField = VALUE, mutatedStatic = VALUE;
public int foo(int argument, int mutableArgument) {
return argument;
}
public int bar(int argument, int mutableArgument) {
throw new RuntimeException();
}
@Advice.OnMethodEnter
public static int enter(@Advice.Unused int value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) int argument,
@Advice.Argument(value = 1, readOnly = false) int mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) int field,
@Advice.FieldValue(STATIC_FIELD) int staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) int mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) int mutatedStatic,
@CustomAnnotation int custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
value = VALUE;
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Integer) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((int) VALUE) || !boxed[1].equals((int) (VALUE))) {
throw new AssertionError();
}
mutableArgument = VALUE * 2;
mutableArgument++;
if (boxed.length != 2 || !boxed[0].equals((int) VALUE) || !boxed[1].equals(VALUE * 2 + 1)) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE || staticField != VALUE || mutatedStatic != VALUE) {
throw new AssertionError();
}
mutated = mutatedStatic = VALUE * 2;
mutated++;
mutatedStatic++;
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static int exit(@Advice.Return int result,
@Advice.Enter int enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) int argument,
@Advice.Argument(value = 1, readOnly = false) int mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) int field,
@Advice.FieldValue(STATIC_FIELD) int staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) int mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) int mutatedStatic,
@CustomAnnotation int custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals((int) (exception ? NUMERIC_DEFAULT : VALUE))) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE * 2 + 1) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((int) VALUE) || !boxed[1].equals(VALUE * 2 + 1)) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE * 2 + 1 || staticField != VALUE || mutatedStatic != VALUE * 2 + 1) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class IntegerDelegationAdvice {
public static int enter, exit;
public static boolean exception;
private int field = VALUE;
private static int staticField = VALUE;
public int foo(int argument, int ignored) {
return argument;
}
public int bar(int argument, int ignored) {
throw new RuntimeException();
}
@Advice.OnMethodEnter(inline = false)
public static int enter(@Advice.Unused int value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) int argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) int field,
@Advice.FieldValue(STATIC_FIELD) int staticField,
@CustomAnnotation int custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Integer) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((int) VALUE) || !boxed[1].equals((int) (VALUE))) {
throw new AssertionError();
}
if (field != VALUE || staticField != VALUE) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(inline = false, onThrowable = Exception.class)
public static int exit(@Advice.Return int result,
@Advice.Enter int enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) int argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) int field,
@Advice.FieldValue(STATIC_FIELD) int staticField,
@CustomAnnotation int custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals((int) (exception ? NUMERIC_DEFAULT : VALUE))) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((int) VALUE) || !boxed[1].equals((int) VALUE)) {
throw new AssertionError();
}
if (field != VALUE || staticField != VALUE) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class LongInlineAdvice {
public static int enter, exit;
public static boolean exception;
private long field = VALUE, mutated = VALUE;
private static long staticField = VALUE, mutatedStatic = VALUE;
public long foo(long argument, long mutableArgument) {
return argument;
}
public long bar(long argument, long mutableArgument) {
throw new RuntimeException();
}
@Advice.OnMethodEnter
public static long enter(@Advice.Unused long value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) long argument,
@Advice.Argument(value = 1, readOnly = false) long mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) long field,
@Advice.FieldValue(STATIC_FIELD) long staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) long mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) long mutatedStatic,
@CustomAnnotation long custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
value = VALUE;
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Long) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((long) VALUE) || !boxed[1].equals((long) (VALUE))) {
throw new AssertionError();
}
mutableArgument = VALUE * 2;
if (boxed.length != 2 || !boxed[0].equals((long) VALUE) || !boxed[1].equals((long) (VALUE * 2))) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE || staticField != VALUE || mutatedStatic != VALUE) {
throw new AssertionError();
}
mutated = mutatedStatic = VALUE * 2;
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static long exit(@Advice.Return long result,
@Advice.Enter long enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) long argument,
@Advice.Argument(value = 1, readOnly = false) long mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) long field,
@Advice.FieldValue(STATIC_FIELD) long staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) long mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) long mutatedStatic,
@CustomAnnotation long custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals((long) (exception ? NUMERIC_DEFAULT : VALUE))) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE * 2) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((long) VALUE) || !boxed[1].equals((long) (VALUE * 2))) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE * 2 || staticField != VALUE || mutatedStatic != VALUE * 2) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class LongDelegationAdvice {
public static int enter, exit;
public static boolean exception;
private long field = VALUE;
private static long staticField = VALUE;
public long foo(long argument, long ignored) {
return argument;
}
public long bar(long argument, long ignored) {
throw new RuntimeException();
}
@Advice.OnMethodEnter(inline = false)
public static long enter(@Advice.Unused long value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) long argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) long field,
@Advice.FieldValue(STATIC_FIELD) long staticField,
@CustomAnnotation long custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Long) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((long) VALUE) || !boxed[1].equals((long) (VALUE))) {
throw new AssertionError();
}
if (field != VALUE || staticField != VALUE) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(inline = false, onThrowable = Exception.class)
public static long exit(@Advice.Return long result,
@Advice.Enter long enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) long argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) long field,
@Advice.FieldValue(STATIC_FIELD) long staticField,
@CustomAnnotation long custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals((long) (exception ? NUMERIC_DEFAULT : VALUE))) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((long) VALUE) || !boxed[1].equals((long) VALUE)) {
throw new AssertionError();
}
if (field != VALUE || staticField != VALUE) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class FloatInlineAdvice {
public static int enter, exit;
public static boolean exception;
private float field = VALUE, mutated = VALUE;
private static float staticField = VALUE, mutatedStatic = VALUE;
public float foo(float argument, float mutableArgument) {
return argument;
}
public float bar(float argument, float mutableArgument) {
throw new RuntimeException();
}
@Advice.OnMethodEnter
public static float enter(@Advice.Unused float value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) float argument,
@Advice.Argument(value = 1, readOnly = false) float mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) float field,
@Advice.FieldValue(STATIC_FIELD) float staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) float mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) float mutatedStatic,
@CustomAnnotation float custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
value = VALUE;
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Float) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((float) VALUE) || !boxed[1].equals((float) (VALUE))) {
throw new AssertionError();
}
mutableArgument = VALUE * 2;
if (boxed.length != 2 || !boxed[0].equals((float) VALUE) || !boxed[1].equals((float) (VALUE * 2))) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE || staticField != VALUE || mutatedStatic != VALUE) {
throw new AssertionError();
}
mutated = mutatedStatic = VALUE * 2;
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static float exit(@Advice.Return float result,
@Advice.Enter float enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) float argument,
@Advice.Argument(value = 1, readOnly = false) float mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) float field,
@Advice.FieldValue(STATIC_FIELD) float staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) float mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) float mutatedStatic,
@CustomAnnotation float custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals((float) (exception ? NUMERIC_DEFAULT : VALUE))) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE * 2) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((float) VALUE) || !boxed[1].equals((float) (VALUE * 2))) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE * 2 || staticField != VALUE || mutatedStatic != VALUE * 2) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class FloatDelegationAdvice {
public static int enter, exit;
public static boolean exception;
private float field = VALUE;
private static float staticField = VALUE;
public float foo(float argument, float ignored) {
return argument;
}
public float bar(float argument, float ignored) {
throw new RuntimeException();
}
@Advice.OnMethodEnter(inline = false)
public static float enter(@Advice.Unused float value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) float argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) float field,
@Advice.FieldValue(STATIC_FIELD) float staticField,
@CustomAnnotation float custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Float) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((float) VALUE) || !boxed[1].equals((float) (VALUE))) {
throw new AssertionError();
}
if (field != VALUE || staticField != VALUE) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(inline = false, onThrowable = Exception.class)
public static float exit(@Advice.Return float result,
@Advice.Enter float enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) float argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) float field,
@Advice.FieldValue(STATIC_FIELD) float staticField,
@CustomAnnotation float custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals((float) (exception ? NUMERIC_DEFAULT : VALUE))) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((float) VALUE) || !boxed[1].equals((float) VALUE)) {
throw new AssertionError();
}
if (field != VALUE || staticField != VALUE) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class DoubleInlineAdvice {
public static int enter, exit;
public static boolean exception;
private double field = VALUE, mutated = VALUE;
private static double staticField = VALUE, mutatedStatic = VALUE;
public double foo(double argument, double mutableArgument) {
return argument;
}
public double bar(double argument, double mutableArgument) {
throw new RuntimeException();
}
@Advice.OnMethodEnter
public static double enter(@Advice.Unused double value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) double argument,
@Advice.Argument(value = 1, readOnly = false) double mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) double field,
@Advice.FieldValue(STATIC_FIELD) double staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) double mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) double mutatedStatic,
@CustomAnnotation double custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
value = VALUE;
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Double) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((double) VALUE) || !boxed[1].equals((double) (VALUE))) {
throw new AssertionError();
}
mutableArgument = VALUE * 2;
if (boxed.length != 2 || !boxed[0].equals((double) VALUE) || !boxed[1].equals((double) (VALUE * 2))) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE || staticField != VALUE || mutatedStatic != VALUE) {
throw new AssertionError();
}
mutated = mutatedStatic = VALUE * 2;
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static double exit(@Advice.Return double result,
@Advice.Enter double enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) double argument,
@Advice.Argument(value = 1, readOnly = false) double mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) double field,
@Advice.FieldValue(STATIC_FIELD) double staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) double mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) double mutatedStatic,
@CustomAnnotation double custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals((double) (exception ? NUMERIC_DEFAULT : VALUE))) {
throw new AssertionError();
}
if (argument != VALUE || mutableArgument != VALUE * 2) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((double) VALUE) || !boxed[1].equals((double) (VALUE * 2))) {
throw new AssertionError();
}
if (field != VALUE || mutated != VALUE * 2 || staticField != VALUE || mutatedStatic != VALUE * 2) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class DoubleDelegationAdvice {
public static int enter, exit;
public static boolean exception;
private double field = VALUE;
private static double staticField = VALUE;
public double foo(double argument, double ignored) {
return argument;
}
public double bar(double argument, double ignored) {
throw new RuntimeException();
}
@Advice.OnMethodEnter(inline = false)
public static double enter(@Advice.Unused double value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) double argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) double field,
@Advice.FieldValue(STATIC_FIELD) double staticField,
@CustomAnnotation double custom) {
if (value != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if ((Double) stubValue != NUMERIC_DEFAULT) {
throw new AssertionError();
}
if (argument != VALUE) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((double) VALUE) || !boxed[1].equals((double) (VALUE))) {
throw new AssertionError();
}
if (field != VALUE || staticField != VALUE) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
enter++;
return VALUE * 2;
}
@Advice.OnMethodExit(inline = false, onThrowable = Exception.class)
public static double exit(@Advice.Return double result,
@Advice.Enter double enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) double argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) double field,
@Advice.FieldValue(STATIC_FIELD) double staticField,
@CustomAnnotation double custom) {
if (result != (exception ? 0 : VALUE)
|| enter != VALUE * 2
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (!boxedReturn.equals((double) (exception ? NUMERIC_DEFAULT : VALUE))) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals((double) VALUE) || !boxed[1].equals((double) VALUE)) {
throw new AssertionError();
}
if (custom != VALUE) {
throw new AssertionError();
}
exit++;
return VALUE;
}
}
@SuppressWarnings("unused")
public static class ReferenceInlineAdvice {
public static int enter, exit;
public static boolean exception;
private Object field = FOO, mutated = FOO;
private static Object staticField = FOO, mutatedStatic = FOO;
public Object foo(Object argument, Object mutableArgument) {
return argument;
}
public Object bar(Object argument, Object mutableArgument) {
throw new RuntimeException();
}
@Advice.OnMethodEnter
public static Object enter(@Advice.Unused Object value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) Object argument,
@Advice.Argument(value = 1, readOnly = false) Object mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) Object field,
@Advice.FieldValue(STATIC_FIELD) Object staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) Object mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) Object mutatedStatic,
@CustomAnnotation String custom) {
if (value != null) {
throw new AssertionError();
}
value = FOO;
if (value != null) {
throw new AssertionError();
}
if (stubValue != null) {
throw new AssertionError();
}
if (!argument.equals(FOO) || !mutableArgument.equals(FOO)) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(FOO) || !boxed[1].equals(FOO)) {
throw new AssertionError();
}
mutableArgument = BAR;
if (boxed.length != 2 || !boxed[0].equals(FOO) || !boxed[1].equals(BAR)) {
throw new AssertionError();
}
if (!field.equals(FOO) || !mutated.equals(FOO) || !staticField.equals(FOO) || !mutatedStatic.equals(FOO)) {
throw new AssertionError();
}
mutated = mutatedStatic = BAR;
if (!custom.equals(FOO)) {
throw new AssertionError();
}
enter++;
return FOO + BAR;
}
@Advice.OnMethodExit(onThrowable = Exception.class)
public static Object exit(@Advice.Return Object result,
@Advice.Enter Object enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) Object argument,
@Advice.Argument(value = 1, readOnly = false) Object mutableArgument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) Object field,
@Advice.FieldValue(STATIC_FIELD) Object staticField,
@Advice.FieldValue(value = MUTATED, readOnly = false) Object mutated,
@Advice.FieldValue(value = MUTATED_STATIC_FIELD, readOnly = false) Object mutatedStatic,
@CustomAnnotation String custom) {
if ((exception ? result != null : !result.equals(FOO))
|| !enter.equals(FOO + BAR)
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (exception ? boxedReturn != null : !boxedReturn.equals(FOO)) {
throw new AssertionError();
}
if (!argument.equals(FOO) || !mutableArgument.equals(BAR)) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(FOO) || !boxed[1].equals(BAR)) {
throw new AssertionError();
}
if (!field.equals(FOO) || !mutated.equals(BAR) || !staticField.equals(FOO) || !mutatedStatic.equals(BAR)) {
throw new AssertionError();
}
if (!custom.equals(FOO)) {
throw new AssertionError();
}
exit++;
return FOO;
}
}
@SuppressWarnings("unused")
public static class ReferenceDelegationAdvice {
public static int enter, exit;
public static boolean exception;
private Object field = FOO;
private static Object staticField = FOO;
public Object foo(Object argument, Object ignored) {
return argument;
}
public Object bar(Object argument, Object ignored) {
throw new RuntimeException();
}
@Advice.OnMethodEnter(inline = false)
public static Object enter(@Advice.Unused Object value,
@Advice.StubValue Object stubValue,
@Advice.Argument(0) Object argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) Object field,
@Advice.FieldValue(STATIC_FIELD) Object staticField,
@CustomAnnotation String custom) {
if (value != null) {
throw new AssertionError();
}
if (stubValue != null) {
throw new AssertionError();
}
if (!argument.equals(FOO)) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(FOO) || !boxed[1].equals(FOO)) {
throw new AssertionError();
}
if (!field.equals(FOO) || !staticField.equals(FOO)) {
throw new AssertionError();
}
if (!custom.equals(FOO)) {
throw new AssertionError();
}
enter++;
return FOO + BAR;
}
@Advice.OnMethodExit(inline = false, onThrowable = Exception.class)
public static Object exit(@Advice.Return Object result,
@Advice.Enter Object enter,
@Advice.Thrown Throwable throwable,
@Advice.Return Object boxedReturn,
@Advice.Argument(0) Object argument,
@Advice.AllArguments Object[] boxed,
@Advice.FieldValue(FIELD) Object field,
@Advice.FieldValue(STATIC_FIELD) Object staticField,
@CustomAnnotation String custom) {
if ((exception ? result != null : !result.equals(FOO))
|| !enter.equals(FOO + BAR)
|| !(exception ? throwable instanceof RuntimeException : throwable == null)) {
throw new AssertionError();
}
if (exception ? boxedReturn != null : !boxedReturn.equals(FOO)) {
throw new AssertionError();
}
if (!argument.equals(FOO)) {
throw new AssertionError();
}
if (boxed.length != 2 || !boxed[0].equals(FOO) || !boxed[1].equals(FOO)) {
throw new AssertionError();
}
if (!field.equals(FOO) || !staticField.equals(FOO)) {
throw new AssertionError();
}
if (!custom.equals(FOO)) {
throw new AssertionError();
}
exit++;
return FOO;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@SuppressWarnings("unused")
private @interface CustomAnnotation {
boolean booleanValue() default BOOLEAN;
byte byteValue() default VALUE;
short shortValue() default VALUE;
char charValue() default VALUE;
int intValue() default VALUE;
long longValue() default VALUE;
float floatValue() default VALUE;
double doubleValue() default VALUE;
String objectValue() default FOO;
}
private static class SerializationAssertion extends AsmVisitorWrapper.AbstractBase {
@Override
public ClassVisitor wrap(TypeDescription instrumentedType,
ClassVisitor classVisitor,
Implementation.Context implementationContext,
TypePool typePool,
FieldList<FieldDescription.InDefinedShape> fields,
MethodList<?> methods,
int writerFlags,
int readerFlags) {
return new SerializationClassVisitor(classVisitor);
}
private static class SerializationClassVisitor extends ClassVisitor {
public SerializationClassVisitor(ClassVisitor classVisitor) {
super(Opcodes.ASM5, classVisitor);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new SerializationMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions));
}
}
private static class SerializationMethodVisitor extends MethodVisitor {
public SerializationMethodVisitor(MethodVisitor methodVisitor) {
super(Opcodes.ASM5, methodVisitor);
}
@Override
public void visitTypeInsn(int opcode, String type) {
if (type.equals(Type.getInternalName(ObjectInputStream.class))) {
throw new AssertionError("Unexpected deserialization");
}
super.visitTypeInsn(opcode, type);
}
}
}
}