private Description checkReturnExpression()

in nullaway/src/main/java/com/uber/nullaway/NullAway.java [969:1020]


  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, this, 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) {
      if (GenericsChecks.getGenericMethodReturnTypeNullness(
                  methodSymbol, ASTHelpers.getType(lambdaTree), state, config)
              .equals(Nullness.NULLABLE)
          || GenericsChecks.passingLambdaOrMethodRefWithGenericReturnToUnmarkedCode(
              methodSymbol, lambdaTree, state, config, codeAnnotationInfo, handler)) {
        // 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;
  }