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

Side by Side Diff: tests/compiler/dart2js/async_await_js_transform_test.dart

Issue 839323003: Implementation of async-await transformation on js ast. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Fix setting of the handler in finallies... Created 5 years, 10 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
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 import "package:expect/expect.dart";
6 import "package:compiler/src/js/js.dart";
7 import "package:compiler/src/js/rewrite_async.dart";
8
9 import "backend_dart/dart_printer_test.dart" show PrintDiagnosticListener;
10
11 void testTransform(String source, String expected) {
12 Fun fun = js(source);
13 Fun rewritten = new AsyncRewriter(
14 null, // The diagnostic helper should not be used in these tests.
15 null,
16 thenHelper: new VariableUse("thenHelper"),
17 newCompleter: new VariableUse("Completer"),
18 endOfIteration: new VariableUse("endOfIteration"),
19 newIterable: new VariableUse("Iterator"),
20 safeVariableName: (String name) => "__$name").rewrite(fun);
21 Printer printer = new Printer(new PrintDiagnosticListener(), null);
22 printer.visit(rewritten);
23 Expect.stringEquals(expected, printer.outBuffer.getText());
24 }
25
26 main() {
27 testTransform("""
28 function() async {
29 print(this.x); // Ensure `this` is translated in the helper function.
30 await foo();
31 }""", """
32 function() {
33 var __goto = 0, __completer = new Completer(), __self = this;
34 function __helper(__result) {
35 while (true)
36 switch (__goto) {
37 case 0:
38 // Function start
39 print(__self.x);
40 __goto = 1;
41 return thenHelper(foo(), __helper, __completer, null);
42 case 1:
43 // returning from await.
44 // implicit return
45 return thenHelper(null, null, __completer, null);
46 }
47 }
48 return thenHelper(null, __helper, __completer, null);
49 }""");
50
51 testTransform("""
52 function() async {
53 try {
54 __outer: while (true) { // Overlapping label name.
55 try {
56 inner: while (true) {
57 break __outer; // Break from untranslated loop to translated target.
58 break; // break to untranslated target.
59 }
60 while (true) {
61 return; // Return via finallies.
62 }
63 var __helper = await foo(); // Overlapping variable name.
64 } finally {
65 foo();
66 continue; // Continue from finally with pending finally.
67 return 2; // Return from finally with pending finally.
68 }
69 }
70 } finally {
71 return 3; // Return from finally with no pending finally.
72 }
73 return 4;
74 }""", """
75 function() {
76 var __goto = 0, __completer = new Completer(), __handler = null, __next, __ret urnValue, __helper;
77 function __helper1(__result) {
78 while (true)
79 try {
80 __outer1:
81 switch (__goto) {
82 case 0:
83 // Function start
84 __handler = 2;
85 case 6:
86 // continue __outer
87 case 7:
88 // while condition
89 __handler = 9;
90 inner: {
91 while (true) {
92 __next = [5];
93 // goto finally
94 __goto = 10;
95 break __outer1;
96 break;
97 }
98 }
99 while (true) {
100 __next = [1, 3];
101 // goto finally
102 __goto = 10;
103 break __outer1;
104 }
105 __goto = 12;
106 return thenHelper(foo(), __helper1, __completer, function(__error) {
107 __goto = 9;
108 __helper1(__error);
109 });
110 case 12:
111 // returning from await.
112 __helper = __result;
113 __next = [11];
114 // goto finally
115 __goto = 10;
116 break;
117 case 9:
118 // catch
119 __handler = 2;
120 __next = [11];
floitsch 2015/02/05 20:17:23 The example doesn't have an explicit 'catch', and
sigurdm 2015/02/06 14:26:35 Acknowledged.
121 case 10:
122 // finally
123 __handler = 2;
124 foo();
125 // goto while condition
126 __goto = 7;
127 break;
128 __returnValue = 2;
129 __next = [1];
130 // goto finally
131 __goto = 3;
132 break;
133 // goto the next finally handler
134 __goto = __next.pop();
135 break;
136 case 11:
137 // after finally
138 // goto while condition
139 __goto = 7;
140 break;
141 case 8:
142 // after while
143 case 5:
144 // break __outer
145 __next = [4];
146 // goto finally
147 __goto = 3;
148 break;
149 case 2:
150 // catch
151 __handler = null;
152 __next = [4];
153 case 3:
154 // finally
155 __handler = null;
156 __returnValue = 3;
157 // goto Return
158 __goto = 1;
159 break;
160 // goto the next finally handler
161 __goto = __next.pop();
162 break;
163 case 4:
164 // after finally
165 __returnValue = 4;
166 // goto Return
167 __goto = 1;
168 break;
169 case 1:
170 // Return
171 return thenHelper(__returnValue, null, __completer, null);
172 }
173 } catch (__error) {
174 if (__handler === null)
175 throw __error;
176 __result = __error;
177 __goto = __handler;
178 }
179
180 }
181 return thenHelper(null, __helper1, __completer, null);
182 }""");
183 testTransform("""
184 function() async {
185 var a, b, c, d, e, f;
186 a = b++; // post- and preincrements.
187 b = --b;
188 c = (await foo()).a++;
189 d = ++(await foo()).a;
190 e = foo1()[await foo2()]--;
191 f = --foo1()[await foo2()];
192 }""", """
193 function() {
194 var __goto = 0, __completer = new Completer(), a, b, c, d, e, f, __temp1;
195 function __helper(__result) {
196 while (true)
197 switch (__goto) {
198 case 0:
199 // Function start
200 a = b++;
201 b = --b;
202 __goto = 1;
203 return thenHelper(foo(), __helper, __completer, null);
204 case 1:
205 // returning from await.
206 c = __result.a++;
207 __goto = 2;
208 return thenHelper(foo(), __helper, __completer, null);
209 case 2:
210 // returning from await.
211 d = ++__result.a;
212 __temp1 = foo1();
213 __goto = 3;
214 return thenHelper(foo2(), __helper, __completer, null);
215 case 3:
216 // returning from await.
217 e = __temp1[__result]--;
218 __temp1 = foo1();
219 __goto = 4;
220 return thenHelper(foo2(), __helper, __completer, null);
221 case 4:
222 // returning from await.
223 f = --__temp1[__result];
224 // implicit return
225 return thenHelper(null, null, __completer, null);
226 }
227 }
228 return thenHelper(null, __helper, __completer, null);
229 }""");
230 testTransform("""
231 function() async {
232 var a, b, c, d, e, f, g, h; // empty initializer
233 a = foo1() || await foo2(); // short circuiting operators
234 b = await foo1() || foo2();
235 c = await foo1() || foo3(await foo2());
236 d = foo1() || foo2();
237 e = foo1() && await foo2();
238 f = await foo1() && foo2();
239 g = await foo1() && await foo2();
240 h = foo1() && foo2();
241 }""", """
242 function() {
243 var __goto = 0, __completer = new Completer(), a, b, c, d, e, f, g, h, __temp1 ;
244 function __helper(__result) {
245 while (true)
246 switch (__goto) {
247 case 0:
248 // Function start
249 __temp1 = foo1();
250 if (__temp1) {
251 // goto then
252 __goto = 1;
253 break;
254 } else
255 __result = __temp1;
256 // goto join
257 __goto = 2;
258 break;
259 case 1:
260 // then
261 __goto = 3;
262 return thenHelper(foo2(), __helper, __completer, null);
263 case 3:
264 // returning from await.
265 case 2:
266 // join
267 a = __result;
268 __goto = 4;
269 return thenHelper(foo1(), __helper, __completer, null);
270 case 4:
271 // returning from await.
272 b = __result || foo2();
273 __goto = 7;
274 return thenHelper(foo1(), __helper, __completer, null);
275 case 7:
276 // returning from await.
277 __temp1 = __result;
278 if (__temp1) {
279 // goto then
280 __goto = 5;
281 break;
282 } else
283 __result = __temp1;
284 // goto join
285 __goto = 6;
286 break;
287 case 5:
288 // then
289 __temp1 = foo3;
290 __goto = 8;
291 return thenHelper(foo2(), __helper, __completer, null);
292 case 8:
293 // returning from await.
294 __result = __temp1(__result);
295 case 6:
296 // join
297 c = __result;
298 d = foo1() || foo2();
299 __temp1 = foo1();
300 if (__temp1)
301 __result = __temp1;
302 else {
303 // goto then
304 __goto = 9;
305 break;
306 }
307 // goto join
308 __goto = 10;
309 break;
310 case 9:
311 // then
312 __goto = 11;
313 return thenHelper(foo2(), __helper, __completer, null);
314 case 11:
315 // returning from await.
316 case 10:
317 // join
318 e = __result;
319 __goto = 12;
320 return thenHelper(foo1(), __helper, __completer, null);
321 case 12:
322 // returning from await.
323 f = __result && foo2();
324 __goto = 15;
325 return thenHelper(foo1(), __helper, __completer, null);
326 case 15:
327 // returning from await.
328 __temp1 = __result;
329 if (__temp1)
330 __result = __temp1;
331 else {
332 // goto then
333 __goto = 13;
334 break;
335 }
336 // goto join
337 __goto = 14;
338 break;
339 case 13:
340 // then
341 __goto = 16;
342 return thenHelper(foo2(), __helper, __completer, null);
343 case 16:
344 // returning from await.
345 case 14:
346 // join
347 g = __result;
348 h = foo1() && foo2();
349 // implicit return
350 return thenHelper(null, null, __completer, null);
351 }
352 }
353 return thenHelper(null, __helper, __completer, null);
354 }""");
355 testTransform("""
356 function(x, y) async {
357 while (true) {
358 switch(y) { // Switch with no awaits in case key expressions
359 case 0:
360 case 1:
361 await foo();
362 continue; // Continue the loop, not the switch
363 case 1: // Duplicate case
364 await foo();
365 break; // Break the switch
366 case 2:
367 foo(); // No default
368 }
369 }
370 }""", """
371 function(x, y) {
372 var __goto = 0, __completer = new Completer();
373 function __helper(__result) {
374 while (true)
375 switch (__goto) {
376 case 0:
377 // Function start
378 case 1:
379 // while condition
380 case 3:
381 // switch
382 switch (y) {
383 case 0:
384 // goto case
385 __goto = 5;
386 break;
387 case 1:
388 // goto case
389 __goto = 6;
390 break;
391 case 1:
392 // goto case
393 __goto = 7;
394 break;
395 case 2:
396 // goto case
397 __goto = 8;
398 break;
399 }
400 // goto after switch
401 __goto = 4;
402 break;
403 case 5:
404 // case
405 case 6:
406 // case
407 __goto = 9;
408 return thenHelper(foo(), __helper, __completer, null);
409 case 9:
410 // returning from await.
411 // goto while condition
412 __goto = 1;
413 break;
414 case 7:
415 // case
416 __goto = 10;
417 return thenHelper(foo(), __helper, __completer, null);
418 case 10:
419 // returning from await.
420 // goto after switch
421 __goto = 4;
422 break;
423 case 8:
424 // case
425 foo();
426 case 4:
427 // after switch
428 // goto while condition
429 __goto = 1;
430 break;
431 case 2:
432 // after while
433 // implicit return
434 return thenHelper(null, null, __completer, null);
435 }
436 }
437 return thenHelper(null, __helper, __completer, null);
438 }""");
439 testTransform("""
440 function() async {
441 do {
442 var a = await foo();
443 if (a) // If with no awaits in body
444 break;
445 else
446 continue;
447 } while (await foo());
448 }
449 """, """
450 function() {
451 var __goto = 0, __completer = new Completer(), a;
452 function __helper(__result) {
453 while (true)
454 switch (__goto) {
455 case 0:
456 // Function start
457 case 1:
458 // do body
459 __goto = 4;
460 return thenHelper(foo(), __helper, __completer, null);
461 case 4:
462 // returning from await.
463 a = __result;
464 if (a) {
465 // goto after do
466 __goto = 3;
467 break;
468 } else {
469 // goto do condition
470 __goto = 2;
471 break;
472 }
473 case 2:
474 // do condition
475 __goto = 5;
476 return thenHelper(foo(), __helper, __completer, null);
477 case 5:
478 // returning from await.
479 if (__result) {
480 // goto do body
481 __goto = 1;
482 break;
483 }
484 case 3:
485 // after do
486 // implicit return
487 return thenHelper(null, null, __completer, null);
488 }
489 }
490 return thenHelper(null, __helper, __completer, null);
491 }""");
492
493 testTransform("""
494 function() async {
495 for (var i = 0; i < await foo1(); i += await foo2()) {
496 if (foo(i))
497 continue;
498 else
499 break;
500 if (!foo(i)) { // If with no else and await in body.
501 await foo();
502 return;
503 }
504 print(await(foo(i)));
505 }
506 }
507 """, """
508 function() {
509 var __goto = 0, __completer = new Completer(), __returnValue, i, __temp1;
510 function __helper(__result) {
511 while (true)
512 switch (__goto) {
513 case 0:
514 // Function start
515 i = 0;
516 case 2:
517 // for condition
518 __temp1 = i;
519 __goto = 5;
520 return thenHelper(foo1(), __helper, __completer, null);
521 case 5:
522 // returning from await.
523 if (!(__temp1 < __result)) {
524 // goto after for
525 __goto = 4;
526 break;
527 }
528 if (foo(i)) {
529 // goto for update
530 __goto = 3;
531 break;
532 } else {
533 // goto after for
534 __goto = 4;
535 break;
536 }
537 __goto = !foo(i) ? 6 : 7;
538 break;
539 case 6:
540 // then
541 __goto = 8;
542 return thenHelper(foo(), __helper, __completer, null);
543 case 8:
544 // returning from await.
545 // goto Return
546 __goto = 1;
547 break;
548 case 7:
549 // join
550 __temp1 = print;
551 __goto = 9;
552 return thenHelper(foo(i), __helper, __completer, null);
553 case 9:
554 // returning from await.
555 __temp1(__result);
556 case 3:
557 // for update
558 __goto = 10;
559 return thenHelper(foo2(), __helper, __completer, null);
560 case 10:
561 // returning from await.
562 i = __result;
563 // goto for condition
564 __goto = 2;
565 break;
566 case 4:
567 // after for
568 case 1:
569 // Return
570 return thenHelper(__returnValue, null, __completer, null);
571 }
572 }
573 return thenHelper(null, __helper, __completer, null);
574 }""");
575
576 testTransform("""
577 function(a) async {
578 var x = {"a": foo1(), "b": await foo2(), "c": foo3()};
579 x["a"] = 2; // Different assignments
580 (await foo()).a = 3;
581 x[await foo()] = 4;
582 x[(await foo1()).a = await foo2()] = 5;
583 (await foo1())[await foo2()] = await foo3(6);
584 }
585 """, """
586 function(a) {
587 var __goto = 0, __completer = new Completer(), x, __temp1, __temp2;
588 function __helper(__result) {
589 while (true)
590 switch (__goto) {
591 case 0:
592 // Function start
593 __temp1 = foo1();
594 __goto = 1;
595 return thenHelper(foo2(), __helper, __completer, null);
596 case 1:
597 // returning from await.
598 x = {a: __temp1, b: __result, c: foo3()};
599 x.a = 2;
600 __goto = 2;
601 return thenHelper(foo(), __helper, __completer, null);
602 case 2:
603 // returning from await.
604 __result.a = 3;
605 __temp1 = x;
606 __goto = 3;
607 return thenHelper(foo(), __helper, __completer, null);
608 case 3:
609 // returning from await.
610 __temp1[__result] = 4;
611 __temp1 = x;
612 __goto = 4;
613 return thenHelper(foo1(), __helper, __completer, null);
614 case 4:
615 // returning from await.
616 __temp2 = __result;
617 __goto = 5;
618 return thenHelper(foo2(), __helper, __completer, null);
619 case 5:
620 // returning from await.
621 __temp1[__temp2.a = __result] = 5;
622 __goto = 6;
623 return thenHelper(foo1(), __helper, __completer, null);
624 case 6:
625 // returning from await.
626 __temp1 = __result;
627 __goto = 7;
628 return thenHelper(foo2(), __helper, __completer, null);
629 case 7:
630 // returning from await.
631 __temp2 = __result;
632 __goto = 8;
633 return thenHelper(foo3(6), __helper, __completer, null);
634 case 8:
635 // returning from await.
636 __temp1[__temp2] = __result;
637 // implicit return
638 return thenHelper(null, null, __completer, null);
639 }
640 }
641 return thenHelper(null, __helper, __completer, null);
642 }""");
643 testTransform("""
644 function(c) async {
645 try {
646 var x = c ? await foo() : foo(); // conditional
647 var y = {};
648 } catch (error) {
649 try {
650 x = c ? await fooError(error) : fooError(error);
651 } catch (error) { // nested error handler with overlapping name
652 y.x = foo(error);
653 } finally {
654 foo(x);
655 }
656 }
657 }
658 """, """
659 function(c) {
660 var __goto = 0, __completer = new Completer(), __handler = null, x, y, __error 1, __error2;
661 function __helper(__result) {
662 while (true)
663 try {
664 switch (__goto) {
665 case 0:
666 // Function start
667 __handler = 1;
668 __goto = c ? 4 : 6;
669 break;
670 case 4:
671 // then
672 __goto = 7;
673 return thenHelper(foo(), __helper, __completer, function(__error) {
674 __goto = 1;
675 __helper(__error);
676 });
677 case 7:
678 // returning from await.
679 // goto join
680 __goto = 5;
681 break;
682 case 6:
683 // else
684 __result = foo();
685 case 5:
686 // join
687 x = __result;
688 y = {};
689 __next = [3];
690 __handler = null;
691 // goto after finally
692 __goto = 3;
693 break;
694 case 1:
695 // catch
696 __handler = null;
697 __error1 = __result;
698 __handler = 8;
699 __goto = c ? 11 : 13;
700 break;
701 case 11:
702 // then
703 __goto = 14;
704 return thenHelper(fooError(__error1), __helper, __completer, functio n(__error) {
705 __goto = 8;
706 __helper(__error);
707 });
708 case 14:
709 // returning from await.
710 // goto join
711 __goto = 12;
712 break;
713 case 13:
714 // else
715 __result = fooError(__error1);
716 case 12:
717 // join
718 x = __result;
719 __next = [10];
720 // goto finally
721 __goto = 9;
722 break;
723 case 8:
724 // catch
725 __handler = null;
726 __error2 = __result;
727 y.x = foo(__error2);
728 __handler = null;
729 __next = [10];
730 case 9:
731 // finally
732 __handler = null;
733 foo(x);
734 // goto the next finally handler
735 __goto = __next.pop();
736 break;
737 case 10:
738 // after finally
739 case 3:
740 // after finally
741 // implicit return
742 return thenHelper(null, null, __completer, null);
743 }
744 } catch (__error) {
745 if (__handler === null)
746 throw __error;
747 __result = __error;
748 __goto = __handler;
749 }
750
751 }
752 return thenHelper(null, __helper, __completer, null);
753 }""");
754 testTransform("""
755 function(x, y) async {
756 print(await(foo(x))); // calls
757 (await print)(foo(x));
758 print(foo(await x));
759 await (print(foo(await x)));
760 print(foo(x, await y, z));
761 }
762 """, """
763 function(x, y) {
764 var __goto = 0, __completer = new Completer(), __temp1, __temp2, __temp3;
765 function __helper(__result) {
766 while (true)
767 switch (__goto) {
768 case 0:
769 // Function start
770 __temp1 = print;
771 __goto = 1;
772 return thenHelper(foo(x), __helper, __completer, null);
773 case 1:
774 // returning from await.
775 __temp1(__result);
776 __goto = 2;
777 return thenHelper(print, __helper, __completer, null);
778 case 2:
779 // returning from await.
780 __result(foo(x));
781 __temp1 = print;
782 __temp2 = foo;
783 __goto = 3;
784 return thenHelper(x, __helper, __completer, null);
785 case 3:
786 // returning from await.
787 __temp1(__temp2(__result));
788 __temp1 = print;
789 __temp2 = foo;
790 __goto = 5;
791 return thenHelper(x, __helper, __completer, null);
792 case 5:
793 // returning from await.
794 __goto = 4;
795 return thenHelper(__temp1(__temp2(__result)), __helper, __completer, n ull);
796 case 4:
797 // returning from await.
798 __temp1 = print;
799 __temp2 = foo;
800 __temp3 = x;
801 __goto = 6;
802 return thenHelper(y, __helper, __completer, null);
803 case 6:
804 // returning from await.
805 __temp1(__temp2(__temp3, __result, z));
806 // implicit return
807 return thenHelper(null, null, __completer, null);
808 }
809 }
810 return thenHelper(null, __helper, __completer, null);
811 }""");
812 testTransform("""
813 function(x, y) async {
814 while (await(foo())) {
815 lab: { // labelled statement
816 switch(y) {
817 case 0:
818 foo();
819 case 0: // Duplicate case
820 print(await foo1(x));
821 return y;
822 case await bar(): // await in case
823 print(await foobar(x));
824 return y;
825 case x:
826 if (a) {
827 throw new Error();
828 } else {
829 continue;
830 }
831 default: // defaul case
832 break lab; // break to label
833 }
834 foo();
835 }
836 }
837 }""", """
838 function(x, y) {
839 var __goto = 0, __completer = new Completer(), __returnValue, __temp1;
840 function __helper(__result) {
841 while (true)
842 switch (__goto) {
843 case 0:
844 // Function start
845 case 2:
846 // while condition
847 __goto = 4;
848 return thenHelper(foo(), __helper, __completer, null);
849 case 4:
850 // returning from await.
851 if (!__result) {
852 // goto after while
853 __goto = 3;
854 break;
855 }
856 case 6:
857 // continue lab
858 case 7:
859 // switch
860 __temp1 = y;
861 if (__temp1 === 0) {
862 // goto case
863 __goto = 9;
864 break;
865 }
866 if (__temp1 === 0) {
867 // goto case
868 __goto = 10;
869 break;
870 }
871 __goto = 12;
872 return thenHelper(bar(), __helper, __completer, null);
873 case 12:
874 // returning from await.
875 if (__temp1 === __result) {
876 // goto case
877 __goto = 11;
878 break;
879 }
880 if (__temp1 === x) {
881 // goto case
882 __goto = 13;
883 break;
884 }
885 // goto default
886 __goto = 14;
887 break;
888 case 9:
889 // case
890 foo();
891 case 10:
892 // case
893 __temp1 = print;
894 __goto = 15;
895 return thenHelper(foo1(x), __helper, __completer, null);
896 case 15:
897 // returning from await.
898 __temp1(__result);
899 __returnValue = y;
900 // goto Return
901 __goto = 1;
902 break;
903 case 11:
904 // case
905 __temp1 = print;
906 __goto = 16;
907 return thenHelper(foobar(x), __helper, __completer, null);
908 case 16:
909 // returning from await.
910 __temp1(__result);
911 __returnValue = y;
912 // goto Return
913 __goto = 1;
914 break;
915 case 13:
916 // case
917 if (a) {
918 throw new Error();
919 } else {
920 // goto while condition
921 __goto = 2;
922 break;
923 }
924 case 14:
925 // default
926 // goto break lab
927 __goto = 5;
928 break;
929 case 8:
930 // after switch
931 foo();
932 case 5:
933 // break lab
934 // goto while condition
935 __goto = 2;
936 break;
937 case 3:
938 // after while
939 case 1:
940 // Return
941 return thenHelper(__returnValue, null, __completer, null);
942 }
943 }
944 return thenHelper(null, __helper, __completer, null);
945 }""");
946 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698