Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: tests/compiler/dart2js/serialization/model_test_helper.dart

Issue 2879593004: Reorganize equivalence test helpers (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_model_test; 5 library dart2js.serialization_model_test;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:io';
9 import 'package:async_helper/async_helper.dart'; 8 import 'package:async_helper/async_helper.dart';
10 import 'package:expect/expect.dart'; 9 import 'package:expect/expect.dart';
11 import 'package:compiler/src/closure.dart'; 10 import 'package:compiler/src/closure.dart';
12 import 'package:compiler/src/commandline_options.dart'; 11 import 'package:compiler/src/commandline_options.dart';
13 import 'package:compiler/src/common.dart';
14 import 'package:compiler/src/constants/values.dart'; 12 import 'package:compiler/src/constants/values.dart';
15 import 'package:compiler/src/compiler.dart'; 13 import 'package:compiler/src/compiler.dart';
16 import 'package:compiler/src/elements/resolution_types.dart';
17 import 'package:compiler/src/elements/types.dart';
18 import 'package:compiler/src/deferred_load.dart'; 14 import 'package:compiler/src/deferred_load.dart';
19 import 'package:compiler/src/elements/elements.dart'; 15 import 'package:compiler/src/elements/elements.dart';
20 import 'package:compiler/src/elements/entities.dart'; 16 import 'package:compiler/src/elements/entities.dart';
21 import 'package:compiler/src/enqueue.dart';
22 import 'package:compiler/src/filenames.dart';
23 import 'package:compiler/src/js_backend/js_backend.dart'; 17 import 'package:compiler/src/js_backend/js_backend.dart';
24 import 'package:compiler/src/js_backend/backend_usage.dart';
25 import 'package:compiler/src/js_backend/native_data.dart';
26 import 'package:compiler/src/js_backend/interceptor_data.dart';
27 import 'package:compiler/src/serialization/equivalence.dart'; 18 import 'package:compiler/src/serialization/equivalence.dart';
28 import 'package:compiler/src/tree/nodes.dart'; 19 import 'package:compiler/src/tree/nodes.dart';
29 import 'package:compiler/src/universe/class_set.dart';
30 import 'package:compiler/src/universe/world_builder.dart';
31 import 'package:compiler/src/util/enumset.dart';
32 import 'package:compiler/src/world.dart' show ClosedWorld;
33 import '../memory_compiler.dart'; 20 import '../memory_compiler.dart';
21 import '../equivalence/check_helpers.dart';
22 import '../equivalence/check_functions.dart';
34 import 'helper.dart'; 23 import 'helper.dart';
35 import 'test_data.dart'; 24 import 'test_data.dart';
36 import 'test_helper.dart';
37 25
38 /// Number of tests that are not part of the automatic test grouping. 26 /// Number of tests that are not part of the automatic test grouping.
39 int SKIP_COUNT = 2; 27 int SKIP_COUNT = 2;
40 28
41 /// Number of groups that the [TESTS] are split into. 29 /// Number of groups that the [TESTS] are split into.
42 int SPLIT_COUNT = 5; 30 int SPLIT_COUNT = 5;
43 31
44 main(List<String> args) { 32 main(List<String> args) {
45 asyncTest(() async { 33 asyncTest(() async {
46 Arguments arguments = new Arguments.from(args); 34 Arguments arguments = new Arguments.from(args);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 checkClosedWorlds( 97 checkClosedWorlds(
110 compilerNormal.resolutionWorldBuilder.closedWorldForTesting, 98 compilerNormal.resolutionWorldBuilder.closedWorldForTesting,
111 compilerDeserialized.resolutionWorldBuilder.closedWorldForTesting, 99 compilerDeserialized.resolutionWorldBuilder.closedWorldForTesting,
112 // Serialized native data include non-live members. 100 // Serialized native data include non-live members.
113 allowExtra: true, 101 allowExtra: true,
114 verbose: verbose); 102 verbose: verbose);
115 checkBackendInfo(compilerNormal, compilerDeserialized, verbose: verbose); 103 checkBackendInfo(compilerNormal, compilerDeserialized, verbose: verbose);
116 }); 104 });
117 } 105 }
118 106
119 void checkResolutionEnqueuers(
120 BackendUsage backendUsage1,
121 BackendUsage backendUsage2,
122 ResolutionEnqueuer enqueuer1,
123 ResolutionEnqueuer enqueuer2,
124 {bool elementEquivalence(Entity a, Entity b): areElementsEquivalent,
125 bool typeEquivalence(DartType a, DartType b): areTypesEquivalent,
126 bool elementFilter(Element element),
127 bool verbose: false}) {
128 ResolutionWorldBuilderBase worldBuilder1 = enqueuer1.worldBuilder;
129 ResolutionWorldBuilderBase worldBuilder2 = enqueuer2.worldBuilder;
130
131 checkSets(
132 enqueuer1.worldBuilder.instantiatedTypes,
133 enqueuer2.worldBuilder.instantiatedTypes,
134 "Instantiated types mismatch",
135 typeEquivalence,
136 verbose: verbose);
137
138 checkSets(
139 enqueuer1.worldBuilder.directlyInstantiatedClasses,
140 enqueuer2.worldBuilder.directlyInstantiatedClasses,
141 "Directly instantiated classes mismatch",
142 elementEquivalence,
143 verbose: verbose);
144
145 checkMaps(
146 worldBuilder1.getInstantiationMap(),
147 worldBuilder2.getInstantiationMap(),
148 "Instantiated classes mismatch",
149 elementEquivalence,
150 (a, b) => areInstantiationInfosEquivalent(
151 a, b, elementEquivalence, typeEquivalence),
152 verbose: verbose);
153
154 checkSets(enqueuer1.processedEntities, enqueuer2.processedEntities,
155 "Processed element mismatch", elementEquivalence, elementFilter: (e) {
156 return elementFilter != null ? elementFilter(e) : true;
157 }, verbose: verbose);
158
159 checkSets(enqueuer1.worldBuilder.isChecks, enqueuer2.worldBuilder.isChecks,
160 "Is-check mismatch", typeEquivalence,
161 verbose: verbose);
162
163 Expect.equals(backendUsage1.isInvokeOnUsed, backendUsage2.isInvokeOnUsed,
164 "JavaScriptBackend.hasInvokeOnSupport mismatch");
165 Expect.equals(
166 backendUsage1.isFunctionApplyUsed,
167 backendUsage1.isFunctionApplyUsed,
168 "JavaScriptBackend.hasFunctionApplySupport mismatch");
169 Expect.equals(
170 backendUsage1.isRuntimeTypeUsed,
171 backendUsage2.isRuntimeTypeUsed,
172 "JavaScriptBackend.hasRuntimeTypeSupport mismatch");
173 Expect.equals(backendUsage1.isIsolateInUse, backendUsage2.isIsolateInUse,
174 "JavaScriptBackend.hasIsolateSupport mismatch");
175 }
176
177 void checkClosedWorlds(ClosedWorld closedWorld1, ClosedWorld closedWorld2,
178 {TestStrategy strategy: const TestStrategy(),
179 bool allowExtra: false,
180 bool verbose: false}) {
181 if (verbose) {
182 print(closedWorld1.dump());
183 print(closedWorld2.dump());
184 }
185 checkClassHierarchyNodes(
186 closedWorld1,
187 closedWorld2,
188 closedWorld1
189 .getClassHierarchyNode(closedWorld1.commonElements.objectClass),
190 closedWorld2
191 .getClassHierarchyNode(closedWorld2.commonElements.objectClass),
192 strategy.elementEquivalence,
193 verbose: verbose);
194
195 checkNativeData(closedWorld1.nativeData, closedWorld2.nativeData,
196 strategy: strategy, allowExtra: allowExtra, verbose: verbose);
197 checkInterceptorData(closedWorld1.interceptorData,
198 closedWorld2.interceptorData, strategy.elementEquivalence,
199 verbose: verbose);
200 }
201
202 void checkNativeData(NativeDataImpl data1, NativeDataImpl data2,
203 {TestStrategy strategy: const TestStrategy(),
204 bool allowExtra: false,
205 bool verbose: false}) {
206 checkMapEquivalence(data1, data2, 'nativeMemberName', data1.nativeMemberName,
207 data2.nativeMemberName, strategy.elementEquivalence, equality,
208 allowExtra: allowExtra);
209
210 checkMapEquivalence(
211 data1,
212 data2,
213 'nativeMethodBehavior',
214 data1.nativeMethodBehavior,
215 data2.nativeMethodBehavior,
216 strategy.elementEquivalence,
217 (a, b) => testNativeBehavior(a, b, strategy: strategy),
218 allowExtra: allowExtra);
219
220 checkMapEquivalence(
221 data1,
222 data2,
223 'nativeFieldLoadBehavior',
224 data1.nativeFieldLoadBehavior,
225 data2.nativeFieldLoadBehavior,
226 strategy.elementEquivalence,
227 (a, b) => testNativeBehavior(a, b, strategy: strategy),
228 allowExtra: allowExtra);
229
230 checkMapEquivalence(
231 data1,
232 data2,
233 'nativeFieldStoreBehavior',
234 data1.nativeFieldStoreBehavior,
235 data2.nativeFieldStoreBehavior,
236 strategy.elementEquivalence,
237 (a, b) => testNativeBehavior(a, b, strategy: strategy),
238 allowExtra: allowExtra);
239
240 checkMapEquivalence(
241 data1,
242 data2,
243 'jsInteropLibraryNames',
244 data1.jsInteropLibraryNames,
245 data2.jsInteropLibraryNames,
246 strategy.elementEquivalence,
247 equality);
248
249 checkSetEquivalence(
250 data1,
251 data2,
252 'anonymousJsInteropClasses',
253 data1.anonymousJsInteropClasses,
254 data2.anonymousJsInteropClasses,
255 strategy.elementEquivalence);
256
257 checkMapEquivalence(
258 data1,
259 data2,
260 'jsInteropClassNames',
261 data1.jsInteropClassNames,
262 data2.jsInteropClassNames,
263 strategy.elementEquivalence,
264 equality);
265
266 checkMapEquivalence(
267 data1,
268 data2,
269 'jsInteropMemberNames',
270 data1.jsInteropMemberNames,
271 data2.jsInteropMemberNames,
272 strategy.elementEquivalence,
273 equality);
274 }
275
276 void checkInterceptorData(InterceptorDataImpl data1, InterceptorDataImpl data2,
277 bool elementEquivalence(Entity a, Entity b),
278 {bool verbose: false}) {
279 checkMapEquivalence(
280 data1,
281 data2,
282 'interceptedElements',
283 data1.interceptedElementsForTesting,
284 data2.interceptedElementsForTesting,
285 equality,
286 (a, b) => areSetsEquivalent(a, b, elementEquivalence));
287
288 checkSetEquivalence(data1, data2, 'interceptedClasses',
289 data1.interceptedClasses, data2.interceptedClasses, elementEquivalence);
290
291 checkSetEquivalence(
292 data1,
293 data2,
294 'classesMixedIntoInterceptedClasses',
295 data1.classesMixedIntoInterceptedClassesForTesting,
296 data2.classesMixedIntoInterceptedClassesForTesting,
297 elementEquivalence);
298 }
299
300 void checkBackendInfo(Compiler compilerNormal, Compiler compilerDeserialized, 107 void checkBackendInfo(Compiler compilerNormal, Compiler compilerDeserialized,
301 {bool verbose: false}) { 108 {bool verbose: false}) {
302 checkSets( 109 checkSets(
303 compilerNormal.enqueuer.resolution.processedEntities, 110 compilerNormal.enqueuer.resolution.processedEntities,
304 compilerDeserialized.enqueuer.resolution.processedEntities, 111 compilerDeserialized.enqueuer.resolution.processedEntities,
305 "Processed element mismatch", 112 "Processed element mismatch",
306 areElementsEquivalent, onSameElement: (a, b) { 113 areElementsEquivalent, onSameElement: (a, b) {
307 checkElements(compilerNormal, compilerDeserialized, a, b, verbose: verbose); 114 checkElements(compilerNormal, compilerDeserialized, a, b, verbose: verbose);
308 }, verbose: verbose); 115 }, verbose: verbose);
309 Expect.equals( 116 Expect.equals(
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 if (element1 is MethodElement && element2 is MethodElement) { 221 if (element1 is MethodElement && element2 is MethodElement) {
415 Expect.equals( 222 Expect.equals(
416 backend1.inlineCache.getCurrentCacheDecisionForTesting(element1), 223 backend1.inlineCache.getCurrentCacheDecisionForTesting(element1),
417 backend2.inlineCache.getCurrentCacheDecisionForTesting(element2), 224 backend2.inlineCache.getCurrentCacheDecisionForTesting(element2),
418 "Inline cache decision mismatch for $element1 vs $element2"); 225 "Inline cache decision mismatch for $element1 vs $element2");
419 } 226 }
420 227
421 checkElementOutputUnits(compiler1, compiler2, element1, element2); 228 checkElementOutputUnits(compiler1, compiler2, element1, element2);
422 } 229 }
423 230
424 void checkMixinUses(
425 ClosedWorld closedWorld1,
426 ClosedWorld closedWorld2,
427 ClassEntity class1,
428 ClassEntity class2,
429 bool elementEquivalence(Entity a, Entity b),
430 {bool verbose: false}) {
431 checkSets(closedWorld1.mixinUsesOf(class1), closedWorld2.mixinUsesOf(class2),
432 "Mixin uses of $class1 vs $class2", elementEquivalence,
433 verbose: verbose);
434 }
435
436 void checkClassHierarchyNodes(
437 ClosedWorld closedWorld1,
438 ClosedWorld closedWorld2,
439 ClassHierarchyNode node1,
440 ClassHierarchyNode node2,
441 bool elementEquivalence(Entity a, Entity b),
442 {bool verbose: false}) {
443 if (verbose) {
444 print('Checking $node1 vs $node2');
445 }
446 ClassEntity cls1 = node1.cls;
447 ClassEntity cls2 = node2.cls;
448 Expect.isTrue(elementEquivalence(cls1, cls2),
449 "Element identity mismatch for ${cls1} vs ${cls2}.");
450 Expect.equals(
451 node1.isDirectlyInstantiated,
452 node2.isDirectlyInstantiated,
453 "Value mismatch for 'isDirectlyInstantiated' "
454 "for ${cls1} vs ${cls2}.");
455 Expect.equals(
456 node1.isIndirectlyInstantiated,
457 node2.isIndirectlyInstantiated,
458 "Value mismatch for 'isIndirectlyInstantiated' "
459 "for ${node1.cls} vs ${node2.cls}.");
460 // TODO(johnniwinther): Enforce a canonical and stable order on direct
461 // subclasses.
462 for (ClassHierarchyNode child in node1.directSubclasses) {
463 bool found = false;
464 for (ClassHierarchyNode other in node2.directSubclasses) {
465 ClassEntity child1 = child.cls;
466 ClassEntity child2 = other.cls;
467 if (elementEquivalence(child1, child2)) {
468 checkClassHierarchyNodes(
469 closedWorld1, closedWorld2, child, other, elementEquivalence,
470 verbose: verbose);
471 found = true;
472 break;
473 }
474 }
475 if (!found) {
476 if (child.isInstantiated) {
477 print('Missing subclass ${child.cls} of ${node1.cls} '
478 'in ${node2.directSubclasses}');
479 print(closedWorld1.dump(
480 verbose ? closedWorld1.commonElements.objectClass : node1.cls));
481 print(closedWorld2.dump(
482 verbose ? closedWorld2.commonElements.objectClass : node2.cls));
483 }
484 Expect.isFalse(
485 child.isInstantiated,
486 'Missing subclass ${child.cls} of ${node1.cls} in '
487 '${node2.directSubclasses}');
488 }
489 }
490 checkMixinUses(
491 closedWorld1, closedWorld2, node1.cls, node2.cls, elementEquivalence,
492 verbose: verbose);
493 }
494
495 bool areLocalsEquivalent(Local a, Local b) { 231 bool areLocalsEquivalent(Local a, Local b) {
496 if (a == b) return true; 232 if (a == b) return true;
497 if (a == null || b == null) return false; 233 if (a == null || b == null) return false;
498 234
499 if (a is Element) { 235 if (a is Element) {
500 return b is Element && areElementsEquivalent(a as Element, b as Element); 236 return b is Element && areElementsEquivalent(a as Element, b as Element);
501 } else { 237 } else {
502 return a.runtimeType == b.runtimeType && 238 return a.runtimeType == b.runtimeType &&
503 areElementsEquivalent(a.executableContext, b.executableContext); 239 areElementsEquivalent(a.executableContext, b.executableContext);
504 } 240 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 check(outputUnit1, outputUnit2, 'OutputUnit.isMainOutput $message', 293 check(outputUnit1, outputUnit2, 'OutputUnit.isMainOutput $message',
558 outputUnit1.isMainOutput, outputUnit2.isMainOutput); 294 outputUnit1.isMainOutput, outputUnit2.isMainOutput);
559 checkSetEquivalence( 295 checkSetEquivalence(
560 outputUnit1, 296 outputUnit1,
561 outputUnit2, 297 outputUnit2,
562 'OutputUnit.imports $message', 298 'OutputUnit.imports $message',
563 outputUnit1.imports, 299 outputUnit1.imports,
564 outputUnit2.imports, 300 outputUnit2.imports,
565 (a, b) => areElementsEquivalent(a.declaration, b.declaration)); 301 (a, b) => areElementsEquivalent(a.declaration, b.declaration));
566 } 302 }
567
568 bool areInstantiationInfosEquivalent(
569 InstantiationInfo info1,
570 InstantiationInfo info2,
571 bool elementEquivalence(Entity a, Entity b),
572 bool typeEquivalence(DartType a, DartType b)) {
573 checkMaps(
574 info1.instantiationMap,
575 info2.instantiationMap,
576 'instantiationMap of\n '
577 '${info1.instantiationMap}\nvs ${info2.instantiationMap}',
578 elementEquivalence,
579 (a, b) => areSetsEquivalent(
580 a, b, (a, b) => areInstancesEquivalent(a, b, typeEquivalence)));
581 return true;
582 }
583
584 bool areInstancesEquivalent(Instance instance1, Instance instance2,
585 bool typeEquivalence(DartType a, DartType b)) {
586 InterfaceType type1 = instance1.type;
587 InterfaceType type2 = instance2.type;
588 return typeEquivalence(type1, type2) &&
589 instance1.kind == instance2.kind &&
590 instance1.isRedirection == instance2.isRedirection;
591 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698