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

// @dart = 2.9

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 = 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;

  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;
    uf2 = f;
    foo = f;
    fooIntString = f;

    fooIntString = foo;

    foo = fooObjectObject;
    fooObjectObject = foo;

    uf = uf2;
    uf2 = uf;
  }
}

main() {
  FunctionTest.testMain();
}
