// Copyright (c) 2012, 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.

// @dart = 2.7

library type_substitution_test;

import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common/elements.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart';
import '../helpers/type_test_helper.dart';

DartType getType(ElementEnvironment elementEnvironment, String name) {
  ClassEntity cls =
      elementEnvironment.lookupClass(elementEnvironment.mainLibrary, 'Class');
  FunctionEntity element = elementEnvironment.lookupClassMember(cls, name);
  Expect.isNotNull(element);
  FunctionType type = elementEnvironment.getFunctionType(element);

  // Function signatures are used to be to provide void types (only occurring as
  // as return types) and (inlined) function types (only occurring as method
  // parameter types).
  //
  // Only a single type is used from each signature. That is, it is not the
  // intention to check the whole signatures against eachother.
  if (type.parameterTypes.isEmpty) {
    // If parameters is empty, use return type.
    return type.returnType;
  } else {
    // Otherwise use the first argument type.
    return type.parameterTypes.first;
  }
}

void main() {
  asyncTest(() async {
    await testAsInstanceOf();
    await testTypeSubstitution();
  });
}

testAsInstanceOf() async {
  var env = await TypeEnvironment.create('''
      class A<T> {}
      class B<T> {}
      class C<T> extends A<T> {}
      class D<T> extends A<int> {}
      class E<T> extends A<A<T>> {}
      class F<T, U> extends B<F<T, String>> implements A<F<B<U>, int>> {}

      main() {
        new A();
        new B();
        new C();
        new D();
        new E();
        new F();
      }
      ''', options: [Flags.noSoundNullSafety]);
  var types = env.types;
  ClassEntity A = env.getElement("A");
  ClassEntity B = env.getElement("B");
  ClassEntity C = env.getElement("C");
  ClassEntity D = env.getElement("D");
  ClassEntity E = env.getElement("E");
  ClassEntity F = env.getElement("F");

  DartType intType = env['int'];
  DartType stringType = env['String'];

  InterfaceType C_int = env.instantiate(C, [intType]);
  Expect.equals(env.instantiate(C, [intType]), C_int);
  Expect.equals(env.instantiate(A, [intType]), types.asInstanceOf(C_int, A));

  InterfaceType D_int = env.instantiate(D, [stringType]);
  Expect.equals(env.instantiate(A, [intType]), types.asInstanceOf(D_int, A));

  InterfaceType E_int = env.instantiate(E, [intType]);
  Expect.equals(
      env.instantiate(A, [
        env.instantiate(A, [intType])
      ]),
      types.asInstanceOf(E_int, A));

  InterfaceType F_int_string = env.instantiate(F, [intType, stringType]);
  Expect.equals(
      env.instantiate(B, [
        env.instantiate(F, [intType, stringType])
      ]),
      types.asInstanceOf(F_int_string, B));
  Expect.equals(
      env.instantiate(A, [
        env.instantiate(F, [
          env.instantiate(B, [stringType]),
          intType
        ])
      ]),
      types.asInstanceOf(F_int_string, A));
}

/**
 * Test that substitution of [parameters] by [arguments] in the type found
 * through [name1] is the same as the type found through [name2].
 */
void testSubstitution(
    DartTypes dartTypes,
    ElementEnvironment elementEnvironment,
    List<DartType> arguments,
    List<DartType> parameters,
    DartType type1,
    DartType type2) {
  DartType subst = dartTypes.subst(arguments, parameters, type1);
  Expect.equals(
      type2, subst, "$type1.subst($arguments,$parameters)=$subst != $type2");
}

testTypeSubstitution() async {
  var env = await TypeEnvironment.create(r"""
      class Class<T,S> {}

      main() => new Class();
      """, options: [Flags.noSoundNullSafety]);
  var types = env.types;
  InterfaceType Class_T_S = env["Class"];
  Expect.isNotNull(Class_T_S);
  Expect.isTrue(Class_T_S is InterfaceType);
  Expect.equals(2, Class_T_S.typeArguments.length);

  DartType T = Class_T_S.typeArguments[0];
  Expect.isNotNull(T);
  Expect.isTrue(T is TypeVariableType);

  DartType S = Class_T_S.typeArguments[1];
  Expect.isNotNull(S);
  Expect.isTrue(S is TypeVariableType);

  DartType intType = env['int'];
  Expect.isNotNull(intType);
  Expect.isTrue(intType is InterfaceType);

  DartType StringType = env['String'];
  Expect.isNotNull(StringType);
  Expect.isTrue(StringType is InterfaceType);

  ClassEntity ListClass = env.getElement('List');
  ClassEntity MapClass = env.getElement('Map');

  List<DartType> parameters = <DartType>[T, S];
  List<DartType> arguments = <DartType>[intType, StringType];

  testSubstitution(types, env.elementEnvironment, arguments, parameters,
      types.voidType(), types.voidType());
  testSubstitution(types, env.elementEnvironment, arguments, parameters,
      types.dynamicType(), types.dynamicType());
  testSubstitution(
      types, env.elementEnvironment, arguments, parameters, intType, intType);
  testSubstitution(types, env.elementEnvironment, arguments, parameters,
      StringType, StringType);
  testSubstitution(
      types,
      env.elementEnvironment,
      arguments,
      parameters,
      env.instantiate(ListClass, [intType]),
      env.instantiate(ListClass, [intType]));
  testSubstitution(types, env.elementEnvironment, arguments, parameters,
      env.instantiate(ListClass, [T]), env.instantiate(ListClass, [intType]));
  testSubstitution(
      types,
      env.elementEnvironment,
      arguments,
      parameters,
      env.instantiate(ListClass, [S]),
      env.instantiate(ListClass, [StringType]));
  testSubstitution(
      types,
      env.elementEnvironment,
      arguments,
      parameters,
      env.instantiate(ListClass, [
        env.instantiate(ListClass, [T])
      ]),
      env.instantiate(ListClass, [
        env.instantiate(ListClass, [intType])
      ]));
  testSubstitution(
      types,
      env.elementEnvironment,
      arguments,
      parameters,
      env.instantiate(ListClass, [types.dynamicType()]),
      env.instantiate(ListClass, [types.dynamicType()]));
  testSubstitution(
      types,
      env.elementEnvironment,
      arguments,
      parameters,
      env.instantiate(MapClass, [intType, StringType]),
      env.instantiate(MapClass, [intType, StringType]));
  testSubstitution(
      types,
      env.elementEnvironment,
      arguments,
      parameters,
      env.instantiate(MapClass, [T, StringType]),
      env.instantiate(MapClass, [intType, StringType]));
  testSubstitution(
      types,
      env.elementEnvironment,
      arguments,
      parameters,
      env.instantiate(MapClass, [types.dynamicType(), StringType]),
      env.instantiate(MapClass, [types.dynamicType(), StringType]));
  testSubstitution(
      types, env.elementEnvironment, arguments, parameters, T, intType);
  testSubstitution(
      types, env.elementEnvironment, arguments, parameters, S, StringType);
  testSubstitution(
      types,
      env.elementEnvironment,
      arguments,
      parameters,
      types.functionType(intType, [StringType], [], [], {}, [], []),
      types.functionType(intType, [StringType], [], [], {}, [], []));
  testSubstitution(
      types,
      env.elementEnvironment,
      arguments,
      parameters,
      types.functionType(types.voidType(), [T, S], [], [], {}, [], []),
      types.functionType(
          types.voidType(), [intType, StringType], [], [], {}, [], []));
  testSubstitution(
      types,
      env.elementEnvironment,
      arguments,
      parameters,
      types.functionType(
          types.voidType(), [types.dynamicType()], [], [], {}, [], []),
      types.functionType(
          types.voidType(), [types.dynamicType()], [], [], {}, [], []));
}
