public MethodParameterNullness onOverrideMethodInvocationParametersNullability()

in nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java [127:195]


  public MethodParameterNullness onOverrideMethodInvocationParametersNullability(
      Context context,
      Symbol.MethodSymbol methodSymbol,
      boolean isAnnotated,
      MethodParameterNullness argumentNullness) {
    OptimizedLibraryModels optimizedLibraryModels = getOptLibraryModels(context);
    ImmutableSet<Integer> nullableParamsFromModel =
        optimizedLibraryModels.explicitlyNullableParameters(methodSymbol);
    ImmutableSet<Integer> nonNullParamsFromModel =
        optimizedLibraryModels.nonNullParameters(methodSymbol);
    // For sanity check: $ nonNullParamsFromModel \cap nullableParamsFromModel $ should be empty
    Set<Integer> allParameterPositions = new HashSet<>();
    boolean varargsArrayModeled = false;
    boolean varArgsMethod = methodSymbol.isVarArgs();
    int varargsIndex = methodSymbol.getParameters().size() - 1;
    for (Integer nullParam : nullableParamsFromModel) {
      if (varArgsMethod && nullParam == varargsIndex) {
        argumentNullness.setVarargsArrayNullness(NULLABLE);
        varargsArrayModeled = true;
        continue;
      }
      allParameterPositions.add(nullParam);
      argumentNullness.setParameterNullness(nullParam, NULLABLE);
    }
    for (Integer nonNullParam : nonNullParamsFromModel) {
      if (varArgsMethod && nonNullParam == varargsIndex) {
        if (varargsArrayModeled) {
          throw new IllegalStateException(
              String.format(
                  "Library models give conflicting nullability for the following parameter of method %s: %s",
                  methodSymbol.getQualifiedName().toString(), "varargs array"));
        }
        argumentNullness.setVarargsArrayNullness(NONNULL);
        varargsArrayModeled = true;
        continue;
      }
      if (!allParameterPositions.add(nonNullParam)) {
        // position was already marked as nullable
        throw new IllegalStateException(
            String.format(
                "Library models give conflicting nullability for the following parameter of method %s: %s",
                methodSymbol.getQualifiedName().toString(), nonNullParam.toString()));
      }
      argumentNullness.setParameterNullness(nonNullParam, NONNULL);
    }
    if (varArgsMethod) {
      ImmutableSetMultimap<Integer, NestedAnnotationInfo> nestedAnnotations =
          optimizedLibraryModels.nestedAnnotationsForMethods(methodSymbol);
      Nullness varargsContentsNullness = null;
      for (NestedAnnotationInfo nestedAnnotation : nestedAnnotations.get(varargsIndex)) {
        // check if it's for the array element
        if (nestedAnnotation.typePath().size() == 1
            && nestedAnnotation.typePath().get(0).kind() == ARRAY_ELEMENT) {
          // this is a nested annotation for the varargs array element, which applies when
          // individual parameters are passed
          if (varargsContentsNullness == null) {
            varargsContentsNullness =
                nestedAnnotation.annotation() == Annotation.NULLABLE ? NULLABLE : NONNULL;
            argumentNullness.setParameterNullness(varargsIndex, varargsContentsNullness);
          } else {
            throw new IllegalStateException(
                "varargs contents nullness set multiple times: "
                    + nestedAnnotations.get(varargsIndex));
          }
        }
      }
    }
    return argumentNullness;
  }