// Generated by delombok at Sun Feb 26 12:31:38 KST 2017
package scouter.bytebuddy.implementation.bytecode;
import scouter.bytebuddy.implementation.Implementation;
import scouter.bytebuddy.jar.asm.MethodVisitor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Describes a manipulation of a method's operand stack that does not affect the frame's variable array.
*/
public interface StackManipulation {
/**
* Determines if this stack manipulation is valid.
*
* @return If {@code false}, this manipulation cannot be applied and should throw an exception.
*/
boolean isValid();
/**
* Applies the stack manipulation that is described by this instance.
*
* @param methodVisitor The method visitor used to write the method implementation to.
* @param implementationContext The context of the current implementation.
* @return The changes to the size of the operand stack that are implied by this stack manipulation.
*/
Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext);
/**
* Canonical representation of an illegal stack manipulation.
*/
enum Illegal implements StackManipulation {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public boolean isValid() {
return false;
}
@Override
public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) {
throw new IllegalStateException("An illegal stack manipulation must not be applied");
}
}
/**
* Canonical representation of a legal stack manipulation which does not require any action.
*/
enum Trivial implements StackManipulation {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public boolean isValid() {
return true;
}
@Override
public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) {
return StackSize.ZERO.toIncreasingSize();
}
}
/**
* A description of the size change that is imposed by some
* {@link StackManipulation}.
*/
class Size {
/**
* The impact of any size operation onto the operand stack. This value can be negative if more values
* were consumed from the stack than added to it.
*/
private final int sizeImpact;
/**
* The maximal size of stack slots this stack manipulation ever requires. If an operation for example pushes
* five values onto the stack and subsequently consumes three operations, this value should still be five
* to express that a stack operation requires at least five slots in order to be applicable.
*/
private final int maximalSize;
/**
* Creates an immutable descriptor of the size change that is implied by some stack manipulation.
*
* @param sizeImpact The change of the size of the operand stack that is implied by some stack manipulation.
* @param maximalSize The maximal stack size that is required for executing this stack manipulation. Should
* never be negative number.
*/
public Size(int sizeImpact, int maximalSize) {
this.sizeImpact = sizeImpact;
this.maximalSize = maximalSize;
}
/**
* Returns the size change on the operand stack that is represented by this instance.
*
* @return The size change on the operand stack that is represented by this instance.
*/
public int getSizeImpact() {
return sizeImpact;
}
/**
* Returns the maximal interim size of the operand stack that is represented by this instance.
*
* @return The maximal interim size of the operand stack that is represented by this instance.
*/
public int getMaximalSize() {
return maximalSize;
}
/**
* Concatenates this size representation with another size representation in order to represent the size
* change that is represented by both alterations of the operand stack size.
*
* @param other The other size representation.
* @return A new size representation representing both stack size requirements.
*/
public Size aggregate(Size other) {
return aggregate(other.sizeImpact, other.maximalSize);
}
/**
* Aggregates a size change with this stack manipulation size.
*
* @param sizeChange The change in size the other operation implies.
* @param interimMaximalSize The interim maximal size of the operand stack that the other operation requires
* at least to function.
* @return The aggregated size.
*/
private Size aggregate(int sizeChange, int interimMaximalSize) {
return new Size(sizeImpact + sizeChange, Math.max(maximalSize, sizeImpact + interimMaximalSize));
}
@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 StackManipulation.Size)) return false;
final StackManipulation.Size other = (StackManipulation.Size) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.getSizeImpact() != other.getSizeImpact()) return false;
if (this.getMaximalSize() != other.getMaximalSize()) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof StackManipulation.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.getSizeImpact();
result = result * PRIME + this.getMaximalSize();
return result;
}
}
/**
* An immutable stack manipulation that aggregates a sequence of other stack manipulations.
*/
class Compound implements StackManipulation {
/**
* The stack manipulations this compound operation represents in their application order.
*/
private final List<StackManipulation> stackManipulations;
/**
* Creates a new compound stack manipulation.
*
* @param stackManipulation The stack manipulations to be composed in the order of their composition.
*/
public Compound(StackManipulation... stackManipulation) {
this(Arrays.asList(stackManipulation));
}
/**
* Creates a new compound stack manipulation.
*
* @param stackManipulations The stack manipulations to be composed in the order of their composition.
*/
public Compound(List<? extends StackManipulation> stackManipulations) {
this.stackManipulations = new ArrayList<StackManipulation>();
for (StackManipulation stackManipulation : stackManipulations) {
if (stackManipulation instanceof Compound) {
this.stackManipulations.addAll(((Compound) stackManipulation).stackManipulations);
} else if (!(stackManipulation instanceof Trivial)) {
this.stackManipulations.add(stackManipulation);
}
}
}
@Override
public boolean isValid() {
for (StackManipulation stackManipulation : stackManipulations) {
if (!stackManipulation.isValid()) {
return false;
}
}
return true;
}
@Override
public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) {
Size size = new Size(0, 0);
for (StackManipulation stackManipulation : stackManipulations) {
size = size.aggregate(stackManipulation.apply(methodVisitor, implementationContext));
}
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 StackManipulation.Compound)) return false;
final StackManipulation.Compound other = (StackManipulation.Compound) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$stackManipulations = this.stackManipulations;
final java.lang.Object other$stackManipulations = other.stackManipulations;
if (this$stackManipulations == null ? other$stackManipulations != null : !this$stackManipulations.equals(other$stackManipulations)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof StackManipulation.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 $stackManipulations = this.stackManipulations;
result = result * PRIME + ($stackManipulations == null ? 43 : $stackManipulations.hashCode());
return result;
}
}
}