OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library dart2js.serialization_model_test; |
| 6 |
| 7 import 'dart:async'; |
| 8 import 'dart:io'; |
| 9 import 'package:async_helper/async_helper.dart'; |
| 10 import 'package:expect/expect.dart'; |
| 11 import 'package:compiler/src/commandline_options.dart'; |
| 12 import 'package:compiler/src/common/backend_api.dart'; |
| 13 import 'package:compiler/src/common/names.dart'; |
| 14 import 'package:compiler/src/common/resolution.dart'; |
| 15 import 'package:compiler/src/compiler.dart'; |
| 16 import 'package:compiler/src/dart_types.dart'; |
| 17 import 'package:compiler/src/elements/elements.dart'; |
| 18 import 'package:compiler/src/filenames.dart'; |
| 19 import 'package:compiler/src/serialization/element_serialization.dart'; |
| 20 import 'package:compiler/src/serialization/impact_serialization.dart'; |
| 21 import 'package:compiler/src/serialization/json_serializer.dart'; |
| 22 import 'package:compiler/src/serialization/serialization.dart'; |
| 23 import 'package:compiler/src/serialization/equivalence.dart'; |
| 24 import 'package:compiler/src/serialization/task.dart'; |
| 25 import 'package:compiler/src/universe/world_impact.dart'; |
| 26 import 'package:compiler/src/universe/class_set.dart'; |
| 27 import 'package:compiler/src/universe/use.dart'; |
| 28 import 'memory_compiler.dart'; |
| 29 import 'serialization_helper.dart'; |
| 30 import 'serialization_analysis_test.dart'; |
| 31 import 'serialization_impact_test.dart'; |
| 32 import 'serialization_test.dart'; |
| 33 |
| 34 main(List<String> arguments) { |
| 35 String filename; |
| 36 for (String arg in arguments) { |
| 37 if (!arg.startsWith('-')) { |
| 38 filename = arg; |
| 39 } |
| 40 } |
| 41 bool verbose = arguments.contains('-v'); |
| 42 |
| 43 asyncTest(() async { |
| 44 print('------------------------------------------------------------------'); |
| 45 print('serialize dart:core'); |
| 46 print('------------------------------------------------------------------'); |
| 47 String serializedData; |
| 48 File file = new File('out.data'); |
| 49 if (arguments.contains('-l')) { |
| 50 if (file.existsSync()) { |
| 51 print('Loading data from $file'); |
| 52 serializedData = file.readAsStringSync(); |
| 53 } |
| 54 } |
| 55 if (serializedData == null) { |
| 56 serializedData = await serializeDartCore(); |
| 57 if (arguments.contains('-s')) { |
| 58 print('Saving data to $file'); |
| 59 file.writeAsStringSync(serializedData); |
| 60 } |
| 61 } |
| 62 if (filename != null) { |
| 63 Uri entryPoint = Uri.base.resolve(nativeToUriPath(filename)); |
| 64 await check(serializedData, entryPoint); |
| 65 } else { |
| 66 Uri entryPoint = Uri.parse('memory:main.dart'); |
| 67 for (Test test in TESTS) { |
| 68 if (test.sourceFiles['main.dart'] |
| 69 .contains('main(List<String> arguments)')) { |
| 70 // TODO(johnniwinther): Check this test. |
| 71 continue; |
| 72 } |
| 73 print('=============================================================='); |
| 74 print(test.sourceFiles); |
| 75 await check( |
| 76 serializedData, |
| 77 entryPoint, |
| 78 sourceFiles: test.sourceFiles, |
| 79 verbose: verbose); |
| 80 } |
| 81 } |
| 82 }); |
| 83 } |
| 84 |
| 85 Future check( |
| 86 String serializedData, |
| 87 Uri entryPoint, |
| 88 {Map<String, String> sourceFiles: const <String, String>{}, |
| 89 bool verbose: false}) async { |
| 90 |
| 91 print('------------------------------------------------------------------'); |
| 92 print('compile normal'); |
| 93 print('------------------------------------------------------------------'); |
| 94 Compiler compilerNormal = compilerFor( |
| 95 memorySourceFiles: sourceFiles, |
| 96 options: [Flags.analyzeOnly]); |
| 97 compilerNormal.resolution.retainCachesForTesting = true; |
| 98 await compilerNormal.run(entryPoint); |
| 99 compilerNormal.world.populate(); |
| 100 |
| 101 print('------------------------------------------------------------------'); |
| 102 print('compile deserialized'); |
| 103 print('------------------------------------------------------------------'); |
| 104 Compiler compilerDeserialized = compilerFor( |
| 105 memorySourceFiles: sourceFiles, |
| 106 options: [Flags.analyzeOnly]); |
| 107 compilerDeserialized.resolution.retainCachesForTesting = true; |
| 108 deserialize(compilerDeserialized, serializedData); |
| 109 await compilerDeserialized.run(entryPoint); |
| 110 compilerDeserialized.world.populate(); |
| 111 |
| 112 checkResolutionImpacts( |
| 113 compilerNormal, compilerDeserialized, |
| 114 verbose: verbose); |
| 115 |
| 116 checkSets( |
| 117 compilerNormal.resolverWorld.directlyInstantiatedClasses, |
| 118 compilerDeserialized.resolverWorld.directlyInstantiatedClasses, |
| 119 "Directly instantiated classes mismatch", |
| 120 areElementsEquivalent, |
| 121 verbose: verbose); |
| 122 |
| 123 checkSets( |
| 124 compilerNormal.resolverWorld.instantiatedTypes, |
| 125 compilerDeserialized.resolverWorld.instantiatedTypes, |
| 126 "Instantiated types mismatch", |
| 127 areTypesEquivalent, |
| 128 // TODO(johnniwinther): Ensure that all instantiated types are tracked. |
| 129 failOnUnfound: false, |
| 130 verbose: verbose); |
| 131 |
| 132 checkSets( |
| 133 compilerNormal.resolverWorld.isChecks, |
| 134 compilerDeserialized.resolverWorld.isChecks, |
| 135 "Is-check mismatch", |
| 136 areTypesEquivalent, |
| 137 verbose: verbose); |
| 138 |
| 139 checkSets( |
| 140 compilerNormal.enqueuer.resolution.processedElements, |
| 141 compilerDeserialized.enqueuer.resolution.processedElements, |
| 142 "Processed element mismatch", |
| 143 areElementsEquivalent, |
| 144 verbose: verbose); |
| 145 |
| 146 checkClassHierarchyNodes( |
| 147 compilerNormal.world.getClassHierarchyNode( |
| 148 compilerNormal.coreClasses.objectClass), |
| 149 compilerDeserialized.world.getClassHierarchyNode( |
| 150 compilerDeserialized.coreClasses.objectClass), |
| 151 verbose: verbose); |
| 152 } |
| 153 |
| 154 void checkClassHierarchyNodes( |
| 155 ClassHierarchyNode a, ClassHierarchyNode b, |
| 156 {bool verbose: false}) { |
| 157 if (verbose) { |
| 158 print('Checking $a vs $b'); |
| 159 } |
| 160 Expect.isTrue( |
| 161 areElementsEquivalent(a.cls, b.cls), |
| 162 "Element identity mismatch for ${a.cls} vs ${b.cls}."); |
| 163 Expect.equals( |
| 164 a.isDirectlyInstantiated, |
| 165 b.isDirectlyInstantiated, |
| 166 "Value mismatch for 'isDirectlyInstantiated' for ${a.cls} vs ${b.cls}."); |
| 167 Expect.equals( |
| 168 a.isIndirectlyInstantiated, |
| 169 b.isIndirectlyInstantiated, |
| 170 "Value mismatch for 'isIndirectlyInstantiated' " |
| 171 "for ${a.cls} vs ${b.cls}."); |
| 172 // TODO(johnniwinther): Enforce a canonical and stable order on direct |
| 173 // subclasses. |
| 174 for (ClassHierarchyNode child in a.directSubclasses) { |
| 175 bool found = false; |
| 176 for (ClassHierarchyNode other in b.directSubclasses) { |
| 177 if (areElementsEquivalent(child.cls, other.cls)) { |
| 178 checkClassHierarchyNodes(child, other, |
| 179 verbose: verbose); |
| 180 found = true; |
| 181 break; |
| 182 } |
| 183 } |
| 184 if (!found) { |
| 185 Expect.isFalse( |
| 186 child.isInstantiated, 'Missing subclass ${child.cls} of ${a.cls}'); |
| 187 } |
| 188 } |
| 189 } |
| 190 |
| 191 void checkSets( |
| 192 Iterable set1, |
| 193 Iterable set2, |
| 194 String messagePrefix, |
| 195 bool areEquivalent(a, b), |
| 196 {bool failOnUnfound: true, |
| 197 bool verbose: false}) { |
| 198 List common = []; |
| 199 List unfound = []; |
| 200 Set remaining = computeSetDifference( |
| 201 set1, set2, common, unfound, areEquivalent); |
| 202 StringBuffer sb = new StringBuffer(); |
| 203 sb.write("$messagePrefix:"); |
| 204 if (verbose) { |
| 205 sb.write("\n Common:\n ${common.join('\n ')}"); |
| 206 } |
| 207 if (unfound.isNotEmpty || verbose) { |
| 208 sb.write("\n Unfound:\n ${unfound.join('\n ')}"); |
| 209 } |
| 210 if (remaining.isNotEmpty || verbose) { |
| 211 sb.write("\n Extra: \n ${remaining.join('\n ')}"); |
| 212 } |
| 213 String message = sb.toString(); |
| 214 if (unfound.isNotEmpty || remaining.isNotEmpty) { |
| 215 |
| 216 if (failOnUnfound || remaining.isNotEmpty) { |
| 217 Expect.fail(message); |
| 218 } else { |
| 219 print(message); |
| 220 } |
| 221 } else if (verbose) { |
| 222 print(message); |
| 223 } |
| 224 } |
OLD | NEW |