Class ActualValueInference.InferenceMethodVisitor
- java.lang.Object
-
- org.objectweb.asm.MethodVisitor
-
- com.google.common.truth.ActualValueInference.InferenceMethodVisitor
-
- Enclosing class:
- ActualValueInference
private static final class ActualValueInference.InferenceMethodVisitor extends org.objectweb.asm.MethodVisitor
-
-
Field Summary
Fields Modifier and Type Field Description private com.google.common.collect.ImmutableSetMultimap.Builder<java.lang.Integer,ActualValueInference.StackEntry>
actualValueAtLine
The output of this process: a mapping from line number to the root actual values with assertions on that line.private com.google.common.collect.ImmutableSetMultimap.Builder<com.google.common.collect.ImmutableList<org.objectweb.asm.Label>,ActualValueInference.StackEntry>
actualValueAtLocation
The mapping that indexes every root actual value by the full list of labels we'd visited before we visited it.private com.google.common.collect.ImmutableList.Builder<org.objectweb.asm.Label>
labelsSeen
The ASM labels that we've seen so far, which we use to look up the closest line number for each assertion.private com.google.common.collect.ImmutableSetMultimap.Builder<org.objectweb.asm.Label,java.lang.Integer>
lineNumbersAtLabel
The mapping from label to line number.private java.util.ArrayList<ActualValueInference.StackEntry>
localVariableSlots
private java.lang.String
methodSignature
For debugging purpose.private java.util.ArrayList<ActualValueInference.StackEntry>
operandStack
private ActualValueInference.FrameInfo
previousFrame
private boolean
seenJump
Set totrue
whenever a method permits multiple execution paths.private boolean
used
-
Constructor Summary
Constructors Constructor Description InferenceMethodVisitor(int access, java.lang.String owner, java.lang.String name, java.lang.String methodDescriptor, com.google.common.collect.ImmutableSetMultimap.Builder<java.lang.Integer,ActualValueInference.StackEntry> actualValueAtLine)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private com.google.common.collect.ImmutableList<ActualValueInference.StackEntry>
appendArrayToList(com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> list, int size, java.lang.Object[] array)
private static java.lang.String
convertToDescriptor(java.lang.String type)
private ActualValueInference.InferredType
convertTypeInStackMapFrame(java.lang.Object typeInStackMapFrame)
Convert the type in stack map frame to inference type.private com.google.common.collect.ImmutableList<ActualValueInference.StackEntry>
convertTypesInStackMapFrame(int size, java.lang.Object[] array)
private static java.util.ArrayList<ActualValueInference.StackEntry>
createInitialLocalVariableSlots(int access, java.lang.String ownerClass, java.lang.String methodName, java.lang.String methodDescriptor)
Create the slots for local variables at the very beginning of the method with the information of the declaring class and the method descriptor.private ActualValueInference.StackEntry
getLocalVariable(int index)
private ActualValueInference.StackEntry
getOperandFromTop(int offsetFromTop)
Returns the entry for the operand at the specified offset.private static com.google.common.collect.ImmutableSet<java.lang.Integer>
lineNumbers(com.google.common.collect.ImmutableList<org.objectweb.asm.Label> labels, com.google.common.collect.ImmutableSetMultimap<org.objectweb.asm.Label,java.lang.Integer> lineNumbersAtLabel)
private ActualValueInference.StackEntry
pop()
private ActualValueInference.StackEntry
pop(int count)
Pop elements from the end of the operand stack, and return the last popped element.private void
popDescriptor(java.lang.String desc)
private void
push(ActualValueInference.InferredType type)
private void
push(ActualValueInference.StackEntry entry)
private void
pushDescriptor(java.lang.String desc)
private void
pushDescriptorAndMaybeProcessMethodCall(java.lang.String desc, ActualValueInference.Invocation invocation)
Pushes entries onto the stack for the given arguments, and, if the descriptor is for a method call, records the assertion made by that call (if any).private void
pushMaybeDescribed(ActualValueInference.InferredType type, ActualValueInference.Invocation invocation, boolean hasParams)
private static com.google.common.collect.ImmutableList<ActualValueInference.StackEntry>
removeBackFromList(com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> list, int countToRemove)
private void
replaceUninitializedTypeInStack(ActualValueInference.InferredType oldType, ActualValueInference.InferredType newType)
private void
setLocalVariable(int index, ActualValueInference.StackEntry entry)
private ActualValueInference.StackEntry
top()
void
visitCode()
void
visitEnd()
void
visitFieldInsn(int opcode, java.lang.String owner, java.lang.String name, java.lang.String desc)
void
visitFrame(int type, int nLocal, java.lang.Object[] local, int nStack, java.lang.Object[] stack)
void
visitIincInsn(int var, int increment)
void
visitInsn(int opcode)
void
visitIntInsn(int opcode, int operand)
void
visitInvokeDynamicInsn(java.lang.String name, java.lang.String desc, org.objectweb.asm.Handle bsm, java.lang.Object... bsmArgs)
void
visitJumpInsn(int opcode, org.objectweb.asm.Label label)
void
visitLabel(org.objectweb.asm.Label label)
void
visitLdcInsn(java.lang.Object cst)
void
visitLineNumber(int line, org.objectweb.asm.Label start)
void
visitLookupSwitchInsn(org.objectweb.asm.Label dflt, int[] keys, org.objectweb.asm.Label[] labels)
void
visitMethodInsn(int opcode, java.lang.String owner, java.lang.String name, java.lang.String desc, boolean itf)
void
visitMultiANewArrayInsn(java.lang.String desc, int dims)
void
visitTableSwitchInsn(int min, int max, org.objectweb.asm.Label dflt, org.objectweb.asm.Label... labels)
void
visitTryCatchBlock(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label handler, java.lang.String type)
void
visitTypeInsn(int opcode, java.lang.String type)
void
visitVarInsn(int opcode, int var)
-
Methods inherited from class org.objectweb.asm.MethodVisitor
visitAnnotableParameterCount, visitAnnotation, visitAnnotationDefault, visitAttribute, visitInsnAnnotation, visitLocalVariable, visitLocalVariableAnnotation, visitMaxs, visitMethodInsn, visitParameter, visitParameterAnnotation, visitTryCatchAnnotation, visitTypeAnnotation
-
-
-
-
Field Detail
-
used
private boolean used
-
localVariableSlots
private final java.util.ArrayList<ActualValueInference.StackEntry> localVariableSlots
-
operandStack
private final java.util.ArrayList<ActualValueInference.StackEntry> operandStack
-
previousFrame
private ActualValueInference.FrameInfo previousFrame
-
methodSignature
private final java.lang.String methodSignature
For debugging purpose.
-
labelsSeen
private final com.google.common.collect.ImmutableList.Builder<org.objectweb.asm.Label> labelsSeen
The ASM labels that we've seen so far, which we use to look up the closest line number for each assertion.
-
lineNumbersAtLabel
private final com.google.common.collect.ImmutableSetMultimap.Builder<org.objectweb.asm.Label,java.lang.Integer> lineNumbersAtLabel
The mapping from label to line number.I had hoped that we didn't need this: In the
.class
files I looked at,visitLineNumber
calls were interleaved with the actual instructions. (I even have evidence that the current implementation visits labels and line numbers together: See Label.accept.) If that were guaranteed, then we could identify the line number for each assertion just by looking at whichvisitLineNumber
call we'd seen most recently. However, that doesn't appear to be guaranteed, so we store this mapping and then join it with the labels at the end.I would expect to be able to use a map here. But I'm seeing multiple line numbers for the same label in some Kotlin code.
-
actualValueAtLocation
private final com.google.common.collect.ImmutableSetMultimap.Builder<com.google.common.collect.ImmutableList<org.objectweb.asm.Label>,ActualValueInference.StackEntry> actualValueAtLocation
The mapping that indexes every root actual value by the full list of labels we'd visited before we visited it.
-
seenJump
private boolean seenJump
Set totrue
whenever a method permits multiple execution paths.
-
actualValueAtLine
private final com.google.common.collect.ImmutableSetMultimap.Builder<java.lang.Integer,ActualValueInference.StackEntry> actualValueAtLine
The output of this process: a mapping from line number to the root actual values with assertions on that line. This builder is potentially shared across multiple method visitors for the same class visitor.
-
-
Constructor Detail
-
InferenceMethodVisitor
InferenceMethodVisitor(int access, java.lang.String owner, java.lang.String name, java.lang.String methodDescriptor, com.google.common.collect.ImmutableSetMultimap.Builder<java.lang.Integer,ActualValueInference.StackEntry> actualValueAtLine)
-
-
Method Detail
-
visitCode
public void visitCode()
- Overrides:
visitCode
in classorg.objectweb.asm.MethodVisitor
-
visitEnd
public void visitEnd()
- Overrides:
visitEnd
in classorg.objectweb.asm.MethodVisitor
-
lineNumbers
private static com.google.common.collect.ImmutableSet<java.lang.Integer> lineNumbers(com.google.common.collect.ImmutableList<org.objectweb.asm.Label> labels, com.google.common.collect.ImmutableSetMultimap<org.objectweb.asm.Label,java.lang.Integer> lineNumbersAtLabel)
-
visitLineNumber
public void visitLineNumber(int line, org.objectweb.asm.Label start)
- Overrides:
visitLineNumber
in classorg.objectweb.asm.MethodVisitor
-
visitLabel
public void visitLabel(org.objectweb.asm.Label label)
- Overrides:
visitLabel
in classorg.objectweb.asm.MethodVisitor
-
getOperandFromTop
private ActualValueInference.StackEntry getOperandFromTop(int offsetFromTop)
Returns the entry for the operand at the specified offset. 0 means the top of the stack.
-
visitInsn
public void visitInsn(int opcode)
- Overrides:
visitInsn
in classorg.objectweb.asm.MethodVisitor
-
visitIntInsn
public void visitIntInsn(int opcode, int operand)
- Overrides:
visitIntInsn
in classorg.objectweb.asm.MethodVisitor
-
visitVarInsn
public void visitVarInsn(int opcode, int var)
- Overrides:
visitVarInsn
in classorg.objectweb.asm.MethodVisitor
-
visitTypeInsn
public void visitTypeInsn(int opcode, java.lang.String type)
- Overrides:
visitTypeInsn
in classorg.objectweb.asm.MethodVisitor
-
visitFieldInsn
public void visitFieldInsn(int opcode, java.lang.String owner, java.lang.String name, java.lang.String desc)
- Overrides:
visitFieldInsn
in classorg.objectweb.asm.MethodVisitor
-
visitMethodInsn
public void visitMethodInsn(int opcode, java.lang.String owner, java.lang.String name, java.lang.String desc, boolean itf)
- Overrides:
visitMethodInsn
in classorg.objectweb.asm.MethodVisitor
-
visitInvokeDynamicInsn
public void visitInvokeDynamicInsn(java.lang.String name, java.lang.String desc, org.objectweb.asm.Handle bsm, java.lang.Object... bsmArgs)
- Overrides:
visitInvokeDynamicInsn
in classorg.objectweb.asm.MethodVisitor
-
visitJumpInsn
public void visitJumpInsn(int opcode, org.objectweb.asm.Label label)
- Overrides:
visitJumpInsn
in classorg.objectweb.asm.MethodVisitor
-
visitLdcInsn
public void visitLdcInsn(java.lang.Object cst)
- Overrides:
visitLdcInsn
in classorg.objectweb.asm.MethodVisitor
-
visitIincInsn
public void visitIincInsn(int var, int increment)
- Overrides:
visitIincInsn
in classorg.objectweb.asm.MethodVisitor
-
visitTableSwitchInsn
public void visitTableSwitchInsn(int min, int max, org.objectweb.asm.Label dflt, org.objectweb.asm.Label... labels)
- Overrides:
visitTableSwitchInsn
in classorg.objectweb.asm.MethodVisitor
-
visitLookupSwitchInsn
public void visitLookupSwitchInsn(org.objectweb.asm.Label dflt, int[] keys, org.objectweb.asm.Label[] labels)
- Overrides:
visitLookupSwitchInsn
in classorg.objectweb.asm.MethodVisitor
-
visitTryCatchBlock
public void visitTryCatchBlock(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label handler, java.lang.String type)
- Overrides:
visitTryCatchBlock
in classorg.objectweb.asm.MethodVisitor
-
visitMultiANewArrayInsn
public void visitMultiANewArrayInsn(java.lang.String desc, int dims)
- Overrides:
visitMultiANewArrayInsn
in classorg.objectweb.asm.MethodVisitor
-
visitFrame
public void visitFrame(int type, int nLocal, java.lang.Object[] local, int nStack, java.lang.Object[] stack)
- Overrides:
visitFrame
in classorg.objectweb.asm.MethodVisitor
-
convertToDescriptor
private static java.lang.String convertToDescriptor(java.lang.String type)
-
push
private void push(ActualValueInference.InferredType type)
-
push
private void push(ActualValueInference.StackEntry entry)
-
replaceUninitializedTypeInStack
private void replaceUninitializedTypeInStack(ActualValueInference.InferredType oldType, ActualValueInference.InferredType newType)
-
pushDescriptor
private void pushDescriptor(java.lang.String desc)
-
pushDescriptorAndMaybeProcessMethodCall
private void pushDescriptorAndMaybeProcessMethodCall(java.lang.String desc, ActualValueInference.Invocation invocation)
Pushes entries onto the stack for the given arguments, and, if the descriptor is for a method call, records the assertion made by that call (if any).If the descriptor is for a call, this method not only records the assertion made by it (if any) but also examines its parameters to generate more detailed stack entries.
- Parameters:
desc
- the descriptor of the type to be added to the stack (or the descriptor of the method whose return value is to be added to the stack)invocation
- the method invocation being visited, ornull
if a non-method descriptor is being visited
-
pushMaybeDescribed
private void pushMaybeDescribed(ActualValueInference.InferredType type, ActualValueInference.Invocation invocation, boolean hasParams)
-
pop
private ActualValueInference.StackEntry pop()
-
pop
private ActualValueInference.StackEntry pop(int count)
Pop elements from the end of the operand stack, and return the last popped element.
-
popDescriptor
private void popDescriptor(java.lang.String desc)
-
getLocalVariable
private ActualValueInference.StackEntry getLocalVariable(int index)
-
setLocalVariable
private void setLocalVariable(int index, ActualValueInference.StackEntry entry)
-
top
private ActualValueInference.StackEntry top()
-
createInitialLocalVariableSlots
private static java.util.ArrayList<ActualValueInference.StackEntry> createInitialLocalVariableSlots(int access, java.lang.String ownerClass, java.lang.String methodName, java.lang.String methodDescriptor)
Create the slots for local variables at the very beginning of the method with the information of the declaring class and the method descriptor.
-
removeBackFromList
private static com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> removeBackFromList(com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> list, int countToRemove)
-
appendArrayToList
private com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> appendArrayToList(com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> list, int size, java.lang.Object[] array)
-
convertTypeInStackMapFrame
private ActualValueInference.InferredType convertTypeInStackMapFrame(java.lang.Object typeInStackMapFrame)
Convert the type in stack map frame to inference type.
-
convertTypesInStackMapFrame
private com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> convertTypesInStackMapFrame(int size, java.lang.Object[] array)
-
-