in jdk-annotations/astubx-generator/src/main/java/com/uber/nullaway/jdkannotations/AstubxGenerator.java [243:301]
private static void getMethodRecords(
ClassInfo clazz,
String fullyQualifiedClassName,
Map<String, MethodAnnotationsRecord> methodRecords) {
for (MethodInfo method : clazz.methods()) {
String methodName = method.name();
// get return type nullness
String returnType = removeGenericAnnotations(method.returnType());
ImmutableSet<String> returnTypeNullness = ImmutableSet.of();
// check if return type has Nullable annotation
if (returnType.contains("@org.jspecify.annotations.Nullable")) {
returnType = returnType.replace("@org.jspecify.annotations.Nullable ", "");
returnType = returnType.replaceAll("@Nullable\\s*", "");
returnType = returnType.replace(" []", "[]"); // remove whitespace in Array types
returnTypeNullness = ImmutableSet.of("Nullable");
}
ImmutableSet.Builder<Integer> nullableTypeParamBuilder = ImmutableSet.builder();
for (int i = 0; i < method.typeParams().size(); i++) {
TypeParamInfo typeParam = method.typeParams().get(i);
for (String upperBound : typeParam.bounds()) {
if (upperBound.contains("@Nullable")) {
nullableTypeParamBuilder.add(i);
}
}
}
String signatureForMethodRecords = fullyQualifiedClassName + ":" + returnType + " ";
signatureForMethodRecords += methodName.substring(0, methodName.indexOf('(') + 1);
Map<Integer, ImmutableSet<String>> argAnnotation = new LinkedHashMap<>();
// get the argument lists
String[] argumentList = getArgumentsAsArray(methodName);
for (int i = 0; i < argumentList.length; i++) {
// remove generic annotations on arguments
String typeSignature = removeGenericAnnotations(argumentList[i].trim());
if (hasTopLevelNullableAnnotation(typeSignature)) {
argAnnotation.put(i, ImmutableSet.of("Nullable"));
}
// Remove top-level annotations before writing the method signature key, while preserving
// the varargs ellipsis so the generated key still matches the erased bytecode signature.
argumentList[i] = stripTopLevelNullnessAnnotations(typeSignature).replace(" []", "[]");
}
ImmutableSetMultimap.Builder<Integer, NestedAnnotationInfo> nestedAnnotations =
new ImmutableSetMultimap.Builder<>();
for (Map.Entry<Integer, Set<NestedAnnotationInfo>> nestedInfo :
method.nestedAnnotationsList().entrySet()) {
nestedAnnotations.putAll(nestedInfo.getKey(), nestedInfo.getValue());
}
signatureForMethodRecords += String.join(",", argumentList) + ")";
methodRecords.put(
signatureForMethodRecords,
MethodAnnotationsRecord.create(
returnTypeNullness,
nullableTypeParamBuilder.build(),
ImmutableMap.copyOf(argAnnotation),
nestedAnnotations.build()));
}
}