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

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

Powered by Google App Engine
This is Rietveld 408576698