// Generated by delombok at Sun Feb 26 12:31:38 KST 2017
package scouter.bytebuddy.implementation;
import scouter.bytebuddy.description.enumeration.EnumerationDescription;
import scouter.bytebuddy.description.field.FieldDescription;
import scouter.bytebuddy.description.method.MethodDescription;
import scouter.bytebuddy.description.method.MethodList;
import scouter.bytebuddy.description.method.ParameterDescription;
import scouter.bytebuddy.description.method.ParameterList;
import scouter.bytebuddy.description.type.TypeDescription;
import scouter.bytebuddy.dynamic.scaffold.FieldLocator;
import scouter.bytebuddy.dynamic.scaffold.InstrumentedType;
import scouter.bytebuddy.dynamic.scaffold.MethodGraph;
import scouter.bytebuddy.implementation.bytecode.assign.Assigner;
import scouter.bytebuddy.implementation.bytecode.collection.ArrayAccess;
import scouter.bytebuddy.implementation.bytecode.member.FieldAccess;
import scouter.bytebuddy.implementation.bytecode.member.MethodInvocation;
import scouter.bytebuddy.implementation.bytecode.member.MethodReturn;
import scouter.bytebuddy.implementation.bytecode.member.MethodVariableAccess;
import scouter.bytebuddy.matcher.ElementMatcher;
import scouter.bytebuddy.utility.CompoundList;
import scouter.bytebuddy.utility.JavaConstant;
import scouter.bytebuddy.utility.JavaType;
import scouter.bytebuddy.utility.RandomString;
import scouter.bytebuddy.jar.asm.MethodVisitor;
import scouter.bytebuddy.jar.asm.Opcodes;
import scouter.bytebuddy.implementation.bytecode.*;
import scouter.bytebuddy.implementation.bytecode.constant.*;
import scouter.bytebuddy.matcher.ElementMatchers;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
/**
* This {@link Implementation} allows the invocation of a specified method while
* providing explicit arguments to this method.
*/
public class MethodCall implements Implementation.Composable {
/**
* The method locator to use.
*/
protected final MethodLocator methodLocator;
/**
* The target handler to use.
*/
protected final TargetHandler targetHandler;
/**
* The argument loader to load arguments onto the operand stack in their application order.
*/
protected final List<ArgumentLoader.Factory> argumentLoaders;
/**
* The method invoker to use.
*/
protected final MethodInvoker methodInvoker;
/**
* The termination handler to use.
*/
protected final TerminationHandler terminationHandler;
/**
* The assigner to use.
*/
protected final Assigner assigner;
/**
* Indicates if dynamic type castings should be attempted for incompatible assignments.
*/
protected final Assigner.Typing typing;
/**
* Creates a new method call implementation.
*
* @param methodLocator The method locator to use.
* @param targetHandler The target handler to use.
* @param argumentLoaders The argument loader to load arguments onto the operand stack in
* their application order.
* @param methodInvoker The method invoker to use.
* @param terminationHandler The termination handler to use.
* @param assigner The assigner to use.
* @param typing Indicates if dynamic type castings should be attempted for incompatible assignments.
*/
protected MethodCall(MethodLocator methodLocator, TargetHandler targetHandler, List<ArgumentLoader.Factory> argumentLoaders, MethodInvoker methodInvoker, TerminationHandler terminationHandler, Assigner assigner, Assigner.Typing typing) {
this.methodLocator = methodLocator;
this.targetHandler = targetHandler;
this.argumentLoaders = argumentLoaders;
this.methodInvoker = methodInvoker;
this.terminationHandler = terminationHandler;
this.assigner = assigner;
this.typing = typing;
}
/**
* Invokes the given method. Without further specification, the method is invoked without any arguments on
* the instance of the instrumented class or statically, if the given method is {@code static}.
*
* @param method The method to invoke.
* @return A method call implementation that invokes the given method without providing any arguments.
*/
public static WithoutSpecifiedTarget invoke(Method method) {
return invoke(new MethodDescription.ForLoadedMethod(method));
}
/**
* Invokes the given constructor on the instance of the instrumented type.
*
* @param constructor The constructor to invoke.
* @return A method call implementation that invokes the given constructor without providing any arguments.
*/
public static WithoutSpecifiedTarget invoke(Constructor<?> constructor) {
return invoke(new MethodDescription.ForLoadedConstructor(constructor));
}
/**
* Invokes the given method. If the method description describes a constructor, it is automatically invoked as
* a special method invocation on the instance of the instrumented type. The same is true for {@code private}
* methods. Finally, {@code static} methods are invoked statically.
*
* @param methodDescription The method to invoke.
* @return A method call implementation that invokes the given method without providing any arguments.
*/
public static WithoutSpecifiedTarget invoke(MethodDescription methodDescription) {
return invoke(new MethodLocator.ForExplicitMethod(methodDescription));
}
/**
* Invokes a unique virtual method of the instrumented type that is matched by the specified matcher.
*
* @param matcher The matcher to identify the method to invoke.
* @return A method call for the uniquely identified method.
*/
public static WithoutSpecifiedTarget invoke(ElementMatcher<? super MethodDescription> matcher) {
return invoke(matcher, MethodGraph.Compiler.DEFAULT);
}
/**
* Invokes a unique virtual method of the instrumented type that is matched by the specified matcher.
*
* @param matcher The matcher to identify the method to invoke.
* @param methodGraphCompiler The method graph compiler to use.
* @return A method call for the uniquely identified method.
*/
public static WithoutSpecifiedTarget invoke(ElementMatcher<? super MethodDescription> matcher, MethodGraph.Compiler methodGraphCompiler) {
return invoke(new MethodLocator.ForElementMatcher(matcher, methodGraphCompiler));
}
/**
* Invokes a method using the provided method locator.
*
* @param methodLocator The method locator to apply for locating the method to invoke given the instrumented
* method.
* @return A method call implementation that uses the provided method locator for resolving the method
* to be invoked.
*/
public static WithoutSpecifiedTarget invoke(MethodLocator methodLocator) {
return new WithoutSpecifiedTarget(methodLocator);
}
/**
* Invokes the instrumented method recursively. Invoking this method on the same instance causes a {@link StackOverflowError} due to
* infinite recursion.
*
* @return A method call that invokes the method being instrumented.
*/
public static WithoutSpecifiedTarget invokeSelf() {
return new WithoutSpecifiedTarget(MethodLocator.ForInstrumentedMethod.INSTANCE);
}
/**
* Invokes the instrumented method as a super method call on the instance itself. This is a shortcut for {@code invokeSelf().onSuper()}.
*
* @return A method call that invokes the method being instrumented as a super method call.
*/
public static MethodCall invokeSuper() {
return invokeSelf().onSuper();
}
/**
* Implements a method by invoking the provided {@link Callable}. The return value of the provided object is casted to the implemented method's
* return type, if necessary.
*
* @param callable The callable to invoke when a method is intercepted.
* @return A composable method implementation that invokes the given callable.
*/
public static Composable call(Callable<?> callable) {
try {
return invoke(Callable.class.getMethod("call")).on(callable, Callable.class).withAssigner(Assigner.DEFAULT, Assigner.Typing.DYNAMIC);
} catch (NoSuchMethodException exception) {
throw new IllegalStateException("Could not locate Callable::call method", exception);
}
}
/**
* Implements a method by invoking the provided {@link Runnable}. If the instrumented method returns a value, {@code null} is returned.
*
* @param runnable The runnable to invoke when a method is intercepted.
* @return A composable method implementation that invokes the given runnable.
*/
public static Composable run(Runnable runnable) {
try {
return invoke(Runnable.class.getMethod("run")).on(runnable, Runnable.class).withAssigner(Assigner.DEFAULT, Assigner.Typing.DYNAMIC);
} catch (NoSuchMethodException exception) {
throw new IllegalStateException("Could not locate Runnable::run method", exception);
}
}
/**
* Invokes the given constructor in order to create an instance.
*
* @param constructor The constructor to invoke.
* @return A method call that invokes the given constructor without providing any arguments.
*/
public static MethodCall construct(Constructor<?> constructor) {
return construct(new MethodDescription.ForLoadedConstructor(constructor));
}
/**
* Invokes the given constructor in order to create an instance.
*
* @param methodDescription A description of the constructor to invoke.
* @return A method call that invokes the given constructor without providing any arguments.
*/
public static MethodCall construct(MethodDescription methodDescription) {
if (!methodDescription.isConstructor()) {
throw new IllegalArgumentException("Not a constructor: " + methodDescription);
}
return new MethodCall(new MethodLocator.ForExplicitMethod(methodDescription), TargetHandler.ForConstructingInvocation.INSTANCE, Collections.<ArgumentLoader.Factory>emptyList(), MethodInvoker.ForContextualInvocation.INSTANCE, TerminationHandler.RETURNING, Assigner.DEFAULT, Assigner.Typing.STATIC);
}
/**
* Defines a number of arguments to be handed to the method that is being invoked by this implementation. Any
* wrapper type instances for primitive values, instances of {@link java.lang.String} or {@code null} are loaded
* directly onto the operand stack. This might corrupt referential identity for these values. Any other values
* are stored within a {@code static} field that is added to the instrumented type.
*
* @param argument The arguments to provide to the method that is being called in their order.
* @return A method call that hands the provided arguments to the invoked method.
*/
public MethodCall with(Object... argument) {
List<ArgumentLoader.Factory> argumentLoaders = new ArrayList<ArgumentLoader.Factory>(argument.length);
for (Object anArgument : argument) {
argumentLoaders.add(ArgumentLoader.ForInstance.Factory.of(anArgument));
}
return new MethodCall(methodLocator, targetHandler, CompoundList.of(this.argumentLoaders, argumentLoaders), methodInvoker, terminationHandler, assigner, typing);
}
/**
* Defines the given types to be provided as arguments to the invoked method where the represented types
* are stored in the generated class's constant pool.
*
* @param typeDescription The type descriptions to provide as arguments.
* @return A method call that hands the provided arguments to the invoked method.
*/
public MethodCall with(TypeDescription... typeDescription) {
List<ArgumentLoader.Factory> argumentLoaders = new ArrayList<ArgumentLoader.Factory>(typeDescription.length);
for (TypeDescription aTypeDescription : typeDescription) {
argumentLoaders.add(new ArgumentLoader.ForClassConstant(aTypeDescription));
}
return new MethodCall(methodLocator, targetHandler, CompoundList.of(this.argumentLoaders, argumentLoaders), methodInvoker, terminationHandler, assigner, typing);
}
/**
* Defines the given enumeration values to be provided as arguments to the invoked method where the values
* are read from the enumeration class on demand.
*
* @param enumerationDescription The enumeration descriptions to provide as arguments.
* @return A method call that hands the provided arguments to the invoked method.
*/
public MethodCall with(EnumerationDescription... enumerationDescription) {
List<ArgumentLoader.Factory> argumentLoaders = new ArrayList<ArgumentLoader.Factory>(enumerationDescription.length);
for (EnumerationDescription anEnumerationDescription : enumerationDescription) {
argumentLoaders.add(new ArgumentLoader.ForEnumerationValue(anEnumerationDescription));
}
return new MethodCall(methodLocator, targetHandler, CompoundList.of(this.argumentLoaders, argumentLoaders), methodInvoker, terminationHandler, assigner, typing);
}
/**
* Defines the given Java instances to be provided as arguments to the invoked method where the given
* instances are stored in the generated class's constant pool.
*
* @param javaConstant The Java instances to provide as arguments.
* @return A method call that hands the provided arguments to the invoked method.
*/
public MethodCall with(JavaConstant... javaConstant) {
List<ArgumentLoader.Factory> argumentLoaders = new ArrayList<ArgumentLoader.Factory>(javaConstant.length);
for (JavaConstant aJavaConstant : javaConstant) {
argumentLoaders.add(new ArgumentLoader.ForJavaConstant(aJavaConstant));
}
return new MethodCall(methodLocator, targetHandler, CompoundList.of(this.argumentLoaders, argumentLoaders), methodInvoker, terminationHandler, assigner, typing);
}
/**
* Defines a number of arguments to be handed to the method that is being invoked by this implementation. Any
* value is stored within a field in order to preserve referential identity. As an exception, the {@code null}
* value is not stored within a field.
*
* @param argument The arguments to provide to the method that is being called in their order.
* @return A method call that hands the provided arguments to the invoked method.
*/
public MethodCall withReference(Object... argument) {
List<ArgumentLoader.Factory> argumentLoaders = new ArrayList<ArgumentLoader.Factory>(argument.length);
for (Object anArgument : argument) {
argumentLoaders.add(anArgument == null ? ArgumentLoader.ForNullConstant.INSTANCE : new ArgumentLoader.ForInstance.Factory(anArgument));
}
return new MethodCall(methodLocator, targetHandler, CompoundList.of(this.argumentLoaders, argumentLoaders), methodInvoker, terminationHandler, assigner, typing);
}
/**
* Defines a number of arguments of the instrumented method by their parameter indices to be handed
* to the invoked method as an argument.
*
* @param index The parameter indices of the instrumented method to be handed to the invoked method as an
* argument in their order. The indices are zero-based.
* @return A method call that hands the provided arguments to the invoked method.
*/
public MethodCall withArgument(int... index) {
List<ArgumentLoader.Factory> argumentLoaders = new ArrayList<ArgumentLoader.Factory>(index.length);
for (int anIndex : index) {
if (anIndex < 0) {
throw new IllegalArgumentException("Negative index: " + anIndex);
}
argumentLoaders.add(new ArgumentLoader.ForMethodParameter.Factory(anIndex));
}
return new MethodCall(methodLocator, targetHandler, CompoundList.of(this.argumentLoaders, argumentLoaders), methodInvoker, terminationHandler, assigner, typing);
}
/**
* Adds all arguments of the instrumented method as arguments to the invoked method to this method call.
*
* @return A method call that hands all arguments arguments of the instrumented method to the invoked method.
*/
public MethodCall withAllArguments() {
return new MethodCall(methodLocator, targetHandler, CompoundList.of(this.argumentLoaders, ArgumentLoader.ForMethodParameter.OfInstrumentedMethod.INSTANCE), methodInvoker, terminationHandler, assigner, typing);
}
/**
* <p>
* Creates a method call where the parameter with {@code index} is expected to be an array and where each element of the array
* is expected to represent an argument for the method being invoked.
* </p>
* <p>
* <b>Note</b>: This is typically used in combination with dynamic type assignments which is activated via
* {@link MethodCall#withAssigner(Assigner, Assigner.Typing)} using a {@link Assigner.Typing#DYNAMIC}.
* </p>
*
* @param index The index of the parameter.
* @return A method call that loads {@code size} elements from the array handed to the instrumented method as argument {@code index}.
*/
public MethodCall withArgumentArrayElements(int index) {
if (index < 0) {
throw new IllegalArgumentException("A parameter index cannot be negative: " + index);
}
return new MethodCall(methodLocator, targetHandler, CompoundList.of(this.argumentLoaders, new ArgumentLoader.ForMethodParameterArray.OfInvokedMethod(index)), methodInvoker, terminationHandler, assigner, typing);
}
/**
* <p>
* Creates a method call where the parameter with {@code index} is expected to be an array and where {@code size} elements are loaded
* from the array as arguments for the invoked method.
* </p>
* <p>
* <b>Note</b>: This is typically used in combination with dynamic type assignments which is activated via
* {@link MethodCall#withAssigner(Assigner, Assigner.Typing)} using a {@link Assigner.Typing#DYNAMIC}.
* </p>
*
* @param index The index of the parameter.
* @param size The amount of elements to load from the array.
* @return A method call that loads {@code size} elements from the array handed to the instrumented method as argument {@code index}.
*/
public MethodCall withArgumentArrayElements(int index, int size) {
return withArgumentArrayElements(index, 0, size);
}
/**
* <p>
* Creates a method call where the parameter with {@code index} is expected to be an array and where {@code size} elements are loaded
* from the array as arguments for the invoked method. The first element is loaded from index {@code start}.
* </p>
* <p>
* <b>Note</b>: This is typically used in combination with dynamic type assignments which is activated via
* {@link MethodCall#withAssigner(Assigner, Assigner.Typing)} using a {@link Assigner.Typing#DYNAMIC}.
* </p>
*
* @param index The index of the parameter.
* @param start The first array index to consider.
* @param size The amount of elements to load from the array with increasing index from {@code start}.
* @return A method call that loads {@code size} elements from the array handed to the instrumented method as argument {@code index}.
*/
public MethodCall withArgumentArrayElements(int index, int start, int size) {
if (index < 0) {
throw new IllegalArgumentException("A parameter index cannot be negative: " + index);
} else if (start < 0) {
throw new IllegalArgumentException("An array index cannot be negative: " + start);
} else if (size == 0) {
return this;
} else if (size < 0) {
throw new IllegalArgumentException("Size cannot be negative: " + size);
}
List<ArgumentLoader.Factory> argumentLoaders = new ArrayList<ArgumentLoader.Factory>(size);
for (int position = 0; position < size; position++) {
argumentLoaders.add(new ArgumentLoader.ForMethodParameterArray.OfParameter(index, start + position));
}
return new MethodCall(methodLocator, targetHandler, CompoundList.of(this.argumentLoaders, argumentLoaders), methodInvoker, terminationHandler, assigner, typing);
}
/**
* Assigns the {@code this} reference to the next parameter.
*
* @return This method call where the next parameter is a assigned a reference to the {@code this} reference
* of the instance of the intercepted method.
*/
public MethodCall withThis() {
return new MethodCall(methodLocator, targetHandler, CompoundList.of(argumentLoaders, ArgumentLoader.ForThisReference.Factory.INSTANCE), methodInvoker, terminationHandler, assigner, typing);
}
/**
* Assigns the {@link java.lang.Class} value of the instrumented type.
*
* @return This method call where the next parameter is a assigned a reference to the {@link java.lang.Class}
* value of the instrumented type.
*/
public MethodCall withOwnType() {
return new MethodCall(methodLocator, targetHandler, CompoundList.of(argumentLoaders, ArgumentLoader.ForInstrumentedType.Factory.INSTANCE), methodInvoker, terminationHandler, assigner, typing);
}
/**
* Defines a method call which fetches a value from a list of existing fields.
*
* @param name The names of the fields.
* @return A method call which assigns the next parameters to the values of the given fields.
*/
public MethodCall withField(String... name) {
return withField(FieldLocator.ForClassHierarchy.Factory.INSTANCE, name);
}
/**
* Defines a method call which fetches a value from a list of existing fields.
*
* @param fieldLocatorFactory The field locator factory to use.
* @param name The names of the fields.
* @return A method call which assigns the next parameters to the values of the given fields.
*/
public MethodCall withField(FieldLocator.Factory fieldLocatorFactory, String... name) {
List<ArgumentLoader.Factory> argumentLoaders = new ArrayList<ArgumentLoader.Factory>(name.length);
for (String aFieldName : name) {
argumentLoaders.add(new ArgumentLoader.ForField.Factory(aFieldName, fieldLocatorFactory));
}
return new MethodCall(methodLocator, targetHandler, CompoundList.of(this.argumentLoaders, argumentLoaders), methodInvoker, terminationHandler, assigner, typing);
}
/**
* Defines an assigner to be used for assigning values to the parameters of the invoked method. This assigner
* is also used for assigning the invoked method's return value to the return type of the instrumented method,
* if this method is not chained with
* {@link MethodCall#andThen(Implementation)} such
* that a return value of this method call is discarded.
*
* @param assigner The assigner to use.
* @param typing Indicates if dynamic type castings should be attempted for incompatible assignments.
* @return This method call using the provided assigner.
*/
public Implementation.Composable withAssigner(Assigner assigner, Assigner.Typing typing) {
return new MethodCall(methodLocator, targetHandler, argumentLoaders, methodInvoker, terminationHandler, assigner, typing);
}
@Override
public Implementation andThen(Implementation implementation) {
return new Implementation.Compound(new MethodCall(methodLocator, targetHandler, argumentLoaders, methodInvoker, TerminationHandler.DROPPING, assigner, typing), implementation);
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
for (ArgumentLoader.Factory argumentLoader : argumentLoaders) {
instrumentedType = argumentLoader.prepare(instrumentedType);
}
return targetHandler.prepare(instrumentedType);
}
@Override
public ByteCodeAppender appender(Target implementationTarget) {
return new Appender(implementationTarget);
}
/**
* A method locator is responsible for identifying the method that is to be invoked
* by a {@link MethodCall}.
*/
public interface MethodLocator {
/**
* Resolves the method to be invoked.
*
* @param instrumentedType The instrumented type.
* @param instrumentedMethod The method being instrumented.
* @return The method to invoke.
*/
MethodDescription resolve(TypeDescription instrumentedType, MethodDescription instrumentedMethod);
/**
* A method locator that simply returns the intercepted method.
*/
enum ForInstrumentedMethod implements MethodLocator {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public MethodDescription resolve(TypeDescription instrumentedType, MethodDescription instrumentedMethod) {
return instrumentedMethod;
}
}
/**
* Invokes a given method.
*/
class ForExplicitMethod implements MethodLocator {
/**
* The method to be invoked.
*/
private final MethodDescription methodDescription;
/**
* Creates a new method locator for a given method.
*
* @param methodDescription The method to be invoked.
*/
protected ForExplicitMethod(MethodDescription methodDescription) {
this.methodDescription = methodDescription;
}
@Override
public MethodDescription resolve(TypeDescription instrumentedType, MethodDescription instrumentedMethod) {
return methodDescription;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.MethodLocator.ForExplicitMethod)) return false;
final MethodCall.MethodLocator.ForExplicitMethod other = (MethodCall.MethodLocator.ForExplicitMethod) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$methodDescription = this.methodDescription;
final java.lang.Object other$methodDescription = other.methodDescription;
if (this$methodDescription == null ? other$methodDescription != null : !this$methodDescription.equals(other$methodDescription)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.MethodLocator.ForExplicitMethod;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $methodDescription = this.methodDescription;
result = result * PRIME + ($methodDescription == null ? 43 : $methodDescription.hashCode());
return result;
}
}
/**
* A method locator that identifies a unique virtual method.
*/
class ForElementMatcher implements MethodLocator {
/**
* The matcher to use.
*/
private final ElementMatcher<? super MethodDescription> matcher;
/**
* The method graph compiler to use.
*/
private final MethodGraph.Compiler methodGraphCompiler;
/**
* Creates a new method locator for an element matcher.
*
* @param matcher The matcher to use.
* @param methodGraphCompiler The method graph compiler to use.
*/
protected ForElementMatcher(ElementMatcher<? super MethodDescription> matcher, MethodGraph.Compiler methodGraphCompiler) {
this.matcher = matcher;
this.methodGraphCompiler = methodGraphCompiler;
}
@Override
public MethodDescription resolve(TypeDescription instrumentedType, MethodDescription instrumentedMethod) {
MethodList<?> candidates = methodGraphCompiler.compile(instrumentedType).listNodes().asMethodList().filter(matcher);
if (candidates.size() == 1) {
return candidates.getOnly();
} else {
throw new IllegalStateException(instrumentedType + " does not define exactly one virtual method for " + matcher);
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.MethodLocator.ForElementMatcher)) return false;
final MethodCall.MethodLocator.ForElementMatcher other = (MethodCall.MethodLocator.ForElementMatcher) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$matcher = this.matcher;
final java.lang.Object other$matcher = other.matcher;
if (this$matcher == null ? other$matcher != null : !this$matcher.equals(other$matcher)) return false;
final java.lang.Object this$methodGraphCompiler = this.methodGraphCompiler;
final java.lang.Object other$methodGraphCompiler = other.methodGraphCompiler;
if (this$methodGraphCompiler == null ? other$methodGraphCompiler != null : !this$methodGraphCompiler.equals(other$methodGraphCompiler)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.MethodLocator.ForElementMatcher;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $matcher = this.matcher;
result = result * PRIME + ($matcher == null ? 43 : $matcher.hashCode());
final java.lang.Object $methodGraphCompiler = this.methodGraphCompiler;
result = result * PRIME + ($methodGraphCompiler == null ? 43 : $methodGraphCompiler.hashCode());
return result;
}
}
}
/**
* A target handler is responsible for invoking a method for a
* {@link MethodCall}.
*/
protected interface TargetHandler extends InstrumentedType.Prepareable {
/**
* Creates a stack manipulation that represents the method's invocation.
*
* @param invokedMethod The method to be invoked.
* @param instrumentedMethod The instrumented method.
* @param instrumentedType The instrumented type. @return A stack manipulation that invokes the method.
* @param assigner The assigner to use.
* @param typing The typing to apply.
* @return A stack manipulation that loads the method target onto the operand stack.
*/
StackManipulation resolve(MethodDescription invokedMethod, MethodDescription instrumentedMethod, TypeDescription instrumentedType, Assigner assigner, Assigner.Typing typing);
/**
* A target handler that invokes a method either on the instance of the instrumented
* type or as a static method.
*/
enum ForSelfOrStaticInvocation implements TargetHandler {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public StackManipulation resolve(MethodDescription invokedMethod, MethodDescription instrumentedMethod, TypeDescription instrumentedType, Assigner assigner, Assigner.Typing typing) {
return new StackManipulation.Compound(invokedMethod.isStatic() ? StackManipulation.Trivial.INSTANCE : MethodVariableAccess.loadThis(), invokedMethod.isConstructor() ? Duplication.SINGLE : StackManipulation.Trivial.INSTANCE);
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
}
/**
* Invokes a method in order to construct a new instance.
*/
enum ForConstructingInvocation implements TargetHandler {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public StackManipulation resolve(MethodDescription invokedMethod, MethodDescription instrumentedMethod, TypeDescription instrumentedType, Assigner assigner, Assigner.Typing typing) {
return new StackManipulation.Compound(TypeCreation.of(invokedMethod.getDeclaringType().asErasure()), Duplication.SINGLE);
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
}
/**
* A target handler that invokes a method on an instance that is stored in a static field.
*/
class ForValue implements TargetHandler {
/**
* The name prefix of the field to store the instance.
*/
private static final String FIELD_PREFIX = "invocationTarget";
/**
* The target on which the method is to be invoked.
*/
private final Object target;
/**
* The type of the field.
*/
private final TypeDescription.Generic fieldType;
/**
* The name of the field to store the target.
*/
private final String name;
/**
* Creates a new target handler for a static field.
*
* @param target The target on which the method is to be invoked.
* @param fieldType The type of the field.
*/
protected ForValue(Object target, TypeDescription.Generic fieldType) {
this.target = target;
this.fieldType = fieldType;
name = String.format("%s$%s", FIELD_PREFIX, RandomString.make());
}
@Override
public StackManipulation resolve(MethodDescription invokedMethod, MethodDescription instrumentedMethod, TypeDescription instrumentedType, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = assigner.assign(fieldType, invokedMethod.getDeclaringType().asGenericType(), typing);
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + fieldType);
}
return new StackManipulation.Compound(FieldAccess.forField(instrumentedType.getDeclaredFields().filter(ElementMatchers.named(name)).getOnly()).read(), stackManipulation);
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType.withField(new FieldDescription.Token(name, Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, fieldType)).withInitializer(new LoadedTypeInitializer.ForStaticField(name, target));
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.TargetHandler.ForValue)) return false;
final MethodCall.TargetHandler.ForValue other = (MethodCall.TargetHandler.ForValue) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$target = this.target;
final java.lang.Object other$target = other.target;
if (this$target == null ? other$target != null : !this$target.equals(other$target)) return false;
final java.lang.Object this$fieldType = this.fieldType;
final java.lang.Object other$fieldType = other.fieldType;
if (this$fieldType == null ? other$fieldType != null : !this$fieldType.equals(other$fieldType)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.TargetHandler.ForValue;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $target = this.target;
result = result * PRIME + ($target == null ? 43 : $target.hashCode());
final java.lang.Object $fieldType = this.fieldType;
result = result * PRIME + ($fieldType == null ? 43 : $fieldType.hashCode());
return result;
}
}
/**
* Creates a target handler that stores the instance to invoke a method on in an instance field.
*/
class ForField implements TargetHandler {
/**
* The name of the field.
*/
private final String name;
/**
* The field locator factory to use.
*/
private final FieldLocator.Factory fieldLocatorFactory;
/**
* Creates a new target handler for storing a method invocation target in an
* instance field.
*
* @param name The name of the field.
* @param fieldLocatorFactory The field locator factory to use.
*/
protected ForField(String name, FieldLocator.Factory fieldLocatorFactory) {
this.name = name;
this.fieldLocatorFactory = fieldLocatorFactory;
}
@Override
public StackManipulation resolve(MethodDescription invokedMethod, MethodDescription instrumentedMethod, TypeDescription instrumentedType, Assigner assigner, Assigner.Typing typing) {
FieldLocator.Resolution resolution = fieldLocatorFactory.make(instrumentedType).locate(name);
if (!resolution.isResolved()) {
throw new IllegalStateException("Could not locate field name " + name + " on " + instrumentedType);
} else if (!resolution.getField().isStatic() && !instrumentedType.isAssignableTo(resolution.getField().getDeclaringType().asErasure())) {
throw new IllegalStateException("Cannot access " + resolution.getField() + " from " + instrumentedType);
}
StackManipulation stackManipulation = assigner.assign(resolution.getField().getType(), invokedMethod.getDeclaringType().asGenericType(), typing);
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + resolution.getField());
}
return new StackManipulation.Compound(invokedMethod.isStatic() ? StackManipulation.Trivial.INSTANCE : MethodVariableAccess.loadThis(), FieldAccess.forField(resolution.getField()).read(), stackManipulation);
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.TargetHandler.ForField)) return false;
final MethodCall.TargetHandler.ForField other = (MethodCall.TargetHandler.ForField) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$name = this.name;
final java.lang.Object other$name = other.name;
if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
final java.lang.Object this$fieldLocatorFactory = this.fieldLocatorFactory;
final java.lang.Object other$fieldLocatorFactory = other.fieldLocatorFactory;
if (this$fieldLocatorFactory == null ? other$fieldLocatorFactory != null : !this$fieldLocatorFactory.equals(other$fieldLocatorFactory)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.TargetHandler.ForField;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.name;
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
final java.lang.Object $fieldLocatorFactory = this.fieldLocatorFactory;
result = result * PRIME + ($fieldLocatorFactory == null ? 43 : $fieldLocatorFactory.hashCode());
return result;
}
}
/**
* A target handler that loads the parameter of the given index as the target object.
*/
class ForMethodParameter implements TargetHandler {
/**
* The index of the instrumented method's parameter that is the target of the method invocation.
*/
private final int index;
/**
* Creates a new target handler for the instrumented method's argument.
*
* @param index The index of the instrumented method's parameter that is the target of the method invocation.
*/
protected ForMethodParameter(int index) {
this.index = index;
}
@Override
public StackManipulation resolve(MethodDescription invokedMethod, MethodDescription instrumentedMethod, TypeDescription instrumentedType, Assigner assigner, Assigner.Typing typing) {
if (instrumentedMethod.getParameters().size() < index) {
throw new IllegalArgumentException(instrumentedMethod + " does not have a parameter with index " + index);
}
ParameterDescription parameterDescription = instrumentedMethod.getParameters().get(index);
StackManipulation stackManipulation = assigner.assign(parameterDescription.getType(), invokedMethod.getDeclaringType().asGenericType(), typing);
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + parameterDescription.getType());
}
return new StackManipulation.Compound(MethodVariableAccess.load(parameterDescription), stackManipulation);
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.TargetHandler.ForMethodParameter)) return false;
final MethodCall.TargetHandler.ForMethodParameter other = (MethodCall.TargetHandler.ForMethodParameter) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.index != other.index) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.TargetHandler.ForMethodParameter;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.index;
return result;
}
}
}
/**
* An argument loader is responsible for loading an argument for an invoked method
* onto the operand stack.
*/
protected interface ArgumentLoader {
/**
* Loads the argument that is represented by this instance onto the operand stack.
*
* @param target The target parameter.
* @param assigner The assigner to be used.
* @param typing Indicates if dynamic type castings should be attempted for incompatible assignments.
* @return The stack manipulation that loads the represented argument onto the stack.
*/
StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing);
/**
* A factory that produces {@link ArgumentLoader}s for a given instrumented method.
*/
interface Factory {
/**
* Prepares the instrumented type in order to allow the loading of the represented argument.
*
* @param instrumentedType The instrumented type.
* @return The prepared instrumented type.
*/
InstrumentedType prepare(InstrumentedType instrumentedType);
/**
* Creates any number of argument loaders for an instrumentation.
*
* @param instrumentedType The instrumented type.
* @param instrumentedMethod The instrumented method.
* @param invokedMethod The invoked method.
* @return Any number of argument loaders to supply for the method call.
*/
List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod);
}
/**
* An argument loader that loads the {@code null} value onto the operand stack.
*/
enum ForNullConstant implements ArgumentLoader, Factory {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
if (target.getType().isPrimitive()) {
throw new IllegalStateException("Cannot assign null to " + target);
}
return NullConstant.INSTANCE;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
}
/**
* An argument loader that assigns the {@code this} reference to a parameter.
*/
class ForThisReference implements ArgumentLoader {
/**
* The instrumented type.
*/
private final TypeDescription instrumentedType;
/**
* Creates an argument loader that supplies the {@code this} instance as an argument.
*
* @param instrumentedType The instrumented type.
*/
protected ForThisReference(TypeDescription instrumentedType) {
this.instrumentedType = instrumentedType;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(MethodVariableAccess.loadThis(), assigner.assign(instrumentedType.asGenericType(), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign " + instrumentedType + " to " + target);
}
return stackManipulation;
}
/**
* A factory for an argument loader that supplies the {@code this} value as an argument.
*/
protected enum Factory implements ArgumentLoader.Factory {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
if (instrumentedMethod.isStatic()) {
throw new IllegalStateException(instrumentedMethod + " is static and cannot supply an invoker instance");
}
return Collections.<ArgumentLoader>singletonList(new ForThisReference(instrumentedType));
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForThisReference)) return false;
final MethodCall.ArgumentLoader.ForThisReference other = (MethodCall.ArgumentLoader.ForThisReference) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$instrumentedType = this.instrumentedType;
final java.lang.Object other$instrumentedType = other.instrumentedType;
if (this$instrumentedType == null ? other$instrumentedType != null : !this$instrumentedType.equals(other$instrumentedType)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForThisReference;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $instrumentedType = this.instrumentedType;
result = result * PRIME + ($instrumentedType == null ? 43 : $instrumentedType.hashCode());
return result;
}
}
/**
* Loads the instrumented type onto the operand stack.
*/
class ForInstrumentedType implements ArgumentLoader {
/**
* The instrumented type.
*/
private final TypeDescription instrumentedType;
/**
* Creates an argument loader for supporting the instrumented type as a type constant as an argument.
*
* @param instrumentedType The instrumented type.
*/
protected ForInstrumentedType(TypeDescription instrumentedType) {
this.instrumentedType = instrumentedType;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(ClassConstant.of(instrumentedType), assigner.assign(new TypeDescription.Generic.OfNonGenericType.ForLoadedType(Class.class), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign Class value to " + target);
}
return stackManipulation;
}
/**
* A factory for an argument loader that supplies the instrumented type as an argument.
*/
protected enum Factory implements ArgumentLoader.Factory {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(new ForInstrumentedType(instrumentedType));
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForInstrumentedType)) return false;
final MethodCall.ArgumentLoader.ForInstrumentedType other = (MethodCall.ArgumentLoader.ForInstrumentedType) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$instrumentedType = this.instrumentedType;
final java.lang.Object other$instrumentedType = other.instrumentedType;
if (this$instrumentedType == null ? other$instrumentedType != null : !this$instrumentedType.equals(other$instrumentedType)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForInstrumentedType;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $instrumentedType = this.instrumentedType;
result = result * PRIME + ($instrumentedType == null ? 43 : $instrumentedType.hashCode());
return result;
}
}
/**
* Loads a parameter of the instrumented method onto the operand stack.
*/
class ForMethodParameter implements ArgumentLoader {
/**
* The index of the parameter to be loaded onto the operand stack.
*/
private final int index;
/**
* The instrumented method.
*/
private final MethodDescription instrumentedMethod;
/**
* Creates an argument loader for a parameter of the instrumented method.
*
* @param index The index of the parameter to be loaded onto the operand stack.
* @param instrumentedMethod The instrumented method.
*/
protected ForMethodParameter(int index, MethodDescription instrumentedMethod) {
this.index = index;
this.instrumentedMethod = instrumentedMethod;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
ParameterDescription parameterDescription = instrumentedMethod.getParameters().get(index);
StackManipulation stackManipulation = new StackManipulation.Compound(MethodVariableAccess.load(parameterDescription), assigner.assign(parameterDescription.getType(), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign " + parameterDescription + " to " + target + " for " + instrumentedMethod);
}
return stackManipulation;
}
/**
* A factory for argument loaders that supplies all arguments of the instrumented method as arguments.
*/
protected enum OfInstrumentedMethod implements ArgumentLoader.Factory {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
List<ArgumentLoader> argumentLoaders = new ArrayList<ArgumentLoader>(instrumentedMethod.getParameters().size());
for (ParameterDescription parameterDescription : instrumentedMethod.getParameters()) {
argumentLoaders.add(new ForMethodParameter(parameterDescription.getIndex(), instrumentedMethod));
}
return argumentLoaders;
}
}
/**
* A factory for an argument loader that supplies a method parameter as an argument.
*/
protected static class Factory implements ArgumentLoader.Factory {
/**
* The index of the parameter to be loaded onto the operand stack.
*/
private final int index;
/**
* Creates a factory for an argument loader that supplies a method parameter as an argument.
*
* @param index The index of the parameter to supply.
*/
protected Factory(int index) {
this.index = index;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
if (index >= instrumentedMethod.getParameters().size()) {
throw new IllegalStateException(instrumentedMethod + " does not have a parameter with index " + index);
}
return Collections.<ArgumentLoader>singletonList(new ForMethodParameter(index, instrumentedMethod));
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForMethodParameter.Factory)) return false;
final MethodCall.ArgumentLoader.ForMethodParameter.Factory other = (MethodCall.ArgumentLoader.ForMethodParameter.Factory) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.index != other.index) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForMethodParameter.Factory;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.index;
return result;
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForMethodParameter)) return false;
final MethodCall.ArgumentLoader.ForMethodParameter other = (MethodCall.ArgumentLoader.ForMethodParameter) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.index != other.index) return false;
final java.lang.Object this$instrumentedMethod = this.instrumentedMethod;
final java.lang.Object other$instrumentedMethod = other.instrumentedMethod;
if (this$instrumentedMethod == null ? other$instrumentedMethod != null : !this$instrumentedMethod.equals(other$instrumentedMethod)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForMethodParameter;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.index;
final java.lang.Object $instrumentedMethod = this.instrumentedMethod;
result = result * PRIME + ($instrumentedMethod == null ? 43 : $instrumentedMethod.hashCode());
return result;
}
}
/**
* Loads a value onto the operand stack that is stored in a static field.
*/
class ForInstance implements ArgumentLoader {
/**
* The description of the field.
*/
private final FieldDescription fieldDescription;
/**
* Creates an argument loader that supplies the value of a static field as an argument.
*
* @param fieldDescription The description of the field.
*/
protected ForInstance(FieldDescription fieldDescription) {
this.fieldDescription = fieldDescription;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(FieldAccess.forField(fieldDescription).read(), assigner.assign(fieldDescription.getType(), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign " + fieldDescription.getType() + " to " + target);
}
return stackManipulation;
}
/**
* A factory that supplies the value of a static field as an argument.
*/
protected static class Factory implements ArgumentLoader.Factory {
/**
* The name prefix of the field to store the argument.
*/
private static final String FIELD_PREFIX = "methodCall";
/**
* The value to be stored in the field.
*/
private final Object value;
/**
* The name of the field.
*/
private final String name;
/**
* Creates a factory that loads the value of a static field as an argument.
*
* @param value The value to supply as an argument.
*/
protected Factory(Object value) {
this.value = value;
name = String.format("%s$%s", FIELD_PREFIX, RandomString.make());
}
/**
* Creates a factory for loading the supplied value as an argument, either stored as a static field or as a constant pool value.
*
* @param value The value to supply as an argument.
* @return An appropriate factory for an argument loader.
*/
protected static ArgumentLoader.Factory of(Object value) {
if (value == null) {
return ForNullConstant.INSTANCE;
} else if (value instanceof String) {
return new ForTextConstant((String) value);
} else if (value instanceof Boolean) {
return new ForBooleanConstant((Boolean) value);
} else if (value instanceof Byte) {
return new ForByteConstant((Byte) value);
} else if (value instanceof Short) {
return new ForShortConstant((Short) value);
} else if (value instanceof Character) {
return new ForCharacterConstant((Character) value);
} else if (value instanceof Integer) {
return new ForIntegerConstant((Integer) value);
} else if (value instanceof Long) {
return new ForLongConstant((Long) value);
} else if (value instanceof Float) {
return new ForFloatConstant((Float) value);
} else if (value instanceof Double) {
return new ForDoubleConstant((Double) value);
} else if (value instanceof Class) {
return new ForClassConstant(new TypeDescription.ForLoadedType((Class<?>) value));
} else if (JavaType.METHOD_HANDLE.getTypeStub().isInstance(value)) {
return new ForJavaConstant(JavaConstant.MethodHandle.ofLoaded(value));
} else if (JavaType.METHOD_TYPE.getTypeStub().isInstance(value)) {
return new ForJavaConstant(JavaConstant.MethodType.ofLoaded(value));
} else if (value instanceof Enum<?>) {
return new ForEnumerationValue(new EnumerationDescription.ForLoadedEnumeration((Enum<?>) value));
} else {
return new ForInstance.Factory(value);
}
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType.withField(new FieldDescription.Token(name, Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, new TypeDescription.Generic.OfNonGenericType.ForLoadedType(value.getClass()))).withInitializer(new LoadedTypeInitializer.ForStaticField(name, value));
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(new ForInstance(instrumentedType.getDeclaredFields().filter(ElementMatchers.named(name)).getOnly()));
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForInstance.Factory)) return false;
final MethodCall.ArgumentLoader.ForInstance.Factory other = (MethodCall.ArgumentLoader.ForInstance.Factory) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$value = this.value;
final java.lang.Object other$value = other.value;
if (this$value == null ? other$value != null : !this$value.equals(other$value)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForInstance.Factory;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $value = this.value;
result = result * PRIME + ($value == null ? 43 : $value.hashCode());
return result;
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForInstance)) return false;
final MethodCall.ArgumentLoader.ForInstance other = (MethodCall.ArgumentLoader.ForInstance) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$fieldDescription = this.fieldDescription;
final java.lang.Object other$fieldDescription = other.fieldDescription;
if (this$fieldDescription == null ? other$fieldDescription != null : !this$fieldDescription.equals(other$fieldDescription)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForInstance;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $fieldDescription = this.fieldDescription;
result = result * PRIME + ($fieldDescription == null ? 43 : $fieldDescription.hashCode());
return result;
}
}
/**
* Loads the value of an existing field onto the operand stack.
*/
class ForField implements ArgumentLoader {
/**
* The field containing the loaded value.
*/
private final FieldDescription fieldDescription;
/**
* The instrumented method.
*/
private final MethodDescription instrumentedMethod;
/**
* Creates a new argument loader for loading an existing field.
*
* @param fieldDescription The field containing the loaded value.
* @param instrumentedMethod The instrumented method.
*/
protected ForField(FieldDescription fieldDescription, MethodDescription instrumentedMethod) {
this.fieldDescription = fieldDescription;
this.instrumentedMethod = instrumentedMethod;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
if (!fieldDescription.isStatic() && instrumentedMethod.isStatic()) {
throw new IllegalStateException("Cannot access non-static " + fieldDescription + " from " + instrumentedMethod);
}
StackManipulation stackManipulation = new StackManipulation.Compound(fieldDescription.isStatic() ? StackManipulation.Trivial.INSTANCE : MethodVariableAccess.loadThis(), FieldAccess.forField(fieldDescription).read(), assigner.assign(fieldDescription.getType(), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign " + fieldDescription + " to " + target);
}
return stackManipulation;
}
/**
* A factory for an argument loaded that loads the value of an existing field as an argument.
*/
protected static class Factory implements ArgumentLoader.Factory {
/**
* The name of the field.
*/
private final String name;
/**
* The field locator to use.
*/
private final FieldLocator.Factory fieldLocatorFactory;
/**
* Creates a new argument loader for an existing field.
*
* @param name The name of the field.
* @param fieldLocatorFactory The field locator to use.
*/
protected Factory(String name, FieldLocator.Factory fieldLocatorFactory) {
this.name = name;
this.fieldLocatorFactory = fieldLocatorFactory;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
FieldLocator.Resolution resolution = fieldLocatorFactory.make(instrumentedType).locate(name);
if (!resolution.isResolved()) {
throw new IllegalStateException("Could not locate field \'" + name + "\' on " + instrumentedType);
}
return Collections.<ArgumentLoader>singletonList(new ForField(resolution.getField(), instrumentedMethod));
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForField.Factory)) return false;
final MethodCall.ArgumentLoader.ForField.Factory other = (MethodCall.ArgumentLoader.ForField.Factory) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$name = this.name;
final java.lang.Object other$name = other.name;
if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
final java.lang.Object this$fieldLocatorFactory = this.fieldLocatorFactory;
final java.lang.Object other$fieldLocatorFactory = other.fieldLocatorFactory;
if (this$fieldLocatorFactory == null ? other$fieldLocatorFactory != null : !this$fieldLocatorFactory.equals(other$fieldLocatorFactory)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForField.Factory;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $name = this.name;
result = result * PRIME + ($name == null ? 43 : $name.hashCode());
final java.lang.Object $fieldLocatorFactory = this.fieldLocatorFactory;
result = result * PRIME + ($fieldLocatorFactory == null ? 43 : $fieldLocatorFactory.hashCode());
return result;
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForField)) return false;
final MethodCall.ArgumentLoader.ForField other = (MethodCall.ArgumentLoader.ForField) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$fieldDescription = this.fieldDescription;
final java.lang.Object other$fieldDescription = other.fieldDescription;
if (this$fieldDescription == null ? other$fieldDescription != null : !this$fieldDescription.equals(other$fieldDescription)) return false;
final java.lang.Object this$instrumentedMethod = this.instrumentedMethod;
final java.lang.Object other$instrumentedMethod = other.instrumentedMethod;
if (this$instrumentedMethod == null ? other$instrumentedMethod != null : !this$instrumentedMethod.equals(other$instrumentedMethod)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForField;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $fieldDescription = this.fieldDescription;
result = result * PRIME + ($fieldDescription == null ? 43 : $fieldDescription.hashCode());
final java.lang.Object $instrumentedMethod = this.instrumentedMethod;
result = result * PRIME + ($instrumentedMethod == null ? 43 : $instrumentedMethod.hashCode());
return result;
}
}
/**
* An argument loader that loads an element of a parameter of an array type.
*/
class ForMethodParameterArray implements ArgumentLoader {
/**
* The parameter to load the array from.
*/
private final ParameterDescription parameterDescription;
/**
* The array index to load.
*/
private final int index;
/**
* Creates an argument loader for a parameter of the instrumented method where an array element is assigned to the invoked method.
*
* @param parameterDescription The parameter from which to load an array element.
* @param index The array index to load.
*/
protected ForMethodParameterArray(ParameterDescription parameterDescription, int index) {
this.parameterDescription = parameterDescription;
this.index = index;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(MethodVariableAccess.load(parameterDescription), IntegerConstant.forValue(index), ArrayAccess.of(parameterDescription.getType().getComponentType()).load(), assigner.assign(parameterDescription.getType().getComponentType(), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign " + parameterDescription.getType().getComponentType() + " to " + target);
}
return stackManipulation;
}
/**
* Creates an argument loader for an array element that of a specific parameter.
*/
protected static class OfParameter implements ArgumentLoader.Factory {
/**
* The parameter index.
*/
private final int index;
/**
* The array index to load.
*/
private final int arrayIndex;
/**
* Creates a factory for an argument loader that loads a given parameter's array value.
*
* @param index The index of the parameter.
* @param arrayIndex The array index to load.
*/
protected OfParameter(int index, int arrayIndex) {
this.index = index;
this.arrayIndex = arrayIndex;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
if (instrumentedMethod.getParameters().size() <= index) {
throw new IllegalStateException(instrumentedMethod + " does not declare a parameter with index " + index);
} else if (!instrumentedMethod.getParameters().get(index).getType().isArray()) {
throw new IllegalStateException("Cannot access an item from non-array parameter " + instrumentedMethod.getParameters().get(index));
}
return Collections.<ArgumentLoader>singletonList(new ForMethodParameterArray(instrumentedMethod.getParameters().get(index), arrayIndex));
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForMethodParameterArray.OfParameter)) return false;
final MethodCall.ArgumentLoader.ForMethodParameterArray.OfParameter other = (MethodCall.ArgumentLoader.ForMethodParameterArray.OfParameter) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.index != other.index) return false;
if (this.arrayIndex != other.arrayIndex) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForMethodParameterArray.OfParameter;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.index;
result = result * PRIME + this.arrayIndex;
return result;
}
}
/**
* An argument loader factory that loads an array element from a parameter for each argument of the invoked method.
*/
protected static class OfInvokedMethod implements ArgumentLoader.Factory {
/**
* The parameter index.
*/
private final int index;
/**
* Creates an argument loader factory for an invoked method.
*
* @param index The parameter index.
*/
protected OfInvokedMethod(int index) {
this.index = index;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
if (instrumentedMethod.getParameters().size() <= index) {
throw new IllegalStateException(instrumentedMethod + " does not declare a parameter with index " + index);
} else if (!instrumentedMethod.getParameters().get(index).getType().isArray()) {
throw new IllegalStateException("Cannot access an item from non-array parameter " + instrumentedMethod.getParameters().get(index));
}
List<ArgumentLoader> argumentLoaders = new ArrayList<ArgumentLoader>(instrumentedMethod.getParameters().size());
for (int index = 0; index < invokedMethod.getParameters().size(); index++) {
argumentLoaders.add(new ForMethodParameterArray(instrumentedMethod.getParameters().get(this.index), index++));
}
return argumentLoaders;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForMethodParameterArray.OfInvokedMethod)) return false;
final MethodCall.ArgumentLoader.ForMethodParameterArray.OfInvokedMethod other = (MethodCall.ArgumentLoader.ForMethodParameterArray.OfInvokedMethod) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.index != other.index) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForMethodParameterArray.OfInvokedMethod;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.index;
return result;
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForMethodParameterArray)) return false;
final MethodCall.ArgumentLoader.ForMethodParameterArray other = (MethodCall.ArgumentLoader.ForMethodParameterArray) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$parameterDescription = this.parameterDescription;
final java.lang.Object other$parameterDescription = other.parameterDescription;
if (this$parameterDescription == null ? other$parameterDescription != null : !this$parameterDescription.equals(other$parameterDescription)) return false;
if (this.index != other.index) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForMethodParameterArray;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $parameterDescription = this.parameterDescription;
result = result * PRIME + ($parameterDescription == null ? 43 : $parameterDescription.hashCode());
result = result * PRIME + this.index;
return result;
}
}
/**
* Loads a {@code boolean} value onto the operand stack.
*/
class ForBooleanConstant implements ArgumentLoader, Factory {
/**
* The {@code boolean} value to load onto the operand stack.
*/
private final boolean value;
/**
* Creates a new argument loader for a {@code boolean} value.
*
* @param value The {@code boolean} value to load onto the operand stack.
*/
protected ForBooleanConstant(boolean value) {
this.value = value;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(IntegerConstant.forValue(value), assigner.assign(new TypeDescription.Generic.OfNonGenericType.ForLoadedType(boolean.class), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign boolean value to " + target);
}
return stackManipulation;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForBooleanConstant)) return false;
final MethodCall.ArgumentLoader.ForBooleanConstant other = (MethodCall.ArgumentLoader.ForBooleanConstant) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.value != other.value) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForBooleanConstant;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + (this.value ? 79 : 97);
return result;
}
}
/**
* Loads a {@code byte} value onto the operand stack.
*/
class ForByteConstant implements ArgumentLoader, Factory {
/**
* The {@code boolean} value to load onto the operand stack.
*/
private final byte value;
/**
* Creates a new argument loader for a {@code boolean} value.
*
* @param value The {@code boolean} value to load onto the operand stack.
*/
protected ForByteConstant(byte value) {
this.value = value;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(IntegerConstant.forValue(value), assigner.assign(new TypeDescription.Generic.OfNonGenericType.ForLoadedType(byte.class), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign byte value to " + target);
}
return stackManipulation;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForByteConstant)) return false;
final MethodCall.ArgumentLoader.ForByteConstant other = (MethodCall.ArgumentLoader.ForByteConstant) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.value != other.value) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForByteConstant;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.value;
return result;
}
}
/**
* Loads a {@code short} value onto the operand stack.
*/
class ForShortConstant implements ArgumentLoader, Factory {
/**
* The {@code short} value to load onto the operand stack.
*/
private final short value;
/**
* Creates a new argument loader for a {@code short} value.
*
* @param value The {@code short} value to load onto the operand stack.
*/
protected ForShortConstant(short value) {
this.value = value;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(IntegerConstant.forValue(value), assigner.assign(new TypeDescription.Generic.OfNonGenericType.ForLoadedType(short.class), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign short value to " + target);
}
return stackManipulation;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForShortConstant)) return false;
final MethodCall.ArgumentLoader.ForShortConstant other = (MethodCall.ArgumentLoader.ForShortConstant) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.value != other.value) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForShortConstant;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.value;
return result;
}
}
/**
* Loads a {@code char} value onto the operand stack.
*/
class ForCharacterConstant implements ArgumentLoader, Factory {
/**
* The {@code char} value to load onto the operand stack.
*/
private final char value;
/**
* Creates a new argument loader for a {@code char} value.
*
* @param value The {@code char} value to load onto the operand stack.
*/
protected ForCharacterConstant(char value) {
this.value = value;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(IntegerConstant.forValue(value), assigner.assign(new TypeDescription.Generic.OfNonGenericType.ForLoadedType(char.class), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign char value to " + target);
}
return stackManipulation;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForCharacterConstant)) return false;
final MethodCall.ArgumentLoader.ForCharacterConstant other = (MethodCall.ArgumentLoader.ForCharacterConstant) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.value != other.value) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForCharacterConstant;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.value;
return result;
}
}
/**
* Loads an {@code int} value onto the operand stack.
*/
class ForIntegerConstant implements ArgumentLoader, Factory {
/**
* The {@code int} value to load onto the operand stack.
*/
private final int value;
/**
* Creates a new argument loader for a {@code int} value.
*
* @param value The {@code int} value to load onto the operand stack.
*/
protected ForIntegerConstant(int value) {
this.value = value;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(IntegerConstant.forValue(value), assigner.assign(new TypeDescription.Generic.OfNonGenericType.ForLoadedType(int.class), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign integer value to " + target);
}
return stackManipulation;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForIntegerConstant)) return false;
final MethodCall.ArgumentLoader.ForIntegerConstant other = (MethodCall.ArgumentLoader.ForIntegerConstant) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.value != other.value) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForIntegerConstant;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.value;
return result;
}
}
/**
* Loads a {@code long} value onto the operand stack.
*/
class ForLongConstant implements ArgumentLoader, Factory {
/**
* The {@code long} value to load onto the operand stack.
*/
private final long value;
/**
* Creates a new argument loader for a {@code long} value.
*
* @param value The {@code long} value to load onto the operand stack.
*/
protected ForLongConstant(long value) {
this.value = value;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(LongConstant.forValue(value), assigner.assign(new TypeDescription.Generic.OfNonGenericType.ForLoadedType(long.class), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign long value to " + target);
}
return stackManipulation;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForLongConstant)) return false;
final MethodCall.ArgumentLoader.ForLongConstant other = (MethodCall.ArgumentLoader.ForLongConstant) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.value != other.value) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForLongConstant;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final long $value = this.value;
result = result * PRIME + (int) ($value >>> 32 ^ $value);
return result;
}
}
/**
* Loads a {@code float} value onto the operand stack.
*/
class ForFloatConstant implements ArgumentLoader, Factory {
/**
* The {@code float} value to load onto the operand stack.
*/
private final float value;
/**
* Creates a new argument loader for a {@code float} value.
*
* @param value The {@code float} value to load onto the operand stack.
*/
protected ForFloatConstant(float value) {
this.value = value;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(FloatConstant.forValue(value), assigner.assign(new TypeDescription.Generic.OfNonGenericType.ForLoadedType(float.class), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign float value to " + target);
}
return stackManipulation;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForFloatConstant)) return false;
final MethodCall.ArgumentLoader.ForFloatConstant other = (MethodCall.ArgumentLoader.ForFloatConstant) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (java.lang.Float.compare(this.value, other.value) != 0) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForFloatConstant;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + java.lang.Float.floatToIntBits(this.value);
return result;
}
}
/**
* Loads a {@code double} value onto the operand stack.
*/
class ForDoubleConstant implements ArgumentLoader, Factory {
/**
* The {@code double} value to load onto the operand stack.
*/
private final double value;
/**
* Creates a new argument loader for a {@code double} value.
*
* @param value The {@code double} value to load onto the operand stack.
*/
protected ForDoubleConstant(double value) {
this.value = value;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(DoubleConstant.forValue(value), assigner.assign(new TypeDescription.Generic.OfNonGenericType.ForLoadedType(double.class), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign double value to " + target);
}
return stackManipulation;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForDoubleConstant)) return false;
final MethodCall.ArgumentLoader.ForDoubleConstant other = (MethodCall.ArgumentLoader.ForDoubleConstant) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (java.lang.Double.compare(this.value, other.value) != 0) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForDoubleConstant;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final long $value = java.lang.Double.doubleToLongBits(this.value);
result = result * PRIME + (int) ($value >>> 32 ^ $value);
return result;
}
}
/**
* Loads a {@link java.lang.String} value onto the operand stack.
*/
class ForTextConstant implements ArgumentLoader, Factory {
/**
* The {@link java.lang.String} value to load onto the operand stack.
*/
private final String value;
/**
* Creates a new argument loader for a {@link java.lang.String} value.
*
* @param value The {@link java.lang.String} value to load onto the operand stack.
*/
protected ForTextConstant(String value) {
this.value = value;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(new TextConstant(value), assigner.assign(new TypeDescription.Generic.OfNonGenericType.ForLoadedType(String.class), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign String value to " + target);
}
return stackManipulation;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForTextConstant)) return false;
final MethodCall.ArgumentLoader.ForTextConstant other = (MethodCall.ArgumentLoader.ForTextConstant) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$value = this.value;
final java.lang.Object other$value = other.value;
if (this$value == null ? other$value != null : !this$value.equals(other$value)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForTextConstant;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $value = this.value;
result = result * PRIME + ($value == null ? 43 : $value.hashCode());
return result;
}
}
/**
* Loads a {@link java.lang.Class} value onto the operand stack.
*/
class ForClassConstant implements ArgumentLoader, Factory {
/**
* The type to load onto the operand stack.
*/
private final TypeDescription typeDescription;
/**
* Creates a new class constant representation.
*
* @param typeDescription The type to represent.
*/
protected ForClassConstant(TypeDescription typeDescription) {
this.typeDescription = typeDescription;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(ClassConstant.of(typeDescription), assigner.assign(new TypeDescription.Generic.OfNonGenericType.ForLoadedType(Class.class), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign class value to " + target);
}
return stackManipulation;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForClassConstant)) return false;
final MethodCall.ArgumentLoader.ForClassConstant other = (MethodCall.ArgumentLoader.ForClassConstant) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$typeDescription = this.typeDescription;
final java.lang.Object other$typeDescription = other.typeDescription;
if (this$typeDescription == null ? other$typeDescription != null : !this$typeDescription.equals(other$typeDescription)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForClassConstant;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $typeDescription = this.typeDescription;
result = result * PRIME + ($typeDescription == null ? 43 : $typeDescription.hashCode());
return result;
}
}
/**
* An argument loader that loads an enumeration constant.
*/
class ForEnumerationValue implements ArgumentLoader, Factory {
/**
* The enumeration to describe.
*/
private final EnumerationDescription enumerationDescription;
/**
* Creates a new argument loader for an enumeration constant.
*
* @param enumerationDescription The enumeration to describe.
*/
protected ForEnumerationValue(EnumerationDescription enumerationDescription) {
this.enumerationDescription = enumerationDescription;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(FieldAccess.forEnumeration(enumerationDescription), assigner.assign(enumerationDescription.getEnumerationType().asGenericType(), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign " + enumerationDescription.getEnumerationType() + " value to " + target);
}
return stackManipulation;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForEnumerationValue)) return false;
final MethodCall.ArgumentLoader.ForEnumerationValue other = (MethodCall.ArgumentLoader.ForEnumerationValue) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$enumerationDescription = this.enumerationDescription;
final java.lang.Object other$enumerationDescription = other.enumerationDescription;
if (this$enumerationDescription == null ? other$enumerationDescription != null : !this$enumerationDescription.equals(other$enumerationDescription)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForEnumerationValue;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $enumerationDescription = this.enumerationDescription;
result = result * PRIME + ($enumerationDescription == null ? 43 : $enumerationDescription.hashCode());
return result;
}
}
/**
* Loads a Java instance onto the operand stack.
*/
class ForJavaConstant implements ArgumentLoader, Factory {
/**
* The Java instance to load onto the operand stack.
*/
private final JavaConstant javaConstant;
/**
* Creates a new argument loader for a Java instance.
*
* @param javaConstant The Java instance to load as an argument.
*/
public ForJavaConstant(JavaConstant javaConstant) {
this.javaConstant = javaConstant;
}
@Override
public StackManipulation resolve(ParameterDescription target, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = new StackManipulation.Compound(javaConstant.asStackManipulation(), assigner.assign(javaConstant.getType().asGenericType(), target.getType(), typing));
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot assign Class value to " + target);
}
return stackManipulation;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public List<ArgumentLoader> make(TypeDescription instrumentedType, MethodDescription instrumentedMethod, MethodDescription invokedMethod) {
return Collections.<ArgumentLoader>singletonList(this);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.ArgumentLoader.ForJavaConstant)) return false;
final MethodCall.ArgumentLoader.ForJavaConstant other = (MethodCall.ArgumentLoader.ForJavaConstant) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$javaConstant = this.javaConstant;
final java.lang.Object other$javaConstant = other.javaConstant;
if (this$javaConstant == null ? other$javaConstant != null : !this$javaConstant.equals(other$javaConstant)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.ArgumentLoader.ForJavaConstant;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $javaConstant = this.javaConstant;
result = result * PRIME + ($javaConstant == null ? 43 : $javaConstant.hashCode());
return result;
}
}
}
/**
* A method invoker is responsible for creating a method invocation that is to be applied by a
* {@link MethodCall}.
*/
protected interface MethodInvoker {
/**
* Invokes the method.
*
* @param invokedMethod The method to be invoked.
* @param implementationTarget The implementation target of the instrumented instance.
* @return A stack manipulation that represents the method invocation.
*/
StackManipulation invoke(MethodDescription invokedMethod, Target implementationTarget);
/**
* Applies a contextual invocation of the provided method, i.e. a static invocation for static methods,
* a special invocation for constructors and private methods and a virtual invocation for any other method.
*/
enum ForContextualInvocation implements MethodInvoker {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public StackManipulation invoke(MethodDescription invokedMethod, Target implementationTarget) {
if (invokedMethod.isVirtual() && !invokedMethod.isInvokableOn(implementationTarget.getInstrumentedType())) {
throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + implementationTarget.getInstrumentedType());
} else if (!invokedMethod.isVisibleTo(implementationTarget.getInstrumentedType())) {
throw new IllegalStateException(invokedMethod + " is not visible to " + implementationTarget.getInstrumentedType());
}
return invokedMethod.isVirtual() ? MethodInvocation.invoke(invokedMethod).virtual(implementationTarget.getInstrumentedType()) : MethodInvocation.invoke(invokedMethod);
}
}
/**
* Applies a virtual invocation on a given type.
*/
class ForVirtualInvocation implements MethodInvoker {
/**
* The type description to virtually invoke the method upon.
*/
private final TypeDescription typeDescription;
/**
* Creates a new method invoking for a virtual method invocation.
*
* @param typeDescription The type description to virtually invoke the method upon.
*/
protected ForVirtualInvocation(TypeDescription typeDescription) {
this.typeDescription = typeDescription;
}
/**
* Creates a new method invoking for a virtual method invocation.
*
* @param type The type to virtually invoke the method upon.
*/
protected ForVirtualInvocation(Class<?> type) {
this(new TypeDescription.ForLoadedType(type));
}
@Override
public StackManipulation invoke(MethodDescription invokedMethod, Target implementationTarget) {
if (!invokedMethod.isVirtual()) {
throw new IllegalStateException("Cannot invoke " + invokedMethod + " virtually");
} else if (!invokedMethod.isInvokableOn(typeDescription.asErasure())) {
throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + typeDescription);
} else if (!typeDescription.asErasure().isAccessibleTo(implementationTarget.getInstrumentedType())) {
throw new IllegalStateException(typeDescription + " is not accessible to " + implementationTarget.getInstrumentedType());
}
return MethodInvocation.invoke(invokedMethod).virtual(typeDescription.asErasure());
}
/**
* A method invoker for a virtual method that uses an implicit target type.
*/
public enum WithImplicitType implements MethodInvoker {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public StackManipulation invoke(MethodDescription invokedMethod, Target implementationTarget) {
if (!invokedMethod.isVirtual()) {
throw new IllegalStateException("Cannot invoke " + invokedMethod + " virtually");
}
return MethodInvocation.invoke(invokedMethod);
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall.MethodInvoker.ForVirtualInvocation)) return false;
final MethodCall.MethodInvoker.ForVirtualInvocation other = (MethodCall.MethodInvoker.ForVirtualInvocation) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$typeDescription = this.typeDescription;
final java.lang.Object other$typeDescription = other.typeDescription;
if (this$typeDescription == null ? other$typeDescription != null : !this$typeDescription.equals(other$typeDescription)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall.MethodInvoker.ForVirtualInvocation;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $typeDescription = this.typeDescription;
result = result * PRIME + ($typeDescription == null ? 43 : $typeDescription.hashCode());
return result;
}
}
/**
* Applies a super method invocation of the provided method.
*/
enum ForSuperMethodInvocation implements MethodInvoker {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public StackManipulation invoke(MethodDescription invokedMethod, Target implementationTarget) {
if (implementationTarget.getInstrumentedType().getSuperClass() == null) {
throw new IllegalStateException("Cannot invoke super method for " + implementationTarget.getInstrumentedType());
} else if (!invokedMethod.isInvokableOn(implementationTarget.getOriginType().asErasure())) {
throw new IllegalStateException("Cannot invoke " + invokedMethod + " as super method of " + implementationTarget.getInstrumentedType());
}
StackManipulation stackManipulation = implementationTarget.invokeDominant(invokedMethod.asSignatureToken());
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot invoke " + invokedMethod + " as a super method");
}
return stackManipulation;
}
}
/**
* Invokes a method as a Java 8 default method.
*/
enum ForDefaultMethodInvocation implements MethodInvoker {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public StackManipulation invoke(MethodDescription invokedMethod, Target implementationTarget) {
if (!invokedMethod.isInvokableOn(implementationTarget.getInstrumentedType())) {
throw new IllegalStateException("Cannot invoke " + invokedMethod + " as default method of " + implementationTarget.getInstrumentedType());
}
StackManipulation stackManipulation = implementationTarget.invokeDefault(invokedMethod.asSignatureToken(), invokedMethod.getDeclaringType().asErasure());
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot invoke " + invokedMethod + " on " + implementationTarget.getInstrumentedType());
}
return stackManipulation;
}
}
}
/**
* A termination handler is responsible to handle the return value of a method that is invoked via a
* {@link MethodCall}.
*/
protected enum TerminationHandler {
/**
* A termination handler that returns the invoked method's return value.
*/
RETURNING {
@Override
public StackManipulation resolve(MethodDescription invokedMethod, MethodDescription instrumentedMethod, Assigner assigner, Assigner.Typing typing) {
StackManipulation stackManipulation = assigner.assign(invokedMethod.isConstructor() ? invokedMethod.getDeclaringType().asGenericType() : invokedMethod.getReturnType(), instrumentedMethod.getReturnType(), typing);
if (!stackManipulation.isValid()) {
throw new IllegalStateException("Cannot return " + invokedMethod.getReturnType() + " from " + instrumentedMethod);
}
return new StackManipulation.Compound(stackManipulation, MethodReturn.of(instrumentedMethod.getReturnType()));
}
},
/**
* A termination handler that drops the invoked method's return value.
*/
DROPPING {
@Override
protected StackManipulation resolve(MethodDescription invokedMethod, MethodDescription instrumentedMethod, Assigner assigner, Assigner.Typing typing) {
return Removal.of(invokedMethod.isConstructor() ? invokedMethod.getDeclaringType() : invokedMethod.getReturnType());
}
};
/**
* Returns a stack manipulation that handles the method return.
*
* @param invokedMethod The method that was invoked by the method call.
* @param instrumentedMethod The method being intercepted.
* @param assigner The assigner to be used.
* @param typing Indicates if dynamic type castings should be attempted for incompatible assignments.
* @return A stack manipulation that handles the method return.
*/
protected abstract StackManipulation resolve(MethodDescription invokedMethod, MethodDescription instrumentedMethod, Assigner assigner, Assigner.Typing typing);
}
/**
* Represents a {@link MethodCall} that invokes a method without specifying
* an invocation method. Some methods can for example be invoked both virtually or as a super method invocation.
* Similarly, interface methods can be invoked virtually or as an explicit invocation of a default method. If
* no explicit invocation type is set, a method is always invoked virtually unless the method
* represents a static methods or a constructor.
*/
public static class WithoutSpecifiedTarget extends MethodCall {
/**
* Creates a new method call without a specified target.
*
* @param methodLocator The method locator to use.
*/
protected WithoutSpecifiedTarget(MethodLocator methodLocator) {
super(methodLocator, TargetHandler.ForSelfOrStaticInvocation.INSTANCE, Collections.<ArgumentLoader.Factory>emptyList(), MethodInvoker.ForContextualInvocation.INSTANCE, TerminationHandler.RETURNING, Assigner.DEFAULT, Assigner.Typing.STATIC);
}
/**
* Invokes the specified method on the given instance.
*
* @param target The object on which the method is to be invoked upon.
* @return A method call that invokes the provided method on the given object.
*/
@SuppressWarnings("unchecked")
public MethodCall on(Object target) {
return on(target, (Class) target.getClass());
}
/**
* Invokes the specified method on the given instance.
*
* @param target The object on which the method is to be invoked upon.
* @param type The object's type.
* @param <T> The type of the object.
* @return A method call that invokes the provided method on the given object.
*/
public <T> MethodCall on(T target, Class<? super T> type) {
return new MethodCall(methodLocator, new TargetHandler.ForValue(target, new TypeDescription.Generic.OfNonGenericType.ForLoadedType(type)), argumentLoaders, new MethodInvoker.ForVirtualInvocation(type), terminationHandler, assigner, typing);
}
/**
* Invokes the specified method on the instrumented method's argument of the given index.
*
* @param index The index of the method's argument on which the specified method should be invoked.
* @return Amethod call that invokes the provided method on the given method argument.
*/
public MethodCall onArgument(int index) {
if (index < 0) {
throw new IllegalArgumentException("An argument index cannot be negative: " + index);
}
return new MethodCall(methodLocator, new TargetHandler.ForMethodParameter(index), argumentLoaders, MethodInvoker.ForVirtualInvocation.WithImplicitType.INSTANCE, terminationHandler, assigner, typing);
}
/**
* Invokes a method on the object stored in the specified field.
*
* @param name The name of the field.
* @return A method call that invokes the given method on an instance that is read from a field.
*/
public MethodCall onField(String name) {
return onField(name, FieldLocator.ForClassHierarchy.Factory.INSTANCE);
}
/**
* Invokes a method on the object stored in the specified field.
*
* @param name The name of the field.
* @param fieldLocatorFactory The field locator factory to use for locating the field.
* @return A method call that invokes the given method on an instance that is read from a field.
*/
public MethodCall onField(String name, FieldLocator.Factory fieldLocatorFactory) {
return new MethodCall(methodLocator, new TargetHandler.ForField(name, fieldLocatorFactory), argumentLoaders, MethodInvoker.ForVirtualInvocation.WithImplicitType.INSTANCE, terminationHandler, assigner, typing);
}
/**
* Invokes the given method by a super method invocation on the instance of the instrumented type.
* Note that the super method is resolved depending on the type of implementation when this method is called.
* In case that a subclass is created, the super type is invoked. If a type is rebased, the rebased method
* is invoked if such a method exists.
*
* @return A method call where the given method is invoked as a super method invocation.
*/
public MethodCall onSuper() {
return new MethodCall(methodLocator, TargetHandler.ForSelfOrStaticInvocation.INSTANCE, argumentLoaders, MethodInvoker.ForSuperMethodInvocation.INSTANCE, terminationHandler, assigner, typing);
}
/**
* Invokes the given method by a Java 8default method invocation on the instance of the instrumented type.
*
* @return A method call where the given method is invoked as a super method invocation.
*/
public MethodCall onDefault() {
return new MethodCall(methodLocator, TargetHandler.ForSelfOrStaticInvocation.INSTANCE, argumentLoaders, MethodInvoker.ForDefaultMethodInvocation.INSTANCE, terminationHandler, assigner, typing);
}
}
/**
* The appender being used to implement a {@link MethodCall}.
*/
protected class Appender implements ByteCodeAppender {
/**
* The implementation target of the current implementation.
*/
private final Target implementationTarget;
/**
* Creates a new appender.
*
* @param implementationTarget The implementation target of the current implementation.
*/
protected Appender(Target implementationTarget) {
this.implementationTarget = implementationTarget;
}
@Override
public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) {
MethodDescription invokedMethod = methodLocator.resolve(implementationTarget.getInstrumentedType(), instrumentedMethod);
List<ArgumentLoader> argumentLoaders = new ArrayList<ArgumentLoader>(MethodCall.this.argumentLoaders.size());
for (ArgumentLoader.Factory argumentLoader : MethodCall.this.argumentLoaders) {
argumentLoaders.addAll(argumentLoader.make(implementationTarget.getInstrumentedType(), instrumentedMethod, invokedMethod));
}
ParameterList<?> parameters = invokedMethod.getParameters();
Iterator<? extends ParameterDescription> parameterIterator = parameters.iterator();
if (parameters.size() != argumentLoaders.size()) {
throw new IllegalStateException(invokedMethod + " does not take " + argumentLoaders.size() + " arguments");
}
List<StackManipulation> argumentInstructions = new ArrayList<StackManipulation>(argumentLoaders.size());
for (ArgumentLoader argumentLoader : argumentLoaders) {
argumentInstructions.add(argumentLoader.resolve(parameterIterator.next(), assigner, typing));
}
StackManipulation.Size size = new StackManipulation.Compound(targetHandler.resolve(invokedMethod, instrumentedMethod, implementationTarget.getInstrumentedType(), assigner, typing), new StackManipulation.Compound(argumentInstructions), methodInvoker.invoke(invokedMethod, implementationTarget), terminationHandler.resolve(invokedMethod, instrumentedMethod, assigner, typing)).apply(methodVisitor, implementationContext);
return new Size(size.getMaximalSize(), instrumentedMethod.getStackSize());
}
/**
* Returns the outer instance.
*
* @return The outer instance.
*/
private MethodCall getOuter() {
return MethodCall.this;
}
// HE: Remove when Lombok support for getOuter is added.
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (other == null || getClass() != other.getClass()) return false;
Appender appender = (Appender) other;
return implementationTarget.equals(appender.implementationTarget) && MethodCall.this.equals(appender.getOuter());
}
// HE: Remove when Lombok support for getOuter is added.
@Override
public int hashCode() {
return implementationTarget.hashCode() + 31 * MethodCall.this.hashCode();
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof MethodCall)) return false;
final MethodCall other = (MethodCall) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$methodLocator = this.methodLocator;
final java.lang.Object other$methodLocator = other.methodLocator;
if (this$methodLocator == null ? other$methodLocator != null : !this$methodLocator.equals(other$methodLocator)) return false;
final java.lang.Object this$targetHandler = this.targetHandler;
final java.lang.Object other$targetHandler = other.targetHandler;
if (this$targetHandler == null ? other$targetHandler != null : !this$targetHandler.equals(other$targetHandler)) return false;
final java.lang.Object this$argumentLoaders = this.argumentLoaders;
final java.lang.Object other$argumentLoaders = other.argumentLoaders;
if (this$argumentLoaders == null ? other$argumentLoaders != null : !this$argumentLoaders.equals(other$argumentLoaders)) return false;
final java.lang.Object this$methodInvoker = this.methodInvoker;
final java.lang.Object other$methodInvoker = other.methodInvoker;
if (this$methodInvoker == null ? other$methodInvoker != null : !this$methodInvoker.equals(other$methodInvoker)) return false;
final java.lang.Object this$terminationHandler = this.terminationHandler;
final java.lang.Object other$terminationHandler = other.terminationHandler;
if (this$terminationHandler == null ? other$terminationHandler != null : !this$terminationHandler.equals(other$terminationHandler)) return false;
final java.lang.Object this$assigner = this.assigner;
final java.lang.Object other$assigner = other.assigner;
if (this$assigner == null ? other$assigner != null : !this$assigner.equals(other$assigner)) return false;
final java.lang.Object this$typing = this.typing;
final java.lang.Object other$typing = other.typing;
if (this$typing == null ? other$typing != null : !this$typing.equals(other$typing)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof MethodCall;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $methodLocator = this.methodLocator;
result = result * PRIME + ($methodLocator == null ? 43 : $methodLocator.hashCode());
final java.lang.Object $targetHandler = this.targetHandler;
result = result * PRIME + ($targetHandler == null ? 43 : $targetHandler.hashCode());
final java.lang.Object $argumentLoaders = this.argumentLoaders;
result = result * PRIME + ($argumentLoaders == null ? 43 : $argumentLoaders.hashCode());
final java.lang.Object $methodInvoker = this.methodInvoker;
result = result * PRIME + ($methodInvoker == null ? 43 : $methodInvoker.hashCode());
final java.lang.Object $terminationHandler = this.terminationHandler;
result = result * PRIME + ($terminationHandler == null ? 43 : $terminationHandler.hashCode());
final java.lang.Object $assigner = this.assigner;
result = result * PRIME + ($assigner == null ? 43 : $assigner.hashCode());
final java.lang.Object $typing = this.typing;
result = result * PRIME + ($typing == null ? 43 : $typing.hashCode());
return result;
}
}