in nullaway/src/main/java/com/uber/nullaway/CodeAnnotationInfo.java [206:253]
private ClassCacheRecord get(
Symbol.ClassSymbol classSymbol, Config config, @Nullable Handler handler) {
ClassCacheRecord record = classCache.getIfPresent(classSymbol);
if (record != null) {
return record;
}
if (classSymbol.getNestingKind().isNested()) {
Symbol owner = classSymbol.owner;
Preconditions.checkNotNull(owner, "Symbol.owner should only be null for modules!");
Symbol.MethodSymbol enclosingMethod = null;
if (owner.getKind().equals(ElementKind.METHOD)
|| owner.getKind().equals(ElementKind.CONSTRUCTOR)) {
enclosingMethod = (Symbol.MethodSymbol) owner;
}
Symbol.ClassSymbol enclosingClass = enclosingClass(classSymbol);
// enclosingClass can be null in weird cases like for array methods
if (enclosingClass != null) {
ClassCacheRecord recordForEnclosing = get(enclosingClass, config, handler);
// Check if this class is annotated, recall that enclosed scopes override enclosing scopes
boolean isAnnotated = recordForEnclosing.isNullnessAnnotated;
if (enclosingMethod != null) {
isAnnotated = recordForEnclosing.isMethodNullnessAnnotated(enclosingMethod);
}
if (hasDirectAnnotationWithSimpleName(
classSymbol, NullabilityUtil.NULLUNMARKED_SIMPLE_NAME)) {
isAnnotated = false;
} else if (hasDirectAnnotationWithSimpleName(
classSymbol, NullabilityUtil.NULLMARKED_SIMPLE_NAME)) {
isAnnotated = true;
}
if (shouldTreatAsUnannotated(classSymbol, config)) {
isAnnotated = false;
}
record = new ClassCacheRecord(recordForEnclosing.outermostClassSymbol, isAnnotated);
}
}
if (record == null) {
// We are already at the outermost class (we can find), so let's create a record for it
record =
new ClassCacheRecord(classSymbol, isAnnotatedTopLevelClass(classSymbol, config, handler));
}
// Don't update the cache if the handler is null, as we may not have full info about classes
// being null-marked via library models
if (handler != null) {
classCache.put(classSymbol, record);
}
return record;
}