in nullaway/src/main/java/com/uber/nullaway/handlers/contract/fieldcontract/RequiresNonNullHandler.java [135:203]
public void onMatchMethodInvocation(
MethodInvocationTree tree, MethodAnalysisContext methodAnalysisContext) {
VisitorState state = methodAnalysisContext.state();
Symbol.MethodSymbol methodSymbol = methodAnalysisContext.methodSymbol();
NullAway analysis = methodAnalysisContext.analysis();
Set<String> fieldNames = getAnnotationValueArray(methodSymbol, annotName, false);
if (fieldNames == null) {
super.onMatchMethodInvocation(tree, methodAnalysisContext);
return;
}
fieldNames = ContractUtils.trimReceivers(fieldNames);
for (String fieldName : fieldNames) {
Symbol.ClassSymbol classSymbol = ASTHelpers.enclosingClass(methodSymbol);
Preconditions.checkNotNull(
classSymbol, "Could not find the enclosing class for method symbol: " + methodSymbol);
VariableElement field = getFieldOfClass(classSymbol, fieldName);
if (field == null) {
// we will report an error on the method declaration
continue;
}
if (field.getModifiers().contains(Modifier.STATIC)) {
Set<Element> nonnullStaticFields =
analysis
.getNullnessAnalysis(state)
.getNonnullStaticFieldsBefore(state.getPath(), state.context);
if (!nonnullStaticFields.contains(field)) {
String message =
"Expected static field "
+ fieldName
+ " to be non-null at call site due to @RequiresNonNull annotation on invoked method";
state.reportMatch(
analysis
.getErrorBuilder()
.createErrorDescription(
new ErrorMessage(
ErrorMessage.MessageTypes.PRECONDITION_NOT_SATISFIED, message),
tree,
analysis.buildDescription(tree),
state,
null));
}
continue;
}
ExpressionTree methodSelectTree = tree.getMethodSelect();
Nullness nullness =
analysis
.getNullnessAnalysis(state)
.getNullnessOfFieldForReceiverTree(
state.getPath(), state.context, methodSelectTree, field, true);
if (NullabilityUtil.nullnessToBool(nullness)) {
String message =
"Expected field "
+ fieldName
+ " to be non-null at call site due to @RequiresNonNull annotation on invoked method";
state.reportMatch(
analysis
.getErrorBuilder()
.createErrorDescription(
new ErrorMessage(ErrorMessage.MessageTypes.PRECONDITION_NOT_SATISFIED, message),
tree,
analysis.buildDescription(tree),
state,
null));
}
}
}