OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 /// Equivalence test functions for data objects. | 5 /// Equivalence test functions for data objects. |
6 | 6 |
7 library dart2js.equivalence.functions; | 7 library dart2js.equivalence.functions; |
8 | 8 |
9 import 'package:expect/expect.dart'; | 9 import 'package:expect/expect.dart'; |
10 import 'package:compiler/src/common/resolution.dart'; | 10 import 'package:compiler/src/common/resolution.dart'; |
11 import 'package:compiler/src/common_elements.dart'; | 11 import 'package:compiler/src/common_elements.dart'; |
12 import 'package:compiler/src/compiler.dart'; | 12 import 'package:compiler/src/compiler.dart'; |
13 import 'package:compiler/src/elements/types.dart'; | 13 import 'package:compiler/src/elements/types.dart'; |
14 import 'package:compiler/src/elements/elements.dart'; | 14 import 'package:compiler/src/elements/elements.dart'; |
15 import 'package:compiler/src/elements/entities.dart'; | 15 import 'package:compiler/src/elements/entities.dart'; |
16 import 'package:compiler/src/enqueue.dart'; | 16 import 'package:compiler/src/enqueue.dart'; |
| 17 import 'package:compiler/src/js/js_debug.dart' as js; |
| 18 import 'package:compiler/src/js_backend/backend.dart'; |
17 import 'package:compiler/src/js_backend/backend_usage.dart'; | 19 import 'package:compiler/src/js_backend/backend_usage.dart'; |
18 import 'package:compiler/src/js_backend/enqueuer.dart'; | 20 import 'package:compiler/src/js_backend/enqueuer.dart'; |
19 import 'package:compiler/src/js_backend/native_data.dart'; | 21 import 'package:compiler/src/js_backend/native_data.dart'; |
20 import 'package:compiler/src/js_backend/interceptor_data.dart'; | 22 import 'package:compiler/src/js_backend/interceptor_data.dart'; |
21 import 'package:compiler/src/js_emitter/code_emitter_task.dart'; | 23 import 'package:compiler/src/js_emitter/code_emitter_task.dart'; |
22 import 'package:compiler/src/js_emitter/model.dart'; | 24 import 'package:compiler/src/js_emitter/model.dart'; |
23 import 'package:compiler/src/serialization/equivalence.dart'; | 25 import 'package:compiler/src/serialization/equivalence.dart'; |
24 import 'package:compiler/src/universe/class_set.dart'; | 26 import 'package:compiler/src/universe/class_set.dart'; |
25 import 'package:compiler/src/universe/world_builder.dart'; | 27 import 'package:compiler/src/universe/world_builder.dart'; |
| 28 import 'package:compiler/src/util/util.dart'; |
26 import 'package:compiler/src/world.dart'; | 29 import 'package:compiler/src/world.dart'; |
| 30 import 'package:js_ast/js_ast.dart' as js; |
27 import 'check_helpers.dart'; | 31 import 'check_helpers.dart'; |
28 | 32 |
29 void checkClosedWorlds(ClosedWorld closedWorld1, ClosedWorld closedWorld2, | 33 void checkClosedWorlds(ClosedWorld closedWorld1, ClosedWorld closedWorld2, |
30 {TestStrategy strategy: const TestStrategy(), | 34 {TestStrategy strategy: const TestStrategy(), |
31 bool allowExtra: false, | 35 bool allowExtra: false, |
32 bool verbose: false, | 36 bool verbose: false, |
33 bool allowMissingClosureClasses: false}) { | 37 bool allowMissingClosureClasses: false}) { |
34 if (verbose) { | 38 if (verbose) { |
35 print(closedWorld1.dump()); | 39 print(closedWorld1.dump()); |
36 print(closedWorld2.dump()); | 40 print(closedWorld2.dump()); |
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 (a, b) => a.name.key == b.name.key); | 858 (a, b) => a.name.key == b.name.key); |
855 } | 859 } |
856 | 860 |
857 // TODO(johnniwinther): Check all class properties. | 861 // TODO(johnniwinther): Check all class properties. |
858 void checkEmitterClasses(Class class1, Class class2) { | 862 void checkEmitterClasses(Class class1, Class class2) { |
859 checkLists(class1.methods, class2.methods, 'methods', | 863 checkLists(class1.methods, class2.methods, 'methods', |
860 (a, b) => a.name.key == b.name.key); | 864 (a, b) => a.name.key == b.name.key); |
861 checkLists(class1.isChecks, class2.isChecks, 'isChecks', | 865 checkLists(class1.isChecks, class2.isChecks, 'isChecks', |
862 (a, b) => a.name.key == b.name.key); | 866 (a, b) => a.name.key == b.name.key); |
863 } | 867 } |
| 868 |
| 869 void checkGeneratedCode(JavaScriptBackend backend1, JavaScriptBackend backend2, |
| 870 {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent}) { |
| 871 checkMaps(backend1.generatedCode, backend2.generatedCode, 'generatedCode', |
| 872 elementEquivalence, areJsNodesEquivalent, |
| 873 valueToString: js.nodeToString); |
| 874 } |
| 875 |
| 876 bool areJsNodesEquivalent(js.Node node1, js.Node node2) { |
| 877 return new JsEquivalenceVisitor().testNodes(node1, node2); |
| 878 } |
| 879 |
| 880 class JsEquivalenceVisitor implements js.NodeVisitor<bool> { |
| 881 Link<js.Node> stack1 = const Link<js.Node>(); |
| 882 Link<js.Node> stack2 = const Link<js.Node>(); |
| 883 Map<String, String> labelsMap = <String, String>{}; |
| 884 |
| 885 void push(js.Node node1, js.Node node2) { |
| 886 stack1 = stack1.prepend(node1); |
| 887 stack2 = stack2.prepend(node2); |
| 888 } |
| 889 |
| 890 js.Node peek() => stack2.head; |
| 891 |
| 892 void pop() { |
| 893 stack1 = stack1.tail; |
| 894 stack2 = stack2.tail; |
| 895 } |
| 896 |
| 897 bool failAt(js.Node node1, js.Node node2) { |
| 898 print('Node mismatch:'); |
| 899 print(' ${js.nodeToString(node1)}'); |
| 900 print(' ${js.nodeToString(node2)}'); |
| 901 return false; |
| 902 } |
| 903 |
| 904 bool testValues(Object object1, Object object2) { |
| 905 if (object1 != object2) { |
| 906 print('Value mismatch:'); |
| 907 print(' ${object1}'); |
| 908 print(' ${object2}'); |
| 909 print('at'); |
| 910 print(' ${js.nodeToString(stack1.head)}'); |
| 911 print(' ${js.nodeToString(stack2.head)}'); |
| 912 } |
| 913 return object1 == object2; |
| 914 } |
| 915 |
| 916 bool testLabels(String object1, String object2) { |
| 917 if (object1 == null && object2 == null) return true; |
| 918 if (labelsMap.containsKey(object1)) { |
| 919 String expectedValue = labelsMap[object1]; |
| 920 if (expectedValue != object2) { |
| 921 print('Value mismatch:'); |
| 922 print(' ${object1}'); |
| 923 print(' found ${object2}, expected ${expectedValue}'); |
| 924 print('at'); |
| 925 print(' ${js.nodeToString(stack1.head)}'); |
| 926 print(' ${js.nodeToString(stack2.head)}'); |
| 927 } |
| 928 return expectedValue == object2; |
| 929 } else { |
| 930 labelsMap[object1] = object2; |
| 931 return true; |
| 932 } |
| 933 } |
| 934 |
| 935 bool testNodes(js.Node node1, js.Node node2) { |
| 936 if (identical(node1, node2)) return true; |
| 937 if (node1 == null || node2 == null) return failAt(node1, node2); |
| 938 push(node1, node2); |
| 939 bool result = node1.accept(this); |
| 940 pop(); |
| 941 return result; |
| 942 } |
| 943 |
| 944 bool testNodeLists(List<js.Node> list1, List<js.Node> list2) { |
| 945 int index = 0; |
| 946 while (index < list1.length && index < list2.length) { |
| 947 if (!testNodes(list1[index], list2[index])) return false; |
| 948 index++; |
| 949 } |
| 950 if (index < list1.length) { |
| 951 return failAt(list1[index], null); |
| 952 } else if (index < list2.length) { |
| 953 return failAt(list2[index], null); |
| 954 } |
| 955 return true; |
| 956 } |
| 957 |
| 958 @override |
| 959 bool visitProgram(js.Program node) { |
| 960 if (peek() is! js.Program) return failAt(node, peek()); |
| 961 js.Program other = peek(); |
| 962 return testNodeLists(node.body, other.body); |
| 963 } |
| 964 |
| 965 @override |
| 966 bool visitInterpolatedDeclaration(js.InterpolatedDeclaration node) { |
| 967 if (peek() is! js.InterpolatedDeclaration) return failAt(node, peek()); |
| 968 js.InterpolatedDeclaration other = peek(); |
| 969 return testValues(node.nameOrPosition, other.nameOrPosition); |
| 970 } |
| 971 |
| 972 @override |
| 973 bool visitInterpolatedStatement(js.InterpolatedStatement node) { |
| 974 if (peek() is! js.InterpolatedStatement) return failAt(node, peek()); |
| 975 js.InterpolatedStatement other = peek(); |
| 976 return testValues(node.nameOrPosition, other.nameOrPosition); |
| 977 } |
| 978 |
| 979 @override |
| 980 bool visitInterpolatedSelector(js.InterpolatedSelector node) { |
| 981 if (peek() is! js.InterpolatedSelector) return failAt(node, peek()); |
| 982 js.InterpolatedSelector other = peek(); |
| 983 return testValues(node.nameOrPosition, other.nameOrPosition); |
| 984 } |
| 985 |
| 986 @override |
| 987 bool visitInterpolatedParameter(js.InterpolatedParameter node) { |
| 988 if (peek() is! js.InterpolatedParameter) return failAt(node, peek()); |
| 989 js.InterpolatedParameter other = peek(); |
| 990 return testValues(node.nameOrPosition, other.nameOrPosition); |
| 991 } |
| 992 |
| 993 @override |
| 994 bool visitInterpolatedLiteral(js.InterpolatedLiteral node) { |
| 995 if (peek() is! js.InterpolatedLiteral) return failAt(node, peek()); |
| 996 js.InterpolatedLiteral other = peek(); |
| 997 return testValues(node.nameOrPosition, other.nameOrPosition); |
| 998 } |
| 999 |
| 1000 @override |
| 1001 bool visitInterpolatedExpression(js.InterpolatedExpression node) { |
| 1002 if (peek() is! js.InterpolatedExpression) return failAt(node, peek()); |
| 1003 js.InterpolatedExpression other = peek(); |
| 1004 return testValues(node.nameOrPosition, other.nameOrPosition); |
| 1005 } |
| 1006 |
| 1007 @override |
| 1008 bool visitComment(js.Comment node) { |
| 1009 if (peek() is! js.Comment) return failAt(node, peek()); |
| 1010 js.Comment other = peek(); |
| 1011 return testValues(node.comment, other.comment); |
| 1012 } |
| 1013 |
| 1014 @override |
| 1015 bool visitAwait(js.Await node) { |
| 1016 if (peek() is! js.Await) return failAt(node, peek()); |
| 1017 js.Await other = peek(); |
| 1018 return testNodes(node.expression, other.expression); |
| 1019 } |
| 1020 |
| 1021 @override |
| 1022 bool visitRegExpLiteral(js.RegExpLiteral node) { |
| 1023 if (peek() is! js.RegExpLiteral) return failAt(node, peek()); |
| 1024 js.RegExpLiteral other = peek(); |
| 1025 return testValues(node.pattern, other.pattern); |
| 1026 } |
| 1027 |
| 1028 @override |
| 1029 bool visitProperty(js.Property node) { |
| 1030 if (peek() is! js.Property) return failAt(node, peek()); |
| 1031 js.Property other = peek(); |
| 1032 return testNodes(node.name, other.name) && |
| 1033 testNodes(node.value, other.value); |
| 1034 } |
| 1035 |
| 1036 @override |
| 1037 bool visitObjectInitializer(js.ObjectInitializer node) { |
| 1038 if (peek() is! js.ObjectInitializer) return failAt(node, peek()); |
| 1039 js.ObjectInitializer other = peek(); |
| 1040 return testNodeLists(node.properties, other.properties); |
| 1041 } |
| 1042 |
| 1043 @override |
| 1044 bool visitArrayHole(js.ArrayHole node) { |
| 1045 if (peek() is! js.ArrayHole) return failAt(node, peek()); |
| 1046 return true; |
| 1047 } |
| 1048 |
| 1049 @override |
| 1050 bool visitArrayInitializer(js.ArrayInitializer node) { |
| 1051 if (peek() is! js.ArrayInitializer) return failAt(node, peek()); |
| 1052 js.ArrayInitializer other = peek(); |
| 1053 return testNodeLists(node.elements, other.elements); |
| 1054 } |
| 1055 |
| 1056 @override |
| 1057 bool visitName(js.Name node) { |
| 1058 if (peek() is! js.Name) return failAt(node, peek()); |
| 1059 js.Name other = peek(); |
| 1060 return testValues(node.key, other.key); |
| 1061 } |
| 1062 |
| 1063 @override |
| 1064 bool visitStringConcatenation(js.StringConcatenation node) { |
| 1065 if (peek() is! js.StringConcatenation) return failAt(node, peek()); |
| 1066 js.StringConcatenation other = peek(); |
| 1067 return testNodeLists(node.parts, other.parts); |
| 1068 } |
| 1069 |
| 1070 @override |
| 1071 bool visitLiteralNull(js.LiteralNull node) { |
| 1072 if (peek() is! js.LiteralNull) return failAt(node, peek()); |
| 1073 return true; |
| 1074 } |
| 1075 |
| 1076 @override |
| 1077 bool visitLiteralNumber(js.LiteralNumber node) { |
| 1078 if (peek() is! js.LiteralNumber) return failAt(node, peek()); |
| 1079 js.LiteralNumber other = peek(); |
| 1080 return testValues(node.value, other.value); |
| 1081 } |
| 1082 |
| 1083 @override |
| 1084 bool visitLiteralString(js.LiteralString node) { |
| 1085 if (peek() is! js.LiteralString) return failAt(node, peek()); |
| 1086 js.LiteralString other = peek(); |
| 1087 return testValues(node.value, other.value); |
| 1088 } |
| 1089 |
| 1090 @override |
| 1091 bool visitLiteralBool(js.LiteralBool node) { |
| 1092 if (peek() is! js.LiteralBool) return failAt(node, peek()); |
| 1093 js.LiteralBool other = peek(); |
| 1094 return testValues(node.value, other.value); |
| 1095 } |
| 1096 |
| 1097 @override |
| 1098 bool visitDeferredString(js.DeferredString node) { |
| 1099 if (peek() is! js.DeferredString) return failAt(node, peek()); |
| 1100 js.DeferredString other = peek(); |
| 1101 return testValues(node.value, other.value); |
| 1102 } |
| 1103 |
| 1104 @override |
| 1105 bool visitDeferredNumber(js.DeferredNumber node) { |
| 1106 if (peek() is! js.DeferredNumber) return failAt(node, peek()); |
| 1107 js.DeferredNumber other = peek(); |
| 1108 return testValues(node.value, other.value); |
| 1109 } |
| 1110 |
| 1111 @override |
| 1112 bool visitDeferredExpression(js.DeferredExpression node) { |
| 1113 if (peek() is! js.DeferredExpression) return failAt(node, peek()); |
| 1114 js.DeferredExpression other = peek(); |
| 1115 return testNodes(node.value, other.value); |
| 1116 } |
| 1117 |
| 1118 @override |
| 1119 bool visitFun(js.Fun node) { |
| 1120 if (peek() is! js.Fun) return failAt(node, peek()); |
| 1121 js.Fun other = peek(); |
| 1122 return testNodeLists(node.params, other.params) && |
| 1123 testNodes(node.body, other.body) && |
| 1124 testValues(node.asyncModifier, other.asyncModifier); |
| 1125 } |
| 1126 |
| 1127 @override |
| 1128 bool visitNamedFunction(js.NamedFunction node) { |
| 1129 if (peek() is! js.NamedFunction) return failAt(node, peek()); |
| 1130 js.NamedFunction other = peek(); |
| 1131 return testNodes(node.name, other.name) && |
| 1132 testNodes(node.function, other.function); |
| 1133 } |
| 1134 |
| 1135 @override |
| 1136 bool visitAccess(js.PropertyAccess node) { |
| 1137 if (peek() is! js.PropertyAccess) return failAt(node, peek()); |
| 1138 js.PropertyAccess other = peek(); |
| 1139 return testNodes(node.receiver, other.receiver) && |
| 1140 testNodes(node.selector, other.selector); |
| 1141 } |
| 1142 |
| 1143 @override |
| 1144 bool visitParameter(js.Parameter node) { |
| 1145 if (peek() is! js.Parameter) return failAt(node, peek()); |
| 1146 js.Parameter other = peek(); |
| 1147 return testValues(node.name, other.name); |
| 1148 } |
| 1149 |
| 1150 @override |
| 1151 bool visitVariableDeclaration(js.VariableDeclaration node) { |
| 1152 if (peek() is! js.VariableDeclaration) return failAt(node, peek()); |
| 1153 js.VariableDeclaration other = peek(); |
| 1154 return testValues(node.name, other.name) && |
| 1155 testValues(node.allowRename, other.allowRename); |
| 1156 } |
| 1157 |
| 1158 @override |
| 1159 bool visitThis(js.This node) { |
| 1160 if (peek() is! js.This) return failAt(node, peek()); |
| 1161 return true; |
| 1162 } |
| 1163 |
| 1164 @override |
| 1165 bool visitVariableUse(js.VariableUse node) { |
| 1166 if (peek() is! js.VariableUse) return failAt(node, peek()); |
| 1167 js.VariableUse other = peek(); |
| 1168 return testValues(node.name, other.name); |
| 1169 } |
| 1170 |
| 1171 @override |
| 1172 bool visitPostfix(js.Postfix node) { |
| 1173 if (peek() is! js.Postfix) return failAt(node, peek()); |
| 1174 js.Postfix other = peek(); |
| 1175 return testValues(node.op, other.op) && |
| 1176 testNodes(node.argument, other.argument); |
| 1177 } |
| 1178 |
| 1179 @override |
| 1180 bool visitPrefix(js.Prefix node) { |
| 1181 if (peek() is! js.Prefix) return failAt(node, peek()); |
| 1182 js.Prefix other = peek(); |
| 1183 return testValues(node.op, other.op) && |
| 1184 testNodes(node.argument, other.argument); |
| 1185 } |
| 1186 |
| 1187 @override |
| 1188 bool visitBinary(js.Binary node) { |
| 1189 if (peek() is! js.Binary) return failAt(node, peek()); |
| 1190 js.Binary other = peek(); |
| 1191 return testNodes(node.left, other.left) && |
| 1192 testValues(node.op, other.op) && |
| 1193 testNodes(node.right, other.right); |
| 1194 } |
| 1195 |
| 1196 @override |
| 1197 bool visitCall(js.Call node) { |
| 1198 if (peek() is! js.Call) return failAt(node, peek()); |
| 1199 js.Call other = peek(); |
| 1200 return testNodes(node.target, other.target) && |
| 1201 testNodeLists(node.arguments, other.arguments); |
| 1202 } |
| 1203 |
| 1204 @override |
| 1205 bool visitNew(js.New node) { |
| 1206 if (peek() is! js.New) return failAt(node, peek()); |
| 1207 js.New other = peek(); |
| 1208 return testNodes(node.target, other.target) && |
| 1209 testNodeLists(node.arguments, other.arguments); |
| 1210 } |
| 1211 |
| 1212 @override |
| 1213 bool visitConditional(js.Conditional node) { |
| 1214 if (peek() is! js.Conditional) return failAt(node, peek()); |
| 1215 js.Conditional other = peek(); |
| 1216 return testNodes(node.condition, other.condition) && |
| 1217 testNodes(node.then, other.then) && |
| 1218 testNodes(node.otherwise, other.otherwise); |
| 1219 } |
| 1220 |
| 1221 @override |
| 1222 bool visitVariableInitialization(js.VariableInitialization node) { |
| 1223 if (peek() is! js.VariableInitialization) return failAt(node, peek()); |
| 1224 js.VariableInitialization other = peek(); |
| 1225 return testNodes(node.declaration, other.declaration) && |
| 1226 testNodes(node.leftHandSide, other.leftHandSide) && |
| 1227 testValues(node.op, other.op) && |
| 1228 testNodes(node.value, other.value); |
| 1229 } |
| 1230 |
| 1231 @override |
| 1232 bool visitAssignment(js.Assignment node) { |
| 1233 if (peek() is! js.Assignment) return failAt(node, peek()); |
| 1234 js.Assignment other = peek(); |
| 1235 return testNodes(node.leftHandSide, other.leftHandSide) && |
| 1236 testValues(node.op, other.op) && |
| 1237 testNodes(node.value, other.value); |
| 1238 } |
| 1239 |
| 1240 @override |
| 1241 bool visitVariableDeclarationList(js.VariableDeclarationList node) { |
| 1242 if (peek() is! js.VariableDeclarationList) return failAt(node, peek()); |
| 1243 js.VariableDeclarationList other = peek(); |
| 1244 return testNodeLists(node.declarations, other.declarations); |
| 1245 } |
| 1246 |
| 1247 @override |
| 1248 bool visitLiteralExpression(js.LiteralExpression node) { |
| 1249 if (peek() is! js.LiteralExpression) return failAt(node, peek()); |
| 1250 js.LiteralExpression other = peek(); |
| 1251 return testValues(node.template, other.template) && |
| 1252 testNodeLists(node.inputs, other.inputs); |
| 1253 } |
| 1254 |
| 1255 @override |
| 1256 bool visitDartYield(js.DartYield node) { |
| 1257 if (peek() is! js.DartYield) return failAt(node, peek()); |
| 1258 js.DartYield other = peek(); |
| 1259 return testNodes(node.expression, other.expression) && |
| 1260 testValues(node.hasStar, other.hasStar); |
| 1261 } |
| 1262 |
| 1263 @override |
| 1264 bool visitLiteralStatement(js.LiteralStatement node) { |
| 1265 if (peek() is! js.LiteralStatement) return failAt(node, peek()); |
| 1266 js.LiteralStatement other = peek(); |
| 1267 return testValues(node.code, other.code); |
| 1268 } |
| 1269 |
| 1270 @override |
| 1271 bool visitLabeledStatement(js.LabeledStatement node) { |
| 1272 if (peek() is! js.LabeledStatement) return failAt(node, peek()); |
| 1273 js.LabeledStatement other = peek(); |
| 1274 return testLabels(node.label, other.label) && |
| 1275 testNodes(node.body, other.body); |
| 1276 } |
| 1277 |
| 1278 @override |
| 1279 bool visitFunctionDeclaration(js.FunctionDeclaration node) { |
| 1280 if (peek() is! js.FunctionDeclaration) return failAt(node, peek()); |
| 1281 js.FunctionDeclaration other = peek(); |
| 1282 return testNodes(node.name, other.name) && |
| 1283 testNodes(node.function, other.function); |
| 1284 } |
| 1285 |
| 1286 @override |
| 1287 bool visitDefault(js.Default node) { |
| 1288 if (peek() is! js.Default) return failAt(node, peek()); |
| 1289 js.Default other = peek(); |
| 1290 return testNodes(node.body, other.body); |
| 1291 } |
| 1292 |
| 1293 @override |
| 1294 bool visitCase(js.Case node) { |
| 1295 if (peek() is! js.Case) return failAt(node, peek()); |
| 1296 js.Case other = peek(); |
| 1297 return testNodes(node.expression, other.expression) && |
| 1298 testNodes(node.body, other.body); |
| 1299 } |
| 1300 |
| 1301 @override |
| 1302 bool visitSwitch(js.Switch node) { |
| 1303 if (peek() is! js.Switch) return failAt(node, peek()); |
| 1304 js.Switch other = peek(); |
| 1305 return testNodes(node.key, other.key) && |
| 1306 testNodeLists(node.cases, other.cases); |
| 1307 } |
| 1308 |
| 1309 @override |
| 1310 bool visitCatch(js.Catch node) { |
| 1311 if (peek() is! js.Catch) return failAt(node, peek()); |
| 1312 js.Catch other = peek(); |
| 1313 return testNodes(node.declaration, other.declaration) && |
| 1314 testNodes(node.body, other.body); |
| 1315 } |
| 1316 |
| 1317 @override |
| 1318 bool visitTry(js.Try node) { |
| 1319 if (peek() is! js.Try) return failAt(node, peek()); |
| 1320 js.Try other = peek(); |
| 1321 return testNodes(node.body, other.body) && |
| 1322 testNodes(node.catchPart, other.catchPart) && |
| 1323 testNodes(node.finallyPart, other.finallyPart); |
| 1324 } |
| 1325 |
| 1326 @override |
| 1327 bool visitThrow(js.Throw node) { |
| 1328 if (peek() is! js.Throw) return failAt(node, peek()); |
| 1329 js.Throw other = peek(); |
| 1330 return testNodes(node.expression, other.expression); |
| 1331 } |
| 1332 |
| 1333 @override |
| 1334 bool visitReturn(js.Return node) { |
| 1335 if (peek() is! js.Return) return failAt(node, peek()); |
| 1336 js.Return other = peek(); |
| 1337 return testNodes(node.value, other.value); |
| 1338 } |
| 1339 |
| 1340 @override |
| 1341 bool visitBreak(js.Break node) { |
| 1342 if (peek() is! js.Break) return failAt(node, peek()); |
| 1343 js.Break other = peek(); |
| 1344 return testLabels(node.targetLabel, other.targetLabel); |
| 1345 } |
| 1346 |
| 1347 @override |
| 1348 bool visitContinue(js.Continue node) { |
| 1349 if (peek() is! js.Continue) return failAt(node, peek()); |
| 1350 js.Continue other = peek(); |
| 1351 return testLabels(node.targetLabel, other.targetLabel); |
| 1352 } |
| 1353 |
| 1354 @override |
| 1355 bool visitDo(js.Do node) { |
| 1356 if (peek() is! js.Do) return failAt(node, peek()); |
| 1357 js.Do other = peek(); |
| 1358 return testNodes(node.condition, other.condition) && |
| 1359 testNodes(node.body, other.body); |
| 1360 } |
| 1361 |
| 1362 @override |
| 1363 bool visitWhile(js.While node) { |
| 1364 if (peek() is! js.While) return failAt(node, peek()); |
| 1365 js.While other = peek(); |
| 1366 return testNodes(node.condition, other.condition) && |
| 1367 testNodes(node.body, other.body); |
| 1368 } |
| 1369 |
| 1370 @override |
| 1371 bool visitForIn(js.ForIn node) { |
| 1372 if (peek() is! js.ForIn) return failAt(node, peek()); |
| 1373 js.ForIn other = peek(); |
| 1374 return testNodes(node.leftHandSide, other.leftHandSide) && |
| 1375 testNodes(node.object, other.object) && |
| 1376 testNodes(node.body, other.body); |
| 1377 } |
| 1378 |
| 1379 @override |
| 1380 bool visitFor(js.For node) { |
| 1381 if (peek() is! js.For) return failAt(node, peek()); |
| 1382 js.For other = peek(); |
| 1383 return testNodes(node.init, other.init) && |
| 1384 testNodes(node.condition, other.condition) && |
| 1385 testNodes(node.update, other.update) && |
| 1386 testNodes(node.body, other.body); |
| 1387 } |
| 1388 |
| 1389 @override |
| 1390 bool visitIf(js.If node) { |
| 1391 if (peek() is! js.If) return failAt(node, peek()); |
| 1392 js.If other = peek(); |
| 1393 return testNodes(node.condition, other.condition) && |
| 1394 testNodes(node.then, other.then) && |
| 1395 testNodes(node.otherwise, other.otherwise); |
| 1396 } |
| 1397 |
| 1398 @override |
| 1399 bool visitEmptyStatement(js.EmptyStatement node) { |
| 1400 if (peek() is! js.EmptyStatement) return failAt(node, peek()); |
| 1401 return true; |
| 1402 } |
| 1403 |
| 1404 @override |
| 1405 bool visitExpressionStatement(js.ExpressionStatement node) { |
| 1406 if (peek() is! js.ExpressionStatement) return failAt(node, peek()); |
| 1407 js.ExpressionStatement other = peek(); |
| 1408 return testNodes(node.expression, other.expression); |
| 1409 } |
| 1410 |
| 1411 @override |
| 1412 bool visitBlock(js.Block node) { |
| 1413 if (peek() is! js.Block) return failAt(node, peek()); |
| 1414 js.Block other = peek(); |
| 1415 return testNodeLists(node.statements, other.statements); |
| 1416 } |
| 1417 } |
OLD | NEW |