in jdk-annotations/astubx-generator/src/main/java/com/uber/nullaway/jdkannotations/AstubxGenerator.java [94:144]
public static AstubxData getAstubxData(String jsonDirPath) {
Map<String, List<ClassInfo>> parsed = parseJson(jsonDirPath);
ImmutableMap<String, String> importedAnnotations =
ImmutableMap.of(
"NonNull", "org.jspecify.annotations.NonNull",
"Nullable", "org.jspecify.annotations.Nullable");
// There is no package-info.java files in jspecify/jdk that were @NullMarked so package
// information support is skipped in jdk-javac-plugin
Map<String, Set<String>> packageAnnotations = new HashMap<>();
Map<String, Set<String>> typeAnnotations = new HashMap<>();
Map<String, MethodAnnotationsRecord> methodRecords = new LinkedHashMap<>();
Set<String> nullMarkedClasses = new LinkedHashSet<>();
Map<String, Set<Integer>> nullableUpperBounds = new LinkedHashMap<>();
for (Map.Entry<String, List<ClassInfo>> entry : parsed.entrySet()) {
for (ClassInfo clazz : entry.getValue()) {
String fullyQualifiedClassName = clazz.type();
if (fullyQualifiedClassName.indexOf('<') != -1) {
fullyQualifiedClassName =
fullyQualifiedClassName.substring(0, fullyQualifiedClassName.indexOf('<'));
}
if (clazz.nullMarked()) {
nullMarkedClasses.add(fullyQualifiedClassName);
}
// check upperbounds of type parameters
Set<Integer> nullableUpperBoundIndices = new LinkedHashSet<>();
for (int idx = 0; idx < clazz.typeParams().size(); idx++) {
TypeParamInfo typeParam = clazz.typeParams().get(idx);
for (String bound : typeParam.bounds()) {
if (bound.contains("@org.jspecify.annotations.Nullable")
|| bound.contains("@Nullable")) {
nullableUpperBoundIndices.add(idx);
}
}
}
if (!nullableUpperBoundIndices.isEmpty()) {
nullableUpperBounds.put(fullyQualifiedClassName, nullableUpperBoundIndices);
}
getMethodRecords(clazz, fullyQualifiedClassName, methodRecords);
}
}
return new AstubxData(
importedAnnotations,
packageAnnotations,
typeAnnotations,
methodRecords,
nullableUpperBounds,
nullMarkedClasses);
}