// Generated by delombok at Sun Feb 26 12:31:38 KST 2017
package scouter.bytebuddy.implementation.bytecode;
import scouter.bytebuddy.description.method.MethodDescription;
import scouter.bytebuddy.implementation.Implementation;
import scouter.bytebuddy.jar.asm.MethodVisitor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* An appender that generates the byte code for a given method. This is done by writing the byte code instructions to
* the given ASM {@link MethodVisitor}.
* <p> </p>
* The {@code ByteCodeAppender} is not allowed to write
* annotations to the method or call the {@link MethodVisitor#visitCode()},
* {@link MethodVisitor#visitMaxs(int, int)} or {@link MethodVisitor#visitEnd()}
* methods which is both done by the entity delegating the call to the {@code ByteCodeAppender}. This is done in order
* to allow for the concatenation of several byte code appenders and therefore a more modular description of method
* implementations.
*/
public interface ByteCodeAppender {
/**
* Applies this byte code appender to a type creation process.
*
* @param methodVisitor The method visitor to which the byte code appender writes its code to.
* @param implementationContext The implementation context of the current type creation process.
* @param instrumentedMethod The method that is the target of the instrumentation.
* @return The required size for the applied byte code to run.
*/
Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext, MethodDescription instrumentedMethod);
/**
* An immutable description of both the operand stack size and the size of the local variable array that is
* required to run the code generated by this {@code ByteCodeAppender}.
*/
class Size {
/**
* The size of the operand stack.
*/
private final int operandStackSize;
/**
* The size of the local variable array.
*/
private final int localVariableSize;
/**
* @param operandStackSize The operand stack size that is required for running given byte code.
* @param localVariableSize The local variable array size that is required for running given byte code.
*/
public Size(int operandStackSize, int localVariableSize) {
this.operandStackSize = operandStackSize;
this.localVariableSize = localVariableSize;
}
/**
* Returns the required operand stack size.
*
* @return The required operand stack size.
*/
public int getOperandStackSize() {
return operandStackSize;
}
/**
* Returns the required size of the local variable array.
*
* @return The required size of the local variable array.
*/
public int getLocalVariableSize() {
return localVariableSize;
}
/**
* Merges two sizes in order to describe the size that is required by both size descriptions.
*
* @param other The other size description.
* @return A size description incorporating both size requirements.
*/
public Size merge(Size other) {
return new Size(Math.max(operandStackSize, other.operandStackSize), Math.max(localVariableSize, other.localVariableSize));
}
@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 ByteCodeAppender.Size)) return false;
final ByteCodeAppender.Size other = (ByteCodeAppender.Size) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.getOperandStackSize() != other.getOperandStackSize()) return false;
if (this.getLocalVariableSize() != other.getLocalVariableSize()) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof ByteCodeAppender.Size;
}
@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.getOperandStackSize();
result = result * PRIME + this.getLocalVariableSize();
return result;
}
}
/**
* A compound appender that combines a given number of other byte code appenders.
*/
class Compound implements ByteCodeAppender {
/**
* The byte code appenders that are represented by this compound appender in their application order.
*/
private final List<ByteCodeAppender> byteCodeAppenders;
/**
* Creates a new compound byte code appender.
*
* @param byteCodeAppender The byte code appenders to combine in their order.
*/
public Compound(ByteCodeAppender... byteCodeAppender) {
this(Arrays.asList(byteCodeAppender));
}
/**
* Creates a new compound byte code appender.
*
* @param byteCodeAppenders The byte code appenders to combine in their order.
*/
public Compound(List<? extends ByteCodeAppender> byteCodeAppenders) {
this.byteCodeAppenders = new ArrayList<ByteCodeAppender>();
for (ByteCodeAppender byteCodeAppender : byteCodeAppenders) {
if (byteCodeAppender instanceof Compound) {
this.byteCodeAppenders.addAll(((Compound) byteCodeAppender).byteCodeAppenders);
} else {
this.byteCodeAppenders.add(byteCodeAppender);
}
}
}
@Override
public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext, MethodDescription instrumentedMethod) {
Size size = new Size(0, instrumentedMethod.getStackSize());
for (ByteCodeAppender byteCodeAppender : byteCodeAppenders) {
size = size.merge(byteCodeAppender.apply(methodVisitor, implementationContext, instrumentedMethod));
}
return size;
}
@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 ByteCodeAppender.Compound)) return false;
final ByteCodeAppender.Compound other = (ByteCodeAppender.Compound) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$byteCodeAppenders = this.byteCodeAppenders;
final java.lang.Object other$byteCodeAppenders = other.byteCodeAppenders;
if (this$byteCodeAppenders == null ? other$byteCodeAppenders != null : !this$byteCodeAppenders.equals(other$byteCodeAppenders)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof ByteCodeAppender.Compound;
}
@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 $byteCodeAppenders = this.byteCodeAppenders;
result = result * PRIME + ($byteCodeAppenders == null ? 43 : $byteCodeAppenders.hashCode());
return result;
}
}
/**
* A simple byte code appender that only represents a given array of
* {@link StackManipulation}s.
*/
class Simple implements ByteCodeAppender {
/**
* A compound stack manipulation to be applied for this byte code appender.
*/
private final StackManipulation stackManipulation;
/**
* Creates a new simple byte code appender which represents the given stack manipulation.
*
* @param stackManipulation The stack manipulations to apply for this byte code appender in their application order.
*/
public Simple(StackManipulation... stackManipulation) {
this(Arrays.asList(stackManipulation));
}
/**
* Creates a new simple byte code appender which represents the given stack manipulation.
*
* @param stackManipulations The stack manipulations to apply for this byte code appender in their application order.
*/
public Simple(List<? extends StackManipulation> stackManipulations) {
this.stackManipulation = new StackManipulation.Compound(stackManipulations);
}
@Override
public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext, MethodDescription instrumentedMethod) {
return new Size(stackManipulation.apply(methodVisitor, implementationContext).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 ByteCodeAppender.Simple)) return false;
final ByteCodeAppender.Simple other = (ByteCodeAppender.Simple) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$stackManipulation = this.stackManipulation;
final java.lang.Object other$stackManipulation = other.stackManipulation;
if (this$stackManipulation == null ? other$stackManipulation != null : !this$stackManipulation.equals(other$stackManipulation)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof ByteCodeAppender.Simple;
}
@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 $stackManipulation = this.stackManipulation;
result = result * PRIME + ($stackManipulation == null ? 43 : $stackManipulation.hashCode());
return result;
}
}
}