in nullaway/src/main/java/com/uber/nullaway/NullAway.java [1094:1144]
private Description checkOverriding(
Symbol.MethodSymbol overriddenMethod,
Symbol.MethodSymbol overridingMethod,
@Nullable MemberReferenceTree memberReferenceTree,
VisitorState state) {
// if the super method returns nonnull, overriding method better not return nullable
// Note that, for the overriding method, the permissive default is non-null,
// but it's nullable for the overridden one.
if (overriddenMethodReturnsNonNull(
overriddenMethod, overridingMethod.owner, memberReferenceTree, state)
&& getMethodReturnNullness(overridingMethod, state, Nullness.NONNULL)
.equals(Nullness.NULLABLE)
&& (memberReferenceTree == null
|| getComputedNullness(memberReferenceTree).equals(Nullness.NULLABLE))) {
String message;
if (memberReferenceTree != null) {
message =
"referenced method returns @Nullable, but functional interface method "
+ ASTHelpers.enclosingClass(overriddenMethod)
+ "."
+ overriddenMethod.toString()
+ " returns @NonNull";
} else {
message =
"method returns @Nullable, but superclass method "
+ ASTHelpers.enclosingClass(overriddenMethod)
+ "."
+ overriddenMethod.toString()
+ " returns @NonNull";
}
Tree errorTree =
memberReferenceTree != null
? memberReferenceTree
: getTreesInstance(state).getTree(overridingMethod);
return errorBuilder.createErrorDescription(
new ErrorMessage(MessageTypes.WRONG_OVERRIDE_RETURN, message),
buildDescription(errorTree),
state,
overriddenMethod);
}
// if any parameter in the super method is annotated @Nullable,
// overriding method cannot assume @Nonnull
return checkParamOverriding(
overridingMethod.getParameters(),
overriddenMethod,
null,
memberReferenceTree,
state,
overridingMethod);
}