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

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

// Tests that constructor tear-offs from type aliases work and
// are canonicalized correctly

import "package:expect/expect.dart";

import "../static_type_helper.dart";

void use(Type type) {}

class C<T> {
  final T x;
  C(this.x);
  C.named(this.x);
}

typedef Special = C<int>; // Not generic. Not proper rename.
typedef Direct<T> = C<T>; // A proper rename
typedef Bounded<T extends num> = C<T>; // Not proper rename.
typedef Wrapping<T> = C<C<T>>; // Not proper rename.
typedef Extra<T, S> = C<T>; // Not proper rename.

class D<S, T> {
  D();
  D.named();
}

typedef Swapped<T, S> = D<S, T>; // Not a proper rename.

void main() {
  // Tear-offs are constant if uninstantiated
  // or if instantiated with a constant type.
  const List<Object> constructors = [
    Special.new,
    Special.named,
    Direct.new,
    Direct.named,
    Bounded.new,
    Bounded.named,
    Wrapping.new,
    Wrapping.named,
    Extra.new,
    Extra.named,
    Direct<int>.new,
    Direct<int>.named,
    Bounded<int>.new,
    Bounded<int>.named,
    Wrapping<int>.new,
    Wrapping<int>.named,
    Extra<int, int>.new,
    Extra<int, int>.named,
    const <C<int> Function(int)>[
      Direct.new,
      Direct.named,
      Bounded.new,
      Bounded.named,
    ],
    const <C<C<int>> Function(C<int>)>[
      Wrapping.new,
      Wrapping.named,
    ],
    const <C<int> Function(int)>[
      Extra.new,
      Extra.named,
    ]
  ];
  Expect.isNotNull(constructors); // Use variable.

  // The static type is as expected.

  Special.new.expectStaticType<Exactly<C<int> Function(int)>>();
  Special.named.expectStaticType<Exactly<C<int> Function(int)>>();

  // Generic tear-off uses the generics of the type alias.
  Direct.new.expectStaticType<Exactly<C<T> Function<T>(T)>>();
  Direct.named.expectStaticType<Exactly<C<T> Function<T>(T)>>();

  Bounded.new.expectStaticType<Exactly<C<T> Function<T extends num>(T)>>();
  Bounded.named.expectStaticType<Exactly<C<T> Function<T extends num>(T)>>();

  Wrapping.new.expectStaticType<Exactly<C<C<T>> Function<T>(C<T>)>>();
  Wrapping.named.expectStaticType<Exactly<C<C<T>> Function<T>(C<T>)>>();

  Extra.new.expectStaticType<Exactly<C<T> Function<T, S>(T)>>();
  Extra.named.expectStaticType<Exactly<C<T> Function<T, S>(T)>>();

  // Instantiated tear-off uses the instantiated aliased type.

  // Explicitly instantiated.
  Direct<int>.new.expectStaticType<Exactly<C<int> Function(int)>>();
  Direct<int>.named.expectStaticType<Exactly<C<int> Function(int)>>();

  Bounded<int>.new.expectStaticType<Exactly<C<int> Function(int)>>();
  Bounded<int>.named.expectStaticType<Exactly<C<int> Function(int)>>();

  Wrapping<int>.new.expectStaticType<Exactly<C<C<int>> Function(C<int>)>>();
  Wrapping<int>.named.expectStaticType<Exactly<C<C<int>> Function(C<int>)>>();

  Extra<int, String>.new.expectStaticType<Exactly<C<int> Function(int)>>();
  Extra<int, String>.named.expectStaticType<Exactly<C<int> Function(int)>>();

  // Implicitly instantiated.
  context<C<int> Function(int)>(
      Direct.new..expectStaticType<Exactly<C<int> Function(int)>>());
  context<C<int> Function(int)>(
      Direct.named..expectStaticType<Exactly<C<int> Function(int)>>());

  context<C<int> Function(int)>(
      Bounded.new..expectStaticType<Exactly<C<int> Function(int)>>());
  context<C<int> Function(int)>(
      Bounded.named..expectStaticType<Exactly<C<int> Function(int)>>());

  context<C<C<int>> Function(C<int>)>(Wrapping.new
    ..expectStaticType<Exactly<C<C<int>> Function(C<int>)>>());
  context<C<C<int>> Function(C<int>)>(Wrapping.named
    ..expectStaticType<Exactly<C<C<int>> Function(C<int>)>>());

  context<C<int> Function(int)>(Extra.new
    ..expectStaticType<Exactly<C<int> Function(int)>>());
  context<C<int> Function(int)>(Extra.named
    ..expectStaticType<Exactly<C<int> Function(int)>>());

  // Uninstantiated tear-offs always canonicalize.
  Expect.identical(Direct.new, Direct.new);
  Expect.identical(Direct.named, Direct.named);
  Expect.identical(Bounded.new, Bounded.new);
  Expect.identical(Bounded.named, Bounded.named);
  Expect.identical(Wrapping.new, Wrapping.new);
  Expect.identical(Wrapping.named, Wrapping.named);
  Expect.identical(Extra.new, Extra.new);
  Expect.identical(Extra.named, Extra.named);

  // Here the type is the same, and the alias is a proper rename.
  Expect.identical(Direct.named, C.named);
  Expect.identical(Direct.new, C.new);

  // The next are unsurprising since the types are different.
  Expect.notEquals(Bounded.named, C.named);
  Expect.notEquals(Bounded.new, C.new);

  Expect.notEquals(Wrapping.named, C.named);
  Expect.notEquals(Wrapping.new, C.new);

  Expect.notEquals(Extra.named, C.named);
  Expect.notEquals(Extra.new, C.new);

  Expect.notEquals(Swapped.new, D.new);
  Expect.notEquals(Swapped.named, D.named);

  // Instantiated alias tear-offs are canonicalized along with direct tear-offs
  // when instantiation uses constant types.

  // Explicit instantiation.
  Expect.identical(Special.new, C<int>.new);
  Expect.identical(Special.named, C<int>.named);

  Expect.identical(Direct<int>.new, C<int>.new);
  Expect.identical(Direct<int>.named, C<int>.named);
  Expect.identical(Bounded<int>.new, C<int>.new);
  Expect.identical(Bounded<int>.named, C<int>.named);
  Expect.identical(Wrapping<int>.new, C<C<int>>.new);
  Expect.identical(Wrapping<int>.named, C<C<int>>.named);
  Expect.identical(Extra<int, String>.new, C<int>.new);
  Expect.identical(Extra<int, String>.named, C<int>.named);
  // And, since the second type parameter doesn't matter:
  Expect.identical(Extra<int, String>.new, Extra<int, bool>.new);
  Expect.identical(Extra<int, String>.named, Extra<int, bool>.named);

  Expect.identical(Swapped<int, String>.new, D<String, int>.new);
  Expect.identical(Swapped<int, String>.named, D<String, int>.named);

  // Implicit instantiation.
  Expect.identical(
    context<C<int> Function(int)>(Direct.new),
    C<int>.new,
  );
  Expect.identical(
    context<C<int> Function(int)>(Direct.named),
    C<int>.named,
  );
  Expect.identical(
    context<C<int> Function(int)>(Bounded.new),
    C<int>.new,
  );
  Expect.identical(
    context<C<int> Function(int)>(Bounded.named),
    C<int>.named,
  );
  Expect.identical(
    context<C<C<int>> Function(C<int>)>(Wrapping.new),
    C<C<int>>.new,
  );
  Expect.identical(
    context<C<C<int>> Function(C<int>)>(Wrapping.named),
    C<C<int>>.named,
  );
  Expect.identical(
    context<D<int, String> Function()>(Swapped.new),
    D<int, String>.new,
  );
  Expect.identical(
    context<D<int, String> Function()>(Swapped.named),
    D<int, String>.named,
  );

  (<T extends num>() {
    // Non-constant type instantiation implies non-constant expressions.
    // Canonicalization is unspecified, but equality holds.
    Expect.equals(Direct<T>.new, Direct<T>.new);
    Expect.equals(Direct<T>.named, Direct<T>.named);
    Expect.equals(Bounded<T>.new, Bounded<T>.new);
    Expect.equals(Bounded<T>.named, Bounded<T>.named);
    Expect.equals(Wrapping<T>.new, Wrapping<T>.new);
    Expect.equals(Wrapping<T>.named, Wrapping<T>.named);
    Expect.equals(Extra<T, String>.new, Extra<T, String>.new);
    Expect.equals(Extra<T, String>.named, Extra<T, String>.named);
    // Also if the non-constant type doesn't occur in the expansion.
    Expect.equals(Extra<int, T>.new, Extra<int, T>.new);
    Expect.equals(Extra<int, T>.named, Extra<int, T>.named);

    Expect.equals(Swapped<T, int>.new, Swapped<T, int>.new);
    Expect.equals(Swapped<T, int>.named, Swapped<T, int>.named);
    Expect.equals(Swapped<int, T>.new, Swapped<int, T>.new);
    Expect.equals(Swapped<int, T>.named, Swapped<int, T>.named);
  }<int>());
}
