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

// Tests that we can call functions through getters.

const TOP_LEVEL_CONST = 1;
const TOP_LEVEL_CONST_REF = TOP_LEVEL_CONST;
const TOP_LEVEL_NULL = null;

var topLevel;

class CallThroughGetterTest {

  static void testMain() {
    testTopLevel();
    testField();
    testGetter();
    testMethod();
    testEvaluationOrder();
  }

  static void testTopLevel() {
    topLevel = () {
      return 2;
    };
    Expect.equals(1, TOP_LEVEL_CONST);
    Expect.equals(1, TOP_LEVEL_CONST_REF);
    Expect.equals(2, topLevel());

    expectThrowsNoSuchMethod(() {
      TOP_LEVEL_CONST(); /// static type warning
    });
    expectThrowsNoSuchMethod(() {
      (TOP_LEVEL_CONST)();  /// static type warning
    });
  }

  static void testField() {
    A a = new A();
    a.field = () => 42;
    Expect.equals(42, a.field());
    Expect.equals(42, (a.field)());

    a.field = () => 87;
    Expect.equals(87, a.field());
    Expect.equals(87, (a.field)());

    a.field = 99;
    expectThrowsNoSuchMethod(() { a.field(); });
    expectThrowsNoSuchMethod(() { (a.field)(); });
  }

  static void testGetter() {
    A a = new A();
    a.field = () => 42;
    Expect.equals(42, a.getter());
    Expect.equals(42, (a.getter)());

    a.field = () => 87;
    Expect.equals(87, a.getter());
    Expect.equals(87, (a.getter)());

    a.field = 99;
    expectThrowsNoSuchMethod(() { a.getter(); });
    expectThrowsNoSuchMethod(() { (a.getter)(); });
  }

  static void testMethod() {
    A a = new A();
    a.field = () => 42;
    Expect.equals(true, a.method() is Function);
    Expect.equals(42, a.method()());

    a.field = () => 87;
    Expect.equals(true, a.method() is Function);
    Expect.equals(87, a.method()());

    a.field = null;
    Expect.equals(null, a.method());
  }

  static void testEvaluationOrder() {
    B b = new B();
    Expect.equals("gf", b.g0());
    b = new B();
    Expect.equals("gf", (b.g0)());

    b = new B();
    Expect.equals("xgf", b.g1(b.x));
    b = new B();
    Expect.equals("gxf", (b.g1)(b.x));

    b = new B();
    Expect.equals("xygf", b.g2(b.x, b.y));
    b = new B();
    Expect.equals("gxyf", (b.g2)(b.x, b.y));

    b = new B();
    Expect.equals("xyzgf", b.g3(b.x, b.y, b.z));
    b = new B();
    Expect.equals("gxyzf", (b.g3)(b.x, b.y, b.z));

    b = new B();
    Expect.equals("yzxgf", b.g3(b.y, b.z, b.x));
    b = new B();
    Expect.equals("gyzxf", (b.g3)(b.y, b.z, b.x));
  }

  static expectThrowsNoSuchMethod(fn) {
    var exception = catchException(fn);
    if (exception is! NoSuchMethodError) {
      Expect.fail("Wrong exception.  Expected: NoSuchMethodError"
          " got: ${exception}");
    }
  }

  static catchException(fn) {
    bool caught = false;
    var result = null;
    try {
      fn();
      Expect.equals(true, false);  // Shouldn't reach this.
    } catch (e) {
      caught = true;
      result = e;
    }
    Expect.equals(true, caught);
    return result;
  }

}


class A {

  A() { }
  var field;
  get getter { return field; }
  method() { return field; }

}


class B {

  B() : _order = new StringBuffer("") { }

  get g0 { _mark('g'); return () { return _mark('f'); }; }
  get g1 { _mark('g'); return (x) { return _mark('f'); }; }
  get g2 { _mark('g'); return (x, y) { return _mark('f'); }; }
  get g3 { _mark('g'); return (x, y, z) { return _mark('f'); }; }

  get x { _mark('x'); return 0; }
  get y { _mark('y'); return 1; }
  get z { _mark('z'); return 2; }

  _mark(m) { _order.write(m); return _order.toString(); }
  StringBuffer _order;

}

main() {
  CallThroughGetterTest.testMain();
}
