in nullaway/src/main/java/com/uber/nullaway/NullAway.java [631:673]
private void checkForMethodNullMarkedness(MethodTree tree, VisitorState state) {
boolean markedMethodInUnmarkedContext = false;
Symbol.MethodSymbol methodSymbol = ASTHelpers.getSymbol(tree);
switch (nullMarkingForTopLevelClass) {
case FULLY_MARKED:
if (hasDirectAnnotationWithSimpleName(
methodSymbol, NullabilityUtil.NULLUNMARKED_SIMPLE_NAME)) {
nullMarkingForTopLevelClass = NullMarking.PARTIALLY_MARKED;
}
break;
case FULLY_UNMARKED:
if (hasDirectAnnotationWithSimpleName(
methodSymbol, NullabilityUtil.NULLMARKED_SIMPLE_NAME)) {
nullMarkingForTopLevelClass = NullMarking.PARTIALLY_MARKED;
markedMethodInUnmarkedContext = true;
}
break;
case PARTIALLY_MARKED:
if (hasDirectAnnotationWithSimpleName(
methodSymbol, NullabilityUtil.NULLMARKED_SIMPLE_NAME)) {
// We still care here if this is a transition between @NullUnmarked and @NullMarked code,
// within partially marked code, see checks below for markedMethodInUnmarkedContext.
if (!codeAnnotationInfo.isClassNullAnnotated(methodSymbol.enclClass(), config, handler)) {
markedMethodInUnmarkedContext = true;
}
}
break;
}
if (markedMethodInUnmarkedContext) {
// If this is a @NullMarked method of a @NullUnmarked local or anonymous class, we need to set
// its environment mapping, since we skipped it during matchClass.
TreePath pathToEnclosingClass =
ASTHelpers.findPathFromEnclosingNodeToTopLevel(state.getPath(), ClassTree.class);
if (pathToEnclosingClass == null) {
return;
}
ClassTree enclosingClass = (ClassTree) pathToEnclosingClass.getLeaf();
NestingKind nestingKind = ASTHelpers.getSymbol(enclosingClass).getNestingKind();
if (nestingKind.equals(NestingKind.LOCAL) || nestingKind.equals(NestingKind.ANONYMOUS)) {
updateEnvironmentMapping(pathToEnclosingClass, state);
}
}
}