OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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.serialization_test_helper; | 5 library dart2js.serialization_test_helper; |
6 | 6 |
| 7 import 'dart:collection'; |
7 import 'package:compiler/src/common/resolution.dart'; | 8 import 'package:compiler/src/common/resolution.dart'; |
8 import 'package:compiler/src/constants/expressions.dart'; | 9 import 'package:compiler/src/constants/expressions.dart'; |
9 import 'package:compiler/src/dart_types.dart'; | 10 import 'package:compiler/src/dart_types.dart'; |
10 import 'package:compiler/src/compiler.dart'; | 11 import 'package:compiler/src/compiler.dart'; |
11 import 'package:compiler/src/elements/elements.dart'; | 12 import 'package:compiler/src/elements/elements.dart'; |
12 import 'package:compiler/src/serialization/equivalence.dart'; | 13 import 'package:compiler/src/serialization/equivalence.dart'; |
13 import 'package:compiler/src/tree/nodes.dart'; | 14 import 'package:compiler/src/tree/nodes.dart'; |
14 | 15 |
| 16 Check currentCheck; |
| 17 |
| 18 class Check { |
| 19 final Check parent; |
| 20 final Object object1; |
| 21 final Object object2; |
| 22 final String property; |
| 23 final Object value1; |
| 24 final Object value2; |
| 25 |
| 26 Check(this.parent, this.object1, this.object2, this.property, this.value1, thi
s.value2); |
| 27 |
| 28 String printOn(StringBuffer sb, String indent) { |
| 29 if (parent != null) { |
| 30 indent = parent.printOn(sb, indent); |
| 31 sb.write('\n$indent|\n'); |
| 32 } |
| 33 sb.write("${indent}property='$property'\n "); |
| 34 sb.write("${indent}object1=$object1 (${object1.runtimeType})\n "); |
| 35 sb.write("${indent}value=${value1 == null ? "null" : "'$value1'"} "); |
| 36 sb.write("(${value1.runtimeType}) vs\n "); |
| 37 sb.write("${indent}object2=$object2 (${object2.runtimeType})\n "); |
| 38 sb.write("${indent}value=${value2 == null ? "null" : "'$value2'"} "); |
| 39 sb.write("(${value2.runtimeType})"); |
| 40 return ' $indent'; |
| 41 } |
| 42 |
| 43 String toString() { |
| 44 StringBuffer sb = new StringBuffer(); |
| 45 printOn(sb, ''); |
| 46 return sb.toString(); |
| 47 } |
| 48 } |
| 49 |
15 /// Strategy for checking equivalence. | 50 /// Strategy for checking equivalence. |
16 /// | 51 /// |
17 /// Use this strategy to fail early with contextual information in the event of | 52 /// Use this strategy to fail early with contextual information in the event of |
18 /// inequivalence. | 53 /// inequivalence. |
19 class CheckStrategy implements TestStrategy { | 54 class CheckStrategy implements TestStrategy { |
20 const CheckStrategy(); | 55 const CheckStrategy(); |
21 | 56 |
22 @override | 57 @override |
23 bool test(var object1, var object2, String property, var value1, var value2, | 58 bool test(var object1, var object2, String property, var value1, var value2, |
24 [bool equivalence(a, b) = equality]) { | 59 [bool equivalence(a, b) = equality]) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 Node node1, Node node2) { | 127 Node node1, Node node2) { |
93 return new NodeEquivalenceVisitor(this).testNodes( | 128 return new NodeEquivalenceVisitor(this).testNodes( |
94 object1, object2, property, node1, node2); | 129 object1, object2, property, node1, node2); |
95 } | 130 } |
96 } | 131 } |
97 | 132 |
98 /// Check that the values [property] of [object1] and [object2], [value1] and | 133 /// Check that the values [property] of [object1] and [object2], [value1] and |
99 /// [value2] respectively, are equal and throw otherwise. | 134 /// [value2] respectively, are equal and throw otherwise. |
100 bool check(var object1, var object2, String property, var value1, var value2, | 135 bool check(var object1, var object2, String property, var value1, var value2, |
101 [bool equivalence(a, b) = equality]) { | 136 [bool equivalence(a, b) = equality]) { |
| 137 currentCheck = new Check( |
| 138 currentCheck, object1, object2, property, value1, value2); |
102 if (!equivalence(value1, value2)) { | 139 if (!equivalence(value1, value2)) { |
103 throw "property='$property'\n " | 140 throw currentCheck; |
104 "object1=$object1 (${object1.runtimeType})\n " | |
105 "value=${value1 == null ? "null" : "'$value1'"} " | |
106 "(${value1.runtimeType}) <>\n " | |
107 "object2=$object2 (${object2.runtimeType})\n " | |
108 "value=${value2 == null ? "null" : "'$value2'"} " | |
109 "(${value2.runtimeType})"; | |
110 } | 141 } |
| 142 currentCheck = currentCheck.parent; |
111 return true; | 143 return true; |
112 } | 144 } |
113 | 145 |
114 /// Check equivalence of the two lists, [list1] and [list2], using | 146 /// Check equivalence of the two lists, [list1] and [list2], using |
115 /// [checkEquivalence] to check the pair-wise equivalence. | 147 /// [checkEquivalence] to check the pair-wise equivalence. |
116 /// | 148 /// |
117 /// Uses [object1], [object2] and [property] to provide context for failures. | 149 /// Uses [object1], [object2] and [property] to provide context for failures. |
118 bool checkListEquivalence( | 150 bool checkListEquivalence( |
119 Object object1, Object object2, String property, | 151 Object object1, Object object2, String property, |
120 Iterable list1, Iterable list2, | 152 Iterable list1, Iterable list2, |
121 void checkEquivalence(o1, o2, property, a, b)) { | 153 void checkEquivalence(o1, o2, property, a, b)) { |
| 154 currentCheck = |
| 155 new Check(currentCheck, object1, object2, property, list1, list2); |
122 for (int i = 0; i < list1.length && i < list2.length; i++) { | 156 for (int i = 0; i < list1.length && i < list2.length; i++) { |
123 checkEquivalence( | 157 checkEquivalence( |
124 object1, object2, property, | 158 object1, object2, property, |
125 list1.elementAt(i), list2.elementAt(i)); | 159 list1.elementAt(i), list2.elementAt(i)); |
126 } | 160 } |
127 for (int i = list1.length; i < list2.length; i++) { | 161 for (int i = list1.length; i < list2.length; i++) { |
128 throw | 162 throw |
129 'Missing equivalent for element ' | 163 'Missing equivalent for element ' |
130 '#$i ${list2.elementAt(i)} in `${property}` on $object2.\n' | 164 '#$i ${list2.elementAt(i)} in `${property}` on $object2.\n' |
131 '`${property}` on $object1:\n ${list1.join('\n ')}\n' | 165 '`${property}` on $object1:\n ${list1.join('\n ')}\n' |
132 '`${property}` on $object2:\n ${list2.join('\n ')}'; | 166 '`${property}` on $object2:\n ${list2.join('\n ')}'; |
133 } | 167 } |
134 for (int i = list2.length; i < list1.length; i++) { | 168 for (int i = list2.length; i < list1.length; i++) { |
135 throw | 169 throw |
136 'Missing equivalent for element ' | 170 'Missing equivalent for element ' |
137 '#$i ${list1.elementAt(i)} in `${property}` on $object1.\n' | 171 '#$i ${list1.elementAt(i)} in `${property}` on $object1.\n' |
138 '`${property}` on $object1:\n ${list1.join('\n ')}\n' | 172 '`${property}` on $object1:\n ${list1.join('\n ')}\n' |
139 '`${property}` on $object2:\n ${list2.join('\n ')}'; | 173 '`${property}` on $object2:\n ${list2.join('\n ')}'; |
140 } | 174 } |
| 175 currentCheck = currentCheck.parent; |
141 return true; | 176 return true; |
142 } | 177 } |
143 | 178 |
144 /// Computes the set difference between [set1] and [set2] using | 179 /// Computes the set difference between [set1] and [set2] using |
145 /// [elementEquivalence] to determine element equivalence. | 180 /// [elementEquivalence] to determine element equivalence. |
146 /// | 181 /// |
147 /// Elements both in [set1] and [set2] are added to [common], elements in [set1] | 182 /// Elements both in [set1] and [set2] are added to [common], elements in [set1] |
148 /// but not in [set2] are added to [unfound], and the set of elements in [set2] | 183 /// but not in [set2] are added to [unfound], and the set of elements in [set2] |
149 /// but not in [set1] are returned. | 184 /// but not in [set1] are returned. |
150 Set computeSetDifference( | 185 Set computeSetDifference( |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 /// Checks the equivalence of [type1] and [type2]. | 272 /// Checks the equivalence of [type1] and [type2]. |
238 /// | 273 /// |
239 /// Uses [object1], [object2] and [property] to provide context for failures. | 274 /// Uses [object1], [object2] and [property] to provide context for failures. |
240 bool checkTypes( | 275 bool checkTypes( |
241 Object object1, Object object2, String property, | 276 Object object1, Object object2, String property, |
242 DartType type1, DartType type2) { | 277 DartType type1, DartType type2) { |
243 if (identical(type1, type2)) return true; | 278 if (identical(type1, type2)) return true; |
244 if (type1 == null || type2 == null) { | 279 if (type1 == null || type2 == null) { |
245 return check(object1, object2, property, type1, type2); | 280 return check(object1, object2, property, type1, type2); |
246 } else { | 281 } else { |
247 return const TypeEquivalence(const CheckStrategy()).visit(type1, type2); | 282 return check(object1, object2, property, type1, type2, |
| 283 (a, b) => const TypeEquivalence(const CheckStrategy()).visit(a, b)); |
248 } | 284 } |
249 } | 285 } |
250 | 286 |
251 /// Checks the pair-wise equivalence of the types in [list1] and [list2]. | 287 /// Checks the pair-wise equivalence of the types in [list1] and [list2]. |
252 /// | 288 /// |
253 /// Uses [object1], [object2] and [property] to provide context for failures. | 289 /// Uses [object1], [object2] and [property] to provide context for failures. |
254 bool checkTypeLists( | 290 bool checkTypeLists( |
255 Object object1, Object object2, String property, | 291 Object object1, Object object2, String property, |
256 List<DartType> list1, List<DartType> list2) { | 292 List<DartType> list1, List<DartType> list2) { |
257 return checkListEquivalence( | 293 return checkListEquivalence( |
258 object1, object2, property, list1, list2, checkTypes); | 294 object1, object2, property, list1, list2, checkTypes); |
259 } | 295 } |
260 | 296 |
261 /// Checks the equivalence of [exp1] and [exp2]. | 297 /// Checks the equivalence of [exp1] and [exp2]. |
262 /// | 298 /// |
263 /// Uses [object1], [object2] and [property] to provide context for failures. | 299 /// Uses [object1], [object2] and [property] to provide context for failures. |
264 bool checkConstants( | 300 bool checkConstants( |
265 Object object1, Object object2, String property, | 301 Object object1, Object object2, String property, |
266 ConstantExpression exp1, ConstantExpression exp2) { | 302 ConstantExpression exp1, ConstantExpression exp2) { |
267 if (identical(exp1, exp2)) return true; | 303 if (identical(exp1, exp2)) return true; |
268 if (exp1 == null || exp2 == null) { | 304 if (exp1 == null || exp2 == null) { |
269 return check(object1, object2, property, exp1, exp2); | 305 return check(object1, object2, property, exp1, exp2); |
270 } else { | 306 } else { |
271 return const ConstantEquivalence(const CheckStrategy()).visit(exp1, exp2); | 307 return check(object1, object2, property, exp1, exp2, |
| 308 (a, b) => const ConstantEquivalence(const CheckStrategy()).visit(a, b)); |
272 } | 309 } |
273 } | 310 } |
274 | 311 |
275 /// Checks the pair-wise equivalence of the contants in [list1] and [list2]. | 312 /// Checks the pair-wise equivalence of the contants in [list1] and [list2]. |
276 /// | 313 /// |
277 /// Uses [object1], [object2] and [property] to provide context for failures. | 314 /// Uses [object1], [object2] and [property] to provide context for failures. |
278 bool checkConstantLists( | 315 bool checkConstantLists( |
279 Object object1, Object object2, String property, | 316 Object object1, Object object2, String property, |
280 List<ConstantExpression> list1, | 317 List<ConstantExpression> list1, |
281 List<ConstantExpression> list2) { | 318 List<ConstantExpression> list2) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 | 412 |
376 if (impact1 == null) { | 413 if (impact1 == null) { |
377 throw 'Missing impact for $member1. $member2 has $impact2'; | 414 throw 'Missing impact for $member1. $member2 has $impact2'; |
378 } | 415 } |
379 if (impact2 == null) { | 416 if (impact2 == null) { |
380 throw 'Missing impact for $member2. $member1 has $impact1'; | 417 throw 'Missing impact for $member2. $member1 has $impact1'; |
381 } | 418 } |
382 | 419 |
383 testResolutionImpactEquivalence(impact1, impact2, const CheckStrategy()); | 420 testResolutionImpactEquivalence(impact1, impact2, const CheckStrategy()); |
384 } | 421 } |
OLD | NEW |