// Copyright (c) 2013, 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.
// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation

import "package:expect/expect.dart";

// Test that noSuchMethod dispatching and auto-closurization work correctly.

class A {
  noSuchMethod(m) {
    return 123;
  }

  bar(x) => x + 1;
}

class B extends A {}

class C {
  C(this.pos, this.named, this.posArgs, this.namedArgs);
  var pos, named;
  noSuchMethod(m) {
    Expect.equals(pos, m.positionalArguments.length);
    Expect.equals(named, m.namedArguments.length);
    for (var i = 0; i < posArgs.length; ++i) {
      Expect.equals(posArgs[i], m.positionalArguments[i]);
    }
    for (var k in namedArgs.keys) {
      Expect.equals(namedArgs[k], m.namedArguments[new Symbol(k)]);
    }
    return 123;
  }

  List posArgs;
  Map namedArgs;
}

main() {
  var a = new A();
  for (var i = 0; i < 20; ++i) Expect.equals(123, a.foo());
  Expect.throws(() => (a.foo)());
  Expect.equals("123", (a.foo).toString());

  var b = new B();
  for (var i = 0; i < 20; ++i) {
    Expect.equals(2, b.bar(1));
    Expect.equals(123, b.bar());
    Expect.equals(2, b.bar(1));
  }

  for (var i = 0; i < 20; ++i) {
    Expect.equals(123, b.bar(1, 2, 3));
    Expect.equals(123, b.bar(1, 2, foo: 3));
  }

  // Test named and positional arguments.
  var c = new C(1, 2, [100], {"n1": 101, "n2": 102});
  for (var i = 0; i < 20; ++i) {
    Expect.equals(123, c.bar(100, n1: 101, n2: 102));
    Expect.equals(123, c.bar(100, n2: 102, n1: 101));
  }
}
