| 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 /// Functions for asserting equivalence across serialization. | 5 /// Functions for asserting equivalence across serialization. |
| 6 | 6 |
| 7 library dart2js.serialization.equivalence; | 7 library dart2js.serialization.equivalence; |
| 8 | 8 |
| 9 import '../common/resolution.dart'; | 9 import '../common/resolution.dart'; |
| 10 import '../constants/expressions.dart'; | 10 import '../constants/expressions.dart'; |
| 11 import '../dart_types.dart'; | 11 import '../dart_types.dart'; |
| 12 import '../elements/elements.dart'; | 12 import '../elements/elements.dart'; |
| 13 import '../elements/visitor.dart'; | 13 import '../elements/visitor.dart'; |
| 14 import '../universe/selector.dart'; | 14 import '../universe/selector.dart'; |
| 15 import '../universe/use.dart'; | 15 import '../universe/use.dart'; |
| 16 | 16 |
| 17 /// Equality based equivalence function. | 17 /// Equality based equivalence function. |
| 18 bool equality(a, b) => a == b; | 18 bool equality(a, b) => a == b; |
| 19 | 19 |
| 20 /// Returns `true` if the elements in [a] and [b] are pair-wise equivalent | 20 /// Returns `true` if the elements in [a] and [b] are pair-wise equivalent |
| 21 /// according to [elementEquivalence]. | 21 /// according to [elementEquivalence]. |
| 22 bool areListsEquivalent( | 22 bool areListsEquivalent(List a, List b, |
| 23 List a, | |
| 24 List b, | |
| 25 [bool elementEquivalence(a, b) = equality]) { | 23 [bool elementEquivalence(a, b) = equality]) { |
| 26 | |
| 27 if (a.length != b.length) return false; | 24 if (a.length != b.length) return false; |
| 28 for (int i = 0; i < a.length && i < b.length; i++) { | 25 for (int i = 0; i < a.length && i < b.length; i++) { |
| 29 if (!elementEquivalence(a[i], b[i])) { | 26 if (!elementEquivalence(a[i], b[i])) { |
| 30 return false; | 27 return false; |
| 31 } | 28 } |
| 32 } | 29 } |
| 33 return true; | 30 return true; |
| 34 } | 31 } |
| 35 | 32 |
| 36 /// Returns `true` if the elements in [a] and [b] are equivalent as sets using | 33 /// Returns `true` if the elements in [a] and [b] are equivalent as sets using |
| 37 /// [elementEquivalence] to determine element equivalence. | 34 /// [elementEquivalence] to determine element equivalence. |
| 38 bool areSetsEquivalent( | 35 bool areSetsEquivalent(Iterable set1, Iterable set2, |
| 39 Iterable set1, | |
| 40 Iterable set2, | |
| 41 [bool elementEquivalence(a, b) = equality]) { | 36 [bool elementEquivalence(a, b) = equality]) { |
| 42 Set remaining = set2.toSet(); | 37 Set remaining = set2.toSet(); |
| 43 for (var element1 in set1) { | 38 for (var element1 in set1) { |
| 44 bool found = false; | 39 bool found = false; |
| 45 for (var element2 in set2) { | 40 for (var element2 in set2) { |
| 46 if (elementEquivalence(element1, element2)) { | 41 if (elementEquivalence(element1, element2)) { |
| 47 found = true; | 42 found = true; |
| 48 remaining.remove(element2); | 43 remaining.remove(element2); |
| 49 break; | 44 break; |
| 50 } | 45 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 81 bool areElementListsEquivalent(List<Element> a, List<Element> b) { | 76 bool areElementListsEquivalent(List<Element> a, List<Element> b) { |
| 82 return areListsEquivalent(a, b, areElementsEquivalent); | 77 return areListsEquivalent(a, b, areElementsEquivalent); |
| 83 } | 78 } |
| 84 | 79 |
| 85 /// Returns `true` if the lists of types, [a] and [b], are equivalent. | 80 /// Returns `true` if the lists of types, [a] and [b], are equivalent. |
| 86 bool areTypeListsEquivalent(List<DartType> a, List<DartType> b) { | 81 bool areTypeListsEquivalent(List<DartType> a, List<DartType> b) { |
| 87 return areListsEquivalent(a, b, areTypesEquivalent); | 82 return areListsEquivalent(a, b, areTypesEquivalent); |
| 88 } | 83 } |
| 89 | 84 |
| 90 /// Returns `true` if the lists of constants, [a] and [b], are equivalent. | 85 /// Returns `true` if the lists of constants, [a] and [b], are equivalent. |
| 91 bool areConstantListsEquivalent(List<ConstantExpression> a, | 86 bool areConstantListsEquivalent( |
| 92 List<ConstantExpression> b) { | 87 List<ConstantExpression> a, List<ConstantExpression> b) { |
| 93 return areListsEquivalent(a, b, areConstantsEquivalent); | 88 return areListsEquivalent(a, b, areConstantsEquivalent); |
| 94 } | 89 } |
| 95 | 90 |
| 96 /// Returns `true` if the selectors [a] and [b] are equivalent. | 91 /// Returns `true` if the selectors [a] and [b] are equivalent. |
| 97 bool areSelectorsEquivalent(Selector a, Selector b) { | 92 bool areSelectorsEquivalent(Selector a, Selector b) { |
| 98 return a.kind == b.kind && | 93 return a.kind == b.kind && |
| 99 a.callStructure == b.callStructure && | 94 a.callStructure == b.callStructure && |
| 100 areNamesEquivalent(a.memberName, b.memberName); | 95 areNamesEquivalent(a.memberName, b.memberName); |
| 101 } | 96 } |
| 102 | 97 |
| 103 /// Returns `true` if the names [a] and [b] are equivalent. | 98 /// Returns `true` if the names [a] and [b] are equivalent. |
| 104 bool areNamesEquivalent(Name a, Name b) { | 99 bool areNamesEquivalent(Name a, Name b) { |
| 105 return a.text == b.text && | 100 return a.text == b.text && |
| 106 a.isSetter == b.isSetter && | 101 a.isSetter == b.isSetter && |
| 107 areElementsEquivalent(a.library, b.library); | 102 areElementsEquivalent(a.library, b.library); |
| 108 } | 103 } |
| 109 | 104 |
| 110 /// Returns `true` if the dynamic uses [a] and [b] are equivalent. | 105 /// Returns `true` if the dynamic uses [a] and [b] are equivalent. |
| 111 bool areDynamicUsesEquivalent(DynamicUse a, DynamicUse b) { | 106 bool areDynamicUsesEquivalent(DynamicUse a, DynamicUse b) { |
| 112 return areSelectorsEquivalent(a.selector, b.selector); | 107 return areSelectorsEquivalent(a.selector, b.selector); |
| 113 } | 108 } |
| 114 | 109 |
| 115 /// Returns `true` if the static uses [a] and [b] are equivalent. | 110 /// Returns `true` if the static uses [a] and [b] are equivalent. |
| 116 bool areStaticUsesEquivalent(StaticUse a, StaticUse b) { | 111 bool areStaticUsesEquivalent(StaticUse a, StaticUse b) { |
| 117 return a.kind == b.kind && | 112 return a.kind == b.kind && areElementsEquivalent(a.element, b.element); |
| 118 areElementsEquivalent(a.element, b.element); | |
| 119 } | 113 } |
| 120 | 114 |
| 121 /// Returns `true` if the type uses [a] and [b] are equivalent. | 115 /// Returns `true` if the type uses [a] and [b] are equivalent. |
| 122 bool areTypeUsesEquivalent(TypeUse a, TypeUse b) { | 116 bool areTypeUsesEquivalent(TypeUse a, TypeUse b) { |
| 123 return a.kind == b.kind && | 117 return a.kind == b.kind && areTypesEquivalent(a.type, b.type); |
| 124 areTypesEquivalent(a.type, b.type); | |
| 125 } | 118 } |
| 126 | 119 |
| 127 /// Returns `true` if the list literal uses [a] and [b] are equivalent. | 120 /// Returns `true` if the list literal uses [a] and [b] are equivalent. |
| 128 bool areListLiteralUsesEquivalent(ListLiteralUse a, ListLiteralUse b) { | 121 bool areListLiteralUsesEquivalent(ListLiteralUse a, ListLiteralUse b) { |
| 129 return areTypesEquivalent(a.type, b.type) && | 122 return areTypesEquivalent(a.type, b.type) && |
| 130 a.isConstant == b.isConstant && | 123 a.isConstant == b.isConstant && |
| 131 a.isEmpty == b.isEmpty; | 124 a.isEmpty == b.isEmpty; |
| 132 } | 125 } |
| 133 | 126 |
| 134 /// Returns `true` if the map literal uses [a] and [b] are equivalent. | 127 /// Returns `true` if the map literal uses [a] and [b] are equivalent. |
| 135 bool areMapLiteralUsesEquivalent(MapLiteralUse a, MapLiteralUse b) { | 128 bool areMapLiteralUsesEquivalent(MapLiteralUse a, MapLiteralUse b) { |
| 136 return areTypesEquivalent(a.type, b.type) && | 129 return areTypesEquivalent(a.type, b.type) && |
| 137 a.isConstant == b.isConstant && | 130 a.isConstant == b.isConstant && |
| 138 a.isEmpty == b.isEmpty; | 131 a.isEmpty == b.isEmpty; |
| 139 } | 132 } |
| 140 | 133 |
| 141 /// Strategy for testing equivalence. | 134 /// Strategy for testing equivalence. |
| 142 /// | 135 /// |
| 143 /// Use this strategy to determine equivalence without failing on inequivalence. | 136 /// Use this strategy to determine equivalence without failing on inequivalence. |
| 144 class TestStrategy { | 137 class TestStrategy { |
| 145 const TestStrategy(); | 138 const TestStrategy(); |
| 146 | 139 |
| 147 bool test(var object1, var object2, String property, var value1, var value2) { | 140 bool test(var object1, var object2, String property, var value1, var value2) { |
| 148 return value1 == value2; | 141 return value1 == value2; |
| 149 } | 142 } |
| 150 | 143 |
| 151 bool testLists( | 144 bool testLists( |
| 152 Object object1, Object object2, String property, | 145 Object object1, Object object2, String property, List list1, List list2, |
| 153 List list1, List list2, | |
| 154 [bool elementEquivalence(a, b) = equality]) { | 146 [bool elementEquivalence(a, b) = equality]) { |
| 155 return areListsEquivalent(list1, list2, elementEquivalence); | 147 return areListsEquivalent(list1, list2, elementEquivalence); |
| 156 } | 148 } |
| 157 | 149 |
| 158 bool testSets( | 150 bool testSets( |
| 159 var object1, var object2, String property, | 151 var object1, var object2, String property, Iterable set1, Iterable set2, |
| 160 Iterable set1, Iterable set2, | |
| 161 [bool elementEquivalence(a, b) = equality]) { | 152 [bool elementEquivalence(a, b) = equality]) { |
| 162 return areSetsEquivalent(set1, set2, elementEquivalence); | 153 return areSetsEquivalent(set1, set2, elementEquivalence); |
| 163 } | 154 } |
| 164 | 155 |
| 165 bool testElements( | 156 bool testElements(Object object1, Object object2, String property, |
| 166 Object object1, Object object2, String property, | |
| 167 Element element1, Element element2) { | 157 Element element1, Element element2) { |
| 168 return areElementsEquivalent(element1, element2); | 158 return areElementsEquivalent(element1, element2); |
| 169 } | 159 } |
| 170 | 160 |
| 171 bool testTypes( | 161 bool testTypes(Object object1, Object object2, String property, |
| 172 Object object1, Object object2, String property, | |
| 173 DartType type1, DartType type2) { | 162 DartType type1, DartType type2) { |
| 174 return areTypesEquivalent(type1, type2); | 163 return areTypesEquivalent(type1, type2); |
| 175 } | 164 } |
| 176 | 165 |
| 177 bool testConstants( | 166 bool testConstants(Object object1, Object object2, String property, |
| 178 Object object1, Object object2, String property, | |
| 179 ConstantExpression exp1, ConstantExpression exp2) { | 167 ConstantExpression exp1, ConstantExpression exp2) { |
| 180 return areConstantsEquivalent(exp1, exp2); | 168 return areConstantsEquivalent(exp1, exp2); |
| 181 } | 169 } |
| 182 | 170 |
| 183 bool testTypeLists( | 171 bool testTypeLists(Object object1, Object object2, String property, |
| 184 Object object1, Object object2, String property, | |
| 185 List<DartType> list1, List<DartType> list2) { | 172 List<DartType> list1, List<DartType> list2) { |
| 186 return areTypeListsEquivalent(list1, list2); | 173 return areTypeListsEquivalent(list1, list2); |
| 187 } | 174 } |
| 188 | 175 |
| 189 bool testConstantLists( | 176 bool testConstantLists(Object object1, Object object2, String property, |
| 190 Object object1, Object object2, String property, | 177 List<ConstantExpression> list1, List<ConstantExpression> list2) { |
| 191 List<ConstantExpression> list1, | |
| 192 List<ConstantExpression> list2) { | |
| 193 return areConstantListsEquivalent(list1, list2); | 178 return areConstantListsEquivalent(list1, list2); |
| 194 } | 179 } |
| 195 | |
| 196 } | 180 } |
| 197 | 181 |
| 198 /// Visitor that checks for equivalence of [Element]s. | 182 /// Visitor that checks for equivalence of [Element]s. |
| 199 class ElementIdentityEquivalence extends BaseElementVisitor<bool, Element> { | 183 class ElementIdentityEquivalence extends BaseElementVisitor<bool, Element> { |
| 200 final TestStrategy strategy; | 184 final TestStrategy strategy; |
| 201 | 185 |
| 202 const ElementIdentityEquivalence([this.strategy = const TestStrategy()]); | 186 const ElementIdentityEquivalence([this.strategy = const TestStrategy()]); |
| 203 | 187 |
| 204 bool visit(Element element1, Element element2) { | 188 bool visit(Element element1, Element element2) { |
| 205 if (element1 == null && element2 == null) { | 189 if (element1 == null && element2 == null) { |
| 206 return true; | 190 return true; |
| 207 } else if (element1 == null || element2 == null) { | 191 } else if (element1 == null || element2 == null) { |
| 208 return false; | 192 return false; |
| 209 } | 193 } |
| 210 element1 = element1.declaration; | 194 element1 = element1.declaration; |
| 211 element2 = element2.declaration; | 195 element2 = element2.declaration; |
| 212 if (element1 == element2) { | 196 if (element1 == element2) { |
| 213 return true; | 197 return true; |
| 214 } | 198 } |
| 215 return | 199 return strategy.test( |
| 216 strategy.test( | 200 element1, element2, 'kind', element1.kind, element2.kind) && |
| 217 element1, element2, 'kind', | |
| 218 element1.kind, element2.kind) && | |
| 219 element1.accept(this, element2); | 201 element1.accept(this, element2); |
| 220 } | 202 } |
| 221 | 203 |
| 222 @override | 204 @override |
| 223 bool visitElement(Element e, Element arg) { | 205 bool visitElement(Element e, Element arg) { |
| 224 throw new UnsupportedError("Unsupported element $e"); | 206 throw new UnsupportedError("Unsupported element $e"); |
| 225 } | 207 } |
| 226 | 208 |
| 227 @override | 209 @override |
| 228 bool visitLibraryElement(LibraryElement element1, LibraryElement element2) { | 210 bool visitLibraryElement(LibraryElement element1, LibraryElement element2) { |
| 229 return | 211 return strategy.test(element1, element2, 'canonicalUri', |
| 230 strategy.test(element1, element2, | 212 element1.canonicalUri, element2.canonicalUri); |
| 231 'canonicalUri', | |
| 232 element1.canonicalUri, element2.canonicalUri); | |
| 233 } | 213 } |
| 234 | 214 |
| 235 @override | 215 @override |
| 236 bool visitCompilationUnitElement(CompilationUnitElement element1, | 216 bool visitCompilationUnitElement( |
| 237 CompilationUnitElement element2) { | 217 CompilationUnitElement element1, CompilationUnitElement element2) { |
| 238 return | 218 return strategy.test( |
| 239 strategy.test(element1, element2, | 219 element1, element2, 'name', element1.name, element2.name) && |
| 240 'name', | |
| 241 element1.name, element2.name) && | |
| 242 visit(element1.library, element2.library); | 220 visit(element1.library, element2.library); |
| 243 } | 221 } |
| 244 | 222 |
| 245 @override | 223 @override |
| 246 bool visitClassElement(ClassElement element1, ClassElement element2) { | 224 bool visitClassElement(ClassElement element1, ClassElement element2) { |
| 247 return | 225 return strategy.test( |
| 248 strategy.test(element1, element2, | 226 element1, element2, 'name', element1.name, element2.name) && |
| 249 'name', | |
| 250 element1.name, element2.name) && | |
| 251 visit(element1.library, element2.library); | 227 visit(element1.library, element2.library); |
| 252 } | 228 } |
| 253 | 229 |
| 254 bool checkMembers(Element element1, Element element2) { | 230 bool checkMembers(Element element1, Element element2) { |
| 255 if (!strategy.test(element1, element2, 'name', | 231 if (!strategy.test( |
| 256 element1.name, element2.name)) { | 232 element1, element2, 'name', element1.name, element2.name)) { |
| 257 return false; | 233 return false; |
| 258 } | 234 } |
| 259 if (element1.enclosingClass != null || element2.enclosingClass != null) { | 235 if (element1.enclosingClass != null || element2.enclosingClass != null) { |
| 260 return visit(element1.enclosingClass, element2.enclosingClass); | 236 return visit(element1.enclosingClass, element2.enclosingClass); |
| 261 } else { | 237 } else { |
| 262 return visit(element1.library, element2.library); | 238 return visit(element1.library, element2.library); |
| 263 } | 239 } |
| 264 } | 240 } |
| 265 | 241 |
| 266 @override | 242 @override |
| 267 bool visitFieldElement(FieldElement element1, FieldElement element2) { | 243 bool visitFieldElement(FieldElement element1, FieldElement element2) { |
| 268 return checkMembers(element1, element2); | 244 return checkMembers(element1, element2); |
| 269 } | 245 } |
| 270 | 246 |
| 271 @override | 247 @override |
| 272 bool visitConstructorElement(ConstructorElement element1, | 248 bool visitConstructorElement( |
| 273 ConstructorElement element2) { | 249 ConstructorElement element1, ConstructorElement element2) { |
| 274 return checkMembers(element1, element2); | 250 return checkMembers(element1, element2); |
| 275 } | 251 } |
| 276 | 252 |
| 277 @override | 253 @override |
| 278 bool visitMethodElement(MethodElement element1, | 254 bool visitMethodElement(MethodElement element1, MethodElement element2) { |
| 279 MethodElement element2) { | |
| 280 return checkMembers(element1, element2); | 255 return checkMembers(element1, element2); |
| 281 } | 256 } |
| 282 | 257 |
| 283 @override | 258 @override |
| 284 bool visitGetterElement(GetterElement element1, | 259 bool visitGetterElement(GetterElement element1, GetterElement element2) { |
| 285 GetterElement element2) { | |
| 286 return checkMembers(element1, element2); | 260 return checkMembers(element1, element2); |
| 287 } | 261 } |
| 288 | 262 |
| 289 @override | 263 @override |
| 290 bool visitSetterElement(SetterElement element1, | 264 bool visitSetterElement(SetterElement element1, SetterElement element2) { |
| 291 SetterElement element2) { | |
| 292 return checkMembers(element1, element2); | 265 return checkMembers(element1, element2); |
| 293 } | 266 } |
| 294 | 267 |
| 295 @override | 268 @override |
| 296 bool visitLocalFunctionElement(LocalFunctionElement element1, | 269 bool visitLocalFunctionElement( |
| 297 LocalFunctionElement element2) { | 270 LocalFunctionElement element1, LocalFunctionElement element2) { |
| 298 // TODO(johnniwinther): Define an equivalence on locals. | 271 // TODO(johnniwinther): Define an equivalence on locals. |
| 299 return checkMembers(element1.memberContext, element2.memberContext); | 272 return checkMembers(element1.memberContext, element2.memberContext); |
| 300 } | 273 } |
| 301 | 274 |
| 302 bool visitAbstractFieldElement(AbstractFieldElement element1, | 275 bool visitAbstractFieldElement( |
| 303 AbstractFieldElement element2) { | 276 AbstractFieldElement element1, AbstractFieldElement element2) { |
| 304 return checkMembers(element1, element2); | 277 return checkMembers(element1, element2); |
| 305 } | 278 } |
| 306 | 279 |
| 307 @override | 280 @override |
| 308 bool visitTypeVariableElement(TypeVariableElement element1, | 281 bool visitTypeVariableElement( |
| 309 TypeVariableElement element2) { | 282 TypeVariableElement element1, TypeVariableElement element2) { |
| 310 return | 283 return strategy.test( |
| 311 strategy.test( | 284 element1, element2, 'name', element1.name, element2.name) && |
| 312 element1, element2, 'name', | |
| 313 element1.name, element2.name) && | |
| 314 visit(element1.typeDeclaration, element2.typeDeclaration); | 285 visit(element1.typeDeclaration, element2.typeDeclaration); |
| 315 } | 286 } |
| 316 | 287 |
| 317 @override | 288 @override |
| 318 bool visitTypedefElement(TypedefElement element1, TypedefElement element2) { | 289 bool visitTypedefElement(TypedefElement element1, TypedefElement element2) { |
| 319 return | 290 return strategy.test( |
| 320 strategy.test( | 291 element1, element2, 'name', element1.name, element2.name) && |
| 321 element1, element2, 'name', | |
| 322 element1.name, element2.name) && | |
| 323 visit(element1.library, element2.library); | 292 visit(element1.library, element2.library); |
| 324 } | 293 } |
| 325 | 294 |
| 326 @override | 295 @override |
| 327 bool visitParameterElement(ParameterElement element1, | 296 bool visitParameterElement( |
| 328 ParameterElement element2) { | 297 ParameterElement element1, ParameterElement element2) { |
| 329 return | 298 return strategy.test( |
| 330 strategy.test( | 299 element1, element2, 'name', element1.name, element2.name) && |
| 331 element1, element2, 'name', | |
| 332 element1.name, element2.name) && | |
| 333 visit(element1.functionDeclaration, element2.functionDeclaration); | 300 visit(element1.functionDeclaration, element2.functionDeclaration); |
| 334 } | 301 } |
| 335 | 302 |
| 336 @override | 303 @override |
| 337 bool visitImportElement(ImportElement element1, ImportElement element2) { | 304 bool visitImportElement(ImportElement element1, ImportElement element2) { |
| 338 return | 305 return visit(element1.importedLibrary, element2.importedLibrary) && |
| 339 visit(element1.importedLibrary, element2.importedLibrary) && | |
| 340 visit(element1.library, element2.library); | 306 visit(element1.library, element2.library); |
| 341 } | 307 } |
| 342 | 308 |
| 343 @override | 309 @override |
| 344 bool visitExportElement(ExportElement element1, ExportElement element2) { | 310 bool visitExportElement(ExportElement element1, ExportElement element2) { |
| 345 return | 311 return visit(element1.exportedLibrary, element2.exportedLibrary) && |
| 346 visit(element1.exportedLibrary, element2.exportedLibrary) && | |
| 347 visit(element1.library, element2.library); | 312 visit(element1.library, element2.library); |
| 348 } | 313 } |
| 349 | 314 |
| 350 @override | 315 @override |
| 351 bool visitPrefixElement(PrefixElement element1, PrefixElement element2) { | 316 bool visitPrefixElement(PrefixElement element1, PrefixElement element2) { |
| 352 return | 317 return strategy.test( |
| 353 strategy.test( | 318 element1, element2, 'name', element1.name, element2.name) && |
| 354 element1, element2, 'name', | |
| 355 element1.name, element2.name) && | |
| 356 visit(element1.library, element2.library); | 319 visit(element1.library, element2.library); |
| 357 } | 320 } |
| 358 } | 321 } |
| 359 | 322 |
| 360 | |
| 361 /// Visitor that checks for equivalence of [DartType]s. | 323 /// Visitor that checks for equivalence of [DartType]s. |
| 362 class TypeEquivalence implements DartTypeVisitor<bool, DartType> { | 324 class TypeEquivalence implements DartTypeVisitor<bool, DartType> { |
| 363 final TestStrategy strategy; | 325 final TestStrategy strategy; |
| 364 | 326 |
| 365 const TypeEquivalence([this.strategy = const TestStrategy()]); | 327 const TypeEquivalence([this.strategy = const TestStrategy()]); |
| 366 | 328 |
| 367 bool visit(DartType type1, DartType type2) { | 329 bool visit(DartType type1, DartType type2) { |
| 368 return | 330 return strategy.test(type1, type2, 'kind', type1.kind, type2.kind) && |
| 369 strategy.test(type1, type2, 'kind', type1.kind, type2.kind) && | |
| 370 type1.accept(this, type2); | 331 type1.accept(this, type2); |
| 371 } | 332 } |
| 372 | 333 |
| 373 @override | 334 @override |
| 374 bool visitDynamicType(DynamicType type, DynamicType other) => true; | 335 bool visitDynamicType(DynamicType type, DynamicType other) => true; |
| 375 | 336 |
| 376 @override | 337 @override |
| 377 bool visitFunctionType(FunctionType type, FunctionType other) { | 338 bool visitFunctionType(FunctionType type, FunctionType other) { |
| 378 return | 339 return strategy.testTypeLists(type, other, 'parameterTypes', |
| 379 strategy.testTypeLists( | |
| 380 type, other, 'parameterTypes', | |
| 381 type.parameterTypes, other.parameterTypes) && | 340 type.parameterTypes, other.parameterTypes) && |
| 382 strategy.testTypeLists( | 341 strategy.testTypeLists(type, other, 'optionalParameterTypes', |
| 383 type, other, 'optionalParameterTypes', | |
| 384 type.optionalParameterTypes, other.optionalParameterTypes) && | 342 type.optionalParameterTypes, other.optionalParameterTypes) && |
| 385 strategy.testTypeLists( | 343 strategy.testTypeLists(type, other, 'namedParameterTypes', |
| 386 type, other, 'namedParameterTypes', | |
| 387 type.namedParameterTypes, other.namedParameterTypes) && | 344 type.namedParameterTypes, other.namedParameterTypes) && |
| 388 strategy.testLists( | 345 strategy.testLists(type, other, 'namedParameters', type.namedParameters, |
| 389 type, other, 'namedParameters', | 346 other.namedParameters); |
| 390 type.namedParameters, other.namedParameters); | |
| 391 } | 347 } |
| 392 | 348 |
| 393 bool visitGenericType(GenericType type, GenericType other) { | 349 bool visitGenericType(GenericType type, GenericType other) { |
| 394 return | 350 return strategy.testElements( |
| 395 strategy.testElements( | 351 type, other, 'element', type.element, other.element) && |
| 396 type, other, 'element', | 352 strategy.testTypeLists(type, other, 'typeArguments', type.typeArguments, |
| 397 type.element, other.element) && | 353 other.typeArguments); |
| 398 strategy.testTypeLists( | |
| 399 type, other, 'typeArguments', | |
| 400 type.typeArguments, other.typeArguments); | |
| 401 } | 354 } |
| 402 | 355 |
| 403 @override | 356 @override |
| 404 bool visitMalformedType(MalformedType type, MalformedType other) => true; | 357 bool visitMalformedType(MalformedType type, MalformedType other) => true; |
| 405 | 358 |
| 406 @override | 359 @override |
| 407 bool visitStatementType(StatementType type, StatementType other) { | 360 bool visitStatementType(StatementType type, StatementType other) { |
| 408 throw new UnsupportedError("Unsupported type: $type"); | 361 throw new UnsupportedError("Unsupported type: $type"); |
| 409 } | 362 } |
| 410 | 363 |
| 411 @override | 364 @override |
| 412 bool visitTypeVariableType(TypeVariableType type, TypeVariableType other) { | 365 bool visitTypeVariableType(TypeVariableType type, TypeVariableType other) { |
| 413 return | 366 return strategy.testElements( |
| 414 strategy.testElements( | 367 type, other, 'element', type.element, other.element); |
| 415 type, other, 'element', | |
| 416 type.element, other.element); | |
| 417 } | 368 } |
| 418 | 369 |
| 419 @override | 370 @override |
| 420 bool visitVoidType(VoidType type, VoidType argument) => true; | 371 bool visitVoidType(VoidType type, VoidType argument) => true; |
| 421 | 372 |
| 422 @override | 373 @override |
| 423 bool visitInterfaceType(InterfaceType type, InterfaceType other) { | 374 bool visitInterfaceType(InterfaceType type, InterfaceType other) { |
| 424 return visitGenericType(type, other); | 375 return visitGenericType(type, other); |
| 425 } | 376 } |
| 426 | 377 |
| 427 @override | 378 @override |
| 428 bool visitTypedefType(TypedefType type, TypedefType other) { | 379 bool visitTypedefType(TypedefType type, TypedefType other) { |
| 429 return visitGenericType(type, other); | 380 return visitGenericType(type, other); |
| 430 } | 381 } |
| 431 } | 382 } |
| 432 | 383 |
| 433 /// Visitor that checks for structural equivalence of [ConstantExpression]s. | 384 /// Visitor that checks for structural equivalence of [ConstantExpression]s. |
| 434 class ConstantEquivalence | 385 class ConstantEquivalence |
| 435 implements ConstantExpressionVisitor<bool, ConstantExpression> { | 386 implements ConstantExpressionVisitor<bool, ConstantExpression> { |
| 436 final TestStrategy strategy; | 387 final TestStrategy strategy; |
| 437 | 388 |
| 438 const ConstantEquivalence([this.strategy = const TestStrategy()]); | 389 const ConstantEquivalence([this.strategy = const TestStrategy()]); |
| 439 | 390 |
| 440 @override | 391 @override |
| 441 bool visit(ConstantExpression exp1, ConstantExpression exp2) { | 392 bool visit(ConstantExpression exp1, ConstantExpression exp2) { |
| 442 if (identical(exp1, exp2)) return true; | 393 if (identical(exp1, exp2)) return true; |
| 443 return | 394 return strategy.test(exp1, exp2, 'kind', exp1.kind, exp2.kind) && |
| 444 strategy.test(exp1, exp2, 'kind', exp1.kind, exp2.kind) && | |
| 445 exp1.accept(this, exp2); | 395 exp1.accept(this, exp2); |
| 446 } | 396 } |
| 447 | 397 |
| 448 @override | 398 @override |
| 449 bool visitBinary(BinaryConstantExpression exp1, | 399 bool visitBinary( |
| 450 BinaryConstantExpression exp2) { | 400 BinaryConstantExpression exp1, BinaryConstantExpression exp2) { |
| 451 return | 401 return strategy.test( |
| 452 strategy.test(exp1, exp2, 'operator', exp1.operator, exp2.operator) && | 402 exp1, exp2, 'operator', exp1.operator, exp2.operator) && |
| 453 strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) && | 403 strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) && |
| 454 strategy.testConstants(exp1, exp2, 'right', exp1.right, exp2.right); | 404 strategy.testConstants(exp1, exp2, 'right', exp1.right, exp2.right); |
| 455 } | 405 } |
| 456 | 406 |
| 457 @override | 407 @override |
| 458 bool visitConcatenate(ConcatenateConstantExpression exp1, | 408 bool visitConcatenate( |
| 459 ConcatenateConstantExpression exp2) { | 409 ConcatenateConstantExpression exp1, ConcatenateConstantExpression exp2) { |
| 460 return | 410 return strategy.testConstantLists( |
| 461 strategy.testConstantLists( | 411 exp1, exp2, 'expressions', exp1.expressions, exp2.expressions); |
| 462 exp1, exp2, 'expressions', | |
| 463 exp1.expressions, exp2.expressions); | |
| 464 } | 412 } |
| 465 | 413 |
| 466 @override | 414 @override |
| 467 bool visitConditional(ConditionalConstantExpression exp1, | 415 bool visitConditional( |
| 468 ConditionalConstantExpression exp2) { | 416 ConditionalConstantExpression exp1, ConditionalConstantExpression exp2) { |
| 469 return | 417 return strategy.testConstants( |
| 470 strategy.testConstants( | |
| 471 exp1, exp2, 'condition', exp1.condition, exp2.condition) && | 418 exp1, exp2, 'condition', exp1.condition, exp2.condition) && |
| 472 strategy.testConstants( | 419 strategy.testConstants( |
| 473 exp1, exp2, 'trueExp', exp1.trueExp, exp2.trueExp) && | 420 exp1, exp2, 'trueExp', exp1.trueExp, exp2.trueExp) && |
| 474 strategy.testConstants( | 421 strategy.testConstants( |
| 475 exp1, exp2, 'falseExp', exp1.falseExp, exp2.falseExp); | 422 exp1, exp2, 'falseExp', exp1.falseExp, exp2.falseExp); |
| 476 } | 423 } |
| 477 | 424 |
| 478 @override | 425 @override |
| 479 bool visitConstructed(ConstructedConstantExpression exp1, | 426 bool visitConstructed( |
| 480 ConstructedConstantExpression exp2) { | 427 ConstructedConstantExpression exp1, ConstructedConstantExpression exp2) { |
| 481 return | 428 return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type) && |
| 482 strategy.testTypes( | 429 strategy.testElements(exp1, exp2, 'target', exp1.target, exp2.target) && |
| 483 exp1, exp2, 'type', | |
| 484 exp1.type, exp2.type) && | |
| 485 strategy.testElements( | |
| 486 exp1, exp2, 'target', | |
| 487 exp1.target, exp2.target) && | |
| 488 strategy.testConstantLists( | 430 strategy.testConstantLists( |
| 489 exp1, exp2, 'arguments', | 431 exp1, exp2, 'arguments', exp1.arguments, exp2.arguments) && |
| 490 exp1.arguments, exp2.arguments) && | 432 strategy.test(exp1, exp2, 'callStructure', exp1.callStructure, |
| 491 strategy.test(exp1, exp2, 'callStructure', | 433 exp2.callStructure); |
| 492 exp1.callStructure, exp2.callStructure); | |
| 493 } | 434 } |
| 494 | 435 |
| 495 @override | 436 @override |
| 496 bool visitFunction(FunctionConstantExpression exp1, | 437 bool visitFunction( |
| 497 FunctionConstantExpression exp2) { | 438 FunctionConstantExpression exp1, FunctionConstantExpression exp2) { |
| 498 return | 439 return strategy.testElements( |
| 499 strategy.testElements( | 440 exp1, exp2, 'element', exp1.element, exp2.element); |
| 500 exp1, exp2, 'element', | |
| 501 exp1.element, exp2.element); | |
| 502 } | 441 } |
| 503 | 442 |
| 504 @override | 443 @override |
| 505 bool visitIdentical(IdenticalConstantExpression exp1, | 444 bool visitIdentical( |
| 506 IdenticalConstantExpression exp2) { | 445 IdenticalConstantExpression exp1, IdenticalConstantExpression exp2) { |
| 507 return | 446 return strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) && |
| 508 strategy.testConstants(exp1, exp2, 'left', exp1.left, exp2.left) && | |
| 509 strategy.testConstants(exp1, exp2, 'right', exp1.right, exp2.right); | 447 strategy.testConstants(exp1, exp2, 'right', exp1.right, exp2.right); |
| 510 } | 448 } |
| 511 | 449 |
| 512 @override | 450 @override |
| 513 bool visitList(ListConstantExpression exp1, ListConstantExpression exp2) { | 451 bool visitList(ListConstantExpression exp1, ListConstantExpression exp2) { |
| 514 return | 452 return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type) && |
| 515 strategy.testTypes( | |
| 516 exp1, exp2, 'type', | |
| 517 exp1.type, exp2.type) && | |
| 518 strategy.testConstantLists( | 453 strategy.testConstantLists( |
| 519 exp1, exp2, 'values', | 454 exp1, exp2, 'values', exp1.values, exp2.values); |
| 520 exp1.values, exp2.values); | |
| 521 } | 455 } |
| 522 | 456 |
| 523 @override | 457 @override |
| 524 bool visitMap(MapConstantExpression exp1, MapConstantExpression exp2) { | 458 bool visitMap(MapConstantExpression exp1, MapConstantExpression exp2) { |
| 525 return | 459 return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type) && |
| 526 strategy.testTypes( | 460 strategy.testConstantLists(exp1, exp2, 'keys', exp1.keys, exp2.keys) && |
| 527 exp1, exp2, 'type', | |
| 528 exp1.type, exp2.type) && | |
| 529 strategy.testConstantLists( | 461 strategy.testConstantLists( |
| 530 exp1, exp2, 'keys', | 462 exp1, exp2, 'values', exp1.values, exp2.values); |
| 531 exp1.keys, exp2.keys) && | |
| 532 strategy.testConstantLists( | |
| 533 exp1, exp2, 'values', | |
| 534 exp1.values, exp2.values); | |
| 535 } | 463 } |
| 536 | 464 |
| 537 @override | 465 @override |
| 538 bool visitNamed(NamedArgumentReference exp1, NamedArgumentReference exp2) { | 466 bool visitNamed(NamedArgumentReference exp1, NamedArgumentReference exp2) { |
| 539 return strategy.test(exp1, exp2, 'name', exp1.name, exp2.name); | 467 return strategy.test(exp1, exp2, 'name', exp1.name, exp2.name); |
| 540 } | 468 } |
| 541 | 469 |
| 542 @override | 470 @override |
| 543 bool visitPositional(PositionalArgumentReference exp1, | 471 bool visitPositional( |
| 544 PositionalArgumentReference exp2) { | 472 PositionalArgumentReference exp1, PositionalArgumentReference exp2) { |
| 545 return strategy.test(exp1, exp2, 'index', exp1.index, exp2.index); | 473 return strategy.test(exp1, exp2, 'index', exp1.index, exp2.index); |
| 546 } | 474 } |
| 547 | 475 |
| 548 @override | 476 @override |
| 549 bool visitSymbol(SymbolConstantExpression exp1, | 477 bool visitSymbol( |
| 550 SymbolConstantExpression exp2) { | 478 SymbolConstantExpression exp1, SymbolConstantExpression exp2) { |
| 551 // TODO: implement visitSymbol | 479 // TODO: implement visitSymbol |
| 552 return true; | 480 return true; |
| 553 } | 481 } |
| 554 | 482 |
| 555 @override | 483 @override |
| 556 bool visitType(TypeConstantExpression exp1, TypeConstantExpression exp2) { | 484 bool visitType(TypeConstantExpression exp1, TypeConstantExpression exp2) { |
| 557 return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type); | 485 return strategy.testTypes(exp1, exp2, 'type', exp1.type, exp2.type); |
| 558 } | 486 } |
| 559 | 487 |
| 560 @override | 488 @override |
| 561 bool visitUnary(UnaryConstantExpression exp1, UnaryConstantExpression exp2) { | 489 bool visitUnary(UnaryConstantExpression exp1, UnaryConstantExpression exp2) { |
| 562 return | 490 return strategy.test( |
| 563 strategy.test(exp1, exp2, 'operator', exp1.operator, exp2.operator) && | 491 exp1, exp2, 'operator', exp1.operator, exp2.operator) && |
| 564 strategy.testConstants( | 492 strategy.testConstants( |
| 565 exp1, exp2, 'expression', exp1.expression, exp2.expression); | 493 exp1, exp2, 'expression', exp1.expression, exp2.expression); |
| 566 } | 494 } |
| 567 | 495 |
| 568 @override | 496 @override |
| 569 bool visitVariable(VariableConstantExpression exp1, | 497 bool visitVariable( |
| 570 VariableConstantExpression exp2) { | 498 VariableConstantExpression exp1, VariableConstantExpression exp2) { |
| 571 return | 499 return strategy.testElements( |
| 572 strategy.testElements( | 500 exp1, exp2, 'element', exp1.element, exp2.element); |
| 573 exp1, exp2, 'element', | |
| 574 exp1.element, exp2.element); | |
| 575 } | 501 } |
| 576 | 502 |
| 577 @override | 503 @override |
| 578 bool visitBool(BoolConstantExpression exp1, BoolConstantExpression exp2) { | 504 bool visitBool(BoolConstantExpression exp1, BoolConstantExpression exp2) { |
| 579 return | 505 return strategy.test( |
| 580 strategy.test( | 506 exp1, exp2, 'primitiveValue', exp1.primitiveValue, exp2.primitiveValue); |
| 581 exp1, exp2, 'primitiveValue', | |
| 582 exp1.primitiveValue, exp2.primitiveValue); | |
| 583 } | 507 } |
| 584 | 508 |
| 585 @override | 509 @override |
| 586 bool visitDouble(DoubleConstantExpression exp1, | 510 bool visitDouble( |
| 587 DoubleConstantExpression exp2) { | 511 DoubleConstantExpression exp1, DoubleConstantExpression exp2) { |
| 588 return | 512 return strategy.test( |
| 589 strategy.test( | 513 exp1, exp2, 'primitiveValue', exp1.primitiveValue, exp2.primitiveValue); |
| 590 exp1, exp2, 'primitiveValue', | |
| 591 exp1.primitiveValue, exp2.primitiveValue); | |
| 592 } | 514 } |
| 593 | 515 |
| 594 @override | 516 @override |
| 595 bool visitInt(IntConstantExpression exp1, IntConstantExpression exp2) { | 517 bool visitInt(IntConstantExpression exp1, IntConstantExpression exp2) { |
| 596 return | 518 return strategy.test( |
| 597 strategy.test( | 519 exp1, exp2, 'primitiveValue', exp1.primitiveValue, exp2.primitiveValue); |
| 598 exp1, exp2, 'primitiveValue', | |
| 599 exp1.primitiveValue, exp2.primitiveValue); | |
| 600 } | 520 } |
| 601 | 521 |
| 602 @override | 522 @override |
| 603 bool visitNull(NullConstantExpression exp1, NullConstantExpression exp2) { | 523 bool visitNull(NullConstantExpression exp1, NullConstantExpression exp2) { |
| 604 return true; | 524 return true; |
| 605 } | 525 } |
| 606 | 526 |
| 607 @override | 527 @override |
| 608 bool visitString(StringConstantExpression exp1, | 528 bool visitString( |
| 609 StringConstantExpression exp2) { | 529 StringConstantExpression exp1, StringConstantExpression exp2) { |
| 610 return | 530 return strategy.test( |
| 611 strategy.test( | 531 exp1, exp2, 'primitiveValue', exp1.primitiveValue, exp2.primitiveValue); |
| 612 exp1, exp2, 'primitiveValue', | |
| 613 exp1.primitiveValue, exp2.primitiveValue); | |
| 614 } | 532 } |
| 615 | 533 |
| 616 @override | 534 @override |
| 617 bool visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp1, | 535 bool visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp1, |
| 618 BoolFromEnvironmentConstantExpression exp2) { | 536 BoolFromEnvironmentConstantExpression exp2) { |
| 619 return | 537 return strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) && |
| 620 strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) && | |
| 621 strategy.testConstants( | 538 strategy.testConstants( |
| 622 exp1, exp2, 'defaultValue', | 539 exp1, exp2, 'defaultValue', exp1.defaultValue, exp2.defaultValue); |
| 623 exp1.defaultValue, exp2.defaultValue); | |
| 624 } | 540 } |
| 625 | 541 |
| 626 @override | 542 @override |
| 627 bool visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp1, | 543 bool visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp1, |
| 628 IntFromEnvironmentConstantExpression exp2) { | 544 IntFromEnvironmentConstantExpression exp2) { |
| 629 return | 545 return strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) && |
| 630 strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) && | |
| 631 strategy.testConstants( | 546 strategy.testConstants( |
| 632 exp1, exp2, 'defaultValue', | 547 exp1, exp2, 'defaultValue', exp1.defaultValue, exp2.defaultValue); |
| 633 exp1.defaultValue, exp2.defaultValue); | |
| 634 } | 548 } |
| 635 | 549 |
| 636 @override | 550 @override |
| 637 bool visitStringFromEnvironment( | 551 bool visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp1, |
| 638 StringFromEnvironmentConstantExpression exp1, | |
| 639 StringFromEnvironmentConstantExpression exp2) { | 552 StringFromEnvironmentConstantExpression exp2) { |
| 640 return | 553 return strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) && |
| 641 strategy.testConstants(exp1, exp2, 'name', exp1.name, exp2.name) && | |
| 642 strategy.testConstants( | 554 strategy.testConstants( |
| 643 exp1, exp2, 'defaultValue', | 555 exp1, exp2, 'defaultValue', exp1.defaultValue, exp2.defaultValue); |
| 644 exp1.defaultValue, exp2.defaultValue); | |
| 645 } | 556 } |
| 646 | 557 |
| 647 @override | 558 @override |
| 648 bool visitStringLength(StringLengthConstantExpression exp1, | 559 bool visitStringLength(StringLengthConstantExpression exp1, |
| 649 StringLengthConstantExpression exp2) { | 560 StringLengthConstantExpression exp2) { |
| 650 return | 561 return strategy.testConstants( |
| 651 strategy.testConstants( | 562 exp1, exp2, 'expression', exp1.expression, exp2.expression); |
| 652 exp1, exp2, 'expression', | |
| 653 exp1.expression, exp2.expression); | |
| 654 } | 563 } |
| 655 | 564 |
| 656 @override | 565 @override |
| 657 bool visitDeferred(DeferredConstantExpression exp1, | 566 bool visitDeferred( |
| 658 DeferredConstantExpression exp2) { | 567 DeferredConstantExpression exp1, DeferredConstantExpression exp2) { |
| 659 // TODO: implement visitDeferred | 568 // TODO: implement visitDeferred |
| 660 return true; | 569 return true; |
| 661 } | 570 } |
| 662 } | 571 } |
| 663 | 572 |
| 664 /// Tests the equivalence of [impact1] and [impact2] using [strategy]. | 573 /// Tests the equivalence of [impact1] and [impact2] using [strategy]. |
| 665 bool testResolutionImpactEquivalence( | 574 bool testResolutionImpactEquivalence( |
| 666 ResolutionImpact impact1, | 575 ResolutionImpact impact1, ResolutionImpact impact2, |
| 667 ResolutionImpact impact2, | |
| 668 [TestStrategy strategy = const TestStrategy()]) { | 576 [TestStrategy strategy = const TestStrategy()]) { |
| 669 return | 577 return strategy.testSets(impact1, impact2, 'constSymbolNames', |
| 670 strategy.testSets( | |
| 671 impact1, impact2, 'constSymbolNames', | |
| 672 impact1.constSymbolNames, impact2.constSymbolNames) && | 578 impact1.constSymbolNames, impact2.constSymbolNames) && |
| 673 strategy.testSets( | 579 strategy.testSets( |
| 674 impact1, impact2, 'constantLiterals', | 580 impact1, |
| 675 impact1.constantLiterals, impact2.constantLiterals, | 581 impact2, |
| 582 'constantLiterals', |
| 583 impact1.constantLiterals, |
| 584 impact2.constantLiterals, |
| 676 areConstantsEquivalent) && | 585 areConstantsEquivalent) && |
| 586 strategy.testSets(impact1, impact2, 'dynamicUses', impact1.dynamicUses, |
| 587 impact2.dynamicUses, areDynamicUsesEquivalent) && |
| 677 strategy.testSets( | 588 strategy.testSets( |
| 678 impact1, impact2, 'dynamicUses', | 589 impact1, impact2, 'features', impact1.features, impact2.features) && |
| 679 impact1.dynamicUses, impact2.dynamicUses, | 590 strategy.testSets(impact1, impact2, 'listLiterals', impact1.listLiterals, |
| 680 areDynamicUsesEquivalent) && | 591 impact2.listLiterals, areListLiteralUsesEquivalent) && |
| 681 strategy.testSets( | 592 strategy.testSets(impact1, impact2, 'mapLiterals', impact1.mapLiterals, |
| 682 impact1, impact2, 'features', | 593 impact2.mapLiterals, areMapLiteralUsesEquivalent) && |
| 683 impact1.features, impact2.features) && | 594 strategy.testSets(impact1, impact2, 'staticUses', impact1.staticUses, |
| 684 strategy.testSets( | 595 impact2.staticUses, areStaticUsesEquivalent) && |
| 685 impact1, impact2, 'listLiterals', | 596 strategy.testSets(impact1, impact2, 'typeUses', impact1.typeUses, |
| 686 impact1.listLiterals, impact2.listLiterals, | 597 impact2.typeUses, areTypeUsesEquivalent); |
| 687 areListLiteralUsesEquivalent) && | |
| 688 strategy.testSets( | |
| 689 impact1, impact2, 'mapLiterals', | |
| 690 impact1.mapLiterals, impact2.mapLiterals, | |
| 691 areMapLiteralUsesEquivalent) && | |
| 692 strategy.testSets( | |
| 693 impact1, impact2, 'staticUses', | |
| 694 impact1.staticUses, impact2.staticUses, | |
| 695 areStaticUsesEquivalent) && | |
| 696 strategy.testSets( | |
| 697 impact1, impact2, 'typeUses', | |
| 698 impact1.typeUses, impact2.typeUses, | |
| 699 areTypeUsesEquivalent); | |
| 700 } | 598 } |
| OLD | NEW |