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 Details

    • used

      private boolean used
    • localVariableSlots

      private final ArrayList<ActualValueInference.StackEntry> localVariableSlots
    • operandStack

      private final ArrayList<ActualValueInference.StackEntry> operandStack
    • previousFrame

      private ActualValueInference.FrameInfo previousFrame
    • methodSignature

      private final 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,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 which visitLineNumber 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 to true whenever a method permits multiple execution paths.
    • actualValueAtLine

      private final com.google.common.collect.ImmutableSetMultimap.Builder<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 Details

  • Method Details

    • visitCode

      public void visitCode()
      Overrides:
      visitCode in class org.objectweb.asm.MethodVisitor
    • visitEnd

      public void visitEnd()
      Overrides:
      visitEnd in class org.objectweb.asm.MethodVisitor
    • lineNumbers

      private static com.google.common.collect.ImmutableSet<Integer> lineNumbers(com.google.common.collect.ImmutableList<org.objectweb.asm.Label> labels, com.google.common.collect.ImmutableSetMultimap<org.objectweb.asm.Label,Integer> lineNumbersAtLabel)
    • visitLineNumber

      public void visitLineNumber(int line, org.objectweb.asm.Label start)
      Overrides:
      visitLineNumber in class org.objectweb.asm.MethodVisitor
    • visitLabel

      public void visitLabel(org.objectweb.asm.Label label)
      Overrides:
      visitLabel in class org.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 class org.objectweb.asm.MethodVisitor
    • visitIntInsn

      public void visitIntInsn(int opcode, int operand)
      Overrides:
      visitIntInsn in class org.objectweb.asm.MethodVisitor
    • visitVarInsn

      public void visitVarInsn(int opcode, int var)
      Overrides:
      visitVarInsn in class org.objectweb.asm.MethodVisitor
    • visitTypeInsn

      public void visitTypeInsn(int opcode, String type)
      Overrides:
      visitTypeInsn in class org.objectweb.asm.MethodVisitor
    • visitFieldInsn

      public void visitFieldInsn(int opcode, String owner, String name, String desc)
      Overrides:
      visitFieldInsn in class org.objectweb.asm.MethodVisitor
    • visitMethodInsn

      public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf)
      Overrides:
      visitMethodInsn in class org.objectweb.asm.MethodVisitor
    • visitInvokeDynamicInsn

      public void visitInvokeDynamicInsn(String name, String desc, org.objectweb.asm.Handle bsm, Object... bsmArgs)
      Overrides:
      visitInvokeDynamicInsn in class org.objectweb.asm.MethodVisitor
    • visitJumpInsn

      public void visitJumpInsn(int opcode, org.objectweb.asm.Label label)
      Overrides:
      visitJumpInsn in class org.objectweb.asm.MethodVisitor
    • visitLdcInsn

      public void visitLdcInsn(Object cst)
      Overrides:
      visitLdcInsn in class org.objectweb.asm.MethodVisitor
    • visitIincInsn

      public void visitIincInsn(int var, int increment)
      Overrides:
      visitIincInsn in class org.objectweb.asm.MethodVisitor
    • visitTableSwitchInsn

      public void visitTableSwitchInsn(int min, int max, org.objectweb.asm.Label dflt, org.objectweb.asm.Label... labels)
      Overrides:
      visitTableSwitchInsn in class org.objectweb.asm.MethodVisitor
    • visitLookupSwitchInsn

      public void visitLookupSwitchInsn(org.objectweb.asm.Label dflt, int[] keys, org.objectweb.asm.Label[] labels)
      Overrides:
      visitLookupSwitchInsn in class org.objectweb.asm.MethodVisitor
    • visitTryCatchBlock

      public void visitTryCatchBlock(org.objectweb.asm.Label start, org.objectweb.asm.Label end, org.objectweb.asm.Label handler, String type)
      Overrides:
      visitTryCatchBlock in class org.objectweb.asm.MethodVisitor
    • visitMultiANewArrayInsn

      public void visitMultiANewArrayInsn(String desc, int dims)
      Overrides:
      visitMultiANewArrayInsn in class org.objectweb.asm.MethodVisitor
    • visitFrame

      public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack)
      Overrides:
      visitFrame in class org.objectweb.asm.MethodVisitor
    • convertToDescriptor

      private static String convertToDescriptor(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(String desc)
    • pushDescriptorAndMaybeProcessMethodCall

      private void pushDescriptorAndMaybeProcessMethodCall(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, or null if a non-method descriptor is being visited
    • pushMaybeDescribed

      private void pushMaybeDescribed(ActualValueInference.InferredType type, ActualValueInference.Invocation invocation, boolean hasParams)
    • 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(String desc)
    • getLocalVariable

      private ActualValueInference.StackEntry getLocalVariable(int index)
    • setLocalVariable

      private void setLocalVariable(int index, ActualValueInference.StackEntry entry)
    • top

    • createInitialLocalVariableSlots

      private static ArrayList<ActualValueInference.StackEntry> createInitialLocalVariableSlots(int access, String ownerClass, String methodName, 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, Object[] array)
    • convertTypeInStackMapFrame

      private ActualValueInference.InferredType convertTypeInStackMapFrame(Object typeInStackMapFrame)
      Convert the type in stack map frame to inference type.
    • convertTypesInStackMapFrame

      private com.google.common.collect.ImmutableList<ActualValueInference.StackEntry> convertTypesInStackMapFrame(int size, Object[] array)