/**
   * If this is a putfield or putstatic instruction, check to see if the field is @NonNull, and
   * treat it as dereferences.
   *
   * @param location the Location of the instruction
   * @param vnaFrame the ValueNumberFrame at the Location of the instruction
   * @param fact the dataflow value to modify
   * @throws DataflowAnalysisException
   */
  private void checkNonNullPutField(
      Location location, ValueNumberFrame vnaFrame, UnconditionalValueDerefSet fact)
      throws DataflowAnalysisException {
    INullnessAnnotationDatabase database =
        AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase();

    FieldInstruction fieldIns = (FieldInstruction) location.getHandle().getInstruction();

    XField field = XFactory.createXField(fieldIns, methodGen.getConstantPool());
    char firstChar = field.getSignature().charAt(0);
    if (firstChar != 'L' && firstChar != '[') {
      return;
    }
    NullnessAnnotation resolvedAnnotation = database.getResolvedAnnotation(field, true);
    if (resolvedAnnotation == NullnessAnnotation.NONNULL) {
      IsNullValueFrame invFrame = invDataflow.getFactAtLocation(location);
      if (!invFrame.isValid()) {
        return;
      }
      IsNullValue value = invFrame.getTopValue();
      if (reportDereference(value)) {
        ValueNumber vn = vnaFrame.getTopValue();
        fact.addDeref(vn, location);
      }
    }
  }
  public static Set<ValueNumber> checkNonNullParams(
      Location location,
      ValueNumberFrame vnaFrame,
      ConstantPoolGen constantPool,
      @CheckForNull Method method,
      @CheckForNull IsNullValueFrame invFrame)
      throws DataflowAnalysisException {

    if (invFrame != null && !invFrame.isValid()) {
      return Collections.emptySet();
    }
    INullnessAnnotationDatabase database =
        AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase();

    InvokeInstruction inv = (InvokeInstruction) location.getHandle().getInstruction();
    XMethod called = XFactory.createXMethod(inv, constantPool);
    SignatureParser sigParser = new SignatureParser(called.getSignature());
    int numParams = sigParser.getNumParameters();

    Set<ValueNumber> result = new HashSet<ValueNumber>();
    Iterator<String> parameterIterator = sigParser.parameterSignatureIterator();
    for (int i = 0; i < numParams; i++) {
      String parameterSignature = parameterIterator.next();
      char firstChar = parameterSignature.charAt(0);
      if (firstChar != 'L' && firstChar != '[') {
        continue;
      }
      int offset = sigParser.getSlotsFromTopOfStackForParameter(i);
      if (invFrame != null) {
        int slot = invFrame.getStackLocation(offset);
        if (!reportDereference(invFrame, slot)) {
          continue;
        }
      }
      if (database.parameterMustBeNonNull(called, i)) {
        int catchSizeNPE =
            Util.getSizeOfSurroundingTryBlock(
                method, "java/lang/NullPointerException", location.getHandle().getPosition());
        int catchSizeNFE =
            Util.getSizeOfSurroundingTryBlock(
                method, "java/lang/NumberFormatException", location.getHandle().getPosition());
        if (catchSizeNPE == Integer.MAX_VALUE
            && (!"java.lang.Integer".equals(called.getClassName())
                || catchSizeNFE == Integer.MAX_VALUE)) {
          // Get the corresponding value number
          ValueNumber vn = vnaFrame.getArgument(inv, constantPool, i, sigParser);
          result.add(vn);
        }
      }
    }
    return result;
  }
  /**
   * If this is a method call instruction, check to see if any of the parameters are @NonNull, and
   * treat them as dereferences.
   *
   * @param location the Location of the instruction
   * @param vnaFrame the ValueNumberFrame at the Location of the instruction
   * @param fact the dataflow value to modify
   * @throws DataflowAnalysisException
   */
  private void checkNonNullReturnValue(
      XMethod thisMethod,
      Location location,
      ValueNumberFrame vnaFrame,
      UnconditionalValueDerefSet fact)
      throws DataflowAnalysisException {
    INullnessAnnotationDatabase database =
        AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase();

    if (database.getResolvedAnnotation(thisMethod, true) != NullnessAnnotation.NONNULL) {
      return;
    }
    if (reportPotentialDereference(location, invDataflow.getFactAtLocation(location))) {
      ValueNumber vn = vnaFrame.getTopValue();
      fact.addDeref(vn, location);
    }
  }