// Generated by delombok at Sun Feb 26 12:31:38 KST 2017 package scouter.bytebuddy.implementation.bytecode.member; import scouter.bytebuddy.description.enumeration.EnumerationDescription; import scouter.bytebuddy.description.field.FieldDescription; import scouter.bytebuddy.description.field.FieldList; import scouter.bytebuddy.description.type.TypeDefinition; import scouter.bytebuddy.implementation.Implementation; import scouter.bytebuddy.implementation.bytecode.StackManipulation; import scouter.bytebuddy.implementation.bytecode.StackSize; import scouter.bytebuddy.implementation.bytecode.assign.TypeCasting; import scouter.bytebuddy.jar.asm.MethodVisitor; import scouter.bytebuddy.jar.asm.Opcodes; import scouter.bytebuddy.matcher.ElementMatchers; /** * An access representation to a given field. */ public enum FieldAccess { /** * The representation of field access to a static field. */ STATIC(Opcodes.PUTSTATIC, Opcodes.GETSTATIC, StackSize.ZERO), /** * The representation of field access to an instance field. */ INSTANCE(Opcodes.PUTFIELD, Opcodes.GETFIELD, StackSize.SINGLE); /** * The opcode for setting a field value. */ private final int putterOpcode; /** * The opcode for getting a field value. */ private final int getterOpcode; /** * The amount of operand slots this field access operation consumes when it is applied before eventually * adding new values onto the operand stack. */ private final int targetSizeChange; /** * Creates a new field access. * * @param putterOpcode The opcode for setting a field value. * @param getterOpcode The opcode for getting a field value. * @param targetSizeChange The amount of operand slots this field access operation consumes when it is applied * before eventually adding new values onto the operand stack. */ FieldAccess(int putterOpcode, int getterOpcode, StackSize targetSizeChange) { this.putterOpcode = putterOpcode; this.getterOpcode = getterOpcode; this.targetSizeChange = targetSizeChange.getSize(); } /** * Creates an accessor to read an enumeration value. * * @param enumerationDescription The description of the enumeration. * @return A stack manipulation for reading the enumeration. */ public static StackManipulation forEnumeration(EnumerationDescription enumerationDescription) { FieldList<FieldDescription.InDefinedShape> fieldList = enumerationDescription.getEnumerationType().getDeclaredFields().filter(ElementMatchers.named(enumerationDescription.getValue())); return fieldList.size() != 1 || !fieldList.getOnly().isStatic() || !fieldList.getOnly().isPublic() || !fieldList.getOnly().isEnum() ? StackManipulation.Illegal.INSTANCE : STATIC.new AccessDispatcher(fieldList.getOnly()).read(); } /** * Creates a field access representation for a given field. * * @param fieldDescription The field to be accessed. * @return A field access definition for the given field. */ public static Defined forField(FieldDescription.InDefinedShape fieldDescription) { return fieldDescription.isStatic() ? STATIC.new AccessDispatcher(fieldDescription) : INSTANCE.new AccessDispatcher(fieldDescription); } /** * Creates a field access representation for a given field. If the field's return type derives from its declared shape, the value * is additionally casted to the generically resolved field. * * @param fieldDescription The field to be accessed. * @return A field access definition for the given field. */ public static Defined forField(FieldDescription fieldDescription) { FieldDescription.InDefinedShape declaredField = fieldDescription.asDefined(); return fieldDescription.getType().asErasure().equals(declaredField.getType().asErasure()) ? forField(declaredField) : OfGenericField.of(fieldDescription, forField(declaredField)); } /** * Representation of a field access for which a getter and a setter can be created. */ public interface Defined { /** * Creates a getter representation for a given field. * * @return A stack manipulation representing the retrieval of a field value. */ StackManipulation read(); /** * Creates a setter representation for a given field. * * @return A stack manipulation representing the setting of a field value. */ StackManipulation write(); } /** * A dispatcher for implementing a generic read or write access on a field. */ protected static class OfGenericField implements Defined { /** * The resolved generic field type. */ private final TypeDefinition targetType; /** * An accessor for the field in its defined shape. */ private final Defined defined; /** * Creates a new dispatcher for a generic field. * * @param targetType The resolved generic field type. * @param defined An accessor for the field in its defined shape. */ protected OfGenericField(TypeDefinition targetType, Defined defined) { this.targetType = targetType; this.defined = defined; } /** * Creates a generic access dispatcher for a given field. * * @param fieldDescription The field that is being accessed. * @param fieldAccess A field accessor for the field in its defined shape. * @return A field access dispatcher for the given field. */ protected static Defined of(FieldDescription fieldDescription, Defined fieldAccess) { return new OfGenericField(fieldDescription.getType(), fieldAccess); } @Override public StackManipulation read() { return new StackManipulation.Compound(defined.read(), TypeCasting.to(targetType)); } @Override public StackManipulation write() { return defined.write(); } @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 FieldAccess.OfGenericField)) return false; final FieldAccess.OfGenericField other = (FieldAccess.OfGenericField) o; if (!other.canEqual((java.lang.Object) this)) return false; final java.lang.Object this$targetType = this.targetType; final java.lang.Object other$targetType = other.targetType; if (this$targetType == null ? other$targetType != null : !this$targetType.equals(other$targetType)) return false; final java.lang.Object this$defined = this.defined; final java.lang.Object other$defined = other.defined; if (this$defined == null ? other$defined != null : !this$defined.equals(other$defined)) return false; return true; } @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") protected boolean canEqual(final java.lang.Object other) { return other instanceof FieldAccess.OfGenericField; } @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 $targetType = this.targetType; result = result * PRIME + ($targetType == null ? 43 : $targetType.hashCode()); final java.lang.Object $defined = this.defined; result = result * PRIME + ($defined == null ? 43 : $defined.hashCode()); return result; } } /** * A dispatcher for implementing a non-generic read or write access on a field. */ protected class AccessDispatcher implements Defined { /** * A description of the accessed field. */ private final FieldDescription.InDefinedShape fieldDescription; /** * Creates a new access dispatcher. * * @param fieldDescription A description of the accessed field. */ protected AccessDispatcher(FieldDescription.InDefinedShape fieldDescription) { this.fieldDescription = fieldDescription; } @Override public StackManipulation read() { return new FieldGetInstruction(); } @Override public StackManipulation write() { return new FieldPutInstruction(); } // HE: Remove when Lombok support for getOuter is added. @Override public boolean equals(Object other) { return this == other || !(other == null || getClass() != other.getClass()) && FieldAccess.this.equals(((AccessDispatcher) other).getFieldAccess()) && fieldDescription.equals(((AccessDispatcher) other).fieldDescription); } // HE: Remove when Lombok support for getOuter is added. @Override public int hashCode() { return fieldDescription.hashCode() + 31 * FieldAccess.this.hashCode(); } /** * Returns the outer instance. * * @return The outer instance. */ private FieldAccess getFieldAccess() { return FieldAccess.this; } /** * An abstract base implementation for accessing a field value. */ private abstract class AbstractFieldInstruction implements StackManipulation { @Override public boolean isValid() { return true; } @Override public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) { methodVisitor.visitFieldInsn(getOpcode(), fieldDescription.getDeclaringType().getInternalName(), fieldDescription.getInternalName(), fieldDescription.getDescriptor()); return resolveSize(fieldDescription.getType().getStackSize()); } /** * Returns the opcode for implementing the field access. * * @return The opcode for implementing the field access. */ protected abstract int getOpcode(); /** * Resolves the actual size of this field access operation. * * @param fieldSize The size of the accessed field. * @return The size of the field access operation based on the field's size. */ protected abstract Size resolveSize(StackSize fieldSize); } /** * A reading field access operation. */ protected class FieldGetInstruction extends AbstractFieldInstruction { @Override protected int getOpcode() { return getterOpcode; } @Override protected Size resolveSize(StackSize fieldSize) { int sizeChange = fieldSize.getSize() - targetSizeChange; return new Size(sizeChange, sizeChange); } // HE: Remove when Lombok support for getOuter is added. @Override public boolean equals(Object other) { return this == other || !(other == null || getClass() != other.getClass()) && getAccessDispatcher().equals(((FieldGetInstruction) other).getAccessDispatcher()); } // HE: Remove when Lombok support for getOuter is added. @Override public int hashCode() { return getAccessDispatcher().hashCode() + 7; } /** * Returns the outer instance. * * @return The outer instance. */ private AccessDispatcher getAccessDispatcher() { return AccessDispatcher.this; } } /** * A writing field access operation. */ protected class FieldPutInstruction extends AbstractFieldInstruction { @Override protected int getOpcode() { return putterOpcode; } @Override protected Size resolveSize(StackSize fieldSize) { return new Size(-1 * (fieldSize.getSize() + targetSizeChange), 0); } // HE: Remove when Lombok support for getOuter is added. @Override public boolean equals(Object other) { return this == other || !(other == null || getClass() != other.getClass()) && getAccessDispatcher().equals(((FieldPutInstruction) other).getAccessDispatcher()); } // HE: Remove when Lombok support for getOuter is added. @Override public int hashCode() { return getAccessDispatcher().hashCode() + 14; } /** * Returns the outer instance. * * @return The outer instance. */ private AccessDispatcher getAccessDispatcher() { return AccessDispatcher.this; } } } }