// 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 file.

import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/element/generic_inferrer.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/resolver/variance.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' show toUri;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../../generated/type_system_test.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ConstraintMatchingTest);
    defineReflectiveTests(GenericFunctionInferenceTest);
  });
}

@reflectiveTest
class ConstraintMatchingTest extends AbstractTypeSystemNullSafetyTest {
  TypeParameterElement T;
  TypeParameterType T_none;
  TypeParameterType T_question;

  @override
  void setUp() {
    super.setUp();
    T = typeParameter('T');
    T_none = typeParameterTypeNone(T);
    T_question = typeParameterTypeQuestion(T);
  }

  void test_function_coreFunction() {
    _checkOrdinarySubtypeMatch(
      functionTypeNone(
        returnType: voidNone,
      ),
      typeProvider.functionType,
      [T],
      covariant: true,
    );
  }

  void test_function_parameters_requiredPositional() {
    _checkIsSubtypeMatchOf(
      functionTypeNone(
        parameters: [
          requiredParameter(type: T_none),
        ],
        returnType: intNone,
      ),
      functionTypeNone(
        parameters: [
          requiredParameter(type: stringNone),
        ],
        returnType: intNone,
      ),
      [T],
      ['String <: T'],
      covariant: true,
    );
  }

  void test_function_returnType() {
    _checkIsSubtypeMatchOf(
      functionTypeNone(
        parameters: [
          requiredParameter(type: intNone),
        ],
        returnType: T_none,
      ),
      functionTypeNone(
        parameters: [
          requiredParameter(type: intNone),
        ],
        returnType: stringNone,
      ),
      [T],
      ['T <: String'],
      covariant: true,
    );
  }

  /// Left FutureOr: if `T0` is `FutureOr<S0>` then:
  /// * `T0 <: T1` iff `Future<S0> <: T1` and `S0 <: T1`
  void test_futureOr_left() {
    _checkIsSubtypeMatchOf(
      futureOrNone(T_none),
      futureOrNone(stringNone),
      [T],
      ['T <: String'],
      covariant: true,
    );

    _checkIsSubtypeMatchOf(
      futureOrNone(T_none),
      futureNone(stringNone),
      [T],
      ['T <: String', 'T <: Future<String>'],
      covariant: true,
    );

    // Future<List<T>> <: List<String> can't be satisfied
    _checkIsNotSubtypeMatchOf(
      futureOrNone(listNone(T_none)),
      listNone(stringNone),
      [T],
      covariant: true,
    );

    // List<T> <: Future<List<String>> can't be satisfied
    _checkIsNotSubtypeMatchOf(
      futureOrNone(listNone(T_none)),
      futureNone(listNone(stringNone)),
      [T],
      covariant: true,
    );
  }

  void test_futureOr_right_both_noConstraints() {
    // `Future<String> <: Future<Object>` can be satisfied:
    //    * no constraints
    //
    // `Future<String> <: Object` can be satisfied:
    //    * no constraints
    _checkIsSubtypeMatchOf(
      futureNone(stringNone),
      futureOrNone(objectNone),
      [T],
      [],
      covariant: true,
    );
  }

  void test_futureOr_right_both_prefer_future() {
    // `Future<String> <: Future<T>` can be satisfied:
    //    * `String <: T`
    //
    // `Future<String> <: T` can be satisfied:
    //    * `Future<String> <: T`
    //
    // We prefer `String <: T`.
    _checkIsSubtypeMatchOf(
      futureNone(stringNone),
      futureOrNone(T_none),
      [T],
      ['String <: T'],
      covariant: false,
    );

    // `Future<T> <: Future<Object>` can be satisfied:
    //   * `T <: Object`
    //
    // `Future<T> <: Object` can be satisfied:
    //   * no constraints
    //
    // We prefer `T <: Object`.
    _checkIsSubtypeMatchOf(
      futureNone(T_none),
      futureOrNone(objectNone),
      [T],
      ['T <: Object'],
      covariant: true,
    );
  }

  /// Right FutureOr: if `T1` is `FutureOr<S1>` then:
  /// `T0 <: T1` iff any of the following hold:
  /// * either `T0 <: Future<S1>`
  /// * or `T0 <: S1`
  void test_futureOr_right_none() {
    // `List<T> <: Future<String>` cannot be satisfied.
    // `List<T> <: int` cannot be satisfied.
    _checkIsNotSubtypeMatchOf(
      listNone(T_none),
      futureOrNone(stringNone),
      [T],
      covariant: true,
    );
  }

  void test_futureOr_right_single_future() {
    // `Future<T> <: Future<String>` can be satisfied:
    //    * `T <: String`
    //
    // `Future<T> <: String` cannot be satisfied.
    _checkIsSubtypeMatchOf(
      futureNone(T_none),
      futureOrNone(stringNone),
      [T],
      ['T <: String'],
      covariant: true,
    );
  }

  void test_futureOr_right_single_nonFuture() {
    // `List<T> <: Future<List<String>>` cannot be satisfied.
    //
    // `List<T> <: List<String>` can be satisfied:
    //    * `T <: String`
    _checkIsSubtypeMatchOf(
      listNone(T_none),
      futureOrNone(listNone(stringNone)),
      [T],
      ['T <: String'],
      covariant: true,
    );
  }

  void test_futureOr_right_single_nonFuture_null() {
    // `Null <: Future<T>` can be satisfied:
    //    * no constraints
    //
    // `Null <: T` can be satisfied:
    //    * `Null <: T`
    //
    // We prefer `Null <: T`.
    _checkIsSubtypeMatchOf(
      nullNone,
      futureOrNone(T_none),
      [T],
      ['Null <: T'],
      covariant: false,
    );
  }

  void test_interfaceType_interface_left() {
    _checkIsNotSubtypeMatchOf(
      iterableNone(T_none),
      listNone(stringNone),
      [T],
      covariant: true,
    );
  }

  void test_interfaceType_interface_right() {
    _checkIsSubtypeMatchOf(
      listNone(T_none),
      iterableNone(stringNone),
      [T],
      ['T <: String'],
      covariant: true,
    );
  }

  void test_interfaceType_sameClass() {
    _checkIsSubtypeMatchOf(
      listNone(T_none),
      listNone(stringNone),
      [T],
      ['T <: String'],
      covariant: true,
    );
  }

  void test_interfaceType_topMerge() {
    var testClassIndex = 0;

    void check1(
      DartType extendsTypeArgument,
      DartType implementsTypeArgument,
      String expectedConstraint,
    ) {
      var library = library_(
        uriStr: 'package:test/test.dart',
        analysisSession: analysisContext.analysisSession,
        typeSystem: typeSystem,
      );

      // class A<T> {}
      var A = class_(name: 'A', typeParameters: [
        typeParameter('T'),
      ]);
      A.enclosingElement = library.definingCompilationUnit;

      // class B<T> extends A<T> {}
      var B_T = typeParameter('T');
      var B_T_none = typeParameterTypeNone(B_T);
      var B = class_(
        name: 'B',
        typeParameters: [B_T],
        superType: interfaceTypeNone(A, typeArguments: [B_T_none]),
      );
      B.enclosingElement = library.definingCompilationUnit;

      // class Cx extends A<> implements B<> {}
      var C = class_(
        name: 'C${testClassIndex++}',
        superType: interfaceTypeNone(
          A,
          typeArguments: [extendsTypeArgument],
        ),
        interfaces: [
          interfaceTypeNone(
            B,
            typeArguments: [implementsTypeArgument],
          )
        ],
      );
      C.enclosingElement = library.definingCompilationUnit;

      _checkIsSubtypeMatchOf(
        interfaceTypeNone(C),
        interfaceTypeNone(A, typeArguments: [T_none]),
        [T],
        [expectedConstraint],
        covariant: false,
      );
    }

    void check(
      DartType typeArgument1,
      DartType typeArgument2,
      String expectedConstraint,
    ) {
      check1(typeArgument1, typeArgument2, expectedConstraint);
      check1(typeArgument2, typeArgument1, expectedConstraint);
    }

    check(objectQuestion, dynamicNone, 'Object? <: T');
    check(objectStar, dynamicNone, 'Object? <: T');
    check(voidNone, objectQuestion, 'Object? <: T');
    check(voidNone, objectStar, 'Object? <: T');
  }

  void test_left_null() {
    // Null <: T is trivially satisfied by the constraint Null <: T.
    _checkIsSubtypeMatchOf(nullNone, T_none, [T], ['Null <: T'],
        covariant: false);

    // For any other type X, Null <: X is satisfied without the need for any
    // constraints.
    _checkOrdinarySubtypeMatch(nullNone, listQuestion(T_none), [T],
        covariant: false);
    _checkOrdinarySubtypeMatch(nullNone, stringQuestion, [T], covariant: false);
    _checkOrdinarySubtypeMatch(nullNone, voidNone, [T], covariant: false);
    _checkOrdinarySubtypeMatch(nullNone, dynamicNone, [T], covariant: false);
    _checkOrdinarySubtypeMatch(nullNone, objectQuestion, [T], covariant: false);
    _checkOrdinarySubtypeMatch(nullNone, nullNone, [T], covariant: false);
    _checkOrdinarySubtypeMatch(
      nullNone,
      functionTypeQuestion(returnType: voidNone),
      [T],
      covariant: false,
    );
  }

  void test_right_dynamic() {
    // T <: dynamic is trivially satisfied by the constraint T <: dynamic.
    _checkIsSubtypeMatchOf(T_none, dynamicNone, [T], ['T <: dynamic'],
        covariant: true);

    // For any other type X, X <: dynamic is satisfied without the need for any
    // constraints.
    _checkOrdinarySubtypeMatch(listNone(T_none), dynamicNone, [T],
        covariant: true);
    _checkOrdinarySubtypeMatch(stringNone, dynamicNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(voidNone, dynamicNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(dynamicNone, dynamicNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(objectNone, dynamicNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(nullNone, dynamicNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(
      functionTypeNone(
        parameters: [
          requiredParameter(type: intNone),
        ],
        returnType: stringNone,
      ),
      dynamicNone,
      [T],
      covariant: true,
    );
  }

  void test_right_object() {
    // T <: Object is trivially satisfied by the constraint T <: Object.
    _checkIsSubtypeMatchOf(T_none, objectNone, [T], ['T <: Object'],
        covariant: true);

    // For any other type X, X <: Object is satisfied without the need for any
    // constraints.
    _checkOrdinarySubtypeMatch(listNone(T_none), objectNone, [T],
        covariant: true);
    _checkOrdinarySubtypeMatch(stringNone, objectNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(voidNone, objectNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(dynamicNone, objectNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(objectNone, objectNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(nullNone, objectNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(
      functionTypeNone(
        parameters: [
          requiredParameter(type: intNone),
        ],
        returnType: stringNone,
      ),
      objectNone,
      [T],
      covariant: true,
    );
  }

  void test_right_void() {
    // T <: void is trivially satisfied by the constraint T <: void.
    _checkIsSubtypeMatchOf(T_none, voidNone, [T], ['T <: void'],
        covariant: true);

    // For any other type X, X <: void is satisfied without the need for any
    // constraints.
    _checkOrdinarySubtypeMatch(listNone(T_none), voidNone, [T],
        covariant: true);
    _checkOrdinarySubtypeMatch(stringNone, voidNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(voidNone, voidNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(dynamicNone, voidNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(objectNone, voidNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(nullNone, voidNone, [T], covariant: true);
    _checkOrdinarySubtypeMatch(
      functionTypeNone(
        parameters: [
          requiredParameter(type: intNone),
        ],
        returnType: stringNone,
      ),
      voidNone,
      [T],
      covariant: true,
    );
  }

  void test_typeParameter_left_covariant() {
    // When doing a covariant match, the type parameters we're trying to find
    // types for are on the left hand side.
    _checkIsSubtypeMatchOf(T_none, stringNone, [T], ['T <: String'],
        covariant: true);
  }

  void test_typeParameter_left_covariant_match() {
    // When doing a covariant match, the type parameters we're trying to find
    // types for are on the left hand side.  If a type parameter appears on the
    // right hand side, there is a condition in which the constraint can be
    // satisfied: where both parameters appear at corresponding locations in the
    // type tree.
    //
    // In other words, T <: S can be satisfied trivially by the constraint
    // T <: S.
    var S = typeParameter('S');
    var S_none = typeParameterTypeNone(S);
    _checkIsSubtypeMatchOf(T_none, S_none, [T], ['T <: S'], covariant: true);
  }

  void test_typeParameter_left_covariant_no_match() {
    // When doing a covariant match, the type parameters we're trying to find
    // types for are on the left hand side.  If a type parameter appears on the
    // right hand side, it's probable that the constraint can't be satisfied,
    // because there is no possible type for the LHS (other than bottom)
    // that's guaranteed to satisfy the relation for all possible assignments of
    // the RHS type parameter.
    //
    // In other words, no match can be found for List<T> <: S because regardless
    // of T, we can't guarantee that List<T> <: S for all S.
    var S = typeParameter('S');
    var S_none = typeParameterTypeNone(S);
    _checkIsNotSubtypeMatchOf(listNone(T_none), S_none, [T], covariant: true);
  }

  void test_typeParameter_nullable() {
    _checkIsSubtypeMatchOf(T_question, stringQuestion, [T], ['T <: String'],
        covariant: true);

    _checkIsSubtypeMatchOf(stringQuestion, T_question, [T], ['String <: T'],
        covariant: false);
  }

  void test_typeParameter_right_contravariant() {
    // When doing a contravariant match, the type parameters we're trying to
    // find types for are on the right hand side.
    _checkIsSubtypeMatchOf(stringNone, T_none, [T], ['String <: T'],
        covariant: false);
  }

  void test_typeParameter_right_contravariant_direct() {
    // When doing a contravariant match, the type parameters we're trying to
    // find types for are on the right hand side.  If a type parameter also
    // appears on the left hand side, there is a condition in which the
    // constraint can be satisfied without consulting the bound of the LHS type
    // parameter: the condition where both parameters appear at corresponding
    // locations in the type tree.
    //
    // In other words, List<S> <: List<T> is satisfied provided that
    // S <: T.
    var S = typeParameter('S');
    var S_none = typeParameterTypeNone(S);
    _checkIsSubtypeMatchOf(listNone(S_none), listNone(T_none), [T], ['S <: T'],
        covariant: false);
  }

  void test_typeParameter_right_contravariant_via_bound() {
    // When doing a contravariant match, the type parameters we're trying to
    // find types for are on the right hand side.  If a type parameter also
    // appears on the left hand side, we may have to constrain the RHS type
    // parameter using the bounds of the LHS type parameter.
    //
    // In other words, S <: List<T> is satisfied provided that
    // bound(S) <: List<T>.
    var S = typeParameter('S', bound: listNone(stringNone));
    var S_none = typeParameterTypeNone(S);
    _checkIsSubtypeMatchOf(S_none, listNone(T_none), [T], ['String <: T'],
        covariant: false);
  }

  void test_variance_contravariant() {
    // class A<in T>
    var T = typeParameter('T', variance: Variance.contravariant);
    var T_none = typeParameterTypeNone(T);
    var A = class_(name: 'A', typeParameters: [T]);

    _checkIsSubtypeMatchOf(
      interfaceTypeNone(A, typeArguments: [T_none]),
      interfaceTypeNone(A, typeArguments: [numNone]),
      [T],
      ['num <: in T'],
      covariant: true,
    );
  }

  void test_variance_covariant() {
    // class A<out T>
    var T = typeParameter('T', variance: Variance.covariant);
    var T_none = typeParameterTypeNone(T);
    var A = class_(name: 'A', typeParameters: [T]);

    _checkIsSubtypeMatchOf(
      interfaceTypeNone(A, typeArguments: [T_none]),
      interfaceTypeNone(A, typeArguments: [numNone]),
      [T],
      ['out T <: num'],
      covariant: true,
    );
  }

  void test_variance_invariant() {
    // class A<inout T>
    var T = typeParameter('T', variance: Variance.invariant);
    var T_none = typeParameterTypeNone(T);
    var A = class_(name: 'A', typeParameters: [T]);

    _checkIsSubtypeMatchOf(
      interfaceTypeNone(A, typeArguments: [T_none]),
      interfaceTypeNone(A, typeArguments: [numNone]),
      [T],
      ['inout T <: num', 'num <: inout T'],
      covariant: true,
    );
  }

  void _checkIsNotSubtypeMatchOf(
    DartType subtype,
    DartType supertype,
    List<TypeParameterElement> typeFormals, {
    @required bool covariant,
  }) {
    var inferrer = GenericInferrer(typeSystem, typeFormals);

    var success = inferrer.tryMatchSubtypeOf(subtype, supertype, null,
        covariant: covariant);
    expect(success, isFalse);

    inferrer.constraints.forEach((typeParameter, constraints) {
      expect(constraints, isEmpty);
    });
  }

  void _checkIsSubtypeMatchOf(
    DartType subtype,
    DartType supertype,
    List<TypeParameterElement> typeFormals,
    Iterable<String> expectedConstraints, {
    @required bool covariant,
  }) {
    var inferrer = GenericInferrer(typeSystem, typeFormals);

    var success = inferrer.tryMatchSubtypeOf(subtype, supertype, null,
        covariant: covariant);
    expect(success, isTrue);

    var formattedConstraints = <String>[];
    inferrer.constraints.forEach((typeParameter, constraints) {
      for (var constraint in constraints) {
        formattedConstraints.add(
          constraint.format(
            typeParameter.getDisplayString(withNullability: true),
            withNullability: true,
          ),
        );
      }
    });
    expect(formattedConstraints, unorderedEquals(expectedConstraints));
  }

  void _checkOrdinarySubtypeMatch(
    DartType subtype,
    DartType supertype,
    List<TypeParameterElement> typeFormals, {
    @required bool covariant,
  }) {
    var expectSuccess = typeSystem.isSubtypeOf(subtype, supertype);
    if (expectSuccess) {
      _checkIsSubtypeMatchOf(subtype, supertype, typeFormals, [],
          covariant: covariant);
    } else {
      _checkIsNotSubtypeMatchOf(subtype, supertype, typeFormals,
          covariant: covariant);
    }
  }
}

@reflectiveTest
class GenericFunctionInferenceTest extends AbstractTypeSystemNullSafetyTest {
  void test_boundedByAnotherTypeParameter() {
    // <TFrom, TTo extends Iterable<TFrom>>(TFrom) -> TTo
    var tFrom = typeParameter('TFrom');
    var tTo =
        typeParameter('TTo', bound: iterableNone(typeParameterTypeNone(tFrom)));
    var cast = functionTypeNone(
      typeFormals: [tFrom, tTo],
      parameters: [
        requiredParameter(
          type: typeParameterTypeNone(tFrom),
        ),
      ],
      returnType: typeParameterTypeNone(tTo),
    );
    expect(_inferCall(cast, [stringNone]),
        [stringNone, (iterableNone(stringNone))]);
  }

  void test_boundedByOuterClass() {
    // Regression test for https://github.com/dart-lang/sdk/issues/25740.

    // class A {}
    var A = class_(name: 'A', superType: objectNone);
    var typeA = interfaceTypeNone(A);

    // class B extends A {}
    var B = class_(name: 'B', superType: typeA);
    var typeB = interfaceTypeNone(B);

    // class C<T extends A> {
    var CT = typeParameter('T', bound: typeA);
    var C = class_(
      name: 'C',
      superType: objectNone,
      typeParameters: [CT],
    );
    //   S m<S extends T>(S);
    var S = typeParameter('S', bound: typeParameterTypeNone(CT));
    var m = method(
      'm',
      typeParameterTypeNone(S),
      typeFormals: [S],
      parameters: [
        requiredParameter(
          name: '_',
          type: typeParameterTypeNone(S),
        ),
      ],
    );
    C.methods = [m];
    // }

    // C<Object> cOfObject;
    var cOfObject = interfaceTypeNone(C, typeArguments: [objectNone]);
    // C<A> cOfA;
    var cOfA = interfaceTypeNone(C, typeArguments: [typeA]);
    // C<B> cOfB;
    var cOfB = interfaceTypeNone(C, typeArguments: [typeB]);
    // B b;
    // cOfB.m(b); // infer <B>
    _assertType(
        _inferCall2(cOfB.getMethod('m').type, [typeB]), 'B Function(B)');
    // cOfA.m(b); // infer <B>
    _assertType(
        _inferCall2(cOfA.getMethod('m').type, [typeB]), 'B Function(B)');
    // cOfObject.m(b); // infer <B>
    _assertType(
        _inferCall2(cOfObject.getMethod('m').type, [typeB]), 'B Function(B)');
  }

  void test_boundedByOuterClassSubstituted() {
    // Regression test for https://github.com/dart-lang/sdk/issues/25740.

    // class A {}
    var A = class_(name: 'A', superType: objectNone);
    var typeA = interfaceTypeNone(A);

    // class B extends A {}
    var B = class_(name: 'B', superType: typeA);
    var typeB = interfaceTypeNone(B);

    // class C<T extends A> {
    var CT = typeParameter('T', bound: typeA);
    var C = class_(
      name: 'C',
      superType: objectNone,
      typeParameters: [CT],
    );
    //   S m<S extends Iterable<T>>(S);
    var iterableOfT = iterableNone(typeParameterTypeNone(CT));
    var S = typeParameter('S', bound: iterableOfT);
    var m = method(
      'm',
      typeParameterTypeNone(S),
      typeFormals: [S],
      parameters: [
        requiredParameter(
          name: '_',
          type: typeParameterTypeNone(S),
        ),
      ],
    );
    C.methods = [m];
    // }

    // C<Object> cOfObject;
    var cOfObject = interfaceTypeNone(C, typeArguments: [objectNone]);
    // C<A> cOfA;
    var cOfA = interfaceTypeNone(C, typeArguments: [typeA]);
    // C<B> cOfB;
    var cOfB = interfaceTypeNone(C, typeArguments: [typeB]);
    // List<B> b;
    var listOfB = listNone(typeB);
    // cOfB.m(b); // infer <B>
    _assertType(_inferCall2(cOfB.getMethod('m').type, [listOfB]),
        'List<B> Function(List<B>)');
    // cOfA.m(b); // infer <B>
    _assertType(_inferCall2(cOfA.getMethod('m').type, [listOfB]),
        'List<B> Function(List<B>)');
    // cOfObject.m(b); // infer <B>
    _assertType(_inferCall2(cOfObject.getMethod('m').type, [listOfB]),
        'List<B> Function(List<B>)');
  }

  void test_boundedRecursively() {
    // class A<T extends A<T>>
    var T = typeParameter('T');
    var A = class_(
      name: 'Cloneable',
      superType: objectNone,
      typeParameters: [T],
    );
    T.bound = interfaceTypeNone(
      A,
      typeArguments: [typeParameterTypeNone(T)],
    );

    // class B extends A<B> {}
    var B = class_(name: 'B', superType: null);
    B.supertype = interfaceTypeNone(A, typeArguments: [interfaceTypeNone(B)]);
    var typeB = interfaceTypeNone(B);

    // <S extends A<S>>
    var S = typeParameter('S');
    var typeS = typeParameterTypeNone(S);
    S.bound = interfaceTypeNone(A, typeArguments: [typeS]);

    // (S, S) -> S
    var clone = functionTypeNone(
      typeFormals: [S],
      parameters: [
        requiredParameter(type: typeS),
        requiredParameter(type: typeS),
      ],
      returnType: typeS,
    );
    expect(_inferCall(clone, [typeB, typeB]), [typeB]);

    // Something invalid...
    expect(
      _inferCall(clone, [stringNone, numNone], expectError: true),
      [objectNone],
    );
  }

  void test_genericCastFunction() {
    // <TFrom, TTo>(TFrom) -> TTo
    var tFrom = typeParameter('TFrom');
    var tTo = typeParameter('TTo');
    var cast = functionTypeNone(
      typeFormals: [tFrom, tTo],
      parameters: [
        requiredParameter(
          type: typeParameterTypeNone(tFrom),
        ),
      ],
      returnType: typeParameterTypeNone(tTo),
    );
    expect(_inferCall(cast, [intNone]), [intNone, dynamicNone]);
  }

  void test_genericCastFunctionWithUpperBound() {
    // <TFrom, TTo extends TFrom>(TFrom) -> TTo
    var tFrom = typeParameter('TFrom');
    var tTo = typeParameter(
      'TTo',
      bound: typeParameterTypeNone(tFrom),
    );
    var cast = functionTypeNone(
      typeFormals: [tFrom, tTo],
      parameters: [
        requiredParameter(
          type: typeParameterTypeNone(tFrom),
        ),
      ],
      returnType: typeParameterTypeNone(tTo),
    );
    expect(_inferCall(cast, [intNone]), [intNone, intNone]);
  }

  void test_parameter_contravariantUseUpperBound() {
    // <T>(T x, void Function(T) y) -> T
    // Generates constraints int <: T <: num.
    // Since T is contravariant, choose num.
    var T = typeParameter('T', variance: Variance.contravariant);
    var tFunction = functionTypeNone(
        parameters: [requiredParameter(type: typeParameterTypeNone(T))],
        returnType: voidNone);
    var numFunction = functionTypeNone(
        parameters: [requiredParameter(type: numNone)], returnType: voidNone);
    var function = functionTypeNone(
      typeFormals: [T],
      parameters: [
        requiredParameter(type: typeParameterTypeNone(T)),
        requiredParameter(type: tFunction)
      ],
      returnType: typeParameterTypeNone(T),
    );

    expect(_inferCall(function, [intNone, numFunction]), [numNone]);
  }

  void test_parameter_covariantUseLowerBound() {
    // <T>(T x, void Function(T) y) -> T
    // Generates constraints int <: T <: num.
    // Since T is covariant, choose int.
    var T = typeParameter('T', variance: Variance.covariant);
    var tFunction = functionTypeNone(
        parameters: [requiredParameter(type: typeParameterTypeNone(T))],
        returnType: voidNone);
    var numFunction = functionTypeNone(
        parameters: [requiredParameter(type: numNone)], returnType: voidNone);
    var function = functionTypeNone(
      typeFormals: [T],
      parameters: [
        requiredParameter(type: typeParameterTypeNone(T)),
        requiredParameter(type: tFunction)
      ],
      returnType: typeParameterTypeNone(T),
    );

    expect(_inferCall(function, [intNone, numFunction]), [intNone]);
  }

  void test_parametersToFunctionParam() {
    // <T>(f(T t)) -> T
    var T = typeParameter('T');
    var cast = functionTypeNone(
      typeFormals: [T],
      parameters: [
        requiredParameter(
          type: functionTypeNone(
            parameters: [
              requiredParameter(
                type: typeParameterTypeNone(T),
              ),
            ],
            returnType: dynamicNone,
          ),
        ),
      ],
      returnType: typeParameterTypeNone(T),
    );
    expect(
      _inferCall(cast, [
        functionTypeNone(
          parameters: [
            requiredParameter(type: numNone),
          ],
          returnType: dynamicNone,
        )
      ]),
      [numNone],
    );
  }

  void test_parametersUseLeastUpperBound() {
    // <T>(T x, T y) -> T
    var T = typeParameter('T');
    var cast = functionTypeNone(
      typeFormals: [T],
      parameters: [
        requiredParameter(type: typeParameterTypeNone(T)),
        requiredParameter(type: typeParameterTypeNone(T)),
      ],
      returnType: typeParameterTypeNone(T),
    );
    expect(_inferCall(cast, [intNone, doubleNone]), [numNone]);
  }

  void test_parameterTypeUsesUpperBound() {
    // <T extends num>(T) -> dynamic
    var T = typeParameter('T', bound: numNone);
    var f = functionTypeNone(
      typeFormals: [T],
      parameters: [
        requiredParameter(type: typeParameterTypeNone(T)),
      ],
      returnType: dynamicNone,
    );
    expect(_inferCall(f, [intNone]), [intNone]);
  }

  void test_returnFunctionWithGenericParameter() {
    // <T>(T -> T) -> (T -> void)
    var T = typeParameter('T');
    var f = functionTypeNone(
      typeFormals: [T],
      parameters: [
        requiredParameter(
          type: functionTypeNone(
            parameters: [
              requiredParameter(type: typeParameterTypeNone(T)),
            ],
            returnType: typeParameterTypeNone(T),
          ),
        ),
      ],
      returnType: functionTypeNone(
        parameters: [
          requiredParameter(type: typeParameterTypeNone(T)),
        ],
        returnType: voidNone,
      ),
    );
    expect(
      _inferCall(f, [
        functionTypeNone(
          parameters: [
            requiredParameter(type: numNone),
          ],
          returnType: intNone,
        ),
      ]),
      [intNone],
    );
  }

  void test_returnFunctionWithGenericParameterAndContext() {
    // <T>(T -> T) -> (T -> Null)
    var T = typeParameter('T');
    var f = functionTypeNone(
      typeFormals: [T],
      parameters: [
        requiredParameter(
          type: functionTypeNone(
            parameters: [
              requiredParameter(type: typeParameterTypeNone(T)),
            ],
            returnType: typeParameterTypeNone(T),
          ),
        ),
      ],
      returnType: functionTypeNone(
        parameters: [
          requiredParameter(type: typeParameterTypeNone(T)),
        ],
        returnType: nullNone,
      ),
    );
    expect(
      _inferCall(
        f,
        [],
        returnType: functionTypeNone(
          parameters: [
            requiredParameter(type: numNone),
          ],
          returnType: intNone,
        ),
      ),
      [numNone],
    );
  }

  void test_returnFunctionWithGenericParameterAndReturn() {
    // <T>(T -> T) -> (T -> T)
    var T = typeParameter('T');
    var f = functionTypeNone(
      typeFormals: [T],
      parameters: [
        requiredParameter(
          type: functionTypeNone(
            parameters: [
              requiredParameter(type: typeParameterTypeNone(T)),
            ],
            returnType: typeParameterTypeNone(T),
          ),
        ),
      ],
      returnType: functionTypeNone(
        parameters: [
          requiredParameter(type: typeParameterTypeNone(T)),
        ],
        returnType: typeParameterTypeNone(T),
      ),
    );
    expect(
      _inferCall(f, [
        functionTypeNone(
          parameters: [
            requiredParameter(type: numNone),
          ],
          returnType: intNone,
        )
      ]),
      [intNone],
    );
  }

  void test_returnFunctionWithGenericReturn() {
    // <T>(T -> T) -> (() -> T)
    var T = typeParameter('T');
    var f = functionTypeNone(
      typeFormals: [T],
      parameters: [
        requiredParameter(
          type: functionTypeNone(
            parameters: [
              requiredParameter(type: typeParameterTypeNone(T)),
            ],
            returnType: typeParameterTypeNone(T),
          ),
        ),
      ],
      returnType: functionTypeNone(
        returnType: typeParameterTypeNone(T),
      ),
    );
    expect(
      _inferCall(f, [
        functionTypeNone(
          parameters: [
            requiredParameter(type: numNone),
          ],
          returnType: intNone,
        )
      ]),
      [intNone],
    );
  }

  void test_returnTypeFromContext() {
    // <T>() -> T
    var T = typeParameter('T');
    var f = functionTypeNone(
      typeFormals: [T],
      returnType: typeParameterTypeNone(T),
    );
    expect(_inferCall(f, [], returnType: stringNone), [stringNone]);
  }

  void test_returnTypeWithBoundFromContext() {
    // <T extends num>() -> T
    var T = typeParameter('T', bound: numNone);
    var f = functionTypeNone(
      typeFormals: [T],
      returnType: typeParameterTypeNone(T),
    );
    expect(_inferCall(f, [], returnType: doubleNone), [doubleNone]);
  }

  void test_returnTypeWithBoundFromInvalidContext() {
    // <T extends num>() -> T
    var T = typeParameter('T', bound: numNone);
    var f = functionTypeNone(
      typeFormals: [T],
      returnType: typeParameterTypeNone(T),
    );
    expect(_inferCall(f, [], returnType: stringNone), [neverNone]);
  }

  void test_unifyParametersToFunctionParam() {
    // <T>(f(T t), g(T t)) -> T
    var T = typeParameter('T');
    var cast = functionTypeNone(
      typeFormals: [T],
      parameters: [
        requiredParameter(
          type: functionTypeNone(
            parameters: [
              requiredParameter(
                type: typeParameterTypeNone(T),
              ),
            ],
            returnType: dynamicNone,
          ),
        ),
        requiredParameter(
          type: functionTypeNone(
            parameters: [
              requiredParameter(
                type: typeParameterTypeNone(T),
              ),
            ],
            returnType: dynamicNone,
          ),
        ),
      ],
      returnType: typeParameterTypeNone(T),
    );
    expect(
      _inferCall(cast, [
        functionTypeNone(
          parameters: [
            requiredParameter(type: intNone),
          ],
          returnType: dynamicNone,
        ),
        functionTypeNone(
          parameters: [
            requiredParameter(type: doubleNone),
          ],
          returnType: dynamicNone,
        )
      ]),
      [neverNone],
    );
  }

  void test_unusedReturnTypeIsDynamic() {
    // <T>() -> T
    var T = typeParameter('T');
    var f = functionTypeNone(
      typeFormals: [T],
      returnType: typeParameterTypeNone(T),
    );
    expect(_inferCall(f, []), [dynamicNone]);
  }

  void test_unusedReturnTypeWithUpperBound() {
    // <T extends num>() -> T
    var T = typeParameter('T', bound: numNone);
    var f = functionTypeNone(
      typeFormals: [T],
      returnType: typeParameterTypeNone(T),
    );
    expect(_inferCall(f, []), [numNone]);
  }

  void _assertType(DartType type, String expected) {
    var typeStr = type.getDisplayString(withNullability: false);
    expect(typeStr, expected);
  }

  List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments,
      {DartType returnType, bool expectError = false}) {
    var listener = RecordingErrorListener();

    var reporter = ErrorReporter(
      listener,
      NonExistingSource('/test.dart', toUri('/test.dart'), UriKind.FILE_URI),
      isNonNullableByDefault: false,
    );

    var typeArguments = typeSystem.inferGenericFunctionOrType(
      typeParameters: ft.typeFormals,
      parameters: ft.parameters,
      declaredReturnType: ft.returnType,
      argumentTypes: arguments,
      contextReturnType: returnType,
      errorReporter: reporter,
      errorNode: astFactory.nullLiteral(KeywordToken(Keyword.NULL, 0)),
    );

    if (expectError) {
      expect(listener.errors.map((e) => e.errorCode).toList(),
          [StrongModeCode.COULD_NOT_INFER],
          reason: 'expected exactly 1 could not infer error.');
    } else {
      expect(listener.errors, isEmpty, reason: 'did not expect any errors.');
    }
    return typeArguments;
  }

  FunctionType _inferCall2(FunctionTypeImpl ft, List<DartType> arguments,
      {DartType returnType, bool expectError = false}) {
    var typeArguments = _inferCall(
      ft,
      arguments,
      returnType: returnType,
      expectError: expectError,
    );
    return ft.instantiate(typeArguments);
  }
}
