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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart

Issue 349923004: Add support for superSend to the new IR and dart backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Also handle sendSet Created 6 years, 5 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
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 dart2js.ir_builder; 5 library dart2js.ir_builder;
6 6
7 import 'ir_nodes.dart' as ir; 7 import 'ir_nodes.dart' as ir;
8 import '../elements/elements.dart'; 8 import '../elements/elements.dart';
9 import '../dart2jslib.dart'; 9 import '../dart2jslib.dart';
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 return result; 820 return result;
821 } 821 }
822 822
823 ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) { 823 ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) {
824 assert(isOpen); 824 assert(isOpen);
825 return translateConstant(node); 825 return translateConstant(node);
826 } 826 }
827 827
828 ir.Primitive visitIdentifier(ast.Identifier node) { 828 ir.Primitive visitIdentifier(ast.Identifier node) {
829 assert(isOpen); 829 assert(isOpen);
830 // "this" is the only identifier that should be met by the visitor.
830 assert(node.isThis()); 831 assert(node.isThis());
831 return lookupThis(); 832 return lookupThis();
832 } 833 }
833 834
834 ir.Primitive visitParenthesizedExpression( 835 ir.Primitive visitParenthesizedExpression(
835 ast.ParenthesizedExpression node) { 836 ast.ParenthesizedExpression node) {
836 assert(isOpen); 837 assert(isOpen);
837 return visit(node.expression); 838 return visit(node.expression);
838 } 839 }
839 840
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 closureTarget = visit(node.selector); 907 closureTarget = visit(node.selector);
907 } else { 908 } else {
908 assert(Elements.isLocal(element)); 909 assert(Elements.isLocal(element));
909 closureTarget = lookupLocal(element); 910 closureTarget = lookupLocal(element);
910 } 911 }
911 Selector closureSelector = elements.getSelector(node); 912 Selector closureSelector = elements.getSelector(node);
912 return translateClosureCall(closureTarget, closureSelector, 913 return translateClosureCall(closureTarget, closureSelector,
913 node.argumentsNode); 914 node.argumentsNode);
914 } 915 }
915 916
917 /// If [node] is null, returns this.
918 /// If [node] is super, returns null (for special handling)
919 /// Otherwise visits [node] and returns the result.
920 ir.Primitive visitReceiver(ast.Expression node) {
921 if (node == null) return lookupThis();
922 if (node.isSuper()) return null;
923 return visit(node);
924 }
925
926 /// Makes an [InvokeMethod] unless [node.receiver.isSuper()], in that case
927 /// makes an [InvokeSuperMethod] ignoring [receiver].
928 ir.Expression createDynamicInvoke(ast.Send node,
929 Selector selector,
930 ir.Definition receiver,
931 ir.Continuation k,
932 List<ir.Definition> arguments) {
933 return node.receiver != null && node.receiver.isSuper()
934 ? new ir.InvokeSuperMethod(selector, k, arguments)
935 : new ir.InvokeMethod(receiver, selector, k, arguments);
936 }
937
916 ir.Primitive visitDynamicSend(ast.Send node) { 938 ir.Primitive visitDynamicSend(ast.Send node) {
917 assert(isOpen); 939 assert(isOpen);
918 if (node.receiver == null || node.receiver.isSuper()) {
919 return giveup(node, 'DynamicSend without receiver, or super receiver');
920 }
921 Selector selector = elements.getSelector(node); 940 Selector selector = elements.getSelector(node);
922 ir.Primitive receiver = visit(node.receiver); 941 ir.Primitive receiver = visitReceiver(node.receiver);
923 List<ir.Primitive> arguments = new List<ir.Primitive>(); 942 List<ir.Primitive> arguments = new List<ir.Primitive>();
924 for (ast.Node n in node.arguments) { 943 for (ast.Node n in node.arguments) {
925 arguments.add(visit(n)); 944 arguments.add(visit(n));
926 } 945 }
927 ir.Parameter v = new ir.Parameter(null); 946 ir.Parameter v = new ir.Parameter(null);
928 ir.Continuation k = new ir.Continuation([v]); 947 ir.Continuation k = new ir.Continuation([v]);
929 ir.Expression invoke = 948 ir.Expression invoke =
930 new ir.InvokeMethod(receiver, selector, k, arguments); 949 createDynamicInvoke(node, selector, receiver, k, arguments);
931 add(new ir.LetCont(k, invoke)); 950 add(new ir.LetCont(k, invoke));
932 return v; 951 return v;
933 } 952 }
934 953
935 ir.Primitive visitGetterSend(ast.Send node) { 954 ir.Primitive visitGetterSend(ast.Send node) {
955 // This code should be kept in sync with the getter part of visitSendSet
936 assert(isOpen); 956 assert(isOpen);
937 Element element = elements[node]; 957 Element element = elements[node];
958 Selector selector = elements.getSelector(node);
938 959
939 // TODO(asgerf): Generate code for erroneous getter access 960 // TODO(asgerf): Generate code for erroneous getter access
940 if (Elements.isErroneousElement(element)) { 961 if (Elements.isErroneousElement(element)) {
941 return giveup(node, 'Erroneous element on GetterSend'); 962 return giveup(node, 'Erroneous element on GetterSend');
942 } 963 }
943 964
944 // Reference to constant local, top-level or static field 965 // Reference to constant local, top-level or static field
945 if (element != null && element.isConst) { 966 if (element != null && element.isConst) {
946 return translateConstant(node); 967 return translateConstant(node);
947 } 968 }
948 969
949 // Reference to local variable 970 // Reference to local variable
950 if (Elements.isLocal(element)) { 971 if (Elements.isLocal(element)) {
951 return lookupLocal(element); 972 return lookupLocal(element);
952 } 973 }
953 974
954 // Dynamic dispatch to a getter. Sometimes resolution will suggest a target 975 // Dynamic dispatch to a getter. Sometimes resolution will suggest a target
955 // element, but in these cases we must still emit a dynamic dispatch. 976 // element, but in these cases we must still emit a dynamic dispatch.
956 // The target element may be an instance method in case we are converting 977 // The target element may be an instance method in case we are converting
957 // a method to a function object. 978 // a method to a function object.
958 if (element == null || 979 if (element == null ||
959 Elements.isInstanceField(element) || 980 Elements.isInstanceField(element) ||
960 Elements.isInstanceMethod(element)) { 981 Elements.isInstanceMethod(element)) {
961 ir.Primitive receiver = node.receiver == null 982 ir.Primitive receiver = visitReceiver(node.receiver);
962 ? lookupThis()
963 : visit(node.receiver);
964 ir.Parameter v = new ir.Parameter(null); 983 ir.Parameter v = new ir.Parameter(null);
965 ir.Continuation k = new ir.Continuation([v]); 984 ir.Continuation k = new ir.Continuation([v]);
966 Selector selector = elements.getSelector(node);
967 assert(selector.kind == SelectorKind.GETTER); 985 assert(selector.kind == SelectorKind.GETTER);
968 ir.InvokeMethod invoke = new ir.InvokeMethod(receiver, selector, k, []); 986 ir.Expression invoke =
987 createDynamicInvoke(node, selector, receiver, k, []);
969 add(new ir.LetCont(k, invoke)); 988 add(new ir.LetCont(k, invoke));
970 return v; 989 return v;
971 } 990 }
972 991
973 // Access to a static field or getter (non-static case handled above). 992 // Access to a static field or getter (non-static case handled above).
974 if (element.isField || element.isGetter) { 993 if (element.isField || element.isGetter) {
975 ir.Parameter v = new ir.Parameter(null); 994 ir.Parameter v = new ir.Parameter(null);
976 ir.Continuation k = new ir.Continuation([v]); 995 ir.Continuation k = new ir.Continuation([v]);
977 Selector selector = elements.getSelector(node); 996 ir.Expression invoke =
978 assert(selector.kind == SelectorKind.GETTER); 997 new ir.InvokeStatic(element, selector, k, []);
979 ir.InvokeStatic invoke = new ir.InvokeStatic(element, selector, k, []);
980 add(new ir.LetCont(k, invoke)); 998 add(new ir.LetCont(k, invoke));
981 return v; 999 return v;
982 } 1000 }
983 1001
984 // Convert a top-level or static function to a function object. 1002 // Convert a top-level or static function to a function object.
985 if (Elements.isStaticOrTopLevelFunction(element)) { 1003 if (Elements.isStaticOrTopLevelFunction(element)) {
986 return translateConstant(node); 1004 return translateConstant(node);
987 } 1005 }
988 1006
989 throw "Unexpected GetterSend: $node, $element"; 1007 throw "Unexpected GetterSend: $node, $element";
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 ir.Parameter v = new ir.Parameter(null); 1192 ir.Parameter v = new ir.Parameter(null);
1175 ir.Continuation k = new ir.Continuation([v]); 1193 ir.Continuation k = new ir.Continuation([v]);
1176 ir.Expression invoke = 1194 ir.Expression invoke =
1177 new ir.InvokeStatic(element, selector, k, arguments); 1195 new ir.InvokeStatic(element, selector, k, arguments);
1178 add(new ir.LetCont(k, invoke)); 1196 add(new ir.LetCont(k, invoke));
1179 return v; 1197 return v;
1180 } 1198 }
1181 1199
1182 ir.Primitive visitSuperSend(ast.Send node) { 1200 ir.Primitive visitSuperSend(ast.Send node) {
1183 assert(isOpen); 1201 assert(isOpen);
1184 return giveup(node, 'SuperSend'); 1202 if (node.isPropertyAccess) {
1203 return visitGetterSend(node);
1204 } else {
1205 return visitDynamicSend(node);
1206 }
1185 } 1207 }
1186 1208
1187 ir.Primitive visitTypeReferenceSend(ast.Send node) { 1209 ir.Primitive visitTypeReferenceSend(ast.Send node) {
1188 assert(isOpen); 1210 assert(isOpen);
1189 Element element = elements[node]; 1211 Element element = elements[node];
1190 assert(element is TypeDeclarationElement || element.isTypeVariable); 1212 assert(element is TypeDeclarationElement || element.isTypeVariable);
1191 1213
1192 // If the user is trying to invoke the type literal or variable, 1214 // If the user is trying to invoke the type literal or variable,
1193 // it must be treated as a function call. 1215 // it must be treated as a function call.
1194 if (node.argumentsNode != null) { 1216 if (node.argumentsNode != null) {
1195 return visitDynamicSend(node); 1217 return visitDynamicSend(node);
1196 } 1218 }
1197 1219
1198 if (element is TypeDeclarationElement) { 1220 if (element is TypeDeclarationElement) {
1199 return translateConstant(node); 1221 return translateConstant(node);
1200 } else { 1222 } else {
1201 ir.Primitive prim = new ir.ReifyTypeVar(element); 1223 ir.Primitive prim = new ir.ReifyTypeVar(element);
1202 add(new ir.LetPrim(prim)); 1224 add(new ir.LetPrim(prim));
1203 return prim; 1225 return prim;
1204 } 1226 }
1205 } 1227 }
1206 1228
1207 ir.Primitive visitSendSet(ast.SendSet node) { 1229 ir.Primitive visitSendSet(ast.SendSet node) {
1208 assert(isOpen); 1230 assert(isOpen);
1209 Element element = elements[node]; 1231 Element element = elements[node];
1210 ast.Operator op = node.assignmentOperator; 1232 ast.Operator op = node.assignmentOperator;
1211 ir.Primitive result; 1233 // For complex operators, this is the result of getting (before assigning)
1212 ir.Primitive getter; 1234 ir.Primitive originalValue;
1213 if (op.source == '=') { 1235 // For []+= style operators, this saves the index.
1214 if (Elements.isLocal(element)) { 1236 ir.Primitive index;
1215 // Exactly one argument expected for a simple assignment. 1237 ir.Primitive receiver;
1216 assert(!node.arguments.isEmpty); 1238 // This is what gets assigned.
1217 assert(node.arguments.tail.isEmpty); 1239 ir.Primitive valueToStore;
1218 result = visit(node.arguments.head); 1240 Selector selector = elements.getSelector(node);
1219 result.useElementAsHint(element); 1241 Selector operatorSelector =
1220 assignedVars[variableIndex[element]] = result; 1242 elements.getOperatorSelectorInComplexSendSet(node);
1221 return result; 1243 Selector getterSelector =
1222 } else if (Elements.isStaticOrTopLevel(element)) { 1244 elements.getGetterSelectorInComplexSendSet(node);
1223 assert(element.isField || element.isSetter); 1245 assert(
1224 assert(!node.arguments.isEmpty && node.arguments.tail.isEmpty); 1246 // Indexing send-sets have an argument for the index.
1225 ir.Parameter v = new ir.Parameter(null); 1247 (selector.isIndexSet ? 1 : 0) +
1226 ir.Continuation k = new ir.Continuation([v]); 1248 // Non-increment send-sets have one more argument.
1227 Selector selector = elements.getSelector(node); 1249 (ast.Operator.INCREMENT_OPERATORS.contains(op.source) ? 0 : 1)
1228 ir.Definition arg = visit(node.arguments.head); 1250 == node.argumentCount());
1229 ir.InvokeStatic invoke = 1251
1230 new ir.InvokeStatic(element, selector, k, [arg]); 1252 ast.Node assignArg = selector.isIndexSet
1231 add(new ir.LetCont(k, invoke)); 1253 ? node.arguments.tail.head
1232 return arg; 1254 : node.arguments.head;
1233 } else if (node.receiver == null) { 1255
1234 // Nodes that fall in this case: 1256 // Get the value into valueToStore
1235 // - Unresolved top-level 1257 if (op.source == "=") {
1236 // - Assignment to final variable (will not be resolved) 1258 if (selector.isIndexSet) {
1237 return giveup(node, 'SendSet: non-local, non-static, but no receiver'); 1259 receiver = visitReceiver(node.receiver);
1238 } else { 1260 index = visit(node.arguments.head);
1239 if (element != null && Elements.isUnresolved(element)) { 1261 } else if (element == null || Elements.isInstanceField(element)) {
1240 return giveup(node); 1262 receiver = visitReceiver(node.receiver);
1263 }
1264 valueToStore = visit(assignArg);
1265 } else {
1266 // Get the original value into getter
1267 assert(ast.Operator.COMPLEX_OPERATORS.contains(op.source));
1268
1269 // This code should be kept in sync with visitGetterSend
1270 // We have to handle index-set specially, to ensure the index only is
1271 // computed once - therefore the duplication.
1272 ir.Primitive getter() {
asgerf 2014/06/27 08:09:56 As discussed offline, we should look for a way to
sigurdm 2014/06/27 09:20:21 Done.
1273 if (Elements.isErroneousElement(element)) {
1274 return giveup(node, 'Erroneous element on GetterSend');
1241 } 1275 }
1242 1276
1243 // Setter or index-setter invocation 1277 // Reference to constant local, top-level or static field
1244 assert(node.receiver != null); 1278 if (element != null && element.isConst) {
1279 return translateConstant(node);
1280 }
1245 1281
1246 if (node.receiver.isSuper()) return giveup(node, 'Super SendSet'); 1282 // Reference to local variable
1283 if (Elements.isLocal(element)) {
1284 return lookupLocal(element);
1285 }
1247 1286
1248 ir.Primitive receiver = node.receiver == null 1287 // Dynamic dispatch to a getter. Sometimes resolution will suggest a
1249 ? lookupThis() 1288 // target element, but in these cases we must still emit a dynamic
1250 : visit(node.receiver); 1289 // dispatch. The target element may be an instance method in case we are
1251 ir.Parameter v = new ir.Parameter(null); 1290 // converting a method to a function object.
1252 ir.Continuation k = new ir.Continuation([v]); 1291 if (element == null ||
1253 Selector selector = elements.getSelector(node); 1292 Elements.isInstanceField(element) ||
1254 assert(selector.kind == SelectorKind.SETTER || 1293 Elements.isInstanceMethod(element) ||
1255 selector.kind == SelectorKind.INDEX); 1294 getterSelector.isIndex ||
1256 List<ir.Definition> args = node.arguments.mapToList(visit, 1295 node.isSuperCall) {
1257 growable:false); 1296
1258 ir.InvokeMethod invoke = 1297 receiver = visitReceiver(node.receiver);
1259 new ir.InvokeMethod(receiver, selector, k, args); 1298 List<ir.Primitive> arguments = new List<ir.Primitive>();
1260 add(new ir.LetCont(k, invoke)); 1299 if (getterSelector.isIndex) {
1261 return args.last; 1300 index = visit(node.arguments.head);
1262 } 1301 arguments.add(index);
1263 } else if (ast.Operator.COMPLEX_OPERATORS.contains(op.source)) { 1302 }
1264 Element selectorElement = elements[node.selector]; 1303
1265 if (selectorElement != null && !selectorElement.isAssignable) { 1304 ir.Parameter v = new ir.Parameter(null);
1266 return giveup(node, 'Unresolved or non-assignable compound assignment'); 1305 ir.Continuation k = new ir.Continuation([v]);
1267 } 1306 assert(getterSelector.kind == SelectorKind.GETTER ||
1268 if (!Elements.isLocal(selectorElement)) { 1307 getterSelector.kind == SelectorKind.INDEX);
1269 return giveup(node, 'Non-local compound assignment'); 1308 ir.Expression invoke =
1309 createDynamicInvoke(node, getterSelector, receiver, k, arguments);
1310 add(new ir.LetCont(k, invoke));
1311 return v;
1312 }
1313
1314 // Access to a static field or getter (non-static case handled above).
1315 if (element.isField || element.isGetter ||
1316 // Even if there is only a setter, we compile as if it was a getter,
1317 // so the vm can fail at runtime.
1318 element.isSetter) {
1319 ir.Parameter v = new ir.Parameter(null);
1320 ir.Continuation k = new ir.Continuation([v]);
1321 assert(getterSelector.kind == SelectorKind.GETTER);
1322 ir.Expression invoke =
1323 new ir.InvokeStatic(element, getterSelector, k, []);
1324 add(new ir.LetCont(k, invoke));
1325 return v;
1326 }
1327
1328 // Convert a top-level or static function to a function object.
1329 if (Elements.isStaticOrTopLevelFunction(element)) {
1330 return translateConstant(node);
1331 }
1332
1333 throw "Unexpected SendSet getter: $node, $element";
1270 } 1334 }
1271 1335
1272 Selector selector = elements.getOperatorSelectorInComplexSendSet(node); 1336 originalValue = getter();
1273 getter = lookupLocal(selectorElement);
1274 1337
1338 // Do the modification of the value in getter.
1275 ir.Primitive arg; 1339 ir.Primitive arg;
1276 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source)) { 1340 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source)) {
1277 assert(node.arguments.isEmpty);
1278 arg = makePrimConst(constantSystem.createInt(1)); 1341 arg = makePrimConst(constantSystem.createInt(1));
1279 add(new ir.LetPrim(arg)); 1342 add(new ir.LetPrim(arg));
1280 } else { 1343 } else {
1281 assert(!node.arguments.isEmpty); 1344 arg = visit(assignArg);
1282 assert(node.arguments.tail.isEmpty);
1283 arg = visit(node.arguments.head);
1284 } 1345 }
1285 arg.useElementAsHint(element); 1346 valueToStore = new ir.Parameter(null);
1286 result = new ir.Parameter(null); 1347 ir.Continuation k = new ir.Continuation([valueToStore]);
1287 ir.Continuation k = new ir.Continuation([result]); 1348 ir.Expression invoke =
1288 ir.Expression invoke = new ir.InvokeMethod(getter, selector, k, [arg]); 1349 new ir.InvokeMethod(originalValue, operatorSelector, k, [arg]);
1289 add(new ir.LetCont(k, invoke)); 1350 add(new ir.LetCont(k, invoke));
1351 }
1290 1352
1291 assignedVars[variableIndex[element]] = result; 1353 // Set the value
1354 if (Elements.isLocal(element)) {
1355 valueToStore.useElementAsHint(element);
1356 assignedVars[variableIndex[element]] = valueToStore;
1357 } else if (Elements.isStaticOrTopLevel(element)) {
1358 assert(element.isField || element.isSetter);
1359 ir.Parameter v = new ir.Parameter(null);
1360 ir.Continuation k = new ir.Continuation([v]);
1361 Selector selector = elements.getSelector(node);
1362 ir.InvokeStatic invoke =
1363 new ir.InvokeStatic(element, selector, k, [valueToStore]);
1364 add(new ir.LetCont(k, invoke));
1365 } else {
1366 if (element != null && Elements.isUnresolved(element)) {
1367 return giveup(node, 'SendSet: non-local, non-static, unresolved');
1368 }
1369 // Setter or index-setter invocation
1370 ir.Parameter v = new ir.Parameter(null);
1371 ir.Continuation k = new ir.Continuation([v]);
1372 Selector selector = elements.getSelector(node);
1373 assert(selector.kind == SelectorKind.SETTER ||
1374 selector.kind == SelectorKind.INDEX);
1375 List<ir.Definition> arguments = selector.isIndexSet
1376 ? [index, valueToStore]
1377 : [valueToStore];
1378 ir.Expression invoke =
1379 createDynamicInvoke(node, selector, receiver, k, arguments);
1380 add(new ir.LetCont(k, invoke));
1381 }
1292 1382
1293 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source) && 1383 if (node.isPostfix) {
1294 !node.isPrefix) { 1384 assert(originalValue != null);
1295 assert(getter != null); 1385 return originalValue;
1296 return getter;
1297 } else {
1298 return result;
1299 }
1300 } else { 1386 } else {
1301 compiler.internalError(node, "Unknown assignment operator ${op.source}"); 1387 return valueToStore;
1302 return null;
1303 } 1388 }
1304 } 1389 }
1305 1390
1306 ir.Primitive visitNewExpression(ast.NewExpression node) { 1391 ir.Primitive visitNewExpression(ast.NewExpression node) {
1307 assert(isOpen); 1392 assert(isOpen);
1308 if (node.isConst) { 1393 if (node.isConst) {
1309 return translateConstant(node); 1394 return translateConstant(node);
1310 } 1395 }
1311 FunctionElement element = elements[node.send]; 1396 FunctionElement element = elements[node.send];
1312 if (Elements.isUnresolved(element)) { 1397 if (Elements.isUnresolved(element)) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 1451
1367 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted"; 1452 static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
1368 1453
1369 ir.Primitive giveup(ast.Node node, [String reason]) { 1454 ir.Primitive giveup(ast.Node node, [String reason]) {
1370 throw ABORT_IRNODE_BUILDER; 1455 throw ABORT_IRNODE_BUILDER;
1371 } 1456 }
1372 1457
1373 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) { 1458 ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
1374 try { 1459 try {
1375 return action(); 1460 return action();
1376 } catch(e) { 1461 } catch(e, tr) {
1377 if (e == ABORT_IRNODE_BUILDER) return null; 1462 if (e == ABORT_IRNODE_BUILDER) {
1463 return null;
1464 }
1378 rethrow; 1465 rethrow;
1379 } 1466 }
1380 } 1467 }
1381 1468
1382 void internalError(String reason, {ast.Node node}) { 1469 void internalError(String reason, {ast.Node node}) {
1383 giveup(node); 1470 giveup(node);
1384 } 1471 }
1385 } 1472 }
1386 1473
1387 /// Translates constant expressions from the AST to the [ConstExp] language. 1474 /// Translates constant expressions from the AST to the [ConstExp] language.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1532 ConstExp visitConditional(ast.Conditional node) { 1619 ConstExp visitConditional(ast.Conditional node) {
1533 BoolConstant condition = computeConstant(node.condition); 1620 BoolConstant condition = computeConstant(node.condition);
1534 return visit(condition.isTrue ? node.thenExpression : node.elseExpression); 1621 return visit(condition.isTrue ? node.thenExpression : node.elseExpression);
1535 } 1622 }
1536 1623
1537 ConstExp visitNode(ast.Node node) { 1624 ConstExp visitNode(ast.Node node) {
1538 throw "Unexpected constant: $node"; 1625 throw "Unexpected constant: $node";
1539 } 1626 }
1540 1627
1541 } 1628 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698