in nullaway/src/main/java/com/uber/nullaway/NullAway.java [1090:1145]
private Description checkReturnExpression(
ExpressionTree retExpr,
Symbol.MethodSymbol methodSymbol,
@Nullable LambdaExpressionTree lambdaTree,
Tree errorTree,
VisitorState state) {
Type returnType = methodSymbol.getReturnType();
if (returnType.isPrimitive()) {
// check for unboxing
doUnboxingCheck(state, retExpr);
return Description.NO_MATCH;
}
if (ASTHelpers.isSameType(returnType, Suppliers.JAVA_LANG_VOID_TYPE.get(state), state)) {
// Temporarily treat a Void return type as if it were @Nullable Void. Change this once
// we are confident that all use cases can be type checked reasonably (may require generics
// support)
return Description.NO_MATCH;
}
// Check generic type arguments for returned expression here, since we need to check the type
// arguments regardless of the top-level nullability of the return type
genericsChecks.checkTypeParameterNullnessForFunctionReturnType(retExpr, methodSymbol, state);
// Now, perform the check for returning @Nullable from @NonNull. First, we check if the return
// type is @Nullable, and if so, bail out.
if (getMethodReturnNullness(methodSymbol, state, Nullness.NULLABLE).equals(Nullness.NULLABLE)) {
return Description.NO_MATCH;
} else if (config.isJSpecifyMode() && lambdaTree != null) {
Type lambdaType = ASTHelpers.getType(lambdaTree);
Type inferredType = genericsChecks.getInferredPolyExpressionType(lambdaTree);
if (inferredType != null) {
lambdaType = inferredType;
}
if (genericsChecks
.getGenericMethodReturnTypeNullness(methodSymbol, lambdaType, state)
.equals(Nullness.NULLABLE)
|| genericsChecks.passingLambdaOrMethodRefWithGenericReturnToUnmarkedCode(
methodSymbol, lambdaTree, state, codeAnnotationInfo)) {
// In JSpecify mode, the return type of a lambda may be @Nullable via a type argument
return Description.NO_MATCH;
}
}
// Return type is @NonNull. Check if the expression is @Nullable
if (mayBeNullExpr(state, retExpr)) {
return errorBuilder.createErrorDescriptionForNullAssignment(
new ErrorMessage(
MessageTypes.RETURN_NULLABLE,
"returning @Nullable expression from method with @NonNull return type"),
retExpr,
buildDescription(errorTree),
state,
methodSymbol);
}
return Description.NO_MATCH;
}