public Description matchAssignment()

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;
  }