// Copyright (c) 2017, 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:expect/expect.dart';

class Fields<T> {
  T x;
  T _y;
  T _z;

  m() {
    _y = x;
  }

  n(Fields<T> c) {
    c._z = x;
  }
}

testField() {
  Fields<Object> c = new Fields<int>();
  Expect.throwsTypeError(() => c.x = 'hello');

  Fields<dynamic> d = new Fields<int>();
  Expect.throwsTypeError(() => c.x = 'hello');
}

testPrivateFields() {
  Fields<Object> c = new Fields<int>()..x = 42;
  c.m();
  Expect.equals(c._y, 42);

  Fields<Object> c2 = new Fields<String>()..x = 'hi';
  c2.n(c2);
  Expect.equals(c2._z, 'hi');
  Expect.throwsTypeError(() => c.n(c2));
  Expect.equals(c2._z, 'hi');
}

class NumBounds<T extends num> {
  bool m(T t) => t.isNegative;
}

class MethodTakesNum extends NumBounds<int> {
  bool m(num obj) => obj.isNegative; // does not need check
}

class MethodTakesInt extends NumBounds<int> {
  bool m(int obj) => obj.isNegative; // needs a check
}

testClassBounds() {
  NumBounds<num> d = new MethodTakesNum();
  Expect.equals(d.m(-1.1), true);
  d = new MethodTakesInt();
  Expect.throwsTypeError(() => d.m(-1.1));
}

typedef void F<T>(T t);
typedef G<T> = void Function<S extends T>(S s);

class FnChecks<T> {
  F<T> f;
  G<T> g;
  T _t;
  T getT() => _t;
  F<T> setterForT() {
    return (T t) {
      _t = t;
    };
  }
}

testReturnOfFunctionType() {
  FnChecks<int> cInt = new FnChecks<int>();
  FnChecks<Object> cObj = cInt;
  Expect.throwsTypeError(() => cObj.setterForT());
  Expect.throwsTypeError(() => (cObj.setterForT() as F<Object>));
  FnChecks<dynamic> cDyn = cInt;
  Expect.throwsTypeError(() => cDyn.setterForT());
  Expect.throwsTypeError(
      () => (cDyn as dynamic).setterForT()('hi')); // dcall throws
  cInt.setterForT()(42);
  Expect.equals(cObj.getT(), 42);
}

testTearoffReturningFunctionType() {
  FnChecks<int> cInt = new FnChecks<int>();
  FnChecks<Object> cObj = cInt;

  Expect.throwsTypeError(
      () => cObj.setterForT, 'unsound tear-off throws at runtime');
  Expect.equals(cInt.setterForT, cInt.setterForT, 'sound tear-off works');
}

testFieldOfFunctionType() {
  FnChecks<Object> c = new FnChecks<String>()..f = (String b) {};
  Expect.throwsTypeError(() {
    F<Object> f = c.f;
  });
  Expect.throwsTypeError(() {
    Object f = c.f;
  });
  Expect.throwsTypeError(() => c.f);
  Expect.throwsTypeError(() => c.f(42));
  Expect.throwsTypeError(() => c.f('hi'));
  FnChecks<String> cStr = c;
  cStr.f('hi');
  FnChecks<dynamic> cDyn = c;
  Expect.throwsTypeError(() => cDyn.f);
  Expect.throwsTypeError(() => (cDyn as dynamic).f(42)); // dcall throws
}

testFieldOfGenericFunctionType() {
  FnChecks<Object> c = new FnChecks<num>()
    ..g = <S extends num>(S s) => s.isNegative;

  Expect.throwsTypeError(() {
    G<Object> g = c.g;
  });
  Expect.throwsTypeError(() {
    var g = c.g;
  });
  Expect.throwsTypeError(() => c.g<String>('hi'));
  Expect.throwsTypeError(() => c.g<int>(42));
  FnChecks<num> cNum = c;
  cNum.g(42);
}

class Base {
  int _t = 0;
  add(int t) {
    _t += t;
  }
}

abstract class I<T> {
  add(T t);
}

class ExtendsBase extends Base implements I<int> {}

class MixinBase extends Object with Base implements I<int> {}

class MixinBase2 = Object with Base implements I<int>;

testMixinApplication() {
  I<Object> i = new ExtendsBase();
  I<Object> j = new MixinBase();
  I<Object> k = new MixinBase2();
  Expect.throwsTypeError(() => i.add('hi'));
  Expect.throwsTypeError(() => j.add('hi'));
  Expect.throwsTypeError(() => k.add('hi'));
}

class GenericMethodBounds<T> {
  Type get t => T;
  GenericMethodBounds<E> foo<E extends T>() => new GenericMethodBounds<E>();
  GenericMethodBounds<E> bar<E extends void Function(T)>() =>
      new GenericMethodBounds<E>();
}

class GenericMethodBoundsDerived extends GenericMethodBounds<num> {
  GenericMethodBounds<E> foo<E extends num>() => new GenericMethodBounds<E>();
  GenericMethodBounds<E> bar<E extends void Function(num)>() =>
      new GenericMethodBounds<E>();
}

GenericMethodBounds<E> Function<E extends T>() genericFunctionWithBounds<T>() {
  inner<E extends T>() => new GenericMethodBounds<E>();
  return inner;
}

testGenericMethodBounds() {
  test(GenericMethodBounds<Object> g) {
    Expect.throwsTypeError(() => g.foo<String>());
    Expect.throwsTypeError(() => g.foo());
    Expect.equals(g.foo<Null>().t, Null);
    Expect.equals(g.foo<int>().t, int);
    Expect.isFalse(g.foo<int>() is GenericMethodBounds<double>);
    g.bar<Function(Object)>();
    dynamic d = g;
    d.bar<Function(num)>();
    Expect.throwsTypeError(() => d.bar<Function(String)>());
    Expect.throwsTypeError(() => d.bar<Function(Null)>());
  }

  test(new GenericMethodBounds<num>());
  test(new GenericMethodBounds<int>());
  test(new GenericMethodBoundsDerived());
  test(genericFunctionWithBounds<num>()<int>());
}

class ClassF<T> {
  T x;
  void call(T t) {
    x = t;
  }
}

testCallMethod() {
  ClassF<int> cc = new ClassF<int>();
  ClassF<Object> ca = cc; // An upcast, per covariance.
  F<Object> f = ca;
  void f2(Object x) {}
  Expect.equals(f.runtimeType, f2.runtimeType);
  Expect.throwsTypeError(() => f(new Object()));
}

class TearOff<T> {
  method1(T t) => null; // needs check
  method2(Function(T) takesT) => null;
  method3(T Function() returnsT) => null; // needs check
  method4(Function(Function(T)) takesTakesT) => null; // needs check
  method5(Function(T Function()) takesReturnsT) => null;
  method6(Function(T) Function() returnsTakesT) => null;
  method7(T Function() Function() returnsReturnsT) => null; // needs check
}

testTearOffRuntimeType() {
  expectRTTI(tearoff, type) => Expect.equals('${tearoff.runtimeType}', type,
      'covariant params should reify with Object as their type');

  TearOff<num> t = new TearOff<int>();
  expectRTTI(t.method1, '(Object) => dynamic');

  expectRTTI(t.method2, '((int) => dynamic) => dynamic');
  expectRTTI(t.method3, '(Object) => dynamic');

  expectRTTI(t.method4, '(Object) => dynamic');
  expectRTTI(t.method5, '((() => int) => dynamic) => dynamic');
  expectRTTI(t.method6, '(() => (int) => dynamic) => dynamic');
  expectRTTI(t.method7, '(Object) => dynamic');
}

main() {
  testField();
  testPrivateFields();
  testClassBounds();
  testReturnOfFunctionType();
  testTearoffReturningFunctionType();
  testFieldOfFunctionType();
  testFieldOfGenericFunctionType();
  testMixinApplication();
  testGenericMethodBounds();
  testCallMethod();
  testTearOffRuntimeType();
}
