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

Side by Side Diff: tests/compiler/dart2js/serialization_test.dart

Issue 1192103002: Support serialization of the compiler backbone. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Handle (bypass) external const constructors. Created 5 years, 5 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
« no previous file with comments | « tests/compiler/dart2js/serialization_analysis_test.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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_test;
6
7 import 'dart:io';
8 import 'memory_compiler.dart';
9 import 'package:async_helper/async_helper.dart';
10 import 'package:compiler/src/constants/expressions.dart';
11 import 'package:compiler/src/dart_types.dart';
12 import 'package:compiler/src/dart2jslib.dart';
13 import 'package:compiler/src/elements/elements.dart';
14 import 'package:compiler/src/elements/visitor.dart';
15 import 'package:compiler/src/ordered_typeset.dart';
16 import 'package:compiler/src/serialization/serialization.dart';
17 import 'package:compiler/src/serialization/json_serializer.dart';
18 import 'package:compiler/src/tree/tree.dart';
19
20 main(List<String> arguments) {
21 // Ensure that we can print out constant expressions.
22 DEBUG_MODE = true;
23
24 Uri entryPoint;
25 String outPath;
26 bool prettyPrint = false;
27 for (String arg in arguments) {
28 if (arg.startsWith('--')) {
29 if (arg.startsWith('--out=')) {
30 outPath = arg.substring('--out='.length);
31 } else if (arg == '--pretty-print') {
32 prettyPrint = true;
33 } else {
34 print("Unknown option $arg");
35 }
36 } else {
37 if (entryPoint != null) {
38 print("Multiple entrypoints is not supported.");
39 }
40 entryPoint = Uri.parse(arg);
41 }
42 }
43 if (entryPoint == null) {
44 entryPoint = Uri.parse('dart:core');
45 }
46 Compiler compiler = compilerFor({}, options: ['--analyze-all']);
47 asyncTest(() async {
48 await compiler.runCompiler(entryPoint);
49 testSerialization(compiler.libraryLoader.libraries,
50 outPath: outPath,
51 prettyPrint: prettyPrint);
52 });
53 }
54
55 void testSerialization(Iterable<LibraryElement> libraries1,
56 {String outPath,
57 bool prettyPrint}) {
58 Serializer serializer = new Serializer(const JsonSerializationEncoder());
59 for (LibraryElement library1 in libraries1) {
60 serializer.serialize(library1);
61 }
62 String text = serializer.toText();
63 String outText = text;
64 if (prettyPrint) {
65 outText = serializer.prettyPrint();
66 }
67 if (outPath != null) {
68 new File(outPath).writeAsStringSync(outText);
69 } else if (prettyPrint) {
70 print(outText);
71 }
72
73 Deserializer deserializer = new Deserializer.fromText(
74 text, const JsonSerializationDecoder());
75 List<LibraryElement> libraries2 = <LibraryElement>[];
76 for (LibraryElement library1 in libraries1) {
77 LibraryElement library2 =
78 deserializer.lookupLibrary(library1.canonicalUri);
79 if (library2 == null) {
80 throw new ArgumentError('No library ${library1.canonicalUri} found.');
81 }
82 checkLibraryContent('library1', 'library2', 'library', library1, library2);
83 libraries2.add(library2);
84 }
85
86 Serializer serializer2 = new Serializer(const JsonSerializationEncoder());
87 for (LibraryElement library2 in libraries2) {
88 serializer2.serialize(library2);
89 }
90 String text2 = serializer2.toText();
91
92 Deserializer deserializer3 = new Deserializer.fromText(
93 text2, const JsonSerializationDecoder());
94 for (LibraryElement library1 in libraries1) {
95 LibraryElement library2 =
96 deserializer.lookupLibrary(library1.canonicalUri);
97 if (library2 == null) {
98 throw new ArgumentError('No library ${library1.canonicalUri} found.');
99 }
100 LibraryElement library3 =
101 deserializer3.lookupLibrary(library1.canonicalUri);
102 if (library3 == null) {
103 throw new ArgumentError('No library ${library1.canonicalUri} found.');
104 }
105 checkLibraryContent('library1', 'library3', 'library', library1, library3);
106 checkLibraryContent('library2', 'library3', 'library', library2, library3);
107 }
108 }
109
110 /// Check the equivalence of [library1] and [library2] and their content.
111 ///
112 /// Uses [object1], [object2] and [property] to provide context for failures.
113 checkLibraryContent(
114 Object object1, object2, String property,
115 LibraryElement library1, LibraryElement library2) {
116 checkElementProperties(object1, object2, property, library1, library2);
117 }
118
119 /// Check the equivalence of [element1] and [element2] and their properties.
120 ///
121 /// Uses [object1], [object2] and [property] to provide context for failures.
122 checkElementProperties(
123 Object object1, object2, String property,
124 Element element1, Element element2) {
125 const ElementPropertyEquivalence().visit(element1, element2);
126 }
127
128 /// Check the equivalence of the two lists of elements, [list1] and [list2].
129 ///
130 /// Uses [object1], [object2] and [property] to provide context for failures.
131 checkElementLists(Object object1, Object object2, String property,
132 Iterable<Element> list1, Iterable<Element> list2) {
133 checkListEquivalence(object1, object2, property,
134 list1, list2, checkElementProperties);
135 }
136
137 /// Check equivalence of the two lists, [list1] and [list2], using
138 /// [checkEquivalence] to check the pair-wise equivalence.
139 ///
140 /// Uses [object1], [object2] and [property] to provide context for failures.
141 void checkListEquivalence(
142 Object object1, Object object2, String property,
143 Iterable list1, Iterable list2,
144 void checkEquivalence(o1, o2, property, a, b)) {
145 for (int i = 0; i < list1.length && i < list2.length; i++) {
146 checkEquivalence(
147 object1, object2, property,
148 list1.elementAt(i), list2.elementAt(i));
149 }
150 for (int i = list1.length; i < list2.length; i++) {
151 throw
152 'Missing equivalent for element '
153 '#$i ${list2.elementAt(i)} in `${property}` on $object2.\n'
154 '`${property}` on $object1:\n ${list1.join('\n ')}\n'
155 '`${property}` on $object2:\n ${list2.join('\n ')}';
156 }
157 for (int i = list2.length; i < list1.length; i++) {
158 throw
159 'Missing equivalent for element '
160 '#$i ${list1.elementAt(i)} in `${property}` on $object1.\n'
161 '`${property}` on $object1:\n ${list1.join('\n ')}\n'
162 '`${property}` on $object2:\n ${list2.join('\n ')}';
163 }
164 }
165
166 /// Checks the equivalence of the identity (but not properties) of [element1]
167 /// and [element2].
168 ///
169 /// Uses [object1], [object2] and [property] to provide context for failures.
170 void checkElementIdentities(
171 Object object1, Object object2, String property,
172 Element element1, Element element2) {
173 if (identical(element1, element2)) return;
174 if (element1 == null || element2 == null) {
175 check(object1, object2, property, element1, element2);
176 }
177 const ElementIdentityEquivalence().visit(element1, element2);
178 }
179
180 /// Checks the pair-wise equivalence of the identity (but not properties) of the
181 /// elements in [list] and [list2].
182 ///
183 /// Uses [object1], [object2] and [property] to provide context for failures.
184 void checkElementListIdentities(
185 Object object1, Object object2, String property,
186 Iterable<Element> list1, Iterable<Element> list2) {
187 checkListEquivalence(
188 object1, object2, property,
189 list1, list2, checkElementIdentities);
190 }
191
192 /// Checks the equivalence of [type1] and [type2].
193 ///
194 /// Uses [object1], [object2] and [property] to provide context for failures.
195 void checkTypes(
196 Object object1, Object object2, String property,
197 DartType type1, DartType type2) {
198 if (identical(type1, type2)) return;
199 if (type1 == null || type2 == null) {
200 check(object1, object2, property, type1, type2);
201 }
202 const TypeEquivalence().visit(type1, type2);
203 }
204
205 /// Checks the pair-wise equivalence of the types in [list1] and [list2].
206 ///
207 /// Uses [object1], [object2] and [property] to provide context for failures.
208 void checkTypeLists(
209 Object object1, Object object2, String property,
210 List<DartType> list1, List<DartType> list2) {
211 checkListEquivalence(object1, object2, property, list1, list2, checkTypes);
212 }
213
214 /// Checks the equivalence of [exp1] and [exp2].
215 ///
216 /// Uses [object1], [object2] and [property] to provide context for failures.
217 void checkConstants(
218 Object object1, Object object2, String property,
219 ConstantExpression exp1, ConstantExpression exp2) {
220 if (identical(exp1, exp2)) return;
221 if (exp1 == null || exp2 == null) {
222 check(object1, object2, property, exp1, exp2);
223 }
224 const ConstantEquivalence().visit(exp1, exp2);
225 }
226
227 /// Checks the pair-wise equivalence of the contants in [list1] and [list2].
228 ///
229 /// Uses [object1], [object2] and [property] to provide context for failures.
230 void checkConstantLists(
231 Object object1, Object object2, String property,
232 List<ConstantExpression> list1,
233 List<ConstantExpression> list2) {
234 checkListEquivalence(
235 object1, object2, property,
236 list1, list2, checkConstants);
237 }
238
239 /// Checks the equivalence of [constructor1] and [constructor2].
240 void constantConstructorEquivalence(ConstantConstructor constructor1,
241 ConstantConstructor constructor2) {
242 const ConstantConstructorEquivalence().visit(constructor1, constructor2);
243 }
244
245 /// Visitor that checks the equivalence of [ConstantConstructor]s.
246 class ConstantConstructorEquivalence
247 extends ConstantConstructorVisitor<dynamic, ConstantConstructor> {
248 const ConstantConstructorEquivalence();
249
250 @override
251 void visit(ConstantConstructor constructor1,
252 ConstantConstructor constructor2) {
253 if (identical(constructor1, constructor2)) return;
254 check(constructor1, constructor2, 'kind',
255 constructor1.kind, constructor2.kind);
256 constructor1.accept(this, constructor2);
257 }
258
259 @override
260 visitGenerative(
261 GenerativeConstantConstructor constructor1,
262 GenerativeConstantConstructor constructor2) {
263 checkTypes(
264 constructor1, constructor2, 'type',
265 constructor1.type, constructor2.type);
266 check(constructor1, constructor2, 'defaultValues.length',
267 constructor1.defaultValues.length,
268 constructor2.defaultValues.length);
269 constructor1.defaultValues.forEach((k, v) {
270 checkConstants(
271 constructor1, constructor2, 'defaultValue[$k]',
272 v, constructor2.defaultValues[k]);
273 });
274 check(constructor1, constructor2, 'fieldMap.length',
275 constructor1.fieldMap.length,
276 constructor2.fieldMap.length);
277 constructor1.fieldMap.forEach((k1, v1) {
278 bool matched = false;
279 constructor2.fieldMap.forEach((k2, v2) {
280 if (k1.name == k2.name &&
281 k1.library.canonicalUri == k2.library.canonicalUri) {
282 checkElementIdentities(
283 constructor1, constructor2, 'fieldMap[${k1.name}].key', k1, k2);
284 checkConstants(
285 constructor1, constructor2, 'fieldMap[${k1.name}].value', v1, v2);
286 matched = true;
287 }
288 });
289 if (!matched) {
290 throw 'Unmatched field $k1 = $v1';
291 }
292 });
293 checkConstants(
294 constructor1, constructor2, 'superConstructorInvocation',
295 constructor1.superConstructorInvocation,
296 constructor2.superConstructorInvocation);
297 }
298
299 @override
300 visitRedirectingFactory(
301 RedirectingFactoryConstantConstructor constructor1,
302 RedirectingFactoryConstantConstructor constructor2) {
303 checkConstants(
304 constructor1, constructor2, 'targetConstructorInvocation',
305 constructor1.targetConstructorInvocation,
306 constructor2.targetConstructorInvocation);
307 }
308
309 @override
310 visitRedirectingGenerative(
311 RedirectingGenerativeConstantConstructor constructor1,
312 RedirectingGenerativeConstantConstructor constructor2) {
313 check(constructor1, constructor2, 'defaultValues.length',
314 constructor1.defaultValues.length,
315 constructor2.defaultValues.length);
316 constructor1.defaultValues.forEach((k, v) {
317 checkConstants(
318 constructor1, constructor2, 'defaultValue[$k]',
319 v, constructor2.defaultValues[k]);
320 });
321 checkConstants(
322 constructor1, constructor2, 'thisConstructorInvocation',
323 constructor1.thisConstructorInvocation,
324 constructor2.thisConstructorInvocation);
325 }
326 }
327
328 /// Check that the values [property] of [object1] and [object2], [value1] and
329 /// [value2] respectively, are equal and throw otherwise.
330 void check(var object1, var object2, String property, var value1, value2) {
331 if (value1 != value2) {
332 throw "$object1.$property = '${value1}' <> "
333 "$object2.$property = '${value2}'";
334 }
335 }
336
337 /// Visitor that checks for equivalence of [Element] identities.
338 class ElementIdentityEquivalence extends BaseElementVisitor<dynamic, Element> {
339 const ElementIdentityEquivalence();
340
341 void visit(Element element1, Element element2) {
342 check(element1, element2, 'kind', element1.kind, element2.kind);
343 element1.accept(this, element2);
344 }
345
346 @override
347 void visitElement(Element e, Element arg) {
348 throw new UnsupportedError("Unsupported element $e");
349 }
350
351 @override
352 void visitLibraryElement(LibraryElement element1, LibraryElement element2) {
353 check(element1, element2,
354 'canonicalUri',
355 element1.canonicalUri, element2.canonicalUri);
356 }
357
358 @override
359 void visitCompilationUnitElement(CompilationUnitElement element1,
360 CompilationUnitElement element2) {
361 check(element1, element2,
362 'name',
363 element1.name, element2.name);
364 visit(element1.library, element2.library);
365 }
366
367 @override
368 void visitClassElement(ClassElement element1, ClassElement element2) {
369 check(element1, element2,
370 'name',
371 element1.name, element2.name);
372 visit(element1.library, element2.library);
373 }
374
375 void checkMembers(Element element1, Element element2) {
376 check(element1, element2,
377 'name',
378 element1.name, element2.name);
379 if (element1.enclosingClass != null || element2.enclosingClass != null) {
380 visit(element1.enclosingClass, element2.enclosingClass);
381 } else {
382 visit(element1.library, element2.library);
383 }
384 }
385
386 @override
387 void visitFieldElement(FieldElement element1, FieldElement element2) {
388 checkMembers(element1, element2);
389 }
390
391 @override
392 void visitFunctionElement(FunctionElement element1,
393 FunctionElement element2) {
394 checkMembers(element1, element2);
395 }
396
397 void visitAbstractFieldElement(AbstractFieldElement element1,
398 AbstractFieldElement element2) {
399 checkMembers(element1, element2);
400 }
401
402 @override
403 void visitTypeVariableElement(TypeVariableElement element1,
404 TypeVariableElement element2) {
405 check(element1, element2,
406 'name',
407 element1.name, element2.name);
408 visit(element1.typeDeclaration, element2.typeDeclaration);
409 }
410
411 @override
412 void visitTypedefElement(TypedefElement element1, TypedefElement element2) {
413 check(element1, element2,
414 'name',
415 element1.name, element2.name);
416 visit(element1.library, element2.library);
417 }
418
419 @override
420 void visitParameterElement(ParameterElement element1,
421 ParameterElement element2) {
422 check(element1, element2,
423 'name',
424 element1.name, element2.name);
425 visit(element1.functionDeclaration, element2.functionDeclaration);
426 }
427 }
428
429 /// Visitor that checks for equivalence of [Element] properties.
430 class ElementPropertyEquivalence extends BaseElementVisitor<dynamic, Element> {
431 const ElementPropertyEquivalence();
432
433 void visit(Element element1, Element element2) {
434 if (element1 == element2) return;
435 check(element1, element2, 'kind', element1.kind, element2.kind);
436 element1.accept(this, element2);
437 }
438
439 @override
440 void visitElement(Element e, Element arg) {
441 throw new UnsupportedError("Unsupported element $e");
442 }
443
444 @override
445 void visitLibraryElement(LibraryElement element1, LibraryElement element2) {
446 checkElementIdentities(null, null, null, element1, element2);
447 check(element1, element2, 'name', element1.name, element2.name);
448 check(element1, element2, 'getLibraryName',
449 element1.getLibraryName(), element2.getLibraryName());
450 visitMembers(element1, element2);
451 visit(element1.entryCompilationUnit, element2.entryCompilationUnit);
452 checkElementLists(
453 element1, element2, 'compilationUnits',
454 element1.compilationUnits.toList(),
455 element2.compilationUnits.toList());
456
457 bool filterTags(LibraryTag tag) => tag.asLibraryDependency() != null;
458
459 List<LibraryTag> tags1 = element1.tags.where(filterTags).toList();
460 List<LibraryTag> tags2 = element2.tags.where(filterTags).toList();
461 checkListEquivalence(element1, element2, 'tags', tags1, tags2,
462 (Object object1, Object object2, String property,
463 LibraryDependency tag1, LibraryDependency tag2) {
464 checkElementIdentities(
465 tag1, tag2, 'getLibraryFromTag',
466 element1.getLibraryFromTag(tag1),
467 element2.getLibraryFromTag(tag2));
468 });
469
470 List<Element> imports1 = <Element>[];
471 List<Element> imports2 = <Element>[];
472 element1.forEachImport((Element import) {
473 if (import.isAmbiguous) return;
474 imports1.add(import);
475 });
476 element2.forEachImport((Element import) {
477 if (import.isAmbiguous) return;
478 imports2.add(import);
479 });
480 checkElementListIdentities(
481 element1, element2, 'imports', imports1, imports2);
482
483 List<Element> exports1 = <Element>[];
484 List<Element> exports2 = <Element>[];
485 element1.forEachExport((Element export) {
486 if (export.isAmbiguous) return;
487 exports1.add(export);
488 });
489 element2.forEachExport((Element export) {
490 if (export.isAmbiguous) return;
491 exports2.add(export);
492 });
493 checkElementListIdentities(
494 element1, element2, 'exports', exports1, exports2);
495 }
496
497 @override
498 void visitCompilationUnitElement(CompilationUnitElement element1,
499 CompilationUnitElement element2) {
500 check(element1, element2,
501 'name',
502 element1.name, element2.name);
503 checkElementIdentities(
504 element1, element2, 'library',
505 element1.library, element2.library);
506 check(element1, element2,
507 'script.resourceUri',
508 element1.script.resourceUri, element2.script.resourceUri);
509 List<Element> members1 = <Element>[];
510 List<Element> members2 = <Element>[];
511 element1.forEachLocalMember((Element member) {
512 members1.add(member);
513 });
514 element2.forEachLocalMember((Element member) {
515 members2.add(member);
516 });
517 checkElementListIdentities(
518 element1, element2, 'localMembers', members1, members2);
519 }
520
521 void visitMembers(ScopeContainerElement element1,
522 ScopeContainerElement element2) {
523 Set<String> names = new Set<String>();
524 element1.forEachLocalMember((Element member) {
525 names.add(member.name);
526 });
527 element2.forEachLocalMember((Element member) {
528 names.add(member.name);
529 });
530 for (String name in names) {
531 Element member1 = element1.localLookup(name);
532 Element member2 = element2.localLookup(name);
533 if (member1 == null) {
534 print('Missing member for $member2');
535 continue;
536 }
537 if (member2 == null) {
538 print('Missing member for $member1');
539 continue;
540 }
541 visit(member1, member2);
542 }
543 }
544
545 @override
546 void visitClassElement(ClassElement element1, ClassElement element2) {
547 checkElementIdentities(null, null, null, element1, element2);
548 check(element1, element2, 'name',
549 element1.name, element2.name);
550 check(element1, element2, 'sourcePosition',
551 element1.sourcePosition, element2.sourcePosition);
552 checkElementIdentities(
553 element1, element2, 'library',
554 element1.library, element2.library);
555 checkElementIdentities(
556 element1, element2, 'compilationUnit',
557 element1.compilationUnit, element2.compilationUnit);
558 check(element1, element2, 'isObject',
559 element1.isObject, element2.isObject);
560 checkTypeLists(element1, element2, 'typeVariables',
561 element1.typeVariables, element2.typeVariables);
562 check(element1, element2, 'isAbstract',
563 element1.isAbstract, element2.isAbstract);
564 if (!element1.isObject) {
565 checkTypes(element1, element2, 'supertype',
566 element1.supertype, element2.supertype);
567 }
568 check(element1, element2, 'hierarchyDepth',
569 element1.hierarchyDepth, element2.hierarchyDepth);
570 checkTypeLists(
571 element1, element2, 'allSupertypes',
572 element1.allSupertypes.toList(),
573 element2.allSupertypes.toList());
574 OrderedTypeSet typeSet1 = element1.allSupertypesAndSelf;
575 OrderedTypeSet typeSet2 = element1.allSupertypesAndSelf;
576 checkListEquivalence(
577 element1, element2, 'allSupertypes',
578 typeSet1.levelOffsets,
579 typeSet2.levelOffsets,
580 check);
581 check(element1, element2, 'allSupertypesAndSelf.levels',
582 typeSet1.levels, typeSet2.levels);
583 checkTypeLists(
584 element1, element2, 'supertypes',
585 typeSet1.supertypes.toList(),
586 typeSet2.supertypes.toList());
587 checkTypeLists(
588 element1, element2, 'types',
589 typeSet1.types.toList(),
590 typeSet2.types.toList());
591
592 checkTypeLists(
593 element1, element2, 'interfaces',
594 element1.interfaces.toList(),
595 element2.interfaces.toList());
596
597 visitMembers(element1, element2);
598 }
599
600 @override
601 void visitFieldElement(FieldElement element1, FieldElement element2) {
602 checkElementIdentities(null, null, null, element1, element2);
603 check(element1, element2, 'name',
604 element1.name, element2.name);
605 check(element1, element2, 'sourcePosition',
606 element1.sourcePosition, element2.sourcePosition);
607 checkTypes(
608 element1, element2, 'type',
609 element1.type, element2.type);
610 check(element1, element2, 'isConst',
611 element1.isConst, element2.isConst);
612 check(element1, element2, 'isFinal',
613 element1.isFinal, element2.isFinal);
614 if (element1.isConst) {
615 checkConstants(
616 element1, element2, 'constant',
617 element1.constant, element2.constant);
618 }
619 check(element1, element2, 'isTopLevel',
620 element1.isTopLevel, element2.isTopLevel);
621 check(element1, element2, 'isStatic',
622 element1.isStatic, element2.isStatic);
623 check(element1, element2, 'isInstanceMember',
624 element1.isInstanceMember, element2.isInstanceMember);
625
626 checkElementIdentities(
627 element1, element2, 'library',
628 element1.library, element2.library);
629 checkElementIdentities(
630 element1, element2, 'compilationUnit',
631 element1.compilationUnit, element2.compilationUnit);
632 checkElementIdentities(
633 element1, element2, 'enclosingClass',
634 element1.enclosingClass, element2.enclosingClass);
635 }
636
637 @override
638 void visitFunctionElement(FunctionElement element1,
639 FunctionElement element2) {
640 checkElementIdentities(null, null, null, element1, element2);
641 check(element1, element2, 'name',
642 element1.name, element2.name);
643 check(element1, element2, 'sourcePosition',
644 element1.sourcePosition, element2.sourcePosition);
645 checkTypes(
646 element1, element2, 'type',
647 element1.type, element2.type);
648 checkListEquivalence(
649 element1, element2, 'parameters',
650 element1.parameters, element2.parameters,
651 checkElementProperties);
652 check(element1, element2, 'isOperator',
653 element1.isOperator, element2.isOperator);
654
655 checkElementIdentities(
656 element1, element2, 'library',
657 element1.library, element2.library);
658 checkElementIdentities(
659 element1, element2, 'compilationUnit',
660 element1.compilationUnit, element2.compilationUnit);
661 checkElementIdentities(
662 element1, element2, 'enclosingClass',
663 element1.enclosingClass, element2.enclosingClass);
664 }
665
666 @override
667 void visitConstructorElement(ConstructorElement element1,
668 ConstructorElement element2) {
669 checkElementIdentities(null, null, null, element1, element2);
670 checkElementIdentities(
671 element1, element2, 'enclosingClass',
672 element1.enclosingClass, element2.enclosingClass);
673 check(
674 element1, element2, 'name',
675 element1.name, element2.name);
676 check(element1, element2, 'sourcePosition',
677 element1.sourcePosition, element2.sourcePosition);
678 checkListEquivalence(
679 element1, element2, 'parameters',
680 element1.parameters, element2.parameters,
681 checkElementProperties);
682 checkTypes(
683 element1, element2, 'type',
684 element1.type, element2.type);
685 check(element1, element2, 'isConst',
686 element1.isConst, element2.isConst);
687 check(element1, element2, 'isExternal',
688 element1.isExternal, element2.isExternal);
689 if (element1.isConst && !element1.isExternal) {
690 constantConstructorEquivalence(
691 element1.constantConstructor,
692 element2.constantConstructor);
693 }
694 }
695
696 @override
697 void visitAbstractFieldElement(AbstractFieldElement element1,
698 AbstractFieldElement element2) {
699 visit(element1.getter, element2.getter);
700 visit(element1.setter, element2.setter);
701 }
702
703 @override
704 void visitTypeVariableElement(TypeVariableElement element1,
705 TypeVariableElement element2) {
706 checkElementIdentities(null, null, null, element1, element2);
707 check(element1, element2, 'name', element1.name, element2.name);
708 check(element1, element2, 'sourcePosition',
709 element1.sourcePosition, element2.sourcePosition);
710 check(element1, element2, 'index', element1.index, element2.index);
711 checkTypes(
712 element1, element2, 'type',
713 element1.type, element2.type);
714 checkTypes(
715 element1, element2, 'bound',
716 element1.bound, element2.bound);
717 }
718
719 @override
720 void visitTypedefElement(TypedefElement element1,
721 TypedefElement element2) {
722 checkElementIdentities(null, null, null, element1, element2);
723 check(element1, element2, 'name', element1.name, element2.name);
724 check(element1, element2, 'sourcePosition',
725 element1.sourcePosition, element2.sourcePosition);
726 checkTypes(
727 element1, element2, 'alias',
728 element1.alias, element2.alias);
729 checkTypeLists(
730 element1, element2, 'typeVariables',
731 element1.typeVariables, element2.typeVariables);
732 checkElementIdentities(
733 element1, element2, 'library',
734 element1.library, element2.library);
735 checkElementIdentities(
736 element1, element2, 'compilationUnit',
737 element1.compilationUnit, element2.compilationUnit);
738 // TODO(johnniwinther): Check the equivalence of typedef parameters.
739 }
740
741 @override
742 void visitParameterElement(ParameterElement element1,
743 ParameterElement element2) {
744 checkElementIdentities(null, null, null, element1, element2);
745 checkElementIdentities(
746 element1, element2, 'functionDeclaration',
747 element1.functionDeclaration, element2.functionDeclaration);
748 check(element1, element2, 'name', element1.name, element2.name);
749 check(element1, element2, 'sourcePosition',
750 element1.sourcePosition, element2.sourcePosition);
751 checkTypes(
752 element1, element2, 'type',
753 element1.type, element2.type);
754 check(
755 element1, element2, 'isOptional',
756 element1.isOptional, element2.isOptional);
757 check(
758 element1, element2, 'isNamed',
759 element1.isNamed, element2.isNamed);
760 check(element1, element2, 'name', element1.name, element2.name);
761 if (element1.isOptional) {
762 checkConstants(
763 element1, element2, 'constant',
764 element1.constant, element2.constant);
765 }
766 checkElementIdentities(
767 element1, element2, 'compilationUnit',
768 element1.compilationUnit, element2.compilationUnit);
769 }
770
771 @override
772 void visitFieldParameterElement(InitializingFormalElement element1,
773 InitializingFormalElement element2) {
774 visitParameterElement(element1, element2);
775 checkElementIdentities(
776 element1, element2, 'fieldElement',
777 element1.fieldElement, element2.fieldElement);
778 }
779 }
780
781 /// Visitor that checks for equivalence of [DartType]s.
782 class TypeEquivalence implements DartTypeVisitor<dynamic, DartType> {
783 const TypeEquivalence();
784
785 void visit(DartType type1, DartType type2) {
786 check(type1, type2, 'kind', type1.kind, type2.kind);
787 type1.accept(this, type2);
788 }
789
790 @override
791 void visitDynamicType(DynamicType type, DynamicType other) {
792 }
793
794 @override
795 void visitFunctionType(FunctionType type, FunctionType other) {
796 checkTypeLists(
797 type, other, 'parameterTypes',
798 type.parameterTypes, other.parameterTypes);
799 checkTypeLists(
800 type, other, 'optionalParameterTypes',
801 type.optionalParameterTypes, other.optionalParameterTypes);
802 checkTypeLists(
803 type, other, 'namedParameterTypes',
804 type.namedParameterTypes, other.namedParameterTypes);
805 for (int i = 0; i < type.namedParameters.length; i++) {
806 if (type.namedParameters[i] != other.namedParameters[i]) {
807 throw "Named parameter '$type.namedParameters[i]' <> "
808 "'${other.namedParameters[i]}'";
809 }
810 }
811 }
812
813 void visitGenericType(GenericType type, GenericType other) {
814 checkElementIdentities(
815 type, other, 'element',
816 type.element, other.element);
817 checkTypeLists(
818 type, other, 'typeArguments',
819 type.typeArguments, other.typeArguments);
820 }
821
822 @override
823 void visitMalformedType(MalformedType type, MalformedType other) {
824 }
825
826 @override
827 void visitStatementType(StatementType type, StatementType other) {
828 throw new UnsupportedError("Unsupported type: $type");
829 }
830
831 @override
832 void visitTypeVariableType(TypeVariableType type, TypeVariableType other) {
833 checkElementIdentities(
834 type, other, 'element',
835 type.element, other.element);
836 }
837
838 @override
839 void visitVoidType(VoidType type, VoidType argument) {
840 }
841
842 @override
843 void visitInterfaceType(InterfaceType type, InterfaceType other) {
844 visitGenericType(type, other);
845 }
846
847 @override
848 void visitTypedefType(TypedefType type, TypedefType other) {
849 visitGenericType(type, other);
850 }
851 }
852
853 /// Visitor that checks for structural equivalence of [ConstantExpression]s.
854 class ConstantEquivalence
855 implements ConstantExpressionVisitor<dynamic, ConstantExpression> {
856 const ConstantEquivalence();
857
858 @override
859 visit(ConstantExpression exp1, ConstantExpression exp2) {
860 if (identical(exp1, exp2)) return;
861 check(exp1, exp2, 'kind', exp1.kind, exp2.kind);
862 exp1.accept(this, exp2);
863 }
864
865 @override
866 visitBinary(BinaryConstantExpression exp1, BinaryConstantExpression exp2) {
867 check(exp1, exp2, 'operator', exp1.operator, exp2.operator);
868 checkConstants(exp1, exp2, 'left', exp1.left, exp2.left);
869 checkConstants(exp1, exp2, 'right', exp1.right, exp2.right);
870 }
871
872 @override
873 visitConcatenate(ConcatenateConstantExpression exp1,
874 ConcatenateConstantExpression exp2) {
875 checkConstantLists(
876 exp1, exp2, 'expressions',
877 exp1.expressions, exp2.expressions);
878 }
879
880 @override
881 visitConditional(ConditionalConstantExpression exp1,
882 ConditionalConstantExpression exp2) {
883 checkConstants(
884 exp1, exp2, 'condition', exp1.condition, exp2.condition);
885 checkConstants(exp1, exp2, 'trueExp', exp1.trueExp, exp2.trueExp);
886 checkConstants(exp1, exp2, 'falseExp', exp1.falseExp, exp2.falseExp);
887 }
888
889 @override
890 visitConstructed(ConstructedConstantExpression exp1,
891 ConstructedConstantExpression exp2) {
892 checkTypes(
893 exp1, exp2, 'type',
894 exp1.type, exp2.type);
895 checkElementIdentities(
896 exp1, exp2, 'target',
897 exp1.target, exp2.target);
898 checkConstantLists(
899 exp1, exp2, 'arguments',
900 exp1.arguments, exp2.arguments);
901 check(exp1, exp2, 'callStructure', exp1.callStructure, exp2.callStructure);
902 }
903
904 @override
905 visitFunction(FunctionConstantExpression exp1,
906 FunctionConstantExpression exp2) {
907 checkElementIdentities(
908 exp1, exp2, 'element',
909 exp1.element, exp2.element);
910 }
911
912 @override
913 visitIdentical(IdenticalConstantExpression exp1,
914 IdenticalConstantExpression exp2) {
915 checkConstants(exp1, exp2, 'left', exp1.left, exp2.left);
916 checkConstants(exp1, exp2, 'right', exp1.right, exp2.right);
917 }
918
919 @override
920 visitList(ListConstantExpression exp1, ListConstantExpression exp2) {
921 checkTypes(
922 exp1, exp2, 'type',
923 exp1.type, exp2.type);
924 checkConstantLists(
925 exp1, exp2, 'values',
926 exp1.values, exp2.values);
927 }
928
929 @override
930 visitMap(MapConstantExpression exp1, MapConstantExpression exp2) {
931 checkTypes(
932 exp1, exp2, 'type',
933 exp1.type, exp2.type);
934 checkConstantLists(
935 exp1, exp2, 'keys',
936 exp1.keys, exp2.keys);
937 checkConstantLists(
938 exp1, exp2, 'values',
939 exp1.values, exp2.values);
940 }
941
942 @override
943 visitNamed(NamedArgumentReference exp1, NamedArgumentReference exp2) {
944 check(exp1, exp2, 'name', exp1.name, exp2.name);
945 }
946
947 @override
948 visitPositional(PositionalArgumentReference exp1,
949 PositionalArgumentReference exp2) {
950 check(exp1, exp2, 'index', exp1.index, exp2.index);
951 }
952
953 @override
954 visitSymbol(SymbolConstantExpression exp1, SymbolConstantExpression exp2) {
955 // TODO: implement visitSymbol
956 }
957
958 @override
959 visitType(TypeConstantExpression exp1, TypeConstantExpression exp2) {
960 checkTypes(
961 exp1, exp2, 'type',
962 exp1.type, exp2.type);
963 }
964
965 @override
966 visitUnary(UnaryConstantExpression exp1, UnaryConstantExpression exp2) {
967 check(exp1, exp2, 'operator', exp1.operator, exp2.operator);
968 checkConstants(
969 exp1, exp2, 'expression', exp1.expression, exp2.expression);
970 }
971
972 @override
973 visitVariable(VariableConstantExpression exp1,
974 VariableConstantExpression exp2) {
975 checkElementIdentities(
976 exp1, exp2, 'element',
977 exp1.element, exp2.element);
978 }
979
980 @override
981 visitBool(BoolConstantExpression exp1, BoolConstantExpression exp2) {
982 check(exp1, exp2, 'primitiveValue',
983 exp1.primitiveValue, exp2.primitiveValue);
984 }
985
986 @override
987 visitDouble(DoubleConstantExpression exp1, DoubleConstantExpression exp2) {
988 check(exp1, exp2, 'primitiveValue',
989 exp1.primitiveValue, exp2.primitiveValue);
990 }
991
992 @override
993 visitInt(IntConstantExpression exp1, IntConstantExpression exp2) {
994 check(exp1, exp2, 'primitiveValue',
995 exp1.primitiveValue, exp2.primitiveValue);
996 }
997
998 @override
999 visitNull(NullConstantExpression exp1, NullConstantExpression exp2) {
1000 // Do nothing.
1001 }
1002
1003 @override
1004 visitString(StringConstantExpression exp1, StringConstantExpression exp2) {
1005 check(exp1, exp2, 'primitiveValue',
1006 exp1.primitiveValue, exp2.primitiveValue);
1007 }
1008
1009 @override
1010 visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp1,
1011 BoolFromEnvironmentConstantExpression exp2) {
1012 checkConstants(exp1, exp2, 'name', exp1.name, exp2.name);
1013 checkConstants(
1014 exp1, exp2, 'defaultValue',
1015 exp1.defaultValue, exp2.defaultValue);
1016 }
1017
1018 @override
1019 visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp1,
1020 IntFromEnvironmentConstantExpression exp2) {
1021 checkConstants(exp1, exp2, 'name', exp1.name, exp2.name);
1022 checkConstants(
1023 exp1, exp2, 'defaultValue',
1024 exp1.defaultValue, exp2.defaultValue);
1025 }
1026
1027 @override
1028 visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp1,
1029 StringFromEnvironmentConstantExpression exp2) {
1030 checkConstants(exp1, exp2, 'name', exp1.name, exp2.name);
1031 checkConstants(
1032 exp1, exp2, 'defaultValue',
1033 exp1.defaultValue, exp2.defaultValue);
1034 }
1035
1036 @override
1037 visitStringLength(StringLengthConstantExpression exp1,
1038 StringLengthConstantExpression exp2) {
1039 checkConstants(
1040 exp1, exp2, 'expression',
1041 exp1.expression, exp2.expression);
1042 }
1043
1044 @override
1045 visitDeferred(DeferredConstantExpression exp1,
1046 DeferredConstantExpression exp2) {
1047 // TODO: implement visitDeferred
1048 }
1049 }
OLDNEW
« no previous file with comments | « tests/compiler/dart2js/serialization_analysis_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698