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

// Testing that `noSuchMethod` forwarding properly handles optional, named and
// type parameters, and result type checking.

// VMOptions=--lazy-dispatchers
// VMOptions=--no-lazy-dispatchers

import 'package:expect/expect.dart';

class A {
  dynamic noSuchMethod(Invocation invoke) {
    if (invoke.memberName == #test0) {
      Expect.equals(invoke.positionalArguments[0], 1);
      Expect.equals(invoke.positionalArguments[1], 2);
      return null;
    } else if (invoke.memberName == #test1) {
      Expect.isTrue(invoke.namedArguments.length == 1);
      Expect.equals(null, invoke.namedArguments[#x]);
      return null;
    } else if (invoke.memberName == #test2) {
      Expect.isTrue(invoke.namedArguments.length == 1);
      Expect.equals("w/e", invoke.namedArguments[#x]);
      return null;
    } else if (invoke.memberName == #test3) {
      Expect.equals(invoke.namedArguments[#x], "ok");
      return null;
    } else if (invoke.memberName == #test4) {
      Expect.equals(invoke.positionalArguments[0], "ok");
      return null;
    } else if (invoke.memberName == #test5) {
      Expect.equals(invoke.typeArguments[0].toString(), "int");
      return null;
    } else if (invoke.memberName == #test6) {
      return 1;
    } else if (invoke.memberName == #test7) {
      return "hi";
    } else if (invoke.memberName == #allTogetherNow) {
      Expect.equals(invoke.typeArguments.length, 2);
      Expect.equals(invoke.typeArguments[0].toString(), "num");
      Expect.equals(invoke.typeArguments[1].toString(), "double");

      Expect.equals(invoke.positionalArguments.length, 1);
      Expect.equals(invoke.positionalArguments[0], 2.0);

      Expect.equals(invoke.namedArguments.length, 1);
      Expect.equals(invoke.namedArguments[#foo], const <num>[3, 4]);
    } else if (invoke.memberName == #test8) {
      Expect.equals(1, invoke.positionalArguments.length);
      Expect.equals(null, invoke.positionalArguments[0]);
    } else if (invoke.memberName == #test9) {
      Expect.equals(invoke.typeArguments.length, 2);
      Expect.equals(invoke.typeArguments[0].toString(), "num");
      Expect.equals(invoke.typeArguments[1].toString(), "double");

      Expect.equals(1, invoke.positionalArguments.length);
      Expect.equals(4.2, invoke.positionalArguments[0]);

      Expect.equals(1, invoke.namedArguments.length);
      Expect.equals(3, invoke.namedArguments[#foo]);
    }
  }

  void test0(int x, int y);
  void test1({String x});
  void test2({String x: "w/e"});
  void test3({String x: "w/e"});
  void test4([String x]);
  void test5<T extends num>(T x);
  String test6();

  int get test7;
  void set test7(int x);

  void test8([String x]);
  void test9<T, S extends T>(S x1, {T foo});

  T allTogetherNow<T, S extends T>(S x1, {List<T> foo: const <Null>[]});
}

main() {
  var a = new A();

  a.test0(1, 2);
  (a.test0 as dynamic)(1, 2);

  a.test1();
  (a.test1 as dynamic)();

  a.test2();
  (a.test2 as dynamic)();

  a.test3(x: "ok");
  (a.test3 as dynamic)(x: "ok");

  a.test4("ok");
  (a.test4 as dynamic)("ok");

  a.test5<int>(1);
  (a.test5 as dynamic)<int>(1);
  Expect.throwsTypeError(() => (a.test5 as dynamic)<String>("foo"));
  Expect.throwsTypeError(() => (a.test5 as dynamic)<int>(3.1));

  Expect.throwsTypeError(() => a.test6());
  Expect.throwsTypeError(() => (a.test6 as dynamic)());

  Expect.throwsTypeError(() => a.test7);
  Expect.throwsTypeError(() => (a as dynamic).test7 = "hi");

  a.allTogetherNow<num, double>(2.0, foo: const <num>[3, 4]);
  Expect.throwsTypeError(() =>
      (a.allTogetherNow as dynamic)<int, double>(2.0, foo: const <num>[3, 4]));
  Expect.throwsTypeError(() =>
      (a.allTogetherNow as dynamic)<int, int>(2.0, foo: const <num>[3, 4]));
  Expect.throwsTypeError(() => (a.allTogetherNow
      as dynamic)<double, double>(2.0, foo: const <int>[3, 4]));

  a.test8();

  a.test9<num, double>(4.2, foo: 3);
  Expect.throwsTypeError(() => (a.test9 as dynamic)<int, double>(3, foo: 3));
  Expect.throwsTypeError(
      () => (a.test9 as dynamic)<double, double>(3, foo: 3.2));
  // Added to check that uses of positions from the ArgumentsDescriptor in the
  // VM properly offsets named argument positions if there are also type
  // arguments. allTogetherNow doesn't work for this because the runtime type of
  // the positional argument cannot be the same as the type of the named
  // argument without the positional argument failing to match its own type,
  // and positional argument types are usually checked first.
  Expect.throwsTypeError(
      () => (a.test9 as dynamic)<int, double>(4.2, foo: 3.2));
}
