Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: tests/language/async_star_test.dart

Issue 968963002: Add some async/await tests. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update more test expectations. Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tests/language/async_await_test.dart ('k') | tests/language/language.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, 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 library async_start_test;
6
7 import "package:unittest/unittest.dart";
ahe 2015/08/18 13:55:09 This means that the package unittest cannot use th
8 import "dart:async";
9
10 main() {
11 group("basic", () {
12 test("empty", () {
13 f() async* {}
14 return f().toList().then((v) {
15 expect(v, equals([]));
16 });
17 });
18
19 test("single", () {
20 f() async* { yield 42; }
21 return f().toList().then((v) {
22 expect(v, equals([42]));
23 });
24 });
25
26 test("call delays", () {
27 var list = [];
28 f() async* { list.add(1); yield 2; }
29 var res = f().forEach(list.add);
30 list.add(0);
31 return res.whenComplete(() {
32 expect(list, equals([0, 1, 2]));
33 });
34 });
35
36 test("throws", () {
37 f() async* { yield 1; throw 2; }
38 var completer = new Completer();
39 var list = [];
40 f().listen(list.add,
41 onError: (v) => list.add("$v"),
42 onDone: completer.complete);
43 return completer.future.whenComplete(() {
44 expect(list, equals([1, "2"]));
45 });
46 });
47
48 test("multiple", () {
49 f() async* {
50 for (int i = 0; i < 10; i++) {
51 yield i;
52 }
53 }
54 return expectList(f(), new List.generate(10, id));
55 });
56
57 test("allows await", () {
58 f() async* {
59 var x = await new Future.value(42);
60 yield x;
61 x = await new Future.value(42);
62 }
63 return expectList(f(), [42]);
64 });
65
66 test("allows await in loop", () {
67 f() async* {
68 for (int i = 0; i < 10; i++) {
69 yield await i;
70 }
71 }
72 return expectList(f(), new List.generate(10, id));
73 });
74
75 test("allows yield*", () {
76 f() async* {
77 yield* new Stream.fromIterable([1, 2, 3]);
78 }
79 return expectList(f(), [1, 2, 3]);
80 });
81
82 test("allows yield* of async*", () {
83 f(n) async* {
84 yield n;
85 if (n == 0) return;
86 yield* f(n - 1);
87 yield n;
88 }
89 return expectList(f(3), [3, 2, 1, 0, 1, 2, 3]);
90 });
91
92 test("Cannot yield* non-stream", () {
93 f(s) async* {
94 yield* s;
95 }
96 return f(42).transform(getErrors).single.then((v) {
97 // Not implementing Stream.
98 expect(v is Error, isTrue);
99 });
100 });
101
102 test("Cannot yield* non-stream", () {
103 f(s) async* {
104 yield* s;
105 }
106 return f(new NotAStream()).transform(getErrors).single.then((v) {
107 // Not implementing Stream.
108 expect(v is Error, isTrue);
109 });
110 });
111 });
112
113 group("yield statement context", () {
114 test("plain", () {
115 f() async* {
116 yield 0;
117 }
118 return expectList(f(), [0]);
119 });
120
121 test("if-then-else", () {
122 f(b) async* {
123 if (b) yield 0; else yield 1;
124 }
125 return expectList(f(true), [0]).whenComplete(() {
126 expectList(f(false), [1]);
127 });
128 });
129
130 test("block", () {
131 f() async* {
132 yield 0;
133 { yield 1; }
134 yield 2;
135 }
136 return expectList(f(), [0, 1, 2]);
137 });
138
139 test("labeled", () {
140 f() async* {
141 label1: yield 0;
142 }
143 return expectList(f(), [0]);
144 });
145
146 // VM issue 2238
147 test("labeled 2", () { /// 01: ok
148 f() async* { /// 01: continued
149 label1: label2: yield 0; /// 01: continued
150 } /// 01: continued
151 return expectList(f(), [0]); /// 01: continued
152 }); /// 01: continued
153
154 test("for-loop", () {
155 f() async* {
156 for (int i = 0; i < 3; i++) yield i;
157 }
158 return expectList(f(), [0, 1, 2]);
159 });
160
161 test("for-in-loop", () {
162 f() async* {
163 for (var i in [0, 1, 2]) yield i;
164 }
165 return expectList(f(), [0, 1, 2]);
166 });
167
168 test("await for-in-loop", () {
169 f() async* {
170 await for (var i in new Stream.fromIterable([0, 1, 2])) yield i;
171 }
172 return expectList(f(), [0, 1, 2]);
173 });
174
175 test("while-loop", () {
176 f() async* {
177 int i = 0;
178 while (i < 3) yield i++;
179 }
180 return expectList(f(), [0, 1, 2]);
181 });
182
183 test("do-while-loop", () {
184 f() async* {
185 int i = 0;
186 do yield i++; while (i < 3);
187 }
188 return expectList(f(), [0, 1, 2]);
189 });
190
191 test("try-catch-finally", () {
192 f() async* {
193 try { yield 0; } catch (e) { yield 1; } finally { yield 2; }
194 }
195 return expectList(f(), [0, 2]);
196 });
197
198 test("try-catch-finally 2", () {
199 f() async* {
200 try { yield throw 0; } catch (e) { yield 1; } finally { yield 2; }
201 }
202 return expectList(f(), [1, 2]);
203 });
204
205 test("switch-case", () {
206 f(v) async* {
207 switch (v) {
208 case 0:
209 yield 0;
210 continue label1;
211 label1:
212 case 1:
213 yield 1;
214 break;
215 default:
216 yield 2;
217 }
218 }
219 return expectList(f(0), [0, 1]).whenComplete(() {
220 return expectList(f(1), [1]);
221 }).whenComplete(() {
222 return expectList(f(2), [2]);
223 });
224 });
225
226 test("dead-code return", () {
227 f() async* {
228 return;
229 yield 1;
230 }
231 return expectList(f(), []);
232 });
233
234 test("dead-code throw", () {
235 f() async* {
236 try {
237 throw 0;
238 yield 1;
239 } catch (_) {}
240 }
241 return expectList(f(), []);
242 });
243
244 test("dead-code break", () {
245 f() async* {
246 while (true) {
247 break;
248 yield 1;
249 }
250 }
251 return expectList(f(), []);
252 });
253
254 test("dead-code break 2", () {
255 f() async* {
256 label: {
257 break label;
258 yield 1;
259 }
260 }
261 return expectList(f(), []);
262 });
263
264 test("dead-code continue", () {
265 f() async* {
266 do {
267 continue;
268 yield 1;
269 } while (false);
270 }
271 return expectList(f(), []);
272 });
273 });
274
275 group("yield expressions", () {
276 test("local variable", () {
277 f() async* {
278 var x = 42;
279 yield x;
280 }
281 return expectList(f(), [42]);
282 });
283
284 test("constant variable", () {
285 f() async* {
286 const x = 42;
287 yield x;
288 }
289 return expectList(f(), [42]);
290 });
291
292 test("function call", () {
293 g() => 42;
294 f() async* {
295 yield g();
296 }
297 return expectList(f(), [42]);
298 });
299
300 test("unary operator", () {
301 f() async* {
302 var x = -42;
303 yield -x;
304 }
305 return expectList(f(), [42]);
306 });
307
308 test("binary operator", () {
309 f() async* {
310 var x = 21;
311 yield x + x;
312 }
313 return expectList(f(), [42]);
314 });
315
316 test("ternary operator", () {
317 f() async* {
318 var x = 21;
319 yield x == 21 ? x + x : x;
320 }
321 return expectList(f(), [42]);
322 });
323
324 test("suffix post-increment", () {
325 f() async* {
326 var x = 42;
327 yield x++;
328 }
329 return expectList(f(), [42]);
330 });
331
332 test("suffix pre-increment", () {
333 f() async* {
334 var x = 41;
335 yield ++x;
336 }
337 return expectList(f(), [42]);
338 });
339
340 test("assignment", () {
341 f() async* {
342 var x = 37;
343 yield x = 42;
344 }
345 return expectList(f(), [42]);
346 });
347
348 test("assignment op", () {
349 f() async* {
350 var x = 41;
351 yield x += 1;
352 }
353 return expectList(f(), [42]);
354 });
355
356 test("await", () {
357 f() async* {
358 yield await new Future.value(42);
359 }
360 return expectList(f(), [42]);
361 });
362
363 test("index operator", () {
364 f() async* {
365 var x = [42];
366 yield x[0];
367 }
368 return expectList(f(), [42]);
369 });
370
371 test("function expression block", () {
372 var o = new Object();
373 f() async* {
374 yield () { return o; };
375 }
376 return f().first.then((v) {
377 expect(v(), same(o));
378 });
379 });
380
381 test("function expression arrow", () {
382 var o = new Object();
383 f() async* {
384 yield () => o;
385 }
386 return f().first.then((v) {
387 expect(v(), same(o));
388 });
389 });
390
391 test("function expression block async", () {
392 var o = new Object();
393 f() async* {
394 yield () async { return o; };
395 }
396 return f().first.then((v) => v()).then((v) {
397 expect(v, same(o));
398 });
399 });
400
401 test("function expression arrow async", () {
402 var o = new Object();
403 f() async* {
404 yield () async => o;
405 }
406 return f().first.then((v) => v()).then((v) {
407 expect(v, same(o));
408 });
409 });
410
411 test("function expression block async*", () {
412 var o = new Object();
413 f() async* {
414 yield () async* { yield o; };
415 }
416 return f().first.then((v) => v().first).then((v) {
417 expect(v, same(o));
418 });
419 });
420 });
421
422 group("loops", () {
423 test("simple yield", () {
424 f() async* {
425 for (int i = 0; i < 3; i++) {
426 yield i;
427 }
428 }
429 return expectList(f(), [0, 1, 2]);
430 });
431
432 test("yield in double loop", () {
433 f() async* {
434 for (int i = 0; i < 3; i++) {
435 for (int j = 0; j < 2; j++) {
436 yield i * 2 + j;
437 }
438 }
439 }
440 return expectList(f(), [0, 1, 2, 3, 4, 5]);
441 });
442
443 test("yield in try body", () {
444 var list = [];
445 f() async* {
446 for (int i = 0; i < 3; i++) {
447 try {
448 yield i;
449 } finally {
450 list.add("$i");
451 }
452 }
453 }
454 return expectList(f(), [0, 1, 2]).whenComplete(() {
455 expect(list, equals(["0", "1", "2"]));
456 });
457 });
458
459 test("yield in catch", () {
460 var list = [];
461 f() async* {
462 for (int i = 0; i < 3; i++) {
463 try {
464 throw i;
465 } catch (e) {
466 yield e;
467 } finally {
468 list.add("$i");
469 }
470 }
471 }
472 return expectList(f(), [0, 1, 2]).whenComplete(() {
473 expect(list, equals(["0", "1", "2"]));
474 });
475 });
476
477 test("yield in finally", () {
478 var list = [];
479 f() async* {
480 for (int i = 0; i < 3; i++) {
481 try {
482 throw i;
483 } finally {
484 yield i;
485 list.add("$i");
486 continue;
487 }
488 }
489 }
490 return expectList(f(), [0, 1, 2]).whenComplete(() {
491 expect(list, equals(["0", "1", "2"]));
492 });
493 });
494
495 test("keep yielding after cancel", () {
496 f() async* {
497 for (int i = 0; i < 10; i++) {
498 try {
499 yield i;
500 } finally {
501 continue;
502 }
503 }
504 }
505 return expectList(f().take(3), [0, 1, 2]);
506 });
507 });
508
509 group("canceling", () {
510 // Stream.take(n) automatically cancels after seeing the n'th value.
511
512 test("cancels at yield", () {
513 Completer exits = new Completer();
514 var list = [];
515 f() async* {
516 try {
517 list.add(0);
518 yield list.add(1);
519 list.add(2);
520 } finally {
521 exits.complete(3);
522 }
523 }
524 // No events must be fired synchronously in response to a listen.
525 var subscription = f().listen((v) { fail("Received event $v"); },
526 onDone: () { fail("Received done"); });
527 // No events must be delivered after a cancel.
528 subscription.cancel();
529 return exits.future.then((v) {
530 expect(v, equals(3));
531 expect(list, equals([0, 1]));
532 });
533 });
534
535 test("does cancel eventually", () {
536 var exits = new Completer();
537 var list = [];
538 f() async* {
539 int i = 0;
540 try {
541 while (true) yield i++;
542 } finally {
543 list.add("a");
544 exits.complete(i);
545 }
546 }
547 return expectList(f().take(5), [0, 1, 2, 3, 4])
548 .then((_) => exits.future)
549 .then((v) {
550 expect(v, greaterThan(4));
551 expect(list, ["a"]);
552 });
553 });
554
555 group("at index", () {
556 f() async* {
557 try {
558 yield await new Future.microtask(() => 1);
559 } finally {
560 try {
561 yield await new Future.microtask(() => 2);
562 } finally {
563 yield await new Future.microtask(() => 3);
564 }
565 }
566 }
567 test("- all, sanity check", () {
568 return expectList(f(), [1, 2, 3]);
569 });
570 test("after end", () {
571 return expectList(f().take(4), [1, 2, 3]);
572 });
573 test("at end", () {
574 return expectList(f().take(3), [1, 2, 3]);
575 });
576 test("before end", () {
577 return expectList(f().take(2), [1, 2]);
578 });
579 test("early", () {
580 return expectList(f().take(1), [1]);
581 });
582 test("at start", () {
583 return expectList(f().take(0), []);
584 });
585 });
586
587 // Crashes dart2js.
588 // test("regression-fugl/fisk", () {
589 // var res = [];
590 // fisk() async* {
591 // res.add("+fisk");
592 // try {
593 // for (int i = 0; i < 2; i++) {
594 // yield await new Future.microtask(() => i);
595 // }
596 // } finally {
597 // res.add("-fisk");
598 // }
599 // }
600
601 // fugl(int count) async {
602 // res.add("fisk $count");
603 // try {
604 // await for(int i in fisk().take(count)) res.add(i);
605 // } finally {
606 // res.add("done");
607 // }
608 // }
609
610 // return fugl(3).whenComplete(() => fugl(2))
611 // .whenComplete(() => fugl(1))
612 // .whenComplete(() {
613 // expect(res, ["fisk 3", "+fisk", 0, 1, "-fisk", "done",
614 // "fisk 2", "+fisk", 0, 1, "-fisk", "done",
615 // "fisk 1", "+fisk", 0, "done", "-fisk", ]);
616 // });
617 // });
618
619 });
620
621 group("pausing", () {
622 test("pauses execution at yield for at least a microtask", () {
623 var list = [];
624 f() async* {
625 list.add(1);
626 yield 2;
627 list.add(3);
628 yield 4;
629 list.add(5);
630 }
631 var done = new Completer();
632 var sub = f().listen((v) {
633 if (v == 2) {
634 expect(list, equals([1]));
635 } else if (v == 4) {
636 expect(list, equals([1, 3]));
637 } else {
638 fail("Unexpected value $v");
639 }
640 }, onDone: () {
641 expect(list, equals([1, 3, 5]));
642 done.complete();
643 });
644 return done.future;
645 });
646
647 test("pause stops execution at yield", () {
648 var list = [];
649 f() async* {
650 list.add(1);
651 yield 2;
652 list.add(3);
653 yield 4;
654 list.add(5);
655 }
656 var done = new Completer();
657 var sub;
658 sub = f().listen((v) {
659 if (v == 2) {
660 expect(list, equals([1]));
661 sub.pause();
662 new Timer(MS * 300, () {
663 expect(list.length, lessThan(3));
664 sub.resume();
665 });
666 } else if (v == 4) {
667 expect(list, equals([1, 3]));
668 } else {
669 fail("Unexpected value $v");
670 }
671 }, onDone: () {
672 expect(list, equals([1, 3, 5]));
673 done.complete();
674 });
675 return done.future;
676 });
677
678 test("pause stops execution at yield 2", () {
679 var list = [];
680 f() async* {
681 int i = 0;
682 while (true) {
683 yield i;
684 list.add(i);
685 i++;
686 }
687 }
688 int expected = 0;
689 var done = new Completer();
690 var sub;
691 sub = f().listen((v) {
692 expect(v, equals(expected++));
693 if (v % 5 == 0) {
694 sub.pause(new Future.delayed(MS * 300));
695 } else if (v == 17) {
696 sub.cancel();
697 done.complete();
698 }
699 }, onDone: () {
700 fail("Unexpected done!");
701 });
702 return done.future.whenComplete(() {
703 expect(list.length == 18 || list.length == 19, isTrue);
704 });
705 });
706
707 test("multiple pauses, cancel while paused", () {
708 var list = [];
709 f() async* {
710 int i = 0;
711 while (true) {
712 yield i;
713 list.add(i);
714 i++;
715 await null; // extra pause for good measure.
716 }
717 }
718 int expected = 0;
719 var done = new Completer();
720 var sub;
721 sub = f().listen((v) {
722 expect(v, equals(expected++));
723 if (v == 5) {
724 scheduleMicrotask(() {
725 sub.pause();
726 sub.resume();
727 sub.pause();
728 sub.resume();
729 sub.pause();
730 sub.resume();
731 });
732 } else if (v == 6) {
733 sub.pause();
734 new Timer(MS * 300, () {
735 expect(list.length, lessThan(8));
736 sub.cancel();
737 done.complete();
738 });
739 }
740 }, onDone: () {
741 fail("Unexpected done");
742 });
743 });
744
745 test("canceling while paused at yield", () { /// 02: ok
746 var list = []; /// 02: contin ued
747 var sync = new Sync(); /// 02: contin ued
748 f() async* { /// 02: contin ued
749 list.add("*1"); /// 02: contin ued
750 yield 1; /// 02: contin ued
751 await sync.wait(); /// 02: contin ued
752 sync.release(); /// 02: contin ued
753 list.add("*2"); /// 02: contin ued
754 yield 2; /// 02: contin ued
755 list.add("*3"); /// 02: contin ued
756 }; /// 02: contin ued
757 var stream = f(); /// 02: contin ued
758 var sub = stream.listen(list.add); /// 02: contin ued
759 return sync.wait().whenComplete(() { /// 02: contin ued
760 expect(list, equals(["*1", 1])); /// 02: contin ued
761 sub.pause(); /// 02: contin ued
762 return sync.wait(); /// 02: contin ued
763 }).whenComplete(() { /// 02: contin ued
764 expect(list, equals(["*1", 1, "*2"])); /// 02: contin ued
765 sub.cancel(); /// 02: contin ued
766 return new Future.delayed(MS * 200, () { /// 02: contin ued
767 // Should not have yielded 2 or added *3 while paused. /// 02: contin ued
768 expect(list, equals(["*1", 1, "*2"])); /// 02: contin ued
769 }); /// 02: contin ued
770 }); /// 02: contin ued
771 }); /// 02: contin ued
772 });
773
774 group("await for", () {
775 mkStream(int n) async* {
776 for (int i = 0; i < n; i++) yield i;
777 }
778
779 test("simple stream", () {
780 f(s) async {
781 var r = 0;
782 await for(var v in s) r += v;
783 return r;
784 }
785 return f(mkStream(5)).then((v) {
786 expect(v, equals(10));
787 });
788 });
789
790 test("simple stream, await", () {
791 f(s) async {
792 var r = 0;
793 await for(var v in s) r += await new Future.microtask(() => v);
794 return r;
795 }
796 return f(mkStream(5)).then((v) {
797 expect(v, equals(10));
798 });
799 });
800
801 test("simple stream - take", () { /// 03: ok
802 f(s) async { /// 03: continued
803 var r = 0; /// 03: continued
804 await for(var v in s.take(5)) r += v; /// 03: continued
805 return r; /// 03: continued
806 } /// 03: continued
807 return f(mkStream(10)).then((v) { /// 03: continued
808 expect(v, equals(10)); /// 03: continued
809 }); /// 03: continued
810 }); /// 03: continued
811
812 test("simple stream reyield", () {
813 f(s) async* {
814 var r = 0;
815 await for(var v in s) yield r += v;
816 }
817 return expectList(f(mkStream(5)), [0, 1, 3, 6, 10]);
818 });
819
820 test("simple stream, await, reyield", () {
821 f(s) async* {
822 var r = 0;
823 await for(var v in s) yield r += await new Future.microtask(() => v);
824 }
825 return expectList(f(mkStream(5)), [0, 1, 3, 6, 10]);
826 });
827
828 test("simple stream - take, reyield", () { /// 04: ok
829 f(s) async* { /// 04: continued
830 var r = 0; /// 04: continued
831 await for(var v in s.take(5)) yield r += v; /// 04: continued
832 } /// 04: continued
833 return expectList(f(mkStream(10)), [0, 1, 3, 6, 10]); /// 04: continued
834 }); /// 04: continued
835
836 test("nested", () {
837 f() async {
838 var r = 0;
839 await for (var i in mkStream(5)) {
840 await for (var j in mkStream(3)) {
841 r += i * j;
842 }
843 }
844 return r;
845 }
846 return f().then((v) {
847 expect(v, equals((1 + 2 + 3 + 4) * (1 + 2)));
848 });
849 });
850
851 test("nested, await", () {
852 f() async {
853 var r = 0;
854 await for (var i in mkStream(5)) {
855 await for (var j in mkStream(3)) {
856 r += await new Future.microtask(() => i * j);
857 }
858 }
859 return r;
860 }
861 return f().then((v) {
862 expect(v, equals((1 + 2 + 3 + 4) * (1 + 2)));
863 });
864 });
865
866 test("nested, await * 2", () {
867 f() async {
868 var r = 0;
869 await for (var i in mkStream(5)) {
870 var ai = await new Future.microtask(() => i);
871 await for (var j in mkStream(3)) {
872 r += await new Future.microtask(() => ai * j);
873 }
874 }
875 return r;
876 }
877 return f().then((v) {
878 expect(v, equals((1 + 2 + 3 + 4) * (1 + 2)));
879 });
880 });
881
882 test("await pauses loop", () { /// 05: ok
883 var sc; /// 05: con tinued
884 var i = 0; /// 05: con tinued
885 void send() { /// 05: con tinued
886 if (i == 5) { /// 05: con tinued
887 sc.close(); /// 05: con tinued
888 } else { /// 05: con tinued
889 sc.add(i++); /// 05: con tinued
890 } /// 05: con tinued
891 } /// 05: con tinued
892 sc = new StreamController(onListen: send, onResume: send); /// 05: con tinued
893 f(s) async { /// 05: con tinued
894 var r = 0; /// 05: con tinued
895 await for (var i in s) { /// 05: con tinued
896 r += await new Future.delayed(MS * 10, () => i); /// 05: con tinued
897 } /// 05: con tinued
898 return r; /// 05: con tinued
899 } /// 05: con tinued
900 return f(sc.stream).then((v) { /// 05: con tinued
901 expect(v, equals(10)); /// 05: con tinued
902 }); /// 05: con tinued
903 }); /// 05: con tinued
904 });
905 }
906
907 // Obscuring identity function.
908 id(x) {
909 try {
910 if (x != null) throw x;
911 } catch (e) {
912 return e;
913 }
914 return null;
915 }
916
917 expectList(stream, list) {
918 return stream.toList().then((v) {
919 expect(v, equals(list));
920 });
921 }
922
923 const MS = const Duration(milliseconds: 1);
924
925 var getErrors = new StreamTransformer.fromHandlers(
926 handleData:(data, sink) { fail("Unexpected value"); },
927 handleError: (e, s, sink) { sink.add(e); },
928 handleDone: (sink) { sink.close(); });
929
930 class NotAStream {
931 listen(oData, {onError, onDone, cancelOnError}) {
932 fail("Not implementing Stream.");
933 }
934 }
935
936 /**
937 * Allows two asynchronous executions to synchronize.
938 *
939 * Calling [wait] and waiting for the returned future to complete will
940 * wait for the other executions to call [wait] again. At that point,
941 * the waiting execution is allowed to continue (the returned future completes),
942 * and the more resent call to [wait] is now the waiting execution.
943 */
944 class Sync {
945 Completer _completer = null;
946 // Release whoever is currently waiting and start waiting yourself.
947 Future wait([v]) {
948 if (_completer != null) _completer.complete(v);
949 _completer = new Completer();
950 return _completer.future;
951 }
952
953 // Release whoever is currently waiting.
954 void release([v]) {
955 if (_completer != null) {
956 _completer.complete(v);
957 _completer = null;
958 }
959 }
960 }
OLDNEW
« no previous file with comments | « tests/language/async_await_test.dart ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698