in nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPathNullnessPropagation.java [1021:1049]
Nullness returnValueNullness(
MethodInvocationNode node,
TransferInput<Nullness, NullnessStore> input,
NullnessHint returnValueNullnessHint) {
// NULLABLE is our default
Nullness nullness;
if (node != null && returnValueNullnessHint == NullnessHint.FORCE_NONNULL) {
// A handler says this is definitely non-null; trust it. Note that FORCE_NONNULL is quite
// dangerous, since it
// ignores our analysis' own best judgement, so both this value and the annotations that cause
// it (e.g.
// @Contract ) should be used with care.
nullness = NONNULL;
} else if (node != null && returnValueNullnessHint == NullnessHint.HINT_NULLABLE) {
// we have a model saying return value is nullable.
// still, rely on dataflow fact if there is one available
nullness = input.getRegularStore().valueOfMethodCall(node, state, NULLABLE, apContext);
} else if (node == null
|| methodReturnsNonNull.test(node)
|| (!Nullness.hasNullableAnnotation((Symbol) node.getTarget().getMethod(), config)
&& !genericReturnIsNullable(node))) {
// definite non-null return
nullness = NONNULL;
} else {
// rely on dataflow, assuming nullable if no fact
nullness = input.getRegularStore().valueOfMethodCall(node, state, NULLABLE, apContext);
}
return nullness;
}