code: public static Set<JavaClassAndMethod> resolveMethodCallTargets(InvokeInstruction invokeInstruction, TypeFrame typeFrame,
              ConstantPoolGen cpg) throws DataflowAnalysisException, ClassNotFoundException {
  
          short opcode = invokeInstruction.getOpcode();
  
          if (opcode == Const.INVOKESTATIC) {
              HashSet<JavaClassAndMethod> result = new HashSet<>();
              JavaClassAndMethod targetMethod = findInvocationLeastUpperBound(invokeInstruction, cpg, CONCRETE_METHOD);
              if (targetMethod != null) {
                  result.add(targetMethod);
              }
              return result;
          }
  
          if (!typeFrame.isValid()) {
              return new HashSet<>();
          }
  
          Type receiverType;
          boolean receiverTypeIsExact;
  
          if (opcode == Const.INVOKESPECIAL) {
              // invokespecial instructions are dispatched to EXACTLY
              // the class specified by the instruction
              receiverType = ObjectTypeFactory.getInstance(invokeInstruction.getClassName(cpg));
              receiverTypeIsExact = false; // Doesn't actually matter
          } else if (opcode == Const.INVOKEDYNAMIC) {
              // XXX handle INVOKEDYNAMIC
              return new HashSet<>();
          } else {
              // For invokevirtual and invokeinterface instructions, we have
              // virtual dispatch. By taking the receiver type (which may be a
              // subtype of the class specified by the instruction),
              // we may get a more precise set of call targets.
              int instanceStackLocation = typeFrame.getInstanceStackLocation(invokeInstruction, cpg);
              receiverType = typeFrame.getStackValue(instanceStackLocation);
              if (!(receiverType instanceof ReferenceType)) {
                  return new HashSet<>();
              }
              receiverTypeIsExact = typeFrame.isExact(instanceStackLocation);
          }
          if (DEBUG_METHOD_LOOKUP) {
              System.out.println("[receiver type is " + receiverType + ", " + (receiverTypeIsExact ? "exact]" : " not exact]"));
          }
  
          return resolveMethodCallTargets((ReferenceType) receiverType, invokeInstruction, cpg, receiverTypeIsExact);
      }
docs: Resolve possible method call targets. This works for both static and
  instance method calls.
  
  @param invokeInstruction
  the InvokeInstruction
  @param typeFrame
  the TypeFrame containing the types of stack values
  @param cpg
  the ConstantPoolGen
  @return Set of methods which might be called
  @throws DataflowAnalysisException
  @throws ClassNotFoundException