| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 // Tests function statements and expressions. | |
| 6 | |
| 7 class Bug4089219 { | |
| 8 int x; | |
| 9 var f; | |
| 10 | |
| 11 Bug4089219(int i) : this.x = i { | |
| 12 f = () => x; | |
| 13 } | |
| 14 } | |
| 15 | |
| 16 class Bug4342163 { | |
| 17 final m; | |
| 18 Bug4342163(int a) : this.m = (() => a) {} | |
| 19 } | |
| 20 | |
| 21 class StaticFunctionDef { | |
| 22 static final int one = 1; | |
| 23 static var fn1; | |
| 24 static var fn2; | |
| 25 static var fn3; | |
| 26 | |
| 27 static init() { | |
| 28 fn1 = () { return one; }; | |
| 29 fn2 = () { return (() { return one; })(); }; | |
| 30 fn3 = () { | |
| 31 final local = 1; | |
| 32 return (() { return local; })(); | |
| 33 }; | |
| 34 } | |
| 35 } | |
| 36 | |
| 37 class A { | |
| 38 var ma; | |
| 39 A(a) {ma = a;} | |
| 40 } | |
| 41 | |
| 42 class B1 extends A { | |
| 43 final mfn; | |
| 44 B1(int a) : super(a), this.mfn = (() {return a;}) { | |
| 45 } | |
| 46 } | |
| 47 | |
| 48 class B2 extends A { | |
| 49 final mfn; | |
| 50 B2(int a) : super(2), this.mfn = (() {return a;}) { | |
| 51 } | |
| 52 } | |
| 53 | |
| 54 class B3 extends A { | |
| 55 final mfn; | |
| 56 B3(int a) : super(() {return a;}), this.mfn = (() {return a;}) { | |
| 57 } | |
| 58 } | |
| 59 | |
| 60 typedef void Fisk(); | |
| 61 | |
| 62 class FunctionTest { | |
| 63 | |
| 64 FunctionTest() {} | |
| 65 | |
| 66 static void testMain() { | |
| 67 var test = new FunctionTest(); | |
| 68 test.testRecursiveClosureRef(); | |
| 69 test.testForEach(); | |
| 70 test.testVarOrder1(); | |
| 71 test.testVarOrder2(); | |
| 72 test.testLexicalClosureRef1(); | |
| 73 test.testLexicalClosureRef2(); | |
| 74 test.testLexicalClosureRef3(); | |
| 75 test.testLexicalClosureRef4(); | |
| 76 test.testLexicalClosureRef5(); | |
| 77 test.testFunctionScopes(); | |
| 78 test.testDefaultParametersOrder(); | |
| 79 test.testParametersOrder(); | |
| 80 test.testFunctionDefaults1(); | |
| 81 test.testFunctionDefaults2(); | |
| 82 test.testEscapingFunctions(); | |
| 83 test.testThisBinding(); | |
| 84 test.testFnBindingInStatics(); | |
| 85 test.testFnBindingInInitLists(); | |
| 86 test.testSubclassConstructorScopeAlias(); | |
| 87 } | |
| 88 | |
| 89 void testSubclassConstructorScopeAlias() { | |
| 90 var b1 = new B1(10); | |
| 91 Expect.equals(10, (b1.mfn)()); | |
| 92 Expect.equals(10, b1.ma); | |
| 93 | |
| 94 var b2 = new B2(11); | |
| 95 Expect.equals(11, (b2.mfn)()); | |
| 96 Expect.equals(2, b2.ma); | |
| 97 | |
| 98 var b3 = new B3(12); | |
| 99 Expect.equals(12, (b3.mfn)()); | |
| 100 Expect.equals(12, (b3.ma)()); | |
| 101 } | |
| 102 | |
| 103 void testFnBindingInInitLists() { | |
| 104 Expect.equals(1, (new Bug4342163(1).m)()); | |
| 105 } | |
| 106 | |
| 107 void testFnBindingInStatics() { | |
| 108 StaticFunctionDef.init(); | |
| 109 Expect.equals(1, ((StaticFunctionDef.fn1)())); | |
| 110 Expect.equals(1, ((StaticFunctionDef.fn2)())); | |
| 111 Expect.equals(1, ((StaticFunctionDef.fn3)())); | |
| 112 } | |
| 113 | |
| 114 Fisk testReturnVoidFunction() { | |
| 115 void f() {} | |
| 116 Fisk x = f; | |
| 117 return f; | |
| 118 } | |
| 119 | |
| 120 void testVarOrder1() { | |
| 121 var a = 0, b = a++, c = a++; | |
| 122 | |
| 123 Expect.equals(a, 2); | |
| 124 Expect.equals(b, 0); | |
| 125 Expect.equals(c, 1); | |
| 126 } | |
| 127 | |
| 128 void testVarOrder2() { | |
| 129 var a = 0; | |
| 130 f() {return a++;}; | |
| 131 var b = f(), c = f(); | |
| 132 | |
| 133 Expect.equals(a, 2); | |
| 134 Expect.equals(b, 0); | |
| 135 Expect.equals(c, 1); | |
| 136 } | |
| 137 | |
| 138 void testLexicalClosureRef1() { | |
| 139 var a = 1; | |
| 140 var f, g; | |
| 141 { | |
| 142 var b = 2; | |
| 143 f = () {return b - a;}; | |
| 144 } | |
| 145 | |
| 146 { | |
| 147 var b = 3; | |
| 148 g = () {return b - a;}; | |
| 149 } | |
| 150 Expect.equals(1, f()); | |
| 151 Expect.equals(2, g()); | |
| 152 } | |
| 153 | |
| 154 void testLexicalClosureRef2() { | |
| 155 var a = 1; | |
| 156 var f, g; | |
| 157 { | |
| 158 var b = 2; | |
| 159 f = () {return ((){return b - a;})();}; | |
| 160 } | |
| 161 | |
| 162 { | |
| 163 var b = 3; | |
| 164 g = () {return ((){return b - a;})();}; | |
| 165 } | |
| 166 Expect.equals(1, f()); | |
| 167 Expect.equals(2, g()); | |
| 168 } | |
| 169 | |
| 170 void testLexicalClosureRef3() { | |
| 171 var a = new List(); | |
| 172 for (int i = 0; i < 10; i++) { | |
| 173 var x = i; | |
| 174 a.add(() {return x;}); | |
| 175 } | |
| 176 | |
| 177 var sum = 0; | |
| 178 for (int i = 0; i < a.length; i++) { | |
| 179 sum += (a[i])(); | |
| 180 } | |
| 181 | |
| 182 Expect.equals(45, sum); | |
| 183 } | |
| 184 | |
| 185 void testLexicalClosureRef5() { | |
| 186 { | |
| 187 var a; | |
| 188 Expect.equals(null, a); | |
| 189 a = 1; | |
| 190 Expect.equals(1, a); | |
| 191 } | |
| 192 | |
| 193 { | |
| 194 var a; | |
| 195 Expect.equals(null, a); | |
| 196 a = 1; | |
| 197 Expect.equals(1, a); | |
| 198 } | |
| 199 } | |
| 200 | |
| 201 // Make sure labels are preserved, and a second 'i' does influence the first. | |
| 202 void testLexicalClosureRef4() { | |
| 203 var a = new List(); | |
| 204 x:for (int i = 0; i < 10; i++) { | |
| 205 a.add(() {return i;}); | |
| 206 continue x; | |
| 207 } | |
| 208 | |
| 209 var sum = 0; | |
| 210 for (int i = 0; i < a.length; i++) { | |
| 211 sum += (a[i])(); | |
| 212 } | |
| 213 | |
| 214 Expect.equals(45, sum); | |
| 215 } | |
| 216 | |
| 217 int tempField; | |
| 218 | |
| 219 // Validate that a closure that calls the private name of a function (for | |
| 220 // for recursion) calls the version of function with the bound names. | |
| 221 void testRecursiveClosureRef() { | |
| 222 tempField = 2; | |
| 223 var x = 3; | |
| 224 var g = f(a) { | |
| 225 tempField++; | |
| 226 x++; | |
| 227 if (a > 0) { | |
| 228 f(--a); | |
| 229 } | |
| 230 }; | |
| 231 g(2); | |
| 232 | |
| 233 | |
| 234 Expect.equals(5, tempField); | |
| 235 Expect.equals(6, x); | |
| 236 } | |
| 237 | |
| 238 void testForEach() { | |
| 239 List<int> vals = [1,2,3]; | |
| 240 int total = 0; | |
| 241 vals.forEach((int v) { | |
| 242 total += v; | |
| 243 }); | |
| 244 Expect.equals(6, total); | |
| 245 } | |
| 246 | |
| 247 void testFunctionScopes() { | |
| 248 // Function expression. 'recurse' is only defined within the function body. | |
| 249 // FAILS: | |
| 250 // var factorial0 = function recurse(int x) { | |
| 251 // return (x == 1) ? 1 : (x * recurse(x - 1)); | |
| 252 // }; | |
| 253 // TEMP: | |
| 254 var factorial0; | |
| 255 factorial0 = recurse(int x) { | |
| 256 return (x == 1) ? 1 : (x * factorial0(x - 1)); | |
| 257 }; | |
| 258 // END TEMP | |
| 259 | |
| 260 | |
| 261 // Function statement. 'factorial1' is defined in the outer scope. | |
| 262 int factorial1(int x) { | |
| 263 return (x == 1) ? 1 : (x * factorial1(x - 1)); | |
| 264 } | |
| 265 | |
| 266 // This would fail to compile if 'recurse' were defined in the outer scope. | |
| 267 // Which it shouldn't be. | |
| 268 int recurse = 42; | |
| 269 | |
| 270 Expect.equals(6, factorial0(3)); | |
| 271 Expect.equals(24, factorial0(4)); | |
| 272 } | |
| 273 | |
| 274 void testDefaultParametersOrder() { | |
| 275 f([a = 1, b = 3]) { | |
| 276 return a - b; | |
| 277 } | |
| 278 Expect.equals(-2, f()); | |
| 279 } | |
| 280 | |
| 281 void testParametersOrder() { | |
| 282 f(a, b) { | |
| 283 return a - b; | |
| 284 } | |
| 285 Expect.equals(-2, f(1,3)); | |
| 286 } | |
| 287 | |
| 288 void testFunctionDefaults1() { | |
| 289 // TODO(jimhug): This return null shouldn't be necessary. | |
| 290 f() { return null; }; | |
| 291 (([a = 10]) { Expect.equals(10, a); })(); | |
| 292 ((a, [b = 10]) { Expect.equals(10, b); })(1); | |
| 293 (([a = 10]) { Expect.equals(null, a); })( f() ); | |
| 294 // FAILS: (([a = 10]) { Expect.equals(null ,a); })( f() ); | |
| 295 } | |
| 296 | |
| 297 void testFunctionDefaults2() { | |
| 298 Expect.equals(10, helperFunctionDefaults2()); | |
| 299 Expect.equals(1, helperFunctionDefaults2(1)); | |
| 300 } | |
| 301 | |
| 302 num helperFunctionDefaults2([a = 10]) { | |
| 303 return ((){return a;})(); | |
| 304 } | |
| 305 | |
| 306 void testEscapingFunctions() { | |
| 307 f() { return 42; }; | |
| 308 (() { Expect.equals(42, f()); })(); | |
| 309 var o = new Bug4089219(42); | |
| 310 Expect.equals(42, (o.f)()); | |
| 311 } | |
| 312 | |
| 313 void testThisBinding() { | |
| 314 Expect.equals(this, () { return this; }()); | |
| 315 } | |
| 316 } | |
| 317 | |
| 318 typedef void Foo<A, B>(A a, B b); | |
| 319 | |
| 320 class Bar<A, B> { | |
| 321 Foo<A, B> field; | |
| 322 Bar(A a, B b) : this.field = ((A a1, B b2){}) { | |
| 323 field(a, b); | |
| 324 } | |
| 325 } | |
| 326 | |
| 327 typedef UntypedFunction(arg); | |
| 328 typedef UntypedFunction2(arg); | |
| 329 | |
| 330 class UseFunctionTypes { | |
| 331 void test() { | |
| 332 Function f = null; | |
| 333 UntypedFunction uf = null; | |
| 334 UntypedFunction2 uf2 = null; | |
| 335 Foo foo = null; | |
| 336 Foo<int, String> fooIntString = null; | |
| 337 | |
| 338 f = uf; | |
| 339 f = uf2; | |
| 340 f = foo; | |
| 341 f = fooIntString; | |
| 342 | |
| 343 uf = f; | |
| 344 uf2 = f; | |
| 345 foo = f; | |
| 346 fooIntString = f; | |
| 347 | |
| 348 foo = fooIntString; | |
| 349 fooIntString = foo; | |
| 350 | |
| 351 uf = uf2; | |
| 352 uf2 = uf; | |
| 353 } | |
| 354 } | |
| 355 | |
| 356 main() { | |
| 357 FunctionTest.testMain(); | |
| 358 } | |
| OLD | NEW |