| 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_test_data.dart'; | |
| 31 import 'serialization_test_helper.dart'; | |
| 32 | |
| 33 main(List<String> args) { | |
| 34 asyncTest(() async { | |
| 35 Arguments arguments = new Arguments.from(args); | |
| 36 String serializedData = await serializeDartCore(arguments: arguments); | |
| 37 if (arguments.filename != null) { | |
| 38 Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename)); | |
| 39 await check(serializedData, entryPoint); | |
| 40 } else { | |
| 41 Uri entryPoint = Uri.parse('memory:main.dart'); | |
| 42 for (Test test in TESTS) { | |
| 43 print('=============================================================='); | |
| 44 print(test.sourceFiles); | |
| 45 await check( | |
| 46 serializedData, | |
| 47 entryPoint, | |
| 48 sourceFiles: test.sourceFiles, | |
| 49 verbose: arguments.verbose); | |
| 50 } | |
| 51 } | |
| 52 }); | |
| 53 } | |
| 54 | |
| 55 Future check( | |
| 56 String serializedData, | |
| 57 Uri entryPoint, | |
| 58 {Map<String, String> sourceFiles: const <String, String>{}, | |
| 59 bool verbose: false}) async { | |
| 60 | |
| 61 print('------------------------------------------------------------------'); | |
| 62 print('compile normal'); | |
| 63 print('------------------------------------------------------------------'); | |
| 64 Compiler compilerNormal = compilerFor( | |
| 65 memorySourceFiles: sourceFiles, | |
| 66 options: [Flags.analyzeOnly]); | |
| 67 compilerNormal.resolution.retainCachesForTesting = true; | |
| 68 await compilerNormal.run(entryPoint); | |
| 69 compilerNormal.world.populate(); | |
| 70 | |
| 71 print('------------------------------------------------------------------'); | |
| 72 print('compile deserialized'); | |
| 73 print('------------------------------------------------------------------'); | |
| 74 Compiler compilerDeserialized = compilerFor( | |
| 75 memorySourceFiles: sourceFiles, | |
| 76 options: [Flags.analyzeOnly]); | |
| 77 compilerDeserialized.resolution.retainCachesForTesting = true; | |
| 78 deserialize(compilerDeserialized, serializedData); | |
| 79 await compilerDeserialized.run(entryPoint); | |
| 80 compilerDeserialized.world.populate(); | |
| 81 | |
| 82 checkAllImpacts( | |
| 83 compilerNormal, compilerDeserialized, | |
| 84 verbose: verbose); | |
| 85 | |
| 86 checkSets( | |
| 87 compilerNormal.resolverWorld.directlyInstantiatedClasses, | |
| 88 compilerDeserialized.resolverWorld.directlyInstantiatedClasses, | |
| 89 "Directly instantiated classes mismatch", | |
| 90 areElementsEquivalent, | |
| 91 verbose: verbose); | |
| 92 | |
| 93 checkSets( | |
| 94 compilerNormal.resolverWorld.instantiatedTypes, | |
| 95 compilerDeserialized.resolverWorld.instantiatedTypes, | |
| 96 "Instantiated types mismatch", | |
| 97 areTypesEquivalent, | |
| 98 // TODO(johnniwinther): Ensure that all instantiated types are tracked. | |
| 99 failOnUnfound: false, | |
| 100 verbose: verbose); | |
| 101 | |
| 102 checkSets( | |
| 103 compilerNormal.resolverWorld.isChecks, | |
| 104 compilerDeserialized.resolverWorld.isChecks, | |
| 105 "Is-check mismatch", | |
| 106 areTypesEquivalent, | |
| 107 verbose: verbose); | |
| 108 | |
| 109 checkSets( | |
| 110 compilerNormal.enqueuer.resolution.processedElements, | |
| 111 compilerDeserialized.enqueuer.resolution.processedElements, | |
| 112 "Processed element mismatch", | |
| 113 areElementsEquivalent, | |
| 114 verbose: verbose); | |
| 115 | |
| 116 checkClassHierarchyNodes( | |
| 117 compilerNormal.world.getClassHierarchyNode( | |
| 118 compilerNormal.coreClasses.objectClass), | |
| 119 compilerDeserialized.world.getClassHierarchyNode( | |
| 120 compilerDeserialized.coreClasses.objectClass), | |
| 121 verbose: verbose); | |
| 122 } | |
| 123 | |
| 124 void checkClassHierarchyNodes( | |
| 125 ClassHierarchyNode a, ClassHierarchyNode b, | |
| 126 {bool verbose: false}) { | |
| 127 if (verbose) { | |
| 128 print('Checking $a vs $b'); | |
| 129 } | |
| 130 Expect.isTrue( | |
| 131 areElementsEquivalent(a.cls, b.cls), | |
| 132 "Element identity mismatch for ${a.cls} vs ${b.cls}."); | |
| 133 Expect.equals( | |
| 134 a.isDirectlyInstantiated, | |
| 135 b.isDirectlyInstantiated, | |
| 136 "Value mismatch for 'isDirectlyInstantiated' for ${a.cls} vs ${b.cls}."); | |
| 137 Expect.equals( | |
| 138 a.isIndirectlyInstantiated, | |
| 139 b.isIndirectlyInstantiated, | |
| 140 "Value mismatch for 'isIndirectlyInstantiated' " | |
| 141 "for ${a.cls} vs ${b.cls}."); | |
| 142 // TODO(johnniwinther): Enforce a canonical and stable order on direct | |
| 143 // subclasses. | |
| 144 for (ClassHierarchyNode child in a.directSubclasses) { | |
| 145 bool found = false; | |
| 146 for (ClassHierarchyNode other in b.directSubclasses) { | |
| 147 if (areElementsEquivalent(child.cls, other.cls)) { | |
| 148 checkClassHierarchyNodes(child, other, | |
| 149 verbose: verbose); | |
| 150 found = true; | |
| 151 break; | |
| 152 } | |
| 153 } | |
| 154 if (!found) { | |
| 155 Expect.isFalse( | |
| 156 child.isInstantiated, 'Missing subclass ${child.cls} of ${a.cls}'); | |
| 157 } | |
| 158 } | |
| 159 } | |
| 160 | |
| 161 void checkSets( | |
| 162 Iterable set1, | |
| 163 Iterable set2, | |
| 164 String messagePrefix, | |
| 165 bool areEquivalent(a, b), | |
| 166 {bool failOnUnfound: true, | |
| 167 bool verbose: false}) { | |
| 168 List common = []; | |
| 169 List unfound = []; | |
| 170 Set remaining = computeSetDifference( | |
| 171 set1, set2, common, unfound, areEquivalent); | |
| 172 StringBuffer sb = new StringBuffer(); | |
| 173 sb.write("$messagePrefix:"); | |
| 174 if (verbose) { | |
| 175 sb.write("\n Common:\n ${common.join('\n ')}"); | |
| 176 } | |
| 177 if (unfound.isNotEmpty || verbose) { | |
| 178 sb.write("\n Unfound:\n ${unfound.join('\n ')}"); | |
| 179 } | |
| 180 if (remaining.isNotEmpty || verbose) { | |
| 181 sb.write("\n Extra: \n ${remaining.join('\n ')}"); | |
| 182 } | |
| 183 String message = sb.toString(); | |
| 184 if (unfound.isNotEmpty || remaining.isNotEmpty) { | |
| 185 | |
| 186 if (failOnUnfound || remaining.isNotEmpty) { | |
| 187 Expect.fail(message); | |
| 188 } else { | |
| 189 print(message); | |
| 190 } | |
| 191 } else if (verbose) { | |
| 192 print(message); | |
| 193 } | |
| 194 } | |
| OLD | NEW |