| // 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(); | |
| } |