private Description checkReturnExpression()

in nullaway/src/main/java/com/uber/nullaway/NullAway.java [1090:1145]


  private Description checkReturnExpression(
      ExpressionTree retExpr,
      Symbol.MethodSymbol methodSymbol,
      @Nullable LambdaExpressionTree lambdaTree,
      Tree errorTree,
      VisitorState state) {
    Type returnType = methodSymbol.getReturnType();
    if (returnType.isPrimitive()) {
      // check for unboxing
      doUnboxingCheck(state, retExpr);
      return Description.NO_MATCH;
    }
    if (ASTHelpers.isSameType(returnType, Suppliers.JAVA_LANG_VOID_TYPE.get(state), state)) {
      // Temporarily treat a Void return type as if it were @Nullable Void.  Change this once
      // we are confident that all use cases can be type checked reasonably (may require generics
      // support)
      return Description.NO_MATCH;
    }

    // Check generic type arguments for returned expression here, since we need to check the type
    // arguments regardless of the top-level nullability of the return type
    genericsChecks.checkTypeParameterNullnessForFunctionReturnType(retExpr, methodSymbol, state);

    // Now, perform the check for returning @Nullable from @NonNull.  First, we check if the return
    // type is @Nullable, and if so, bail out.
    if (getMethodReturnNullness(methodSymbol, state, Nullness.NULLABLE).equals(Nullness.NULLABLE)) {
      return Description.NO_MATCH;
    } else if (config.isJSpecifyMode() && lambdaTree != null) {
      Type lambdaType = ASTHelpers.getType(lambdaTree);
      Type inferredType = genericsChecks.getInferredPolyExpressionType(lambdaTree);
      if (inferredType != null) {
        lambdaType = inferredType;
      }
      if (genericsChecks
              .getGenericMethodReturnTypeNullness(methodSymbol, lambdaType, state)
              .equals(Nullness.NULLABLE)
          || genericsChecks.passingLambdaOrMethodRefWithGenericReturnToUnmarkedCode(
              methodSymbol, lambdaTree, state, codeAnnotationInfo)) {
        // In JSpecify mode, the return type of a lambda may be @Nullable via a type argument
        return Description.NO_MATCH;
      }
    }

    // Return type is @NonNull.  Check if the expression is @Nullable
    if (mayBeNullExpr(state, retExpr)) {
      return errorBuilder.createErrorDescriptionForNullAssignment(
          new ErrorMessage(
              MessageTypes.RETURN_NULLABLE,
              "returning @Nullable expression from method with @NonNull return type"),
          retExpr,
          buildDescription(errorTree),
          state,
          methodSymbol);
    }
    return Description.NO_MATCH;
  }