OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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; | 5 library dart2js.serialization_test; |
6 | 6 |
7 import 'dart:io'; | 7 import 'dart:io'; |
8 import 'memory_compiler.dart'; | 8 import 'memory_compiler.dart'; |
9 import 'package:async_helper/async_helper.dart'; | 9 import 'package:async_helper/async_helper.dart'; |
10 import 'package:compiler/src/commandline_options.dart'; | 10 import 'package:compiler/src/commandline_options.dart'; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 for (int i = list2.length; i < list1.length; i++) { | 164 for (int i = list2.length; i < list1.length; i++) { |
165 throw | 165 throw |
166 'Missing equivalent for element ' | 166 'Missing equivalent for element ' |
167 '#$i ${list1.elementAt(i)} in `${property}` on $object1.\n' | 167 '#$i ${list1.elementAt(i)} in `${property}` on $object1.\n' |
168 '`${property}` on $object1:\n ${list1.join('\n ')}\n' | 168 '`${property}` on $object1:\n ${list1.join('\n ')}\n' |
169 '`${property}` on $object2:\n ${list2.join('\n ')}'; | 169 '`${property}` on $object2:\n ${list2.join('\n ')}'; |
170 } | 170 } |
171 return true; | 171 return true; |
172 } | 172 } |
173 | 173 |
174 /// Check equivalence of the two iterables, [set1] and [set1], as sets using | 174 /// Computes the set difference between [set1] and [set2] using |
175 /// [elementEquivalence] to compute the pair-wise equivalence. | 175 /// [elementEquivalence] to determine element equivalence. |
176 /// | 176 /// |
177 /// Uses [object1], [object2] and [property] to provide context for failures. | 177 /// Elements both in [set1] and [set2] are added to [common], elements in [set1] |
178 bool checkSetEquivalence( | 178 /// but not in [set2] are added to [unfound], and the set of elements in [set2] |
179 var object1, | 179 /// but not in [set1] are returned. |
180 var object2, | 180 Set computeSetDifference( |
181 String property, | |
182 Iterable set1, | 181 Iterable set1, |
183 Iterable set2, | 182 Iterable set2, |
184 bool sameElement(a, b)) { | 183 List common, |
185 List common = []; | 184 List unfound, |
186 List unfound = []; | 185 [bool sameElement(a, b) = equality]) { |
| 186 // TODO(johnniwinther): Avoid the quadratic cost here. Some ideas: |
| 187 // - convert each set to a list and sort it first, then compare by walking |
| 188 // both lists in parallel |
| 189 // - map each element to a canonical object, create a map containing those |
| 190 // mappings, use the mapped sets to compare (then operations like |
| 191 // set.difference would work) |
187 Set remaining = set2.toSet(); | 192 Set remaining = set2.toSet(); |
188 for (var element1 in set1) { | 193 for (var element1 in set1) { |
189 bool found = false; | 194 bool found = false; |
190 for (var element2 in remaining) { | 195 for (var element2 in remaining) { |
191 if (sameElement(element1, element2)) { | 196 if (sameElement(element1, element2)) { |
192 found = true; | 197 found = true; |
193 remaining.remove(element2); | 198 remaining.remove(element2); |
194 break; | 199 break; |
195 } | 200 } |
196 } | 201 } |
197 if (found) { | 202 if (found) { |
198 common.add(element1); | 203 common.add(element1); |
199 } else { | 204 } else { |
200 unfound.add(element1); | 205 unfound.add(element1); |
201 } | 206 } |
202 } | 207 } |
| 208 return remaining; |
| 209 } |
| 210 |
| 211 /// Check equivalence of the two iterables, [set1] and [set1], as sets using |
| 212 /// [elementEquivalence] to compute the pair-wise equivalence. |
| 213 /// |
| 214 /// Uses [object1], [object2] and [property] to provide context for failures. |
| 215 bool checkSetEquivalence( |
| 216 var object1, |
| 217 var object2, |
| 218 String property, |
| 219 Iterable set1, |
| 220 Iterable set2, |
| 221 bool sameElement(a, b)) { |
| 222 List common = []; |
| 223 List unfound = []; |
| 224 Set remaining = |
| 225 computeSetDifference(set1, set2, common, unfound, sameElement); |
203 if (unfound.isNotEmpty || remaining.isNotEmpty) { | 226 if (unfound.isNotEmpty || remaining.isNotEmpty) { |
204 String message = | 227 String message = |
205 "Set mismatch for `$property` on $object1 vs $object2: \n" | 228 "Set mismatch for `$property` on $object1 vs $object2: \n" |
206 "Common:\n ${common.join('\n ')}\n" | 229 "Common:\n ${common.join('\n ')}\n" |
207 "Unfound:\n ${unfound.join('\n ')}\n" | 230 "Unfound:\n ${unfound.join('\n ')}\n" |
208 "Extra: \n ${remaining.join('\n ')}"; | 231 "Extra: \n ${remaining.join('\n ')}"; |
209 throw message; | 232 throw message; |
210 } | 233 } |
211 return true; | 234 return true; |
212 } | 235 } |
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
865 void visitPrefixElement(PrefixElement element1, PrefixElement element2) { | 888 void visitPrefixElement(PrefixElement element1, PrefixElement element2) { |
866 check( | 889 check( |
867 element1, element2, 'isDeferred', | 890 element1, element2, 'isDeferred', |
868 element1.isDeferred, element2.isDeferred); | 891 element1.isDeferred, element2.isDeferred); |
869 checkElementIdentities( | 892 checkElementIdentities( |
870 element1, element2, 'importedLibrary', | 893 element1, element2, 'importedLibrary', |
871 element1.deferredImport, element2.deferredImport); | 894 element1.deferredImport, element2.deferredImport); |
872 // TODO(johnniwinther): Check members. | 895 // TODO(johnniwinther): Check members. |
873 } | 896 } |
874 } | 897 } |
OLD | NEW |