in nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java [226:276]
public void checkGenericMethodCallTypeArguments(Tree tree, VisitorState state) {
List<? extends Tree> typeArguments =
switch (tree.getKind()) {
case METHOD_INVOCATION -> ((MethodInvocationTree) tree).getTypeArguments();
case NEW_CLASS -> ((NewClassTree) tree).getTypeArguments();
default -> throw new RuntimeException("Unexpected tree kind: " + tree.getKind());
};
if (typeArguments.isEmpty()) {
return;
}
// get Nullable annotated type arguments
Map<Integer, Tree> nullableTypeArguments = new HashMap<>();
for (int i = 0; i < typeArguments.size(); i++) {
Tree curTypeArg = typeArguments.get(i);
if (curTypeArg instanceof AnnotatedTypeTree annotatedType) {
for (AnnotationTree annotation : annotatedType.getAnnotations()) {
Type annotationType = ASTHelpers.getType(annotation);
if (annotationType != null
&& Nullness.isNullableAnnotation(annotationType.toString(), config)) {
nullableTypeArguments.put(i, curTypeArg);
break;
}
}
}
}
Symbol.MethodSymbol methodSymbol =
castToNonNull((Symbol.MethodSymbol) ASTHelpers.getSymbol(tree));
// check if type variables are allowed to be Nullable
Type baseType = methodSymbol.asType();
List<Type> baseTypeVariables = baseType.getTypeArguments();
for (int i = 0; i < baseTypeVariables.size(); i++) {
if (nullableTypeArguments.containsKey(i)) {
Type typeVariable = baseTypeVariables.get(i);
Type upperBound = typeVariable.getUpperBound();
com.sun.tools.javac.util.List<Attribute.TypeCompound> annotationMirrors =
upperBound.getAnnotationMirrors();
boolean hasNullableAnnotation =
Nullness.hasNullableAnnotation(annotationMirrors.stream(), config)
|| handler.onOverrideClassTypeVariableUpperBound(baseType.tsym.toString(), i);
// if type variable's upper bound does not have @Nullable annotation then the instantiation
// is invalid
if (!hasNullableAnnotation
&& !handler.onOverrideMethodTypeVariableUpperBound(methodSymbol, i, state)) {
reportInvalidTypeArgumentError(
nullableTypeArguments.get(i), methodSymbol, typeVariable, state);
}
}
}
}