// 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.

import "package:expect/expect.dart";

// 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)
    : this.mfn = (() {
        return a;
      }),
      super(a);
}

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

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

typedef void Fisk();

class FunctionTest {
  FunctionTest() {}

  static void testMain() {
    var test = new FunctionTest();
    test.testForEach();
    test.testVarOrder1();
    test.testVarOrder2();
    test.testLexicalClosureRef1();
    test.testLexicalClosureRef2();
    test.testLexicalClosureRef3();
    test.testLexicalClosureRef4();
    test.testLexicalClosureRef5();
    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 = [];
    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])() as int;
    }

    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 = [];
    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])() as int;
    }

    Expect.equals(45, sum);
  }

  int tempField = -1;

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

  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;
    Foo<Object, Object>? fooObjectObject = null;

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

    uf = f as UntypedFunction?;
    uf2 = f;
    foo = f as Foo?;
    fooIntString = f as Foo<int, String>?;

    fooIntString = foo as Foo<int, String>?;

    foo = fooObjectObject as Foo?;
    fooObjectObject = foo as Foo<Object, Object>?;

    uf = uf2;
    uf2 = uf;
  }
}

main() {
  FunctionTest.testMain();
}
