// Generated by delombok at Sun Feb 26 12:31:38 KST 2017
package scouter.bytebuddy.implementation.bytecode.assign.primitive;
import scouter.bytebuddy.description.type.TypeDefinition;
import scouter.bytebuddy.description.type.TypeDescription;
import scouter.bytebuddy.implementation.Implementation;
import scouter.bytebuddy.implementation.bytecode.StackManipulation;
import scouter.bytebuddy.implementation.bytecode.StackSize;
import scouter.bytebuddy.implementation.bytecode.assign.Assigner;
import scouter.bytebuddy.jar.asm.MethodVisitor;
import scouter.bytebuddy.jar.asm.Opcodes;
/**
* This delegate is responsible for unboxing a wrapper type to their primitive equivalents.
*/
public enum PrimitiveUnboxingDelegate implements StackManipulation {
/**
* The unboxing delegate for {@code Boolean} types.
*/
BOOLEAN(Boolean.class, boolean.class, StackSize.ZERO, "booleanValue", "()Z"), /**
* The unboxing delegate for {@code Byte} types.
*/
BYTE(Byte.class, byte.class, StackSize.ZERO, "byteValue", "()B"), /**
* The unboxing delegate for {@code Short} types.
*/
SHORT(Short.class, short.class, StackSize.ZERO, "shortValue", "()S"), /**
* The unboxing delegate for {@code Character} types.
*/
CHARACTER(Character.class, char.class, StackSize.ZERO, "charValue", "()C"), /**
* The unboxing delegate for {@code Integer} types.
*/
INTEGER(Integer.class, int.class, StackSize.ZERO, "intValue", "()I"), /**
* The unboxing delegate for {@code Long} types.
*/
LONG(Long.class, long.class, StackSize.SINGLE, "longValue", "()J"), /**
* The unboxing delegate for {@code Float} types.
*/
FLOAT(Float.class, float.class, StackSize.ZERO, "floatValue", "()F"), /**
* The unboxing delegate for {@code Double} types.
*/
DOUBLE(Double.class, double.class, StackSize.SINGLE, "doubleValue", "()D");
/**
* The wrapper type of the represented primitive type.
*/
private final TypeDescription wrapperType;
/**
* The represented primitive type.
*/
private final TypeDescription primitiveType;
/**
* The size increase after a wrapper type was unwrapped.
*/
private final Size size;
/**
* The name of the method for unboxing a wrapper value to its primitive value.
*/
private final String unboxingMethodName;
/**
* The descriptor of the method for unboxing a wrapper value to its primitive value.
*/
private final String unboxingMethodDescriptor;
/**
* Creates a new primitive unboxing delegate.
*
* @param wrapperType The wrapper type of the represented primitive type.
* @param primitiveType The represented primitive type.
* @param sizeDifference The size difference between the wrapper type and its primitive value.
* @param unboxingMethodName The name of the method for unboxing a wrapper value to its primitive value.
* @param unboxingMethodDescriptor The descriptor of the method for unboxing a wrapper value to its primitive value.
*/
PrimitiveUnboxingDelegate(Class<?> wrapperType, Class<?> primitiveType, StackSize sizeDifference, String unboxingMethodName, String unboxingMethodDescriptor) {
this.size = sizeDifference.toIncreasingSize();
this.wrapperType = new TypeDescription.ForLoadedType(wrapperType);
this.primitiveType = new TypeDescription.ForLoadedType(primitiveType);
this.unboxingMethodName = unboxingMethodName;
this.unboxingMethodDescriptor = unboxingMethodDescriptor;
}
/**
* Locates a primitive unboxing delegate for a given primitive type.
*
* @param typeDescription A description of the primitive type.
* @return A corresponding primitive unboxing delegate.
*/
protected static PrimitiveUnboxingDelegate forPrimitive(TypeDescription.Generic typeDescription) {
if (typeDescription.represents(boolean.class)) {
return BOOLEAN;
} else if (typeDescription.represents(byte.class)) {
return BYTE;
} else if (typeDescription.represents(short.class)) {
return SHORT;
} else if (typeDescription.represents(char.class)) {
return CHARACTER;
} else if (typeDescription.represents(int.class)) {
return INTEGER;
} else if (typeDescription.represents(long.class)) {
return LONG;
} else if (typeDescription.represents(float.class)) {
return FLOAT;
} else if (typeDescription.represents(double.class)) {
return DOUBLE;
} else {
throw new IllegalArgumentException("Expected non-void primitive type instead of " + typeDescription);
}
}
/**
* Creates an unboxing responsible that is capable of unboxing a wrapper type.
* <ol>
* <li>If the reference type represents a wrapper type, the wrapper type will simply be unboxed.</li>
* <li>If the reference type does not represent a wrapper type, the wrapper type will be inferred by the primitive target
* type that is later given to the
* {@link PrimitiveUnboxingDelegate.UnboxingResponsible}
* in order to then check if the given type is assignable to the inferred wrapper type.</li>
* </ol>
*
* @param typeDefinition A non-primitive type.
* @return An unboxing responsible capable of performing an unboxing operation while considering a further assignment
* of the unboxed value.
*/
public static UnboxingResponsible forReferenceType(TypeDefinition typeDefinition) {
if (typeDefinition.isPrimitive()) {
throw new IllegalArgumentException("Expected reference type instead of " + typeDefinition);
} else if (typeDefinition.represents(Boolean.class)) {
return ExplicitlyTypedUnboxingResponsible.BOOLEAN;
} else if (typeDefinition.represents(Byte.class)) {
return ExplicitlyTypedUnboxingResponsible.BYTE;
} else if (typeDefinition.represents(Short.class)) {
return ExplicitlyTypedUnboxingResponsible.SHORT;
} else if (typeDefinition.represents(Character.class)) {
return ExplicitlyTypedUnboxingResponsible.CHARACTER;
} else if (typeDefinition.represents(Integer.class)) {
return ExplicitlyTypedUnboxingResponsible.INTEGER;
} else if (typeDefinition.represents(Long.class)) {
return ExplicitlyTypedUnboxingResponsible.LONG;
} else if (typeDefinition.represents(Float.class)) {
return ExplicitlyTypedUnboxingResponsible.FLOAT;
} else if (typeDefinition.represents(Double.class)) {
return ExplicitlyTypedUnboxingResponsible.DOUBLE;
} else {
return new ImplicitlyTypedUnboxingResponsible(typeDefinition.asGenericType());
}
}
/**
* Returns the wrapper type that this unboxing delegate represents.
*
* @return A generic version of this delegate's wrapper type.
*/
protected TypeDescription.Generic getWrapperType() {
return wrapperType.asGenericType();
}
@Override
public boolean isValid() {
return true;
}
@Override
public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) {
methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, wrapperType.asErasure().getInternalName(), unboxingMethodName, unboxingMethodDescriptor, false);
return size;
}
/**
* An explicitly types unboxing responsible is applied for directly unboxing a wrapper type.
*/
protected enum ExplicitlyTypedUnboxingResponsible implements UnboxingResponsible {
/**
* An unboxing responsible for unboxing a {@link java.lang.Boolean} type.
*/
BOOLEAN(PrimitiveUnboxingDelegate.BOOLEAN), /**
* An unboxing responsible for unboxing a {@link java.lang.Byte} type.
*/
BYTE(PrimitiveUnboxingDelegate.BYTE), /**
* An unboxing responsible for unboxing a {@link java.lang.Short} type.
*/
SHORT(PrimitiveUnboxingDelegate.SHORT), /**
* An unboxing responsible for unboxing a {@link java.lang.Character} type.
*/
CHARACTER(PrimitiveUnboxingDelegate.CHARACTER), /**
* An unboxing responsible for unboxing a {@link java.lang.Integer} type.
*/
INTEGER(PrimitiveUnboxingDelegate.INTEGER), /**
* An unboxing responsible for unboxing a {@link java.lang.Long} type.
*/
LONG(PrimitiveUnboxingDelegate.LONG), /**
* An unboxing responsible for unboxing a {@link java.lang.Float} type.
*/
FLOAT(PrimitiveUnboxingDelegate.FLOAT), /**
* An unboxing responsible for unboxing a {@link java.lang.Double} type.
*/
DOUBLE(PrimitiveUnboxingDelegate.DOUBLE);
/**
* The primitive unboxing delegate for handling the given wrapper type.
*/
private final PrimitiveUnboxingDelegate primitiveUnboxingDelegate;
/**
* Creates a new explicitly typed unboxing responsible.
*
* @param primitiveUnboxingDelegate The primitive unboxing delegate for handling the given wrapper type.
*/
ExplicitlyTypedUnboxingResponsible(PrimitiveUnboxingDelegate primitiveUnboxingDelegate) {
this.primitiveUnboxingDelegate = primitiveUnboxingDelegate;
}
@Override
public StackManipulation assignUnboxedTo(TypeDescription.Generic targetType, Assigner assigner, Assigner.Typing typing) {
return new Compound(primitiveUnboxingDelegate, PrimitiveWideningDelegate.forPrimitive(primitiveUnboxingDelegate.primitiveType).widenTo(targetType));
}
}
/**
* Implementations represent an unboxing delegate that is able to perform the unboxing operation.
*/
public interface UnboxingResponsible {
/**
* Attempts to unbox the represented type in order to assign the unboxed value to the given target type
* while using the assigner that is provided by the method call.
*
* @param target The type that is the desired outcome of the assignment.
* @param assigner The assigner used to assign the unboxed type to the target type.
* @param typing Determines if a type-casting should be attempted for incompatible types.
* @return A stack manipulation representing this assignment if such an assignment is possible. An illegal
* assignment otherwise.
*/
StackManipulation assignUnboxedTo(TypeDescription.Generic target, Assigner assigner, Assigner.Typing typing);
}
/**
* An unboxing responsible for an implicitly typed value. This implementation is applied for source types that
* were not found to be of a given wrapper type. Instead, this unboxing responsible tries to assign the
* source type to the primitive target type's wrapper type before performing an unboxing operation.
*/
protected static class ImplicitlyTypedUnboxingResponsible implements UnboxingResponsible {
/**
* The original type which should be unboxed but is not of any known wrapper type.
*/
private final TypeDescription.Generic originalType;
/**
* Creates a new implicitly typed unboxing responsible.
*
* @param originalType The original type which should be unboxed but is not of any known wrapper type.
*/
protected ImplicitlyTypedUnboxingResponsible(TypeDescription.Generic originalType) {
this.originalType = originalType;
}
@Override
public StackManipulation assignUnboxedTo(TypeDescription.Generic target, Assigner assigner, Assigner.Typing typing) {
PrimitiveUnboxingDelegate primitiveUnboxingDelegate = PrimitiveUnboxingDelegate.forPrimitive(target);
return new Compound(assigner.assign(originalType, primitiveUnboxingDelegate.getWrapperType(), typing), primitiveUnboxingDelegate);
}
@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 PrimitiveUnboxingDelegate.ImplicitlyTypedUnboxingResponsible)) return false;
final PrimitiveUnboxingDelegate.ImplicitlyTypedUnboxingResponsible other = (PrimitiveUnboxingDelegate.ImplicitlyTypedUnboxingResponsible) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$originalType = this.originalType;
final java.lang.Object other$originalType = other.originalType;
if (this$originalType == null ? other$originalType != null : !this$originalType.equals(other$originalType)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof PrimitiveUnboxingDelegate.ImplicitlyTypedUnboxingResponsible;
}
@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 $originalType = this.originalType;
result = result * PRIME + ($originalType == null ? 43 : $originalType.hashCode());
return result;
}
}
}