// Generated by delombok at Sun Feb 26 12:31:38 KST 2017
package scouter.bytebuddy.implementation.bind.annotation;
import scouter.bytebuddy.ByteBuddy;
import scouter.bytebuddy.ClassFileVersion;
import scouter.bytebuddy.description.annotation.AnnotationDescription;
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.type.TypeDescription;
import scouter.bytebuddy.dynamic.DynamicType;
import scouter.bytebuddy.dynamic.scaffold.InstrumentedType;
import scouter.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
import scouter.bytebuddy.implementation.Implementation;
import scouter.bytebuddy.implementation.MethodAccessorFactory;
import scouter.bytebuddy.implementation.MethodDelegation;
import scouter.bytebuddy.implementation.auxiliary.AuxiliaryType;
import scouter.bytebuddy.implementation.bind.MethodDelegationBinder;
import scouter.bytebuddy.implementation.bytecode.ByteCodeAppender;
import scouter.bytebuddy.implementation.bytecode.Duplication;
import scouter.bytebuddy.implementation.bytecode.StackManipulation;
import scouter.bytebuddy.implementation.bytecode.TypeCreation;
import scouter.bytebuddy.implementation.bytecode.assign.Assigner;
import scouter.bytebuddy.implementation.bytecode.collection.ArrayAccess;
import scouter.bytebuddy.implementation.bytecode.constant.IntegerConstant;
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.ElementMatchers;
import scouter.bytebuddy.jar.asm.MethodVisitor;
import scouter.bytebuddy.jar.asm.Opcodes;
import java.io.Serializable;
import java.lang.annotation.*;
import java.util.Collections;
import static scouter.bytebuddy.matcher.ElementMatchers.*;
/**
* This annotation instructs Byte Buddy to inject a proxy class that calls a method's super method with
* explicit arguments. For this, the {@link Morph.Binder}
* needs to be installed for an interface type that takes an argument of the array type {@link java.lang.Object} and
* returns a non-array type of {@link java.lang.Object}. This is an alternative to using the
* {@link SuperCall} or
* {@link DefaultCall} annotations which call a super
* method using the same arguments as the intercepted method was invoked with.
*
* @see MethodDelegation
* @see TargetMethodAnnotationDrivenBinder
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Morph {
/**
* Determines if the injected proxy for this parameter should be serializable.
*
* @return {@code true} if the proxy should be serializable.
*/
boolean serializableProxy() default false;
/**
* Determines if the proxy should attempt to invoke a default method. If the default method is ambiguous,
* use the {@link Morph#defaultTarget()} property instead which allows to determine an explicit interface
* on which the default method should be invoked on. If this other method is used, this property is ignored.
*
* @return {@code true} if a default method should be ignored.
*/
boolean defaultMethod() default false;
/**
* The type on which a default method should be invoked. When this property is not set and the
* {@link Morph#defaultMethod()} property is set to {@code false}, a normal super method invocation is attempted.
*
* @return The target interface of a default method call.
*/
Class<?> defaultTarget() default void.class;
/**
* A binder for the {@link Morph} annotation.
*/
class Binder implements TargetMethodAnnotationDrivenBinder.ParameterBinder<Morph> {
/**
* A reference to the serializable proxy method.
*/
private static final MethodDescription.InDefinedShape SERIALIZABLE_PROXY;
/**
* A reference to the default method method.
*/
private static final MethodDescription.InDefinedShape DEFAULT_METHOD;
/**
* A reference to the default target method.
*/
private static final MethodDescription.InDefinedShape DEFAULT_TARGET;
/*
* Looks up references for all annotation properties of the morph annotation.
*/
static {
MethodList<MethodDescription.InDefinedShape> methodList = new TypeDescription.ForLoadedType(Morph.class).getDeclaredMethods();
SERIALIZABLE_PROXY = methodList.filter(named("serializableProxy")).getOnly();
DEFAULT_METHOD = methodList.filter(named("defaultMethod")).getOnly();
DEFAULT_TARGET = methodList.filter(named("defaultTarget")).getOnly();
}
/**
* The method which is overridden for generating the proxy class.
*/
private final MethodDescription forwardingMethod;
/**
* Creates a new binder.
*
* @param forwardingMethod The method which is overridden for generating the proxy class.
*/
protected Binder(MethodDescription forwardingMethod) {
this.forwardingMethod = forwardingMethod;
}
/**
* Installs a given type for use on a {@link Morph}
* annotation. The given type must be an interface without any super interfaces and a single method which
* maps an {@link java.lang.Object} array to a {@link java.lang.Object} type. The use of generics is
* permitted.
*
* @param type The type to install.
* @return A binder for the {@link Morph}
* annotation.
*/
public static TargetMethodAnnotationDrivenBinder.ParameterBinder<Morph> install(Class<?> type) {
return install(new TypeDescription.ForLoadedType(type));
}
/**
* Installs a given type for use on a {@link Morph}
* annotation. The given type must be an interface without any super interfaces and a single method which
* maps an {@link java.lang.Object} array to a {@link java.lang.Object} type. The use of generics is
* permitted.
*
* @param typeDescription The type to install.
* @return A binder for the {@link Morph}
* annotation.
*/
public static TargetMethodAnnotationDrivenBinder.ParameterBinder<Morph> install(TypeDescription typeDescription) {
return new Binder(onlyMethod(typeDescription));
}
/**
* Extracts the only method of a given type and validates to fit the constraints of the morph annotation.
*
* @param typeDescription The type to extract the method from.
* @return The only method after validation.
*/
private static MethodDescription onlyMethod(TypeDescription typeDescription) {
if (!typeDescription.isInterface()) {
throw new IllegalArgumentException(typeDescription + " is not an interface");
} else if (!typeDescription.getInterfaces().isEmpty()) {
throw new IllegalArgumentException(typeDescription + " must not extend other interfaces");
} else if (!typeDescription.isPublic()) {
throw new IllegalArgumentException(typeDescription + " is mot public");
}
MethodList<?> methodCandidates = typeDescription.getDeclaredMethods().filter(isAbstract());
if (methodCandidates.size() != 1) {
throw new IllegalArgumentException(typeDescription + " must declare exactly one abstract method");
}
MethodDescription methodDescription = methodCandidates.getOnly();
if (!methodDescription.getReturnType().asErasure().represents(Object.class)) {
throw new IllegalArgumentException(methodDescription + " does not return an Object-type");
} else if (methodDescription.getParameters().size() != 1 || !methodDescription.getParameters().get(0).getType().asErasure().represents(Object[].class)) {
throw new IllegalArgumentException(methodDescription + " does not take a single argument of type Object[]");
}
return methodDescription;
}
@Override
public Class<Morph> getHandledType() {
return Morph.class;
}
@Override
public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Morph> annotation, MethodDescription source, ParameterDescription target, Implementation.Target implementationTarget, Assigner assigner, Assigner.Typing typing) {
if (!target.getType().asErasure().equals(forwardingMethod.getDeclaringType())) {
throw new IllegalStateException("Illegal use of @Morph for " + target + " which was installed for " + forwardingMethod.getDeclaringType());
}
Implementation.SpecialMethodInvocation specialMethodInvocation;
TypeDescription typeDescription = annotation.getValue(DEFAULT_TARGET).resolve(TypeDescription.class);
if (typeDescription.represents(void.class) && !annotation.getValue(DEFAULT_METHOD).resolve(Boolean.class)) {
specialMethodInvocation = implementationTarget.invokeSuper(source.asSignatureToken());
} else {
specialMethodInvocation = (typeDescription.represents(void.class) ? DefaultMethodLocator.Implicit.INSTANCE : new DefaultMethodLocator.Explicit(typeDescription)).resolve(implementationTarget, source);
}
return specialMethodInvocation.isValid() ? new MethodDelegationBinder.ParameterBinding.Anonymous(new RedirectionProxy(forwardingMethod.getDeclaringType().asErasure(), implementationTarget.getInstrumentedType(), specialMethodInvocation, assigner, annotation.getValue(SERIALIZABLE_PROXY).resolve(Boolean.class))) : MethodDelegationBinder.ParameterBinding.Illegal.INSTANCE;
}
/**
* A default method locator is responsible for looking up a default method to a given source method.
*/
protected interface DefaultMethodLocator {
/**
* Locates the correct default method to a given source method.
*
* @param implementationTarget The current implementation target.
* @param source The source method for which a default method should be looked up.
* @return A special method invocation of the default method or an illegal special method invocation,
* if no suitable invocation could be located.
*/
Implementation.SpecialMethodInvocation resolve(Implementation.Target implementationTarget, MethodDescription source);
/**
* An implicit default method locator that only permits the invocation of a default method if the source
* method itself represents a method that was defined on a default method interface.
*/
enum Implicit implements DefaultMethodLocator {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public Implementation.SpecialMethodInvocation resolve(Implementation.Target implementationTarget, MethodDescription source) {
return implementationTarget.invokeDefault(source.asSignatureToken());
}
}
/**
* An explicit default method locator attempts to look up a default method in the specified interface type.
*/
class Explicit implements DefaultMethodLocator {
/**
* A description of the type on which the default method should be invoked.
*/
private final TypeDescription typeDescription;
/**
* Creates a new explicit default method locator.
*
* @param typeDescription The actual target interface as explicitly defined by
* {@link DefaultCall#targetType()}.
*/
public Explicit(TypeDescription typeDescription) {
this.typeDescription = typeDescription;
}
@Override
public Implementation.SpecialMethodInvocation resolve(Implementation.Target implementationTarget, MethodDescription source) {
if (!typeDescription.isInterface()) {
throw new IllegalStateException(source + " method carries default method call parameter on non-interface type");
}
return implementationTarget.invokeDefault(source.asSignatureToken(), typeDescription);
}
@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 Morph.Binder.DefaultMethodLocator.Explicit)) return false;
final Morph.Binder.DefaultMethodLocator.Explicit other = (Morph.Binder.DefaultMethodLocator.Explicit) 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 Morph.Binder.DefaultMethodLocator.Explicit;
}
@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;
}
}
}
/**
* A proxy that implements the installed interface in order to allow for a morphed super method invocation.
*/
protected static class RedirectionProxy implements AuxiliaryType, StackManipulation {
/**
* The name of the field that carries an instance for invoking a super method on.
*/
protected static final String FIELD_NAME = "target";
/**
* The interface type that is implemented by the generated proxy.
*/
private final TypeDescription morphingType;
/**
* The type that is instrumented on which the super method is invoked.
*/
private final TypeDescription instrumentedType;
/**
* The special method invocation to be executed by the morphing type via an accessor on the
* instrumented type.
*/
private final Implementation.SpecialMethodInvocation specialMethodInvocation;
/**
* The assigner to use.
*/
private final Assigner assigner;
/**
* Determines if the generated proxy should be {@link java.io.Serializable}.
*/
private final boolean serializableProxy;
/**
* Creates a new redirection proxy.
*
* @param morphingType The interface type that is implemented by the generated proxy.
* @param instrumentedType The type that is instrumented on which the super method is invoked.
* @param specialMethodInvocation The special method invocation to be executed by the morphing type via
* an accessor on the instrumented type.
* @param assigner The assigner to use.
* @param serializableProxy {@code true} if the proxy should be serializable.
*/
protected RedirectionProxy(TypeDescription morphingType, TypeDescription instrumentedType, Implementation.SpecialMethodInvocation specialMethodInvocation, Assigner assigner, boolean serializableProxy) {
this.morphingType = morphingType;
this.instrumentedType = instrumentedType;
this.specialMethodInvocation = specialMethodInvocation;
this.assigner = assigner;
this.serializableProxy = serializableProxy;
}
@Override
public DynamicType make(String auxiliaryTypeName, ClassFileVersion classFileVersion, MethodAccessorFactory methodAccessorFactory) {
return new ByteBuddy(classFileVersion).subclass(morphingType, ConstructorStrategy.Default.NO_CONSTRUCTORS).name(auxiliaryTypeName).modifiers(DEFAULT_TYPE_MODIFIER).implement(serializableProxy ? new Class<?>[] {Serializable.class} : new Class<?>[0]).defineConstructor().withParameters(specialMethodInvocation.getMethodDescription().isStatic() ? Collections.<TypeDescription>emptyList() : Collections.singletonList(instrumentedType)).intercept(specialMethodInvocation.getMethodDescription().isStatic() ? StaticFieldConstructor.INSTANCE : new InstanceFieldConstructor(instrumentedType)).method(ElementMatchers.<MethodDescription>isAbstract().and(isDeclaredBy(morphingType))).intercept(new MethodCall(methodAccessorFactory.registerAccessorFor(specialMethodInvocation, MethodAccessorFactory.AccessType.DEFAULT), assigner)).make();
}
@Override
public boolean isValid() {
return true;
}
@Override
public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) {
TypeDescription forwardingType = implementationContext.register(this);
return new Compound(TypeCreation.of(forwardingType), Duplication.SINGLE, specialMethodInvocation.getMethodDescription().isStatic() ? Trivial.INSTANCE : MethodVariableAccess.loadThis(), MethodInvocation.invoke(forwardingType.getDeclaredMethods().filter(isConstructor()).getOnly())).apply(methodVisitor, implementationContext);
}
/**
* Creates an instance of the proxy when instrumenting a static method.
*/
protected enum StaticFieldConstructor implements Implementation {
/**
* The singleton instance.
*/
INSTANCE;
/**
* A reference of the {@link Object} type default constructor.
*/
private final MethodDescription objectTypeDefaultConstructor;
/**
* Creates the constructor call singleton.
*/
StaticFieldConstructor() {
objectTypeDefaultConstructor = TypeDescription.OBJECT.getDeclaredMethods().filter(isConstructor()).getOnly();
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public ByteCodeAppender appender(Target implementationTarget) {
return new ByteCodeAppender.Simple(MethodVariableAccess.loadThis(), MethodInvocation.invoke(objectTypeDefaultConstructor), MethodReturn.VOID);
}
}
/**
* Creates an instance of the proxy when instrumenting an instance method.
*/
protected static class InstanceFieldConstructor implements Implementation {
/**
* The instrumented type.
*/
private final TypeDescription instrumentedType;
/**
* Creates a new instance field constructor implementation.
*
* @param instrumentedType The instrumented type.
*/
protected InstanceFieldConstructor(TypeDescription instrumentedType) {
this.instrumentedType = instrumentedType;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType.withField(new FieldDescription.Token(RedirectionProxy.FIELD_NAME, Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE, this.instrumentedType.asGenericType()));
}
@Override
public ByteCodeAppender appender(Target implementationTarget) {
return new Appender(implementationTarget);
}
/**
* The byte code appender that implements the constructor.
*/
protected static class Appender implements ByteCodeAppender {
/**
* The field that carries the instance on which the super method is invoked.
*/
private final FieldDescription fieldDescription;
/**
* Creates a new appender.
*
* @param implementationTarget The current implementation target.
*/
protected Appender(Target implementationTarget) {
fieldDescription = implementationTarget.getInstrumentedType().getDeclaredFields().filter((named(RedirectionProxy.FIELD_NAME))).getOnly();
}
@Override
public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) {
StackManipulation.Size stackSize = new StackManipulation.Compound(MethodVariableAccess.loadThis(), MethodInvocation.invoke(StaticFieldConstructor.INSTANCE.objectTypeDefaultConstructor), MethodVariableAccess.allArgumentsOf(instrumentedMethod).prependThisReference(), FieldAccess.forField(fieldDescription).write(), MethodReturn.VOID).apply(methodVisitor, implementationContext);
return new Size(stackSize.getMaximalSize(), instrumentedMethod.getStackSize());
}
@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 Morph.Binder.RedirectionProxy.InstanceFieldConstructor.Appender)) return false;
final Morph.Binder.RedirectionProxy.InstanceFieldConstructor.Appender other = (Morph.Binder.RedirectionProxy.InstanceFieldConstructor.Appender) 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 Morph.Binder.RedirectionProxy.InstanceFieldConstructor.Appender;
}
@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;
}
}
@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 Morph.Binder.RedirectionProxy.InstanceFieldConstructor)) return false;
final Morph.Binder.RedirectionProxy.InstanceFieldConstructor other = (Morph.Binder.RedirectionProxy.InstanceFieldConstructor) 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 Morph.Binder.RedirectionProxy.InstanceFieldConstructor;
}
@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;
}
}
/**
* Implements a the method call of the morphing method.
*/
protected static class MethodCall implements Implementation {
/**
* The accessor method to invoke from the proxy's method.
*/
private final MethodDescription accessorMethod;
/**
* The assigner to be used.
*/
private final Assigner assigner;
/**
* Creates a new method call implementation for a proxy method.
*
* @param accessorMethod The accessor method to invoke from the proxy's method.
* @param assigner The assigner to be used.
*/
protected MethodCall(MethodDescription accessorMethod, Assigner assigner) {
this.accessorMethod = accessorMethod;
this.assigner = assigner;
}
@Override
public InstrumentedType prepare(InstrumentedType instrumentedType) {
return instrumentedType;
}
@Override
public ByteCodeAppender appender(Target implementationTarget) {
return new Appender(implementationTarget);
}
/**
* The byte code appender to implement the method.
*/
protected class Appender implements ByteCodeAppender {
/**
* The proxy type.
*/
private final TypeDescription typeDescription;
/**
* Creates a new appender.
*
* @param implementationTarget The current implementation target.
*/
protected Appender(Target implementationTarget) {
typeDescription = implementationTarget.getInstrumentedType();
}
@Override
public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) {
StackManipulation arrayReference = MethodVariableAccess.REFERENCE.loadFrom(1);
StackManipulation[] parameterLoading = new StackManipulation[accessorMethod.getParameters().size()];
int index = 0;
for (TypeDescription.Generic parameterType : accessorMethod.getParameters().asTypeList()) {
parameterLoading[index] = new StackManipulation.Compound(arrayReference, IntegerConstant.forValue(index), ArrayAccess.REFERENCE.load(), assigner.assign(TypeDescription.Generic.OBJECT, parameterType, Assigner.Typing.DYNAMIC));
index++;
}
StackManipulation.Size stackSize = new StackManipulation.Compound(accessorMethod.isStatic() ? Trivial.INSTANCE : new StackManipulation.Compound(MethodVariableAccess.loadThis(), FieldAccess.forField(typeDescription.getDeclaredFields().filter((named(RedirectionProxy.FIELD_NAME))).getOnly()).read()), new StackManipulation.Compound(parameterLoading), MethodInvocation.invoke(accessorMethod), assigner.assign(accessorMethod.getReturnType(), instrumentedMethod.getReturnType(), Assigner.Typing.DYNAMIC), MethodReturn.REFERENCE).apply(methodVisitor, implementationContext);
return new Size(stackSize.getMaximalSize(), instrumentedMethod.getStackSize());
}
/**
* Returns the outer instance.
*
* @return The outer instance.
*/
private MethodCall getMethodCall() {
return MethodCall.this;
}
// HE: Remove when Lombok support for getOuter is added.
@Override
public boolean equals(Object other) {
return this == other || !(other == null || getClass() != other.getClass()) && MethodCall.this.equals(((Appender) other).getMethodCall()) && typeDescription.equals(((Appender) other).typeDescription);
}
// HE: Remove when Lombok support for getOuter is added.
@Override
public int hashCode() {
return typeDescription.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 Morph.Binder.RedirectionProxy.MethodCall)) return false;
final Morph.Binder.RedirectionProxy.MethodCall other = (Morph.Binder.RedirectionProxy.MethodCall) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$accessorMethod = this.accessorMethod;
final java.lang.Object other$accessorMethod = other.accessorMethod;
if (this$accessorMethod == null ? other$accessorMethod != null : !this$accessorMethod.equals(other$accessorMethod)) 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;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof Morph.Binder.RedirectionProxy.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 $accessorMethod = this.accessorMethod;
result = result * PRIME + ($accessorMethod == null ? 43 : $accessorMethod.hashCode());
final java.lang.Object $assigner = this.assigner;
result = result * PRIME + ($assigner == null ? 43 : $assigner.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 Morph.Binder.RedirectionProxy)) return false;
final Morph.Binder.RedirectionProxy other = (Morph.Binder.RedirectionProxy) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$morphingType = this.morphingType;
final java.lang.Object other$morphingType = other.morphingType;
if (this$morphingType == null ? other$morphingType != null : !this$morphingType.equals(other$morphingType)) 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;
final java.lang.Object this$specialMethodInvocation = this.specialMethodInvocation;
final java.lang.Object other$specialMethodInvocation = other.specialMethodInvocation;
if (this$specialMethodInvocation == null ? other$specialMethodInvocation != null : !this$specialMethodInvocation.equals(other$specialMethodInvocation)) 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;
if (this.serializableProxy != other.serializableProxy) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof Morph.Binder.RedirectionProxy;
}
@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 $morphingType = this.morphingType;
result = result * PRIME + ($morphingType == null ? 43 : $morphingType.hashCode());
final java.lang.Object $instrumentedType = this.instrumentedType;
result = result * PRIME + ($instrumentedType == null ? 43 : $instrumentedType.hashCode());
final java.lang.Object $specialMethodInvocation = this.specialMethodInvocation;
result = result * PRIME + ($specialMethodInvocation == null ? 43 : $specialMethodInvocation.hashCode());
final java.lang.Object $assigner = this.assigner;
result = result * PRIME + ($assigner == null ? 43 : $assigner.hashCode());
result = result * PRIME + (this.serializableProxy ? 79 : 97);
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 Morph.Binder)) return false;
final Morph.Binder other = (Morph.Binder) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$forwardingMethod = this.forwardingMethod;
final java.lang.Object other$forwardingMethod = other.forwardingMethod;
if (this$forwardingMethod == null ? other$forwardingMethod != null : !this$forwardingMethod.equals(other$forwardingMethod)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof Morph.Binder;
}
@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 $forwardingMethod = this.forwardingMethod;
result = result * PRIME + ($forwardingMethod == null ? 43 : $forwardingMethod.hashCode());
return result;
}
}
}