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 | |
33 main(List<String> arguments) { | |
34 String filename; | |
35 for (String arg in arguments) { | |
36 if (!arg.startsWith('-')) { | |
37 filename = arg; | |
38 } | |
39 } | |
40 bool verbose = arguments.contains('-v'); | |
41 | |
42 asyncTest(() async { | |
43 print('------------------------------------------------------------------'); | |
44 print('serialize dart:core'); | |
45 print('------------------------------------------------------------------'); | |
46 String serializedData; | |
47 File file = new File('out.data'); | |
48 if (arguments.contains('-l')) { | |
49 if (file.existsSync()) { | |
50 print('Loading data from $file'); | |
51 serializedData = file.readAsStringSync(); | |
52 } | |
53 } | |
54 if (serializedData == null) { | |
55 serializedData = await serializeDartCore(); | |
56 if (arguments.contains('-s')) { | |
57 print('Saving data to $file'); | |
58 file.writeAsStringSync(serializedData); | |
59 } | |
60 } | |
61 if (filename != null) { | |
62 Uri entryPoint = Uri.base.resolve(nativeToUriPath(filename)); | |
63 await check(serializedData, entryPoint); | |
64 } else { | |
65 Uri entryPoint = Uri.parse('memory:main.dart'); | |
66 for (Test test in TESTS) { | |
67 if (test.sourceFiles['main.dart'] | |
68 .contains('main(List<String> arguments)')) { | |
69 // TODO(johnniwinther): Check this test. | |
70 continue; | |
71 } | |
72 print('=============================================================='); | |
73 print(test.sourceFiles); | |
74 await check( | |
75 serializedData, | |
76 entryPoint, | |
77 sourceFiles: test.sourceFiles, | |
78 verbose: verbose); | |
79 } | |
80 } | |
81 }); | |
82 } | |
83 | |
84 Future check( | |
85 String serializedData, | |
86 Uri entryPoint, | |
87 {Map<String, String> sourceFiles: const <String, String>{}, | |
88 bool verbose: false}) async { | |
89 | |
90 print('------------------------------------------------------------------'); | |
91 print('compile normal'); | |
92 print('------------------------------------------------------------------'); | |
93 Compiler compilerNormal = compilerFor( | |
94 memorySourceFiles: sourceFiles, | |
95 options: [Flags.analyzeOnly]); | |
96 compilerNormal.resolution.retainCaches = true; | |
97 await compilerNormal.run(entryPoint); | |
98 compilerNormal.world.populate(); | |
99 | |
100 print('------------------------------------------------------------------'); | |
101 print('compile deserialized'); | |
102 print('------------------------------------------------------------------'); | |
103 Compiler compilerDeserialized = compilerFor( | |
104 memorySourceFiles: sourceFiles, | |
105 options: [Flags.analyzeOnly]); | |
106 compilerDeserialized.resolution.retainCaches = true; | |
107 deserialize(compilerDeserialized, serializedData); | |
108 await compilerDeserialized.run(entryPoint); | |
109 compilerDeserialized.world.populate(); | |
110 | |
111 checkResolutionImpacts( | |
112 compilerNormal, compilerDeserialized, | |
113 verbose: verbose); | |
114 | |
115 checkSets( | |
116 compilerNormal.resolverWorld.directlyInstantiatedClasses, | |
117 compilerDeserialized.resolverWorld.directlyInstantiatedClasses, | |
118 "Directly instantiated classes mismatch", | |
119 areElementsEquivalent, | |
120 verbose: verbose); | |
121 | |
122 checkSets( | |
123 compilerNormal.resolverWorld.instantiatedTypes, | |
124 compilerDeserialized.resolverWorld.instantiatedTypes, | |
125 "Instantiated types mismatch", | |
126 areTypesEquivalent, | |
127 // TODO(johnniwinther): Ensure that all instantiated types are tracked. | |
128 failOnUnfound: false, | |
129 verbose: verbose); | |
130 | |
131 checkSets( | |
132 compilerNormal.resolverWorld.isChecks, | |
133 compilerDeserialized.resolverWorld.isChecks, | |
134 "Is-check mismatch", | |
135 areTypesEquivalent, | |
136 verbose: verbose); | |
137 | |
138 checkSets( | |
139 compilerNormal.enqueuer.resolution.processedElements, | |
140 compilerDeserialized.enqueuer.resolution.processedElements, | |
141 "Processed element mismatch", | |
142 areElementsEquivalent, | |
143 verbose: verbose); | |
144 | |
145 checkClassHierarchyNodes( | |
146 compilerNormal.world.getClassHierarchyNode( | |
147 compilerNormal.coreClasses.objectClass), | |
148 compilerDeserialized.world.getClassHierarchyNode( | |
149 compilerDeserialized.coreClasses.objectClass), | |
150 verbose: verbose); | |
151 } | |
152 | |
153 void checkClassHierarchyNodes( | |
154 ClassHierarchyNode a, ClassHierarchyNode b, | |
155 {bool verbose: false}) { | |
156 if (verbose) { | |
157 print('Checking $a vs $b'); | |
158 } | |
159 Expect.isTrue( | |
160 areElementsEquivalent(a.cls, b.cls), | |
161 "Element identity mismatch for ${a.cls} vs ${b.cls}."); | |
162 Expect.equals( | |
163 a.isDirectlyInstantiated, | |
164 b.isDirectlyInstantiated, | |
165 "Value mismatch for 'isDirectlyInstantiated' for ${a.cls} vs ${b.cls}."); | |
166 Expect.equals( | |
167 a.isIndirectlyInstantiated, | |
168 b.isIndirectlyInstantiated, | |
169 "Value mismatch for 'isIndirectlyInstantiated' " | |
170 "for ${a.cls} vs ${b.cls}."); | |
171 for (ClassHierarchyNode child in a.directSubclasses) { | |
172 bool found = false; | |
173 for (ClassHierarchyNode other in b.directSubclasses) { | |
Siggi Cherem (dart-lang)
2016/04/05 15:19:30
what do we need to do to guarantee that directSubc
Johnni Winther
2016/04/20 10:12:36
Adding a TODO. [ClassHierarchyNode.directSubclasse
| |
174 if (areElementsEquivalent(child.cls, other.cls)) { | |
175 checkClassHierarchyNodes(child, other, | |
176 verbose: verbose); | |
177 found = true; | |
178 break; | |
179 } | |
180 } | |
181 if (!found) { | |
182 Expect.isFalse( | |
183 child.isInstantiated, 'Missing subclass ${child.cls} of ${a.cls}'); | |
184 } | |
185 } | |
186 } | |
187 | |
188 | |
189 void checkSets( | |
190 Iterable set1, | |
191 Iterable set2, | |
192 String messagePrefix, | |
193 bool areEquivalent(a, b), | |
194 {bool failOnUnfound: true, | |
195 bool verbose: false}) { | |
196 List common = []; | |
197 List unfound = []; | |
198 Set remaining = set2.toSet(); | |
199 for (var element1 in set1) { | |
200 bool found = false; | |
201 for (var element2 in remaining) { | |
Siggi Cherem (dart-lang)
2016/04/05 15:19:30
(a) seems that there is a lot in common between th
Johnni Winther
2016/04/20 10:12:36
(a) Done.
(b) Added as a TODO.
| |
202 if (areEquivalent(element1, element2)) { | |
203 found = true; | |
204 remaining.remove(element2); | |
205 break; | |
206 } | |
207 } | |
208 if (found) { | |
209 common.add(element1); | |
210 } else { | |
211 unfound.add(element1); | |
212 } | |
213 } | |
214 StringBuffer sb = new StringBuffer(); | |
215 sb.write("$messagePrefix:"); | |
216 if (verbose) { | |
217 sb.write("\n Common:\n ${common.join('\n ')}"); | |
218 } | |
219 if (unfound.isNotEmpty || verbose) { | |
220 sb.write("\n Unfound:\n ${unfound.join('\n ')}"); | |
221 } | |
222 if (remaining.isNotEmpty || verbose) { | |
223 sb.write("\n Extra: \n ${remaining.join('\n ')}"); | |
224 } | |
225 String message = sb.toString(); | |
226 if (unfound.isNotEmpty || remaining.isNotEmpty) { | |
227 | |
228 if (failOnUnfound || remaining.isNotEmpty) { | |
229 Expect.fail(message); | |
230 } else { | |
231 print(message); | |
232 } | |
233 } else if (verbose) { | |
234 print(message); | |
235 } | |
236 } | |
OLD | NEW |