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