| 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 |