// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE.md file.

part of 'type_inferrer.dart';

/// Keeps track of information about the innermost function or closure being
/// inferred.
abstract class ClosureContext {
  /// Returns `true` if this is an `async` or an `async*` function.
  bool get isAsync;

  /// The typing expectation for the subexpression of a `return` statement
  /// inside the function.
  ///
  /// For an `async` function, this is a "FutureOr" type (since it is
  /// permissible for such a function to return either a direct value or a
  /// future).
  ///
  /// For generator functions (which do not allow return statements) this is the
  /// unknown type.
  DartType get returnContext;

  /// The typing expectation for the subexpression of a `yield` statement inside
  /// the function.
  ///
  /// For `sync*` and `async*` functions, the expected type is the element type
  /// of the generated `Iterable` or `Stream`, respectively.
  ///
  /// For non-generator functions (which do not allow yield statements) this is
  /// the unknown type.
  DartType get yieldContext;

  DartType? get futureValueType;

  factory ClosureContext(TypeInferrerImpl inferrer, AsyncMarker asyncMarker,
      DartType returnContext, bool needToInferReturnType) {
    // ignore: unnecessary_null_comparison
    assert(returnContext != null);
    DartType declaredReturnType =
        inferrer.computeGreatestClosure(returnContext);
    bool isAsync = asyncMarker == AsyncMarker.Async ||
        asyncMarker == AsyncMarker.AsyncStar;
    bool isGenerator = asyncMarker == AsyncMarker.SyncStar ||
        asyncMarker == AsyncMarker.AsyncStar;
    if (isGenerator) {
      if (isAsync) {
        DartType yieldContext = inferrer.getTypeArgumentOf(
            returnContext, inferrer.coreTypes.streamClass);
        return new _AsyncStarClosureContext(
            yieldContext, declaredReturnType, needToInferReturnType);
      } else {
        DartType yieldContext = inferrer.getTypeArgumentOf(
            returnContext, inferrer.coreTypes.iterableClass);
        return new _SyncStarClosureContext(
            yieldContext, declaredReturnType, needToInferReturnType);
      }
    } else if (isAsync) {
      DartType? futureValueType;
      if (inferrer.isNonNullableByDefault) {
        returnContext = inferrer.wrapFutureOrType(
            inferrer.computeFutureValueTypeSchema(returnContext));
        if (!needToInferReturnType) {
          futureValueType =
              computeFutureValueType(inferrer.coreTypes, declaredReturnType);
        }
      } else {
        returnContext = inferrer.wrapFutureOrType(
            inferrer.typeSchemaEnvironment.flatten(returnContext));
      }
      return new _AsyncClosureContext(returnContext, declaredReturnType,
          needToInferReturnType, futureValueType);
    } else {
      return new _SyncClosureContext(
          returnContext, declaredReturnType, needToInferReturnType);
    }
  }

  /// Handles an explicit return statement.
  ///
  /// If the return type is declared, the expression type is checked. If the
  /// return type is inferred the expression type registered for inference
  /// in [inferReturnType].
  void handleReturn(TypeInferrerImpl inferrer, ReturnStatement statement,
      DartType type, bool isArrow);

  /// Handles an explicit yield statement.
  ///
  /// If the return type is declared, the expression type is checked. If the
  /// return type is inferred the expression type registered for inference
  /// in [inferReturnType].
  void handleYield(TypeInferrerImpl inferrer, YieldStatement node,
      ExpressionInferenceResult expressionResult);

  /// Handles an implicit return statement.
  ///
  /// If the return type is declared, the expression type is checked. If the
  /// return type is inferred the expression type registered for inference
  /// in [inferReturnType].
  StatementInferenceResult handleImplicitReturn(TypeInferrerImpl inferrer,
      Statement body, StatementInferenceResult inferenceResult, int fileOffset);

  /// Infers the return type for the function.
  ///
  /// If the function is a non-generator function this is based on the explicit
  /// and implicit return statements registered in [handleReturn] and
  /// [handleImplicitReturn].
  ///
  /// If the function is a generator function this is based on the explicit
  /// yield statements registered in [handleYield].
  DartType inferReturnType(TypeInferrerImpl inferrer,
      {required bool hasImplicitReturn});
}

class _SyncClosureContext implements ClosureContext {
  @override
  bool get isAsync => false;

  /// The typing expectation for the subexpression of a `return` statement
  /// inside the function.
  final DartType _returnContext;

  @override
  DartType get returnContext => _returnContext;

  @override
  DartType get yieldContext => const UnknownType();

  final DartType _declaredReturnType;

  final bool _needToInferReturnType;

  DartType? _inferredReturnType;

  /// Whether the function is an arrow function.
  bool? _isArrow;

  /// A list of return statements in functions whose return type is being
  /// inferred.
  ///
  /// The returns are checked for validity after the return type is inferred.
  List<ReturnStatement>? _returnStatements;

  /// A list of return expression types in functions whose return type is
  /// being inferred.
  List<DartType>? _returnExpressionTypes;

  @override
  DartType? get futureValueType => null;

  _SyncClosureContext(this._returnContext, this._declaredReturnType,
      this._needToInferReturnType) {
    if (_needToInferReturnType) {
      _returnStatements = [];
      _returnExpressionTypes = [];
    }
  }

  void _checkValidReturn(TypeInferrerImpl inferrer, DartType returnType,
      ReturnStatement statement, DartType expressionType) {
    assert(!inferrer.isTopLevel);
    if (inferrer.isNonNullableByDefault) {
      if (statement.expression == null) {
        // It is a compile-time error if s is `return;`, unless T is void,
        // dynamic, or Null.
        if (returnType is VoidType ||
            returnType is DynamicType ||
            returnType is NullType) {
          // Valid return;
        } else {
          statement.expression = inferrer.helper!.wrapInProblem(
              new NullLiteral()..fileOffset = statement.fileOffset,
              messageReturnWithoutExpressionSync,
              statement.fileOffset,
              noLength)
            ..parent = statement;
        }
      } else {
        if (_isArrow! && returnType is VoidType) {
          // For `=> e` it is a compile-time error if T is not void, and it
          // would have been a compile-time error to declare the function with
          // the body `{ return e; }` rather than `=> e`.
          return;
        }

        if (returnType is VoidType &&
            !(expressionType is VoidType ||
                expressionType is DynamicType ||
                expressionType is NullType)) {
          // It is a compile-time error if s is `return e;`, T is void, and S is
          // neither void, dynamic, nor Null.
          statement.expression = inferrer.helper!.wrapInProblem(
              statement.expression!,
              messageReturnFromVoidFunction,
              statement.expression!.fileOffset,
              noLength)
            ..parent = statement;
        } else if (!(returnType is VoidType || returnType is DynamicType) &&
            expressionType is VoidType) {
          // It is a compile-time error if s is `return e;`, T is neither void
          // nor dynamic, and S is void.
          statement.expression = inferrer.helper!.wrapInProblem(
              statement.expression!,
              templateInvalidReturn.withArguments(expressionType,
                  _declaredReturnType, inferrer.isNonNullableByDefault),
              statement.expression!.fileOffset,
              noLength)
            ..parent = statement;
        } else if (expressionType is! VoidType) {
          // It is a compile-time error if s is `return e;`, S is not void, and
          // S is not assignable to T.
          Expression expression = inferrer.ensureAssignable(
              _returnContext, expressionType, statement.expression!,
              fileOffset: statement.expression!.fileOffset,
              isVoidAllowed: true,
              errorTemplate: templateInvalidReturn,
              nullabilityErrorTemplate: templateInvalidReturnNullability,
              nullabilityPartErrorTemplate:
                  templateInvalidReturnPartNullability,
              nullabilityNullErrorTemplate:
                  templateInvalidReturnNullabilityNull,
              nullabilityNullTypeErrorTemplate:
                  templateInvalidReturnNullabilityNullType);
          statement.expression = expression..parent = statement;
        }
      }
    } else {
      // The rules for valid returns for functions with [returnType] `T` and
      // a return expression with static [expressionType] `S`.
      if (statement.expression == null) {
        // `return;` is a valid return if T is void, dynamic, or Null.
        if (returnType is VoidType ||
            returnType is DynamicType ||
            returnType is NullType) {
          // Valid return;
        } else {
          statement.expression = inferrer.helper!.wrapInProblem(
              new NullLiteral()..fileOffset = statement.fileOffset,
              messageReturnWithoutExpression,
              statement.fileOffset,
              noLength)
            ..parent = statement;
        }
      } else {
        void ensureAssignability() {
          Expression expression = inferrer.ensureAssignable(
              _returnContext, expressionType, statement.expression!,
              fileOffset: statement.fileOffset, isVoidAllowed: true);
          statement.expression = expression..parent = statement;
        }

        if (_isArrow! && returnType is VoidType) {
          // Arrow functions are valid if: T is void or return exp; is a valid
          // for a block-bodied function.
          ensureAssignability();
        } else if (returnType is VoidType &&
            expressionType is! VoidType &&
            expressionType is! DynamicType &&
            expressionType is! NullType) {
          // Invalid if T is void and S is not void, dynamic, or Null
          statement.expression = inferrer.helper!.wrapInProblem(
              statement.expression!,
              messageReturnFromVoidFunction,
              statement.expression!.fileOffset,
              noLength)
            ..parent = statement;
        } else if (expressionType is VoidType &&
            returnType is! VoidType &&
            returnType is! DynamicType &&
            returnType is! NullType) {
          // Invalid if S is void and T is not void, dynamic, or Null.
          statement.expression = inferrer.helper!.wrapInProblem(
              statement.expression!,
              messageVoidExpression,
              statement.expression!.fileOffset,
              noLength)
            ..parent = statement;
        } else {
          ensureAssignability();
        }
      }
    }
  }

  /// Updates the inferred return type based on the presence of a return
  /// statement returning the given [type].
  @override
  void handleReturn(TypeInferrerImpl inferrer, ReturnStatement statement,
      DartType type, bool isArrow) {
    // The first return we see tells us if we have an arrow function.
    if (this._isArrow == null) {
      this._isArrow = isArrow;
    } else {
      assert(this._isArrow == isArrow);
    }

    if (_needToInferReturnType) {
      // Add the return to a list to be checked for validity after we've
      // inferred the return type.
      _returnStatements!.add(statement);
      _returnExpressionTypes!.add(type);
    } else if (!inferrer.isTopLevel) {
      _checkValidReturn(inferrer, _declaredReturnType, statement, type);
    }
  }

  @override
  void handleYield(TypeInferrerImpl inferrer, YieldStatement node,
      ExpressionInferenceResult expressionResult) {
    node.expression = expressionResult.expression..parent = node;
  }

  @override
  DartType inferReturnType(TypeInferrerImpl inferrer,
      {required bool hasImplicitReturn}) {
    assert(_needToInferReturnType);
    // ignore: unnecessary_null_comparison
    assert(hasImplicitReturn != null);
    DartType? actualReturnedType;
    DartType inferredReturnType;
    if (inferrer.isNonNullableByDefault) {
      if (hasImplicitReturn) {
        // No explicit returns we have an implicit `return null`.
        actualReturnedType = const NullType();
      } else {
        // No explicit return and the function doesn't complete normally; that
        // is, it throws.
        actualReturnedType =
            NeverType.fromNullability(inferrer.library.nonNullable);
      }
      // Use the types seen from the explicit return statements.
      for (int i = 0; i < _returnStatements!.length; i++) {
        ReturnStatement statement = _returnStatements![i];
        DartType type = _returnExpressionTypes![i];
        // The return expression has to be assignable to the return type
        // expectation from the downwards inference context.
        if (statement.expression != null) {
          if (!inferrer.isAssignable(_returnContext, type)) {
            type = inferrer.computeGreatestClosure(_returnContext);
          }
        }
        if (actualReturnedType == null) {
          actualReturnedType = type;
        } else {
          actualReturnedType = inferrer.typeSchemaEnvironment
              .getStandardUpperBound(
                  actualReturnedType, type, inferrer.library.library);
        }
      }

      // Let T be the actual returned type of a function literal as computed
      // above. Let R be the greatest closure of the typing context K as
      // computed above.
      DartType returnContext =
          inferrer.computeGreatestClosure2(_declaredReturnType);
      if (returnContext is VoidType) {
        // With null safety: if R is void, or the function literal is marked
        // async and R is FutureOr<void>, let S be void.
        inferredReturnType = const VoidType();
      } else if (inferrer.typeSchemaEnvironment.isSubtypeOf(actualReturnedType!,
          returnContext, SubtypeCheckMode.withNullabilities)) {
        // Otherwise, if T <: R then let S be T.
        inferredReturnType = actualReturnedType;
      } else {
        // Otherwise, let S be R.
        inferredReturnType = returnContext;
      }
    } else {
      if (_returnStatements!.isNotEmpty) {
        // Use the types seen from the explicit return statements.
        for (int i = 0; i < _returnStatements!.length; i++) {
          ReturnStatement statement = _returnStatements![i];
          DartType type = _returnExpressionTypes![i];
          // The return expression has to be assignable to the return type
          // expectation from the downwards inference context.
          if (statement.expression != null) {
            if (!inferrer.isAssignable(_returnContext, type)) {
              type = inferrer.computeGreatestClosure(_returnContext);
            }
          }
          if (actualReturnedType == null) {
            actualReturnedType = type;
          } else {
            actualReturnedType = inferrer.typeSchemaEnvironment
                .getStandardUpperBound(
                    actualReturnedType, type, inferrer.library.library);
          }
        }
      } else if (hasImplicitReturn) {
        // No explicit returns we have an implicit `return null`.
        actualReturnedType = const NullType();
      } else {
        // No explicit return and the function doesn't complete normally; that
        // is, it throws.
        actualReturnedType = const NullType();
      }

      if (!inferrer.typeSchemaEnvironment.isSubtypeOf(actualReturnedType!,
          _returnContext, SubtypeCheckMode.withNullabilities)) {
        // If the inferred return type isn't a subtype of the context, we use
        // the context.
        inferredReturnType =
            inferrer.computeGreatestClosure2(_declaredReturnType);
      } else {
        inferredReturnType = actualReturnedType;
      }
    }

    for (int i = 0; i < _returnStatements!.length; ++i) {
      if (!inferrer.isTopLevel) {
        _checkValidReturn(inferrer, inferredReturnType, _returnStatements![i],
            _returnExpressionTypes![i]);
      }
    }

    return _inferredReturnType =
        demoteTypeInLibrary(inferredReturnType, inferrer.library.library);
  }

  @override
  StatementInferenceResult handleImplicitReturn(
      TypeInferrerImpl inferrer,
      Statement body,
      StatementInferenceResult inferenceResult,
      int fileOffset) {
    DartType returnType;
    if (_needToInferReturnType) {
      assert(_inferredReturnType != null,
          "Return type has not yet been inferred.");
      returnType = _inferredReturnType!;
    } else {
      returnType = _declaredReturnType;
    }
    if (!inferrer.isTopLevel &&
        inferrer.library.isNonNullableByDefault &&
        !containsInvalidType(returnType) &&
        returnType.isPotentiallyNonNullable &&
        inferrer.flowAnalysis.isReachable) {
      Statement resultStatement =
          inferenceResult.hasChanged ? inferenceResult.statement : body;
      // Create a synthetic return statement with the error.
      Statement returnStatement = new ReturnStatement(inferrer.helper!
          .wrapInProblem(
              new NullLiteral()..fileOffset = fileOffset,
              templateImplicitReturnNull.withArguments(
                  returnType, inferrer.library.isNonNullableByDefault),
              fileOffset,
              noLength))
        ..fileOffset = fileOffset;
      if (resultStatement is Block) {
        resultStatement.statements.add(returnStatement);
      } else {
        resultStatement =
            new Block(<Statement>[resultStatement, returnStatement])
              ..fileOffset = fileOffset;
      }
      return new StatementInferenceResult.single(resultStatement);
    }
    return inferenceResult;
  }
}

/// Keeps track of information about the innermost function or closure being
/// inferred.
class _AsyncClosureContext implements ClosureContext {
  @override
  bool get isAsync => true;

  /// The typing expectation for the subexpression of a `return` statement
  /// inside the function.
  ///
  /// This will be a "FutureOr" type (since it is permissible for such a
  /// function to return either a direct value or a future).
  final DartType _returnContext;

  @override
  DartType get returnContext => _returnContext;

  @override
  DartType get yieldContext => const UnknownType();

  final DartType _declaredReturnType;

  final bool _needToInferReturnType;

  DartType? _inferredReturnType;

  /// Whether the function is an arrow function.
  bool? _isArrow;

  /// A list of return statements in functions whose return type is being
  /// inferred.
  ///
  /// The returns are checked for validity after the return type is inferred.
  List<ReturnStatement>? _returnStatements;

  /// A list of return expression types in functions whose return type is
  /// being inferred.
  List<DartType>? _returnExpressionTypes;

  @override
  DartType? futureValueType;

  _AsyncClosureContext(this._returnContext, this._declaredReturnType,
      this._needToInferReturnType, this.futureValueType) {
    if (_needToInferReturnType) {
      _returnStatements = [];
      _returnExpressionTypes = [];
    }
  }

  void _checkValidReturn(TypeInferrerImpl inferrer, DartType returnType,
      ReturnStatement statement, DartType expressionType) {
    assert(!inferrer.isTopLevel);
    if (inferrer.isNonNullableByDefault) {
      assert(
          futureValueType != null, "Future value type has not been computed.");

      if (statement.expression == null) {
        // It is a compile-time error if s is `return;`, unless T_v is void,
        // dynamic, or Null.
        if (futureValueType is VoidType ||
            futureValueType is DynamicType ||
            futureValueType is NullType) {
          // Valid return;
        } else {
          statement.expression = inferrer.helper!.wrapInProblem(
              new NullLiteral()..fileOffset = statement.fileOffset,
              messageReturnWithoutExpressionAsync,
              statement.fileOffset,
              noLength)
            ..parent = statement;
        }
      } else {
        if (_isArrow! &&
            inferrer.typeSchemaEnvironment.flatten(returnType) is VoidType) {
          // For `async => e` it is a compile-time error if flatten(T) is not
          // void, and it would have been a compile-time error to declare the
          // function with the body `async { return e; }` rather than
          // `async => e`.
          return;
        }

        DartType flattenedExpressionType =
            inferrer.typeSchemaEnvironment.flatten(expressionType);
        if (futureValueType is VoidType &&
            !(flattenedExpressionType is VoidType ||
                flattenedExpressionType is DynamicType ||
                flattenedExpressionType is NullType)) {
          // It is a compile-time error if s is `return e;`, T_v is void, and
          // flatten(S) is neither void, dynamic, Null.
          statement.expression = inferrer.helper!.wrapInProblem(
              new NullLiteral()..fileOffset = statement.fileOffset,
              templateInvalidReturnAsync.withArguments(
                  expressionType, returnType, inferrer.isNonNullableByDefault),
              statement.expression!.fileOffset,
              noLength)
            ..parent = statement;
        } else if (!(futureValueType is VoidType ||
                futureValueType is DynamicType) &&
            flattenedExpressionType is VoidType) {
          // It is a compile-time error if s is `return e;`, T_v is neither void
          // nor dynamic, and flatten(S) is void.
          statement.expression = inferrer.helper!.wrapInProblem(
              new NullLiteral()..fileOffset = statement.fileOffset,
              templateInvalidReturnAsync.withArguments(
                  expressionType, returnType, inferrer.isNonNullableByDefault),
              statement.expression!.fileOffset,
              noLength)
            ..parent = statement;
        } else if (flattenedExpressionType is! VoidType &&
            !inferrer.typeSchemaEnvironment
                .performNullabilityAwareSubtypeCheck(
                    flattenedExpressionType, futureValueType!)
                .isSubtypeWhenUsingNullabilities()) {
          // It is a compile-time error if s is `return e;`, flatten(S) is not
          // void, S is not assignable to T_v, and flatten(S) is not a subtype
          // of T_v.
          statement.expression = inferrer.ensureAssignable(
              futureValueType!, expressionType, statement.expression!,
              fileOffset: statement.expression!.fileOffset,
              runtimeCheckedType:
                  inferrer.computeGreatestClosure2(_returnContext),
              declaredContextType: returnType,
              isVoidAllowed: false,
              errorTemplate: templateInvalidReturnAsync,
              nullabilityErrorTemplate: templateInvalidReturnAsyncNullability,
              nullabilityPartErrorTemplate:
                  templateInvalidReturnAsyncPartNullability,
              nullabilityNullErrorTemplate:
                  templateInvalidReturnAsyncNullabilityNull,
              nullabilityNullTypeErrorTemplate:
                  templateInvalidReturnAsyncNullabilityNullType)
            ..parent = statement;
        }
      }
    } else {
      // The rules for valid returns for async functions with [returnType] `T`
      // and a return expression with static [expressionType] `S`.
      DartType flattenedReturnType =
          inferrer.typeSchemaEnvironment.flatten(returnType);
      if (statement.expression == null) {
        // `return;` is a valid return if flatten(T) is void, dynamic, or Null.
        if (flattenedReturnType is VoidType ||
            flattenedReturnType is DynamicType ||
            flattenedReturnType is NullType) {
          // Valid return;
        } else {
          statement.expression = inferrer.helper!.wrapInProblem(
              new NullLiteral()..fileOffset = statement.fileOffset,
              messageReturnWithoutExpression,
              statement.fileOffset,
              noLength)
            ..parent = statement;
        }
      } else {
        DartType flattenedExpressionType =
            inferrer.typeSchemaEnvironment.flatten(expressionType);

        void ensureAssignability() {
          DartType wrappedType = inferrer.typeSchemaEnvironment
              .futureType(flattenedExpressionType, Nullability.nonNullable);
          Expression expression = inferrer.ensureAssignable(
              computeAssignableType(inferrer, _returnContext, wrappedType),
              wrappedType,
              statement.expression!,
              fileOffset: statement.fileOffset,
              isVoidAllowed: true,
              runtimeCheckedType:
                  inferrer.computeGreatestClosure(_returnContext));
          statement.expression = expression..parent = statement;
        }

        if (_isArrow! && flattenedReturnType is VoidType) {
          // Arrow functions are valid if: flatten(T) is void or return exp; is
          // valid for a block-bodied function.
          ensureAssignability();
        } else if (returnType is VoidType &&
            flattenedExpressionType is! VoidType &&
            flattenedExpressionType is! DynamicType &&
            flattenedExpressionType is! NullType) {
          // Invalid if T is void and flatten(S) is not void, dynamic, or Null.
          statement.expression = inferrer.helper!.wrapInProblem(
              statement.expression!,
              messageReturnFromVoidFunction,
              statement.expression!.fileOffset,
              noLength)
            ..parent = statement;
        } else if (flattenedExpressionType is VoidType &&
            flattenedReturnType is! VoidType &&
            flattenedReturnType is! DynamicType &&
            flattenedReturnType is! NullType) {
          // Invalid if flatten(S) is void and flatten(T) is not void, dynamic,
          // or Null.
          statement.expression = inferrer.helper!.wrapInProblem(
              statement.expression!,
              messageVoidExpression,
              statement.expression!.fileOffset,
              noLength)
            ..parent = statement;
        } else {
          // The caller will check that the return expression is assignable to
          // the return type.
          ensureAssignability();
        }
      }
    }
  }

  /// Updates the inferred return type based on the presence of a return
  /// statement returning the given [type].
  @override
  void handleReturn(TypeInferrerImpl inferrer, ReturnStatement statement,
      DartType type, bool isArrow) {
    // The first return we see tells us if we have an arrow function.
    if (this._isArrow == null) {
      this._isArrow = isArrow;
    } else {
      assert(this._isArrow == isArrow);
    }

    if (_needToInferReturnType) {
      // Add the return to a list to be checked for validity after we've
      // inferred the return type.
      _returnStatements!.add(statement);
      _returnExpressionTypes!.add(type);
    } else if (!inferrer.isTopLevel) {
      _checkValidReturn(inferrer, _declaredReturnType, statement, type);
    }
  }

  @override
  void handleYield(TypeInferrerImpl inferrer, YieldStatement node,
      ExpressionInferenceResult expressionResult) {
    node.expression = expressionResult.expression..parent = node;
  }

  DartType computeAssignableType(TypeInferrerImpl inferrer,
      DartType contextType, DartType expressionType) {
    contextType = inferrer.computeGreatestClosure(contextType);

    DartType initialContextType = contextType;
    if (!inferrer.isAssignable(initialContextType, expressionType)) {
      // If the body of the function is async, the expected return type has the
      // shape FutureOr<T>.  We check both branches for FutureOr here: both T
      // and Future<T>.
      DartType unfuturedExpectedType =
          inferrer.typeSchemaEnvironment.flatten(contextType);
      DartType futuredExpectedType = inferrer.wrapFutureType(
          unfuturedExpectedType, inferrer.library.nonNullable);
      if (inferrer.isAssignable(unfuturedExpectedType, expressionType)) {
        contextType = unfuturedExpectedType;
      } else if (inferrer.isAssignable(futuredExpectedType, expressionType)) {
        contextType = futuredExpectedType;
      }
    }
    return contextType;
  }

  @override
  DartType inferReturnType(TypeInferrerImpl inferrer,
      {required bool hasImplicitReturn}) {
    assert(_needToInferReturnType);
    // ignore: unnecessary_null_comparison
    assert(hasImplicitReturn != null);
    DartType? inferredType;

    if (inferrer.isNonNullableByDefault) {
      if (hasImplicitReturn) {
        // No explicit returns we have an implicit `return null`.
        inferredType = const NullType();
      } else {
        // No explicit return and the function doesn't complete normally; that
        // is, it throws.
        inferredType = NeverType.fromNullability(inferrer.library.nonNullable);
      }
      // Use the types seen from the explicit return statements.
      for (int i = 0; i < _returnStatements!.length; i++) {
        DartType type = _returnExpressionTypes![i];

        DartType unwrappedType = inferrer.typeSchemaEnvironment.flatten(type);
        if (inferredType == null) {
          inferredType = unwrappedType;
        } else {
          inferredType = inferrer.typeSchemaEnvironment.getStandardUpperBound(
              inferredType, unwrappedType, inferrer.library.library);
        }
      }

      // Let `T` be the **actual returned type** of a function literal as
      // computed above.

      // Let `R` be the greatest closure of the typing context `K` as computed
      // above. If `R` is `void`, or the function literal is marked `async` and
      // `R` is `FutureOr<void>`, let `S` be `void`. Otherwise, if `T <: R` then
      // let `S` be `T`.  Otherwise, let `S` be `R`.
      DartType returnContext = inferrer.computeGreatestClosure2(_returnContext);
      if (returnContext is VoidType ||
          returnContext is FutureOrType &&
              returnContext.typeArgument is VoidType) {
        inferredType = const VoidType();
      } else if (!inferrer.typeSchemaEnvironment.isSubtypeOf(
          inferredType!, returnContext, SubtypeCheckMode.withNullabilities)) {
        // If the inferred return type isn't a subtype of the context, we use
        // the context.
        inferredType = returnContext;
      }
      inferredType = inferrer.wrapFutureType(
          inferrer.typeSchemaEnvironment.flatten(inferredType),
          inferrer.library.nonNullable);
    } else {
      if (_returnStatements!.isNotEmpty) {
        // Use the types seen from the explicit return statements.
        for (int i = 0; i < _returnStatements!.length; i++) {
          ReturnStatement statement = _returnStatements![i];
          DartType type = _returnExpressionTypes![i];

          // The return expression has to be assignable to the return type
          // expectation from the downwards inference context.
          if (statement.expression != null) {
            if (!inferrer.isAssignable(
                computeAssignableType(inferrer, _returnContext, type), type)) {
              // Not assignable, use the expectation.
              type = inferrer.computeGreatestClosure(_returnContext);
            }
          }
          DartType unwrappedType = inferrer.typeSchemaEnvironment.flatten(type);
          if (inferredType == null) {
            inferredType = unwrappedType;
          } else {
            inferredType = inferrer.typeSchemaEnvironment.getStandardUpperBound(
                inferredType, unwrappedType, inferrer.library.library);
          }
        }
      } else if (hasImplicitReturn) {
        // No explicit returns we have an implicit `return null`.
        inferredType = const NullType();
      } else {
        // No explicit return and the function doesn't complete normally;
        // that is, it throws.
        inferredType = const NullType();
      }
      inferredType =
          inferrer.wrapFutureType(inferredType!, inferrer.library.nonNullable);

      if (!inferrer.typeSchemaEnvironment.isSubtypeOf(
          inferredType, _returnContext, SubtypeCheckMode.withNullabilities)) {
        // If the inferred return type isn't a subtype of the context, we use
        // the context.
        inferredType = inferrer.computeGreatestClosure2(_declaredReturnType);
      }
    }

    if (inferrer.isNonNullableByDefault) {
      futureValueType =
          computeFutureValueType(inferrer.coreTypes, inferredType);
    }
    if (!inferrer.isTopLevel) {
      for (int i = 0; i < _returnStatements!.length; ++i) {
        _checkValidReturn(inferrer, inferredType, _returnStatements![i],
            _returnExpressionTypes![i]);
      }
    }

    return _inferredReturnType =
        demoteTypeInLibrary(inferredType, inferrer.library.library);
  }

  @override
  StatementInferenceResult handleImplicitReturn(
      TypeInferrerImpl inferrer,
      Statement body,
      StatementInferenceResult inferenceResult,
      int fileOffset) {
    DartType returnType;
    if (_needToInferReturnType) {
      assert(_inferredReturnType != null,
          "Return type has not yet been inferred.");
      returnType = _inferredReturnType!;
    } else {
      returnType = _declaredReturnType;
    }
    returnType = inferrer.typeSchemaEnvironment.flatten(returnType);
    if (!inferrer.isTopLevel &&
        inferrer.library.isNonNullableByDefault &&
        !containsInvalidType(returnType) &&
        returnType.isPotentiallyNonNullable &&
        inferrer.flowAnalysis.isReachable) {
      Statement resultStatement =
          inferenceResult.hasChanged ? inferenceResult.statement : body;
      // Create a synthetic return statement with the error.
      Statement returnStatement = new ReturnStatement(inferrer.helper!
          .wrapInProblem(
              new NullLiteral()..fileOffset = fileOffset,
              templateImplicitReturnNull.withArguments(
                  returnType, inferrer.library.isNonNullableByDefault),
              fileOffset,
              noLength))
        ..fileOffset = fileOffset;
      if (resultStatement is Block) {
        resultStatement.statements.add(returnStatement);
      } else {
        resultStatement =
            new Block(<Statement>[resultStatement, returnStatement])
              ..fileOffset = fileOffset;
      }
      return new StatementInferenceResult.single(resultStatement);
    }
    return inferenceResult;
  }
}

/// Keeps track of information about the innermost function or closure being
/// inferred.
class _SyncStarClosureContext implements ClosureContext {
  @override
  bool get isAsync => false;

  /// The typing expectation for the subexpression of a `return` or `yield`
  /// statement inside the function.
  ///
  /// For non-generator async functions, this will be a "FutureOr" type (since
  /// it is permissible for such a function to return either a direct value or
  /// a future).
  ///
  /// For generator functions containing a `yield*` statement, the expected type
  /// for the subexpression of the `yield*` statement is the result of wrapping
  /// this typing expectation in `Stream` or `Iterator`, as appropriate.
  final DartType _yieldElementContext;

  @override
  DartType get returnContext => const UnknownType();

  @override
  DartType get yieldContext => _yieldElementContext;

  final DartType _declaredReturnType;

  final bool _needToInferReturnType;

  /// A list of return expression types in functions whose return type is
  /// being inferred.
  List<DartType>? _yieldElementTypes;

  @override
  DartType? get futureValueType => null;

  _SyncStarClosureContext(this._yieldElementContext, this._declaredReturnType,
      this._needToInferReturnType) {
    if (_needToInferReturnType) {
      _yieldElementTypes = [];
    }
  }

  /// Updates the inferred return type based on the presence of a return
  /// statement returning the given [type].
  @override
  void handleReturn(TypeInferrerImpl inferrer, ReturnStatement statement,
      DartType type, bool isArrow) {}

  @override
  void handleYield(TypeInferrerImpl inferrer, YieldStatement node,
      ExpressionInferenceResult expressionResult) {
    DartType expectedType = node.isYieldStar
        ? inferrer.wrapType(_yieldElementContext,
            inferrer.coreTypes.iterableClass, inferrer.library.nonNullable)
        : _yieldElementContext;
    Expression expression = inferrer.ensureAssignableResult(
        expectedType, expressionResult,
        fileOffset: node.fileOffset);
    node.expression = expression..parent = node;
    DartType type = expressionResult.inferredType;
    if (!identical(expressionResult.expression, expression)) {
      type = inferrer.computeGreatestClosure(expectedType);
    }
    if (_needToInferReturnType) {
      DartType elementType = type;
      if (node.isYieldStar) {
        elementType = inferrer.getDerivedTypeArgumentOf(
                type, inferrer.coreTypes.iterableClass) ??
            elementType;
      }
      _yieldElementTypes!.add(elementType);
    }
  }

  @override
  DartType inferReturnType(TypeInferrerImpl inferrer,
      {required bool hasImplicitReturn}) {
    assert(_needToInferReturnType);
    // ignore: unnecessary_null_comparison
    assert(hasImplicitReturn != null);
    DartType? inferredElementType;
    if (_yieldElementTypes!.isNotEmpty) {
      // Use the types seen from the explicit return statements.
      for (int i = 0; i < _yieldElementTypes!.length; i++) {
        DartType type = _yieldElementTypes![i];
        if (inferredElementType == null) {
          inferredElementType = type;
        } else {
          inferredElementType = inferrer.typeSchemaEnvironment
              .getStandardUpperBound(
                  inferredElementType, type, inferrer.library.library);
        }
      }
    } else if (hasImplicitReturn) {
      // No explicit returns we have an implicit `return null`.
      inferredElementType = const NullType();
    } else {
      // No explicit return and the function doesn't complete normally; that is,
      // it throws.
      if (inferrer.isNonNullableByDefault) {
        inferredElementType =
            NeverType.fromNullability(inferrer.library.nonNullable);
      } else {
        inferredElementType = const NullType();
      }
    }

    DartType inferredType = inferrer.wrapType(inferredElementType!,
        inferrer.coreTypes.iterableClass, inferrer.library.nonNullable);

    if (!inferrer.typeSchemaEnvironment.isSubtypeOf(inferredType,
        _yieldElementContext, SubtypeCheckMode.withNullabilities)) {
      // If the inferred return type isn't a subtype of the context, we use the
      // context.
      inferredType = inferrer.computeGreatestClosure2(_declaredReturnType);
    }

    return demoteTypeInLibrary(inferredType, inferrer.library.library);
  }

  @override
  StatementInferenceResult handleImplicitReturn(
      TypeInferrerImpl inferrer,
      Statement body,
      StatementInferenceResult inferenceResult,
      int fileOffset) {
    // There is no implicit return.
    return inferenceResult;
  }
}

/// Keeps track of information about the innermost function or closure being
/// inferred.
class _AsyncStarClosureContext implements ClosureContext {
  @override
  bool get isAsync => true;

  /// The typing expectation for the subexpression of a `return` or `yield`
  /// statement inside the function.
  ///
  /// For non-generator async functions, this will be a "FutureOr" type (since
  /// it is permissible for such a function to return either a direct value or
  /// a future).
  ///
  /// For generator functions containing a `yield*` statement, the expected type
  /// for the subexpression of the `yield*` statement is the result of wrapping
  /// this typing expectation in `Stream` or `Iterator`, as appropriate.
  final DartType _yieldElementContext;

  @override
  DartType get returnContext => const UnknownType();

  @override
  DartType get yieldContext => _yieldElementContext;

  final DartType _declaredReturnType;

  final bool _needToInferReturnType;

  /// A list of return expression types in functions whose return type is
  /// being inferred.
  List<DartType>? _yieldElementTypes;

  @override
  DartType? get futureValueType => null;

  _AsyncStarClosureContext(this._yieldElementContext, this._declaredReturnType,
      this._needToInferReturnType) {
    if (_needToInferReturnType) {
      _yieldElementTypes = [];
    }
  }

  /// Updates the inferred return type based on the presence of a return
  /// statement returning the given [type].
  @override
  void handleReturn(TypeInferrerImpl inferrer, ReturnStatement statement,
      DartType type, bool isArrow) {}

  @override
  void handleYield(TypeInferrerImpl inferrer, YieldStatement node,
      ExpressionInferenceResult expressionResult) {
    DartType expectedType = node.isYieldStar
        ? inferrer.wrapType(_yieldElementContext,
            inferrer.coreTypes.streamClass, inferrer.library.nonNullable)
        : _yieldElementContext;

    Expression expression = inferrer.ensureAssignableResult(
        expectedType, expressionResult,
        fileOffset: node.fileOffset);
    node.expression = expression..parent = node;
    DartType type = expressionResult.inferredType;
    if (!identical(expressionResult.expression, expression)) {
      type = inferrer.computeGreatestClosure(expectedType);
    }
    if (_needToInferReturnType) {
      DartType elementType = type;
      if (node.isYieldStar) {
        elementType = inferrer.getDerivedTypeArgumentOf(
                type, inferrer.coreTypes.streamClass) ??
            type;
      }
      _yieldElementTypes!.add(elementType);
    }
  }

  @override
  DartType inferReturnType(TypeInferrerImpl inferrer,
      {required bool hasImplicitReturn}) {
    assert(_needToInferReturnType);
    // ignore: unnecessary_null_comparison
    assert(hasImplicitReturn != null);
    DartType? inferredElementType;
    if (_yieldElementTypes!.isNotEmpty) {
      // Use the types seen from the explicit return statements.
      for (DartType elementType in _yieldElementTypes!) {
        if (inferredElementType == null) {
          inferredElementType = elementType;
        } else {
          inferredElementType = inferrer.typeSchemaEnvironment
              .getStandardUpperBound(
                  inferredElementType, elementType, inferrer.library.library);
        }
      }
    } else if (hasImplicitReturn) {
      // No explicit returns we have an implicit `return null`.
      inferredElementType = const NullType();
    } else {
      // No explicit return and the function doesn't complete normally; that is,
      // it throws.
      if (inferrer.isNonNullableByDefault) {
        inferredElementType =
            NeverType.fromNullability(inferrer.library.nonNullable);
      } else {
        inferredElementType = const NullType();
      }
    }

    DartType inferredType = inferrer.wrapType(inferredElementType!,
        inferrer.coreTypes.streamClass, inferrer.library.nonNullable);

    if (!inferrer.typeSchemaEnvironment.isSubtypeOf(inferredType,
        _yieldElementContext, SubtypeCheckMode.withNullabilities)) {
      // If the inferred return type isn't a subtype of the context, we use the
      // context.
      inferredType = inferrer.computeGreatestClosure2(_declaredReturnType);
    }

    return demoteTypeInLibrary(inferredType, inferrer.library.library);
  }

  @override
  StatementInferenceResult handleImplicitReturn(
      TypeInferrerImpl inferrer,
      Statement body,
      StatementInferenceResult inferenceResult,
      int fileOffset) {
    // There is no implicit return.
    return inferenceResult;
  }
}
