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

/// @assertion We allow explicit instantiation of tear-offs and type literals, by allowing type arguments where we would otherwise do implicit instantiation of tear-offs, or after type literals. Examples:
///
/// typedef ListList<T> = List<List<T>>;
/// T top<T>(T value) => value;
/// class C {
///   static T stat<T>(T value) => value;
///   T inst<T>(T value) => value;
///   void method() {
///     var f1 = stat<int>;
///     var f1TypeName = stat<int>.runtimeType.toString();
///     var f2 = inst<int>;
///     var f2TypeName = inst<int>.runtimeType.toString();
///     var f3 = this.inst<int>;
///     var f3TypeName = this.inst<int>.runtimeType.toString();
///   }
/// }
/// mixin M on C {
///   static T mstat<T>(T value) => value;
///   T minst<T>(T value) => value;
///   void mmethod() {
///     var f1 = mstat<int>;
///     var f1TypeName = mstat<int>.runtimeType.toString();
///     var f2 = minst<int>;
///     var f2TypeName = minst<int>.runtimeType.toString();
///     var f3 = this.minst<int>;
///     var f3TypeName = this.minst<int>.runtimeType.toString();
///   }
/// }
/// extension Ext on C {
///   static T estat<T>(T value) => value;
///   T einst<T>(T value) => value;
///   void emethod() {
///     var f1 = estat<int>; // works like (int $) => Ext.estat<int>($)
///     var f1TypeName = estat<int>.runtimeType.toString();
///     var f2 = einst<int>; // works like (int $) => Ext(this).einst<int>($)
///     var f2TypeName = einst<int>.runtimeType.toString();
///     var f3 = this.einst<int>; // works like (int $) => Ext(this).einst<int>($)
///     var f3TypeName = this.einst<int>.runtimeType.toString();
///   }
/// }
/// class D extends C with M {
///   void method() {
///     var f4 = super.inst<int>; // works like (int $) => super.inst<int>($)
///     var f4TypeName = super.inst<int>.runtimeType.toString();
///   }
/// }
/// void main() {
///   // Type literals.
///   var t1 = List<int>; // Type object for `List<int>`.
///   var t2 = ListList<int>; // Type object for `List<List<int>>`.
///
///   // Instantiated function tear-offs.
///   T local<T>(T value) => value;
///
///   const f1 = top<int>; // int Function(int), works like (int $) => top<int>($);
///   const f2 = C.stat<int>; // int Function(int), works like (int $) => C.stat<int>($);
///   var f3 = local<int>; // int Function(int), works like (int $) => local<int>($);
///   var d = D();
///   var f4 = d.inst<int>; // int Function(int), works like (int $) => c.inst<int>($);
///   var f5 = d.minst<int>; // int Function(int), works like (int $) => c.minst<int>($);
///   var f6 = d.einst<int>; // int Function(int), works like (int $) => Ext(c).einst<int>($);
///
///   var typeName = List<int>.toString();
///   var functionTypeName = local<int>.runtimeType.toString();
/// }
///
/// @description Checks an example from the specification
/// @author sgrekhov@unipro.ru

// SharedOptions=--enable-experiment=constructor-tearoffs

import "../../Utils/expect.dart";

typedef ListList<T> = List<List<T>>;
T top<T>(T value) => value;

typedef int Func(int i);

class C {
  static T stat<T>(T value) => value;
  T inst<T>(T value) => value;
}

Type typeOf<X>() => X;

void main() {
  // Type literals.
  var t1 = List<int>; // Type object for `List<int>`.
  Expect.isTrue(t1 is Type);
  Expect.isFalse(t1 is Function);
  Expect.runtimeIsType<Type>(t1);
  Expect.runtimeIsNotType<Function>(t1);
  Expect.isTrue(typeOf<List<int>>() == t1);

  var t2 = ListList<int>; // Type object for `List<List<int>>`.
  Expect.isTrue(t2 is Type);
  Expect.isFalse(t2 is Function);
  Expect.runtimeIsType<Type>(t2);
  Expect.runtimeIsNotType<Function>(t2);
  Expect.isTrue(typeOf<List<List<int>>>() == t2);

  // Instantiated function tear-offs.
  T local<T>(T value) => value;

  const f1 = top<int>; // int Function(int), works like (int $) => top<int>($);
  Expect.isTrue(f1 is Func);
  Expect.runtimeIsType<Func>(f1);

  const f2 = C.stat<int>; // int Function(int), works like (int $) => C.stat<int>($);
  Expect.isTrue(f2 is Func);
  Expect.runtimeIsType<Func>(f2);

  var f3 = local<int>; // int Function(int), works like (int $) => local<int>($);
  Expect.isTrue(f3 is Func);
  Expect.runtimeIsType<Func>(f3);

  var typeName = (List<int>).toString();
  Expect.equals("List<int>", typeName);

  var functionTypeName = local<int>.runtimeType.toString();
  Expect.equals("(int) => int", functionTypeName);
}
