// 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 function statements and expressions.

class Bug4089219 {
  int x;
  var f;

  Bug4089219(int i) : this.x = i {
    f = () => x;
  }
}

class Bug4342163 {
  final m;
  Bug4342163(int a) : this.m = (() => a) {}
}

class StaticFunctionDef {
  static const int one = 1;
  static var fn1;
  static var fn2;
  static var fn3;

  static init() {
    fn1 = () { return one; };
    fn2 = () { return (() { return one; })(); };
    fn3 = () {
               final local = 1;
               return (() { return local; })();
             };
  }
}

class A {
  var ma;
  A(a) {ma = a;}
}

class B1 extends A {
  final mfn;
  B1(int a) : super(a), this.mfn = (() {return a;}) {
  }
}

class B2 extends A {
  final mfn;
  B2(int a) : super(2), this.mfn = (() {return a;}) {
  }
}

class B3 extends A {
  final mfn;
  B3(int a) : super(() {return a;}), this.mfn = (() {return a;}) {
  }
}

typedef void Fisk();

class FunctionTest {

  FunctionTest() {}

  static void testMain() {
    var test = new FunctionTest();
    test.testRecursiveClosureRef();
    test.testForEach();
    test.testVarOrder1();
    test.testVarOrder2();
    test.testLexicalClosureRef1();
    test.testLexicalClosureRef2();
    test.testLexicalClosureRef3();
    test.testLexicalClosureRef4();
    test.testLexicalClosureRef5();
    test.testFunctionScopes();
    test.testDefaultParametersOrder();
    test.testParametersOrder();
    test.testFunctionDefaults1();
    test.testFunctionDefaults2();
    test.testEscapingFunctions();
    test.testThisBinding();
    test.testFnBindingInStatics();
    test.testFnBindingInInitLists();
    test.testSubclassConstructorScopeAlias();
  }

  void testSubclassConstructorScopeAlias() {
    var b1 = new B1(10);
    Expect.equals(10, (b1.mfn)());
    Expect.equals(10, b1.ma);

    var b2 = new B2(11);
    Expect.equals(11, (b2.mfn)());
    Expect.equals(2, b2.ma);

    var b3 = new B3(12);
    Expect.equals(12, (b3.mfn)());
    Expect.equals(12, (b3.ma)());
  }

  void testFnBindingInInitLists() {
    Expect.equals(1, (new Bug4342163(1).m)());
  }

  void testFnBindingInStatics() {
    StaticFunctionDef.init();
    Expect.equals(1, ((StaticFunctionDef.fn1)()));
    Expect.equals(1, ((StaticFunctionDef.fn2)()));
    Expect.equals(1, ((StaticFunctionDef.fn3)()));
  }

  Fisk testReturnVoidFunction() {
    void f() {}
    Fisk x = f;
    return f;
  }

  void testVarOrder1() {
    var a = 0, b = a++, c = a++;

    Expect.equals(a, 2);
    Expect.equals(b, 0);
    Expect.equals(c, 1);
  }

  void testVarOrder2() {
    var a = 0;
    f() {return a++;};
    var b = f(), c = f();

    Expect.equals(a, 2);
    Expect.equals(b, 0);
    Expect.equals(c, 1);
  }

  void testLexicalClosureRef1() {
    var a = 1;
    var f, g;
    {
      var b = 2;
      f = () {return b - a;};
    }

    {
      var b = 3;
      g = () {return b - a;};
    }
    Expect.equals(1, f());
    Expect.equals(2, g());
  }

  void testLexicalClosureRef2() {
    var a = 1;
    var f, g;
    {
      var b = 2;
      f = () {return ((){return b - a;})();};
    }

    {
      var b = 3;
      g = () {return ((){return b - a;})();};
    }
    Expect.equals(1, f());
    Expect.equals(2, g());
  }

  void testLexicalClosureRef3() {
    var a = new List();
    for (int i = 0; i < 10; i++) {
      var x = i;
      a.add(() {return x;});
    }

    var sum = 0;
    for (int i = 0; i < a.length; i++) {
      sum += (a[i])();
    }

    Expect.equals(45, sum);
  }

  void testLexicalClosureRef5() {
    {
      var a;
      Expect.equals(null, a);
      a = 1;
      Expect.equals(1, a);
    }

    {
      var a;
      Expect.equals(null, a);
      a = 1;
      Expect.equals(1, a);
    }
  }

  // Make sure labels are preserved, and a second 'i' does influence the first.
  void testLexicalClosureRef4() {
    var a = new List();
    x:for (int i = 0; i < 10; i++) {
      a.add(() {return i;});
      continue x;
    }

    var sum = 0;
    for (int i = 0; i < a.length; i++) {
      sum += (a[i])();
    }

    Expect.equals(45, sum);
  }

  int tempField;

  // Validate that a closure that calls the private name of a function (for
  // for recursion) calls the version of function with the bound names.
  void testRecursiveClosureRef() {
    tempField = 2;
    var x = 3;
    var g = f(a) {
       tempField++;
       x++;
       if (a > 0) {
         f(--a);
       }
    };
    g(2);


    Expect.equals(5, tempField);
    Expect.equals(6, x);
  }

  void testForEach() {
    List<int> vals = [1,2,3];
    int total = 0;
    vals.forEach((int v) {
      total += v;
    });
    Expect.equals(6, total);
  }

  void testFunctionScopes() {
    // Function expression. 'recurse' is only defined within the function body.
    // FAILS:
    // var factorial0 = function recurse(int x) {
    //  return (x == 1) ? 1 : (x * recurse(x - 1));
    // };
    // TEMP:
    var factorial0;
    factorial0 = recurse(int x) {
      return (x == 1) ? 1 : (x * factorial0(x - 1));
    };
    // END TEMP


    // Function statement. 'factorial1' is defined in the outer scope.
    int factorial1(int x) {
      return (x == 1) ? 1 : (x * factorial1(x - 1));
    }

    // This would fail to compile if 'recurse' were defined in the outer scope.
    // Which it shouldn't be.
    int recurse = 42;

    Expect.equals(6, factorial0(3));
    Expect.equals(24, factorial0(4));
  }

  void testDefaultParametersOrder() {
    f([a = 1, b = 3]) {
      return a - b;
    }
    Expect.equals(-2, f());
  }

  void testParametersOrder() {
    f(a, b) {
      return a - b;
    }
    Expect.equals(-2, f(1,3));
  }

  void testFunctionDefaults1() {
    // TODO(jimhug): This return null shouldn't be necessary.
    f() { return null; };
    (([a = 10]) { Expect.equals(10, a); })();
    ((a, [b = 10]) { Expect.equals(10, b); })(1);
    (([a = 10]) { Expect.equals(null, a); })( f() );
    // FAILS: (([a = 10]) { Expect.equals(null ,a); })( f() );
  }

  void testFunctionDefaults2() {
    Expect.equals(10, helperFunctionDefaults2());
    Expect.equals(1, helperFunctionDefaults2(1));
  }

  num helperFunctionDefaults2([a = 10]) {
    return ((){return a;})();
  }

  void testEscapingFunctions() {
    f() { return 42; };
    (() { Expect.equals(42, f()); })();
    var o = new Bug4089219(42);
    Expect.equals(42, (o.f)());
  }

  void testThisBinding() {
    Expect.equals(this, () { return this; }());
  }
}

typedef void Foo<A, B>(A a, B b);

class Bar<A, B> {
  Foo<A, B> field;
  Bar(A a, B b) : this.field = ((A a1, B b2){}) {
    field(a, b);
  }
}

typedef UntypedFunction(arg);
typedef UntypedFunction2(arg);

class UseFunctionTypes {
  void test() {
    Function f = null;
    UntypedFunction uf = null;
    UntypedFunction2 uf2 = null;
    Foo foo = null;
    Foo<int, String> fooIntString = null;

    f = uf;
    f = uf2;
    f = foo;
    f = fooIntString;

    uf = f;
    uf2 = f;
    foo = f;
    fooIntString = f;

    foo = fooIntString;
    fooIntString = foo;

    uf = uf2;
    uf2 = uf;
  }
}

main() {
  FunctionTest.testMain();
}
