in nullaway/src/main/java/com/uber/nullaway/NullAway.java [488:548]
public Description matchAssignment(AssignmentTree tree, VisitorState state) {
if (!withinAnnotatedCode(state)) {
return Description.NO_MATCH;
}
Type lhsType = ASTHelpers.getType(tree.getVariable());
if (lhsType != null && lhsType.isPrimitive()) {
doUnboxingCheck(state, tree.getExpression());
}
// generics check
if (lhsType != null && lhsType.getTypeArguments().length() > 0 && config.isJSpecifyMode()) {
GenericsChecks.checkTypeParameterNullnessForAssignability(tree, this, state);
}
if (config.isJSpecifyMode() && tree.getVariable() instanceof ArrayAccessTree) {
// check for a write of a @Nullable value into @NonNull array contents
ArrayAccessTree arrayAccess = (ArrayAccessTree) tree.getVariable();
ExpressionTree arrayExpr = arrayAccess.getExpression();
ExpressionTree expression = tree.getExpression();
Symbol arraySymbol = ASTHelpers.getSymbol(arrayExpr);
if (arraySymbol != null) {
boolean isElementNullable = isArrayElementNullable(arraySymbol, config);
if (!isElementNullable && mayBeNullExpr(state, expression)) {
final String message = "Writing @Nullable expression into array with @NonNull contents.";
ErrorMessage errorMessage =
new ErrorMessage(MessageTypes.ASSIGN_NULLABLE_TO_NONNULL_ARRAY, message);
// Future enhancements which auto-fix such warnings will require modification to this
// logic
return errorBuilder.createErrorDescription(
errorMessage,
expression,
buildDescription(tree),
state,
ASTHelpers.getSymbol(tree.getVariable()));
}
}
}
Symbol assigned = ASTHelpers.getSymbol(tree.getVariable());
if (assigned == null || assigned.getKind() != ElementKind.FIELD) {
// not a field of nullable type
return Description.NO_MATCH;
}
if (Nullness.hasNullableAnnotation(assigned, config)
|| handler.onOverrideFieldNullability(assigned)) {
// field already annotated
return Description.NO_MATCH;
}
ExpressionTree expression = tree.getExpression();
if (mayBeNullExpr(state, expression)) {
String message = "assigning @Nullable expression to @NonNull field";
return errorBuilder.createErrorDescriptionForNullAssignment(
new ErrorMessage(MessageTypes.ASSIGN_FIELD_NULLABLE, message),
expression,
buildDescription(tree),
state,
ASTHelpers.getSymbol(tree.getVariable()));
}
handler.onNonNullFieldAssignment(assigned, getNullnessAnalysis(state), state);
return Description.NO_MATCH;
}