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>actualValueAtLineThe 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>actualValueAtLocationThe 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>labelsSeenThe 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>lineNumbersAtLabelThe mapping from label to line number.private java.util.ArrayList<ActualValueInference.StackEntry>localVariableSlotsprivate java.lang.StringmethodSignatureFor debugging purpose.private java.util.ArrayList<ActualValueInference.StackEntry>operandStackprivate ActualValueInference.FrameInfopreviousFrameprivate booleanseenJumpSet totruewhenever a method permits multiple execution paths.private booleanused
-
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.StringconvertToDescriptor(java.lang.String type)private ActualValueInference.InferredTypeconvertTypeInStackMapFrame(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.StackEntrygetLocalVariable(int index)private ActualValueInference.StackEntrygetOperandFromTop(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.StackEntrypop()private ActualValueInference.StackEntrypop(int count)Pop elements from the end of the operand stack, and return the last popped element.private voidpopDescriptor(java.lang.String desc)private voidpush(ActualValueInference.InferredType type)private voidpush(ActualValueInference.StackEntry entry)private voidpushDescriptor(java.lang.String desc)private voidpushDescriptorAndMaybeProcessMethodCall(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 voidpushMaybeDescribed(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 voidreplaceUninitializedTypeInStack(ActualValueInference.InferredType oldType, ActualValueInference.InferredType newType)private voidsetLocalVariable(int index, ActualValueInference.StackEntry entry)private ActualValueInference.StackEntrytop()voidvisitCode()voidvisitEnd()voidvisitFieldInsn(int opcode, java.lang.String owner, java.lang.String name, java.lang.String desc)voidvisitFrame(int type, int nLocal, java.lang.Object[] local, int nStack, java.lang.Object[] stack)voidvisitIincInsn(int var, int increment)voidvisitInsn(int opcode)voidvisitIntInsn(int opcode, int operand)voidvisitInvokeDynamicInsn(java.lang.String name, java.lang.String desc, org.objectweb.asm.Handle bsm, java.lang.Object... bsmArgs)voidvisitJumpInsn(int opcode, org.objectweb.asm.Label label)voidvisitLabel(org.objectweb.asm.Label label)voidvisitLdcInsn(java.lang.Object cst)voidvisitLineNumber(int line, org.objectweb.asm.Label start)voidvisitLookupSwitchInsn(org.objectweb.asm.Label dflt, int[] keys, org.objectweb.asm.Label[] labels)voidvisitMethodInsn(int opcode, java.lang.String owner, java.lang.String name, java.lang.String desc, boolean itf)voidvisitMultiANewArrayInsn(java.lang.String desc, int dims)voidvisitTableSwitchInsn(int min, int max, org.objectweb.asm.Label dflt, org.objectweb.asm.Label... labels)voidvisitTryCatchBlock(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label handler, java.lang.String type)voidvisitTypeInsn(int opcode, java.lang.String type)voidvisitVarInsn(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
.classfiles I looked at,visitLineNumbercalls 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 whichvisitLineNumbercall 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 totruewhenever 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:
visitCodein classorg.objectweb.asm.MethodVisitor
-
visitEnd
public void visitEnd()
- Overrides:
visitEndin 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:
visitLineNumberin classorg.objectweb.asm.MethodVisitor
-
visitLabel
public void visitLabel(org.objectweb.asm.Label label)
- Overrides:
visitLabelin 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:
visitInsnin classorg.objectweb.asm.MethodVisitor
-
visitIntInsn
public void visitIntInsn(int opcode, int operand)- Overrides:
visitIntInsnin classorg.objectweb.asm.MethodVisitor
-
visitVarInsn
public void visitVarInsn(int opcode, int var)- Overrides:
visitVarInsnin classorg.objectweb.asm.MethodVisitor
-
visitTypeInsn
public void visitTypeInsn(int opcode, java.lang.String type)- Overrides:
visitTypeInsnin classorg.objectweb.asm.MethodVisitor
-
visitFieldInsn
public void visitFieldInsn(int opcode, java.lang.String owner, java.lang.String name, java.lang.String desc)- Overrides:
visitFieldInsnin 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:
visitMethodInsnin 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:
visitInvokeDynamicInsnin classorg.objectweb.asm.MethodVisitor
-
visitJumpInsn
public void visitJumpInsn(int opcode, org.objectweb.asm.Label label)- Overrides:
visitJumpInsnin classorg.objectweb.asm.MethodVisitor
-
visitLdcInsn
public void visitLdcInsn(java.lang.Object cst)
- Overrides:
visitLdcInsnin classorg.objectweb.asm.MethodVisitor
-
visitIincInsn
public void visitIincInsn(int var, int increment)- Overrides:
visitIincInsnin classorg.objectweb.asm.MethodVisitor
-
visitTableSwitchInsn
public void visitTableSwitchInsn(int min, int max, org.objectweb.asm.Label dflt, org.objectweb.asm.Label... labels)- Overrides:
visitTableSwitchInsnin classorg.objectweb.asm.MethodVisitor
-
visitLookupSwitchInsn
public void visitLookupSwitchInsn(org.objectweb.asm.Label dflt, int[] keys, org.objectweb.asm.Label[] labels)- Overrides:
visitLookupSwitchInsnin 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:
visitTryCatchBlockin classorg.objectweb.asm.MethodVisitor
-
visitMultiANewArrayInsn
public void visitMultiANewArrayInsn(java.lang.String desc, int dims)- Overrides:
visitMultiANewArrayInsnin classorg.objectweb.asm.MethodVisitor
-
visitFrame
public void visitFrame(int type, int nLocal, java.lang.Object[] local, int nStack, java.lang.Object[] stack)- Overrides:
visitFramein 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, ornullif 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)
-
-