Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library rewrite_async; | 5 library rewrite_async; |
| 6 | 6 |
| 7 import "dart:math" show max; | 7 import "dart:math" show max; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'package:_internal/compiler/js_lib/shared/async_await_error_codes.dart' | 10 import 'package:_internal/compiler/js_lib/shared/async_await_error_codes.dart' |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 assert(!labelledParts.containsKey(label)); | 398 assert(!labelledParts.containsKey(label)); |
| 399 currentStatementBuffer = new List<js.Statement>(); | 399 currentStatementBuffer = new List<js.Statement>(); |
| 400 labelledParts[label] = currentStatementBuffer; | 400 labelledParts[label] = currentStatementBuffer; |
| 401 addStatement(new js.Comment(labelComments[label])); | 401 addStatement(new js.Comment(labelComments[label])); |
| 402 } | 402 } |
| 403 | 403 |
| 404 /// Returns a statement assigning to the variable named [gotoName]. | 404 /// Returns a statement assigning to the variable named [gotoName]. |
| 405 /// This should be followed by a break for the goto to be executed. Use | 405 /// This should be followed by a break for the goto to be executed. Use |
| 406 /// [gotoWithBreak] or [addGoto] for this. | 406 /// [gotoWithBreak] or [addGoto] for this. |
| 407 js.Statement setGotoVariable(int label) { | 407 js.Statement setGotoVariable(int label) { |
| 408 return new js.ExpressionStatement( | 408 return js.js.statement('# = #', [gotoName, js.number(label)]); |
| 409 new js.Assignment(new js.VariableUse(gotoName), js.number(label))); | |
| 410 } | 409 } |
| 411 | 410 |
| 412 /// Returns a block that has a goto to [label] including the break. | 411 /// Returns a block that has a goto to [label] including the break. |
| 413 /// | 412 /// |
| 414 /// Also inserts a comment describing the label if available. | 413 /// Also inserts a comment describing the label if available. |
| 415 js.Block gotoAndBreak(int label) { | 414 js.Block gotoAndBreak(int label) { |
| 416 List<js.Statement> statements = new List<js.Statement>(); | 415 List<js.Statement> statements = new List<js.Statement>(); |
| 417 if (labelComments.containsKey(label)) { | 416 if (labelComments.containsKey(label)) { |
| 418 statements.add(new js.Comment("goto ${labelComments[label]}")); | 417 statements.add(new js.Comment("goto ${labelComments[label]}")); |
| 419 } | 418 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 /// - _storeIfNecessary(someLiteral) returns someLiteral. | 499 /// - _storeIfNecessary(someLiteral) returns someLiteral. |
| 501 /// - _storeIfNecessary(someVariable) | 500 /// - _storeIfNecessary(someVariable) |
| 502 /// inserts: var tempX = someVariable | 501 /// inserts: var tempX = someVariable |
| 503 /// returns: tempX | 502 /// returns: tempX |
| 504 /// where tempX is a fresh temporary variable. | 503 /// where tempX is a fresh temporary variable. |
| 505 js.Expression _storeIfNecessary(js.Expression result) { | 504 js.Expression _storeIfNecessary(js.Expression result) { |
| 506 // Note that RegExes, js.ArrayInitializer and js.ObjectInitializer are not | 505 // Note that RegExes, js.ArrayInitializer and js.ObjectInitializer are not |
| 507 // [js.Literal]s. | 506 // [js.Literal]s. |
| 508 if (result is js.Literal) return result; | 507 if (result is js.Literal) return result; |
| 509 js.Expression tempVar = useTempVar(allocateTempVar()); | 508 js.Expression tempVar = useTempVar(allocateTempVar()); |
| 510 addExpressionStatement(new js.Assignment(tempVar, result)); | 509 addStatement(js.js.statement('# = #;', [tempVar, result])); |
|
floitsch
2015/02/23 16:15:34
apparently you don't need the ";". (At least you d
sigurdm
2015/02/24 13:16:20
I'll add it everywhere
| |
| 511 return tempVar; | 510 return tempVar; |
| 512 } | 511 } |
| 513 | 512 |
| 514 withExpression(js.Expression node, fn(js.Expression result), {bool store}) { | 513 withExpression(js.Expression node, fn(js.Expression result), {bool store}) { |
| 515 int oldTempVarIndex = currentTempVarIndex; | 514 int oldTempVarIndex = currentTempVarIndex; |
| 516 js.Expression visited = visitExpression(node); | 515 js.Expression visited = visitExpression(node); |
| 517 if (store) { | 516 if (store) { |
| 518 visited = _storeIfNecessary(visited); | 517 visited = _storeIfNecessary(visited); |
| 519 } | 518 } |
| 520 var result = fn(visited); | 519 var result = fn(visited); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 600 "return #runtimeHelper(#returnValue, #successCode, " | 599 "return #runtimeHelper(#returnValue, #successCode, " |
| 601 "#completer, null)", { | 600 "#completer, null)", { |
| 602 "runtimeHelper": asyncHelper, | 601 "runtimeHelper": asyncHelper, |
| 603 "successCode": js.number(error_codes.SUCCESS), | 602 "successCode": js.number(error_codes.SUCCESS), |
| 604 "returnValue": analysis.hasExplicitReturns | 603 "returnValue": analysis.hasExplicitReturns |
| 605 ? returnValueName | 604 ? returnValueName |
| 606 : new js.LiteralNull(), | 605 : new js.LiteralNull(), |
| 607 "completer": completerName})); | 606 "completer": completerName})); |
| 608 break; | 607 break; |
| 609 case const js.AsyncModifier.syncStar(): | 608 case const js.AsyncModifier.syncStar(): |
| 610 addStatement(new js.Return(new js.Call(endOfIteration, []))); | 609 addStatement(js.js.statement('return #();', [endOfIteration])); |
| 611 break; | 610 break; |
| 612 case const js.AsyncModifier.asyncStar(): | 611 case const js.AsyncModifier.asyncStar(): |
| 613 addStatement(js.js.statement( | 612 addStatement(js.js.statement( |
| 614 "return #streamHelper(null, #successCode, #controller)", { | 613 "return #streamHelper(null, #successCode, #controller)", { |
| 615 "streamHelper": streamHelper, | 614 "streamHelper": streamHelper, |
| 616 "successCode": js.number(error_codes.SUCCESS), | 615 "successCode": js.number(error_codes.SUCCESS), |
| 617 "controller": controllerName})); | 616 "controller": controllerName})); |
| 618 break; | 617 break; |
| 619 default: | 618 default: |
| 620 diagnosticListener.internalError( | 619 diagnosticListener.internalError( |
| 621 spannable, "Internal error, unexpected asyncmodifier $async"); | 620 spannable, "Internal error, unexpected asyncmodifier $async"); |
| 622 } | 621 } |
| 623 if (isAsync || isAsyncStar) { | 622 if (isAsync || isAsyncStar) { |
| 624 beginLabel(rethrowLabel); | 623 beginLabel(rethrowLabel); |
| 625 addStatement(js.js.statement( | 624 addStatement(js.js.statement( |
| 626 "return #thenHelper(#currentError, #errorCode, #controller)", { | 625 "return #thenHelper(#currentError, #errorCode, #controller)", { |
| 627 "thenHelper": isAsync ? asyncHelper : streamHelper, | 626 "thenHelper": isAsync ? asyncHelper : streamHelper, |
| 628 "errorCode": js.number(error_codes.ERROR), | 627 "errorCode": js.number(error_codes.ERROR), |
| 629 "currentError": currentErrorName, | 628 "currentError": currentErrorName, |
| 630 "controller": isAsync ? completerName : controllerName})); | 629 "controller": isAsync ? completerName : controllerName})); |
| 631 } else { | 630 } else { |
| 632 assert(isSyncStar); | 631 assert(isSyncStar); |
| 633 beginLabel(rethrowLabel); | 632 beginLabel(rethrowLabel); |
| 634 addStatement(new js.Return(new js.Call(uncaughtErrorExpression, | 633 addStatement(js.js.statement('return #(#);', |
| 635 [new js.VariableUse(currentErrorName)]))); | 634 [uncaughtErrorExpression, currentErrorName])); |
| 636 } | 635 } |
| 637 } | 636 } |
| 638 | 637 |
| 639 /// The initial call to [asyncHelper]/[streamHelper]. | 638 /// The initial call to [asyncHelper]/[streamHelper]. |
| 640 /// | 639 /// |
| 641 /// There is no value to await/yield, so the first argument is `null` and | 640 /// There is no value to await/yield, so the first argument is `null` and |
| 642 /// also the errorCallback is `null`. | 641 /// also the errorCallback is `null`. |
| 643 /// | 642 /// |
| 644 /// Returns the [Future]/[Stream] coming from [completerName]/ | 643 /// Returns the [Future]/[Stream] coming from [completerName]/ |
| 645 /// [controllerName]. | 644 /// [controllerName]. |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 834 js.VariableInitialization makeInit(String name, js.Expression initValue) { | 833 js.VariableInitialization makeInit(String name, js.Expression initValue) { |
| 835 return new js.VariableInitialization( | 834 return new js.VariableInitialization( |
| 836 new js.VariableDeclaration(name), initValue); | 835 new js.VariableDeclaration(name), initValue); |
| 837 } | 836 } |
| 838 | 837 |
| 839 inits.add(makeInit(gotoName, js.number(0))); | 838 inits.add(makeInit(gotoName, js.number(0))); |
| 840 if (isAsync) { | 839 if (isAsync) { |
| 841 inits.add(makeInit(completerName, new js.New(newCompleter, []))); | 840 inits.add(makeInit(completerName, new js.New(newCompleter, []))); |
| 842 } else if (isAsyncStar) { | 841 } else if (isAsyncStar) { |
| 843 inits.add(makeInit(controllerName, | 842 inits.add(makeInit(controllerName, |
| 844 new js.Call(newController, [new js.VariableUse(bodyName)]))); | 843 js.js('#(#)', [newController, bodyName]))); |
| 845 } | 844 } |
| 846 inits.add(makeInit(handlerName, js.number(rethrowLabel))); | 845 inits.add(makeInit(handlerName, js.number(rethrowLabel))); |
| 847 inits.add(makeInit(currentErrorName, null)); | 846 inits.add(makeInit(currentErrorName, null)); |
| 848 if (hasJumpThroughFinally || analysis.hasYield) { | 847 if (hasJumpThroughFinally || analysis.hasYield) { |
| 849 inits.add(makeInit(nextName, null)); | 848 inits.add(makeInit(nextName, null)); |
| 850 } | 849 } |
| 851 if (isAsyncStar && analysis.hasYield) { | 850 if (isAsyncStar && analysis.hasYield) { |
| 852 inits.add(makeInit(nextWhenCanceledName, null)); | 851 inits.add(makeInit(nextWhenCanceledName, null)); |
| 853 } | 852 } |
| 854 if (analysis.hasExplicitReturns && isAsync) { | 853 if (analysis.hasExplicitReturns && isAsync) { |
| 855 inits.add(makeInit(returnValueName, null)); | 854 inits.add(makeInit(returnValueName, null)); |
| 856 } | 855 } |
| 857 if (analysis.hasThis && !isSyncStar) { | 856 if (analysis.hasThis && !isSyncStar) { |
| 858 // Sync* functions must remember `this` on the level of the outer | 857 // Sync* functions must remember `this` on the level of the outer |
| 859 // function. | 858 // function. |
| 860 inits.add(makeInit(selfName, new js.This())); | 859 inits.add(makeInit(selfName, js.js('this'))); |
| 861 } | 860 } |
| 862 inits.addAll(localVariables.map((js.VariableDeclaration decl) { | 861 inits.addAll(localVariables.map((js.VariableDeclaration decl) { |
| 863 return new js.VariableInitialization(decl, null); | 862 return new js.VariableInitialization(decl, null); |
| 864 })); | 863 })); |
| 865 inits.addAll(new Iterable.generate(tempVarHighWaterMark, | 864 inits.addAll(new Iterable.generate(tempVarHighWaterMark, |
| 866 (int i) => makeInit(useTempVar(i + 1).name, null))); | 865 (int i) => makeInit(useTempVar(i + 1).name, null))); |
| 867 js.VariableDeclarationList varDecl = new js.VariableDeclarationList(inits); | 866 js.VariableDeclarationList varDecl = new js.VariableDeclarationList(inits); |
| 868 // TODO(sigurdm): Explain the difference between these cases. | 867 // TODO(sigurdm): Explain the difference between these cases. |
| 869 if (isSyncStar) { | 868 if (isSyncStar) { |
| 870 return js.js(""" | 869 return js.js(""" |
| 871 function (#params) { | 870 function (#params) { |
| 872 if (#needsThis) | 871 if (#needsThis) |
| 873 var #self = this; | 872 var #self = this; |
| 874 return new #newIterable(function () { | 873 return new #newIterable(function () { |
| 875 #varDecl; | 874 #varDecl; |
| 876 return function #body(#errorCode, #result) { | 875 return function #body(#errorCode, #result) { |
| 877 if (#errorCode == #ERROR) { | 876 if (#errorCode === #ERROR) { |
| 878 #currentError = #result; | 877 #currentError = #result; |
| 879 #goto = #handler; | 878 #goto = #handler; |
| 880 } | 879 } |
| 881 while (true) | 880 while (true) |
| 882 #helperBody; | 881 #helperBody; |
| 883 }; | 882 }; |
| 884 }); | 883 }); |
| 885 } | 884 } |
| 886 """, { | 885 """, { |
| 887 "params": node.params, | 886 "params": node.params, |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 907 switch (#errorCode) { | 906 switch (#errorCode) { |
| 908 case #STREAM_WAS_CANCELED: | 907 case #STREAM_WAS_CANCELED: |
| 909 #next = #nextWhenCanceled; | 908 #next = #nextWhenCanceled; |
| 910 #goto = #next.pop(); | 909 #goto = #next.pop(); |
| 911 break; | 910 break; |
| 912 case #ERROR: | 911 case #ERROR: |
| 913 #currentError = #result; | 912 #currentError = #result; |
| 914 #goto = #handler; | 913 #goto = #handler; |
| 915 } | 914 } |
| 916 else | 915 else |
| 917 if (#errorCode == #ERROR) { | 916 if (#errorCode === #ERROR) { |
| 918 #currentError = #result; | 917 #currentError = #result; |
| 919 #goto = #handler; | 918 #goto = #handler; |
| 920 } | 919 } |
| 921 while (true) | 920 while (true) |
| 922 #helperBody; | 921 #helperBody; |
| 923 } | 922 } |
| 924 #init; | 923 #init; |
| 925 }""", { | 924 }""", { |
| 926 "params": node.params, | 925 "params": node.params, |
| 927 "varDecl": varDecl, | 926 "varDecl": varDecl, |
| 928 "STREAM_WAS_CANCELED": js.number(error_codes.STREAM_WAS_CANCELED), | 927 "STREAM_WAS_CANCELED": js.number(error_codes.STREAM_WAS_CANCELED), |
| 929 "ERROR": js.number(error_codes.ERROR), | 928 "ERROR": js.number(error_codes.ERROR), |
| 930 "hasYield": analysis.hasYield, | 929 "hasYield": analysis.hasYield, |
| 931 "helperBody": helperBody, | 930 "helperBody": helperBody, |
| 932 "init": generateInitializer(), | 931 "init": generateInitializer(), |
| 933 "bodyName": bodyName, | 932 "bodyName": bodyName, |
| 934 "currentError": currentErrorName, | 933 "currentError": currentErrorName, |
| 935 "goto": gotoName, | 934 "goto": gotoName, |
| 936 "handler": handlerName, | 935 "handler": handlerName, |
| 937 "next": nextName, | 936 "next": nextName, |
| 938 "nextWhenCanceled": nextWhenCanceledName, | 937 "nextWhenCanceled": nextWhenCanceledName, |
| 939 "errorCode": errorCodeName, | 938 "errorCode": errorCodeName, |
| 940 "result": resultName, | 939 "result": resultName, |
| 941 }); | 940 }); |
| 942 } | 941 } |
| 943 | 942 |
| 944 @override | 943 @override |
| 945 js.Expression visitAccess(js.PropertyAccess node) { | 944 js.Expression visitAccess(js.PropertyAccess node) { |
| 946 return withExpression2(node.receiver, node.selector, | 945 return withExpression2(node.receiver, node.selector, |
| 947 (receiver, selector) => new js.PropertyAccess(receiver, selector)); | 946 (receiver, selector) => js.js('#[#]', [receiver, selector])); |
| 948 } | 947 } |
| 949 | 948 |
| 950 @override | 949 @override |
| 951 js.Expression visitArrayHole(js.ArrayHole node) { | 950 js.Expression visitArrayHole(js.ArrayHole node) { |
| 952 return node; | 951 return node; |
| 953 } | 952 } |
| 954 | 953 |
| 955 @override | 954 @override |
| 956 js.Expression visitArrayInitializer(js.ArrayInitializer node) { | 955 js.Expression visitArrayInitializer(js.ArrayInitializer node) { |
| 957 return withExpressions(node.elements, (elements) { | 956 return withExpressions(node.elements, (elements) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1022 } | 1021 } |
| 1023 | 1022 |
| 1024 @override | 1023 @override |
| 1025 js.Expression visitBinary(js.Binary node) { | 1024 js.Expression visitBinary(js.Binary node) { |
| 1026 if (shouldTransform(node.right) && (node.op == "||" || node.op == "&&")) { | 1025 if (shouldTransform(node.right) && (node.op == "||" || node.op == "&&")) { |
| 1027 int thenLabel = newLabel("then"); | 1026 int thenLabel = newLabel("then"); |
| 1028 int joinLabel = newLabel("join"); | 1027 int joinLabel = newLabel("join"); |
| 1029 withExpression(node.left, (js.Expression left) { | 1028 withExpression(node.left, (js.Expression left) { |
| 1030 js.Statement assignLeft = isResult(left) | 1029 js.Statement assignLeft = isResult(left) |
| 1031 ? new js.Block.empty() | 1030 ? new js.Block.empty() |
| 1032 : new js.ExpressionStatement( | 1031 : js.js.statement('# = #', [resultName, left]); |
|
floitsch
2015/02/23 16:15:34
ditto.
sigurdm
2015/02/24 13:16:20
Acknowledged.
| |
| 1033 new js.Assignment(new js.VariableUse(resultName), left)); | |
| 1034 if (node.op == "||") { | 1032 if (node.op == "||") { |
| 1035 addStatement(new js.If(left, gotoAndBreak(thenLabel), assignLeft)); | 1033 addStatement(js.js.statement('if (#) {#} else #', |
|
floitsch
2015/02/23 16:15:34
you don't need the "{}" around the 'then' block.
sigurdm
2015/02/24 13:16:20
Yes, otherwise the js parser sees # else as a hole
| |
| 1034 [left, gotoAndBreak(thenLabel), assignLeft])); | |
| 1036 } else { | 1035 } else { |
| 1037 assert(node.op == "&&"); | 1036 assert(node.op == "&&"); |
| 1038 addStatement(new js.If(left, assignLeft, gotoAndBreak(thenLabel))); | 1037 addStatement(js.js.statement('if (#) {#} else #', |
|
floitsch
2015/02/23 16:15:34
ditto
sigurdm
2015/02/24 13:16:20
Acknowledged.
| |
| 1038 [left, assignLeft, gotoAndBreak(thenLabel)])); | |
| 1039 } | 1039 } |
| 1040 }, store: true); | 1040 }, store: true); |
| 1041 addGoto(joinLabel); | 1041 addGoto(joinLabel); |
| 1042 beginLabel(thenLabel); | 1042 beginLabel(thenLabel); |
| 1043 withExpression(node.right, (js.Expression value) { | 1043 withExpression(node.right, (js.Expression value) { |
| 1044 if (!isResult(value)) { | 1044 if (!isResult(value)) { |
| 1045 addExpressionStatement( | 1045 addStatement(js.js.statement('# = #', [resultName, value])); |
|
floitsch
2015/02/23 16:15:34
";" or not. (depending on above).
sigurdm
2015/02/24 13:16:20
Done.
| |
| 1046 new js.Assignment(new js.VariableUse(resultName), value)); | |
| 1047 } | 1046 } |
| 1048 }, store: false); | 1047 }, store: false); |
| 1049 beginLabel(joinLabel); | 1048 beginLabel(joinLabel); |
| 1050 return new js.VariableUse(resultName); | 1049 return new js.VariableUse(resultName); |
| 1051 } | 1050 } |
| 1052 | 1051 |
| 1053 return withExpression2(node.left, node.right, | 1052 return withExpression2(node.left, node.right, |
| 1054 (left, right) => new js.Binary(node.op, left, right)); | 1053 (left, right) => new js.Binary(node.op, left, right)); |
| 1055 } | 1054 } |
| 1056 | 1055 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1093 | 1092 |
| 1094 @override | 1093 @override |
| 1095 void visitComment(js.Comment node) { | 1094 void visitComment(js.Comment node) { |
| 1096 addStatement(node); | 1095 addStatement(node); |
| 1097 } | 1096 } |
| 1098 | 1097 |
| 1099 @override | 1098 @override |
| 1100 js.Expression visitConditional(js.Conditional node) { | 1099 js.Expression visitConditional(js.Conditional node) { |
| 1101 if (!shouldTransform(node.then) && !shouldTransform(node.otherwise)) { | 1100 if (!shouldTransform(node.then) && !shouldTransform(node.otherwise)) { |
| 1102 return withExpression(node.condition, (js.Expression condition) { | 1101 return withExpression(node.condition, (js.Expression condition) { |
| 1103 return new js.Conditional(condition, node.then, node.otherwise); | 1102 return js.js('# ? # : #', [condition, node.then, node.otherwise]); |
| 1104 }); | 1103 }); |
| 1105 } | 1104 } |
| 1106 int thenLabel = newLabel("then"); | 1105 int thenLabel = newLabel("then"); |
| 1107 int joinLabel = newLabel("join"); | 1106 int joinLabel = newLabel("join"); |
| 1108 int elseLabel = newLabel("else"); | 1107 int elseLabel = newLabel("else"); |
| 1109 withExpression(node.condition, (js.Expression condition) { | 1108 withExpression(node.condition, (js.Expression condition) { |
| 1110 addExpressionStatement(new js.Assignment(new js.VariableUse(gotoName), | 1109 addStatement(js.js.statement('# = # ? # : #;', |
| 1111 new js.Conditional( | 1110 [gotoName, condition, js.number(thenLabel), js.number(elseLabel)])); |
| 1112 condition, js.number(thenLabel), js.number(elseLabel)))); | |
| 1113 }, store: false); | 1111 }, store: false); |
| 1114 addBreak(); | 1112 addBreak(); |
| 1115 beginLabel(thenLabel); | 1113 beginLabel(thenLabel); |
| 1116 withExpression(node.then, (js.Expression value) { | 1114 withExpression(node.then, (js.Expression value) { |
| 1117 if (!isResult(value)) { | 1115 if (!isResult(value)) { |
| 1118 addExpressionStatement( | 1116 addStatement(js.js.statement('# = #', [resultName, value])); |
| 1119 new js.Assignment(new js.VariableUse(resultName), value)); | |
| 1120 } | 1117 } |
| 1121 }, store: false); | 1118 }, store: false); |
| 1122 addGoto(joinLabel); | 1119 addGoto(joinLabel); |
| 1123 beginLabel(elseLabel); | 1120 beginLabel(elseLabel); |
| 1124 withExpression(node.otherwise, (js.Expression value) { | 1121 withExpression(node.otherwise, (js.Expression value) { |
| 1125 if (!isResult(value)) { | 1122 if (!isResult(value)) { |
| 1126 addExpressionStatement( | 1123 addStatement(js.js.statement('# = #', [resultName, value])); |
| 1127 new js.Assignment(new js.VariableUse(resultName), value)); | |
| 1128 } | 1124 } |
| 1129 }, store: false); | 1125 }, store: false); |
| 1130 beginLabel(joinLabel); | 1126 beginLabel(joinLabel); |
| 1131 return new js.VariableUse(resultName); | 1127 return new js.VariableUse(resultName); |
| 1132 } | 1128 } |
| 1133 | 1129 |
| 1134 @override | 1130 @override |
| 1135 void visitContinue(js.Continue node) { | 1131 void visitContinue(js.Continue node) { |
| 1136 js.Node target = analysis.targets[node]; | 1132 js.Node target = analysis.targets[node]; |
| 1137 if (!shouldTransform(target)) { | 1133 if (!shouldTransform(target)) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1186 | 1182 |
| 1187 @override | 1183 @override |
| 1188 void visitDefault(js.Default node) => unreachable(node); | 1184 void visitDefault(js.Default node) => unreachable(node); |
| 1189 | 1185 |
| 1190 @override | 1186 @override |
| 1191 void visitDo(js.Do node) { | 1187 void visitDo(js.Do node) { |
| 1192 if (!shouldTransform(node)) { | 1188 if (!shouldTransform(node)) { |
| 1193 bool oldInsideUntranslatedBreakable = insideUntranslatedBreakable; | 1189 bool oldInsideUntranslatedBreakable = insideUntranslatedBreakable; |
| 1194 insideUntranslatedBreakable = true; | 1190 insideUntranslatedBreakable = true; |
| 1195 withExpression(node.condition, (js.Expression condition) { | 1191 withExpression(node.condition, (js.Expression condition) { |
| 1196 addStatement(new js.Do(translateInBlock(node.body), condition)); | 1192 addStatement(js.js.statement('do {#} while #', [node.body, condition])); |
|
floitsch
2015/02/23 16:15:34
no need for "{ }".
sigurdm
2015/02/24 13:16:20
Ditto
| |
| 1197 }, store: false); | 1193 }, store: false); |
| 1198 insideUntranslatedBreakable = oldInsideUntranslatedBreakable; | 1194 insideUntranslatedBreakable = oldInsideUntranslatedBreakable; |
| 1199 return; | 1195 return; |
| 1200 } | 1196 } |
| 1201 int startLabel = newLabel("do body"); | 1197 int startLabel = newLabel("do body"); |
| 1202 | 1198 |
| 1203 int continueLabel = newLabel("do condition"); | 1199 int continueLabel = newLabel("do condition"); |
| 1204 continueLabels[node] = continueLabel; | 1200 continueLabels[node] = continueLabel; |
| 1205 | 1201 |
| 1206 int afterLabel = newLabel("after do"); | 1202 int afterLabel = newLabel("after do"); |
| 1207 breakLabels[node] = afterLabel; | 1203 breakLabels[node] = afterLabel; |
| 1208 | 1204 |
| 1209 beginLabel(startLabel); | 1205 beginLabel(startLabel); |
| 1210 | 1206 |
| 1211 jumpTargets.add(node); | 1207 jumpTargets.add(node); |
| 1212 visitStatement(node.body); | 1208 visitStatement(node.body); |
| 1213 jumpTargets.removeLast(); | 1209 jumpTargets.removeLast(); |
| 1214 | 1210 |
| 1215 beginLabel(continueLabel); | 1211 beginLabel(continueLabel); |
| 1216 withExpression(node.condition, (js.Expression condition) { | 1212 withExpression(node.condition, (js.Expression condition) { |
| 1217 addStatement(new js.If.noElse(condition, gotoAndBreak(startLabel))); | 1213 addStatement(js.js.statement('if (#) #', |
| 1214 [condition, gotoAndBreak(startLabel)])); | |
| 1218 }, store: false); | 1215 }, store: false); |
| 1219 beginLabel(afterLabel); | 1216 beginLabel(afterLabel); |
| 1220 } | 1217 } |
| 1221 | 1218 |
| 1222 @override | 1219 @override |
| 1223 void visitEmptyStatement(js.EmptyStatement node) { | 1220 void visitEmptyStatement(js.EmptyStatement node) { |
| 1224 addStatement(node); | 1221 addStatement(node); |
| 1225 } | 1222 } |
| 1226 | 1223 |
| 1227 void visitExpressionInStatementContext(js.Expression node) { | 1224 void visitExpressionInStatementContext(js.Expression node) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1244 bool oldInsideUntranslated = insideUntranslatedBreakable; | 1241 bool oldInsideUntranslated = insideUntranslatedBreakable; |
| 1245 insideUntranslatedBreakable = true; | 1242 insideUntranslatedBreakable = true; |
| 1246 // Note that node.init, node.condition, node.update all can be null, but | 1243 // Note that node.init, node.condition, node.update all can be null, but |
| 1247 // withExpressions handles that. | 1244 // withExpressions handles that. |
| 1248 withExpressions([ | 1245 withExpressions([ |
| 1249 node.init, | 1246 node.init, |
| 1250 node.condition, | 1247 node.condition, |
| 1251 node.update | 1248 node.update |
| 1252 ], (List<js.Expression> transformed) { | 1249 ], (List<js.Expression> transformed) { |
| 1253 addStatement(new js.For(transformed[0], transformed[1], transformed[2], | 1250 addStatement(new js.For(transformed[0], transformed[1], transformed[2], |
| 1254 translateInBlock(node.body))); | 1251 translateInBlock(node.body))); |
| 1255 }); | 1252 }); |
| 1256 insideUntranslatedBreakable = oldInsideUntranslated; | 1253 insideUntranslatedBreakable = oldInsideUntranslated; |
| 1257 return; | 1254 return; |
| 1258 } | 1255 } |
| 1259 | 1256 |
| 1260 if (node.init != null) { | 1257 if (node.init != null) { |
| 1261 visitExpressionInStatementContext(node.init); | 1258 visitExpressionInStatementContext(node.init); |
| 1262 } | 1259 } |
| 1263 int startLabel = newLabel("for condition"); | 1260 int startLabel = newLabel("for condition"); |
| 1264 // If there is no update, continuing the loop is the same as going to the | 1261 // If there is no update, continuing the loop is the same as going to the |
| (...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2298 return condition || body; | 2295 return condition || body; |
| 2299 } | 2296 } |
| 2300 | 2297 |
| 2301 @override | 2298 @override |
| 2302 bool visitDartYield(js.DartYield node) { | 2299 bool visitDartYield(js.DartYield node) { |
| 2303 hasYield = true; | 2300 hasYield = true; |
| 2304 visit(node.expression); | 2301 visit(node.expression); |
| 2305 return true; | 2302 return true; |
| 2306 } | 2303 } |
| 2307 } | 2304 } |
| OLD | NEW |