| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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_test_helper; | 5 library dart2js.serialization_test_helper; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import 'package:compiler/src/common/resolution.dart'; | 8 import 'package:compiler/src/common/resolution.dart'; |
| 9 import 'package:compiler/src/constants/expressions.dart'; | 9 import 'package:compiler/src/constants/expressions.dart'; |
| 10 import 'package:compiler/src/constants/values.dart'; | 10 import 'package:compiler/src/constants/values.dart'; |
| 11 import 'package:compiler/src/compiler.dart'; |
| 12 import 'package:compiler/src/elements/elements.dart'; |
| 11 import 'package:compiler/src/elements/entities.dart'; | 13 import 'package:compiler/src/elements/entities.dart'; |
| 12 import 'package:compiler/src/elements/resolution_types.dart'; | 14 import 'package:compiler/src/elements/resolution_types.dart'; |
| 13 import 'package:compiler/src/elements/types.dart'; | 15 import 'package:compiler/src/elements/types.dart'; |
| 14 import 'package:compiler/src/compiler.dart'; | 16 import 'package:compiler/src/kernel/elements.dart'; |
| 15 import 'package:compiler/src/elements/elements.dart'; | 17 import 'package:compiler/src/kernel/world_builder.dart'; |
| 16 import 'package:compiler/src/serialization/equivalence.dart'; | 18 import 'package:compiler/src/serialization/equivalence.dart'; |
| 17 import 'package:compiler/src/tree/nodes.dart'; | |
| 18 import 'package:expect/expect.dart'; | 19 import 'package:expect/expect.dart'; |
| 19 import 'test_data.dart'; | 20 import 'test_data.dart'; |
| 20 | 21 |
| 21 Check currentCheck; | 22 Check currentCheck; |
| 22 | 23 |
| 23 class Check { | 24 class Check { |
| 24 final Check parent; | 25 final Check parent; |
| 25 final Object object1; | 26 final Object object1; |
| 26 final Object object2; | 27 final Object object2; |
| 27 final String property; | 28 final String property; |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 print('Checking impacts for $member1 vs $member2'); | 428 print('Checking impacts for $member1 vs $member2'); |
| 428 } | 429 } |
| 429 | 430 |
| 430 if (impact1 == null) { | 431 if (impact1 == null) { |
| 431 throw 'Missing impact for $member1. $member2 has $impact2'; | 432 throw 'Missing impact for $member1. $member2 has $impact2'; |
| 432 } | 433 } |
| 433 if (impact2 == null) { | 434 if (impact2 == null) { |
| 434 throw 'Missing impact for $member2. $member1 has $impact1'; | 435 throw 'Missing impact for $member2. $member1 has $impact1'; |
| 435 } | 436 } |
| 436 | 437 |
| 437 testResolutionImpactEquivalence(impact1, impact2, const CheckStrategy()); | 438 testResolutionImpactEquivalence(impact1, impact2, |
| 439 strategy: const CheckStrategy()); |
| 438 } | 440 } |
| 439 | 441 |
| 440 void checkSets( | 442 void checkSets( |
| 441 Iterable set1, Iterable set2, String messagePrefix, bool sameElement(a, b), | 443 Iterable set1, Iterable set2, String messagePrefix, bool sameElement(a, b), |
| 442 {bool failOnUnfound: true, | 444 {bool failOnUnfound: true, |
| 443 bool failOnExtra: true, | 445 bool failOnExtra: true, |
| 444 bool verbose: false, | 446 bool verbose: false, |
| 445 void onSameElement(a, b), | 447 void onSameElement(a, b), |
| 446 void onUnfoundElement(a), | 448 void onUnfoundElement(a), |
| 447 void onExtraElement(b), | 449 void onExtraElement(b), |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 } | 625 } |
| 624 | 626 |
| 625 if (index == 1 && skip != 0) { | 627 if (index == 1 && skip != 0) { |
| 626 return ['${skip}', segmentNumber(index)]; | 628 return ['${skip}', segmentNumber(index)]; |
| 627 } else if (index == count) { | 629 } else if (index == count) { |
| 628 return [segmentNumber(index - 1)]; | 630 return [segmentNumber(index - 1)]; |
| 629 } else { | 631 } else { |
| 630 return [segmentNumber(index - 1), segmentNumber(index)]; | 632 return [segmentNumber(index - 1), segmentNumber(index)]; |
| 631 } | 633 } |
| 632 } | 634 } |
| 635 |
| 636 class KernelEquivalence { |
| 637 final WorldDeconstructionForTesting testing; |
| 638 |
| 639 KernelEquivalence(KernelWorldBuilder builder) |
| 640 : testing = new WorldDeconstructionForTesting(builder); |
| 641 |
| 642 TestStrategy get defaultStrategy => new TestStrategy( |
| 643 elementEquivalence: entityEquivalence, typeEquivalence: typeEquivalence); |
| 644 |
| 645 bool entityEquivalence(Element a, Entity b, {TestStrategy strategy}) { |
| 646 if (identical(a, b)) return true; |
| 647 if (a == null || b == null) return false; |
| 648 strategy ??= defaultStrategy; |
| 649 switch (a.kind) { |
| 650 case ElementKind.GENERATIVE_CONSTRUCTOR: |
| 651 if (b is KGenerativeConstructor) { |
| 652 return strategy.test(a, b, 'name', a.name, b.name) && |
| 653 strategy.testElements( |
| 654 a, b, 'enclosingClass', a.enclosingClass, b.enclosingClass); |
| 655 } |
| 656 return false; |
| 657 case ElementKind.FACTORY_CONSTRUCTOR: |
| 658 if (b is KFactoryConstructor) { |
| 659 return strategy.test(a, b, 'name', a.name, b.name) && |
| 660 strategy.testElements( |
| 661 a, b, 'enclosingClass', a.enclosingClass, b.enclosingClass); |
| 662 } |
| 663 return false; |
| 664 case ElementKind.CLASS: |
| 665 if (b is KClass) { |
| 666 return strategy.test(a, b, 'name', a.name, b.name) && |
| 667 strategy.testElements( |
| 668 a, b, 'library', a.library, testing.getLibraryForClass(b)); |
| 669 } |
| 670 return false; |
| 671 case ElementKind.LIBRARY: |
| 672 if (b is KLibrary) { |
| 673 LibraryElement libraryA = a; |
| 674 return libraryA.canonicalUri == testing.getLibraryUri(b); |
| 675 } |
| 676 return false; |
| 677 case ElementKind.FUNCTION: |
| 678 if (b is KMethod) { |
| 679 if (!strategy.test(a, b, 'name', a.name, b.name)) return false; |
| 680 if (b.enclosingClass != null) { |
| 681 return strategy.testElements( |
| 682 a, b, 'enclosingClass', a.enclosingClass, b.enclosingClass); |
| 683 } else { |
| 684 return strategy.testElements( |
| 685 a, b, 'library', a.library, testing.getLibraryForFunction(b)); |
| 686 } |
| 687 } else if (b is KLocalFunction) { |
| 688 LocalFunctionElement aLocalFunction = a; |
| 689 return strategy.test(a, b, 'name', a.name, b.name ?? '') && |
| 690 strategy.testElements(a, b, 'executableContext', |
| 691 aLocalFunction.executableContext, b.executableContext) && |
| 692 strategy.testElements(a, b, 'memberContext', |
| 693 aLocalFunction.memberContext, b.memberContext); |
| 694 } |
| 695 return false; |
| 696 case ElementKind.GETTER: |
| 697 if (b is KGetter) { |
| 698 if (!strategy.test(a, b, 'name', a.name, b.name)) return false; |
| 699 if (b.enclosingClass != null) { |
| 700 return strategy.testElements( |
| 701 a, b, 'enclosingClass', a.enclosingClass, b.enclosingClass); |
| 702 } else { |
| 703 return strategy.testElements( |
| 704 a, b, 'library', a.library, testing.getLibraryForFunction(b)); |
| 705 } |
| 706 } |
| 707 return false; |
| 708 case ElementKind.SETTER: |
| 709 if (b is KSetter) { |
| 710 if (!strategy.test(a, b, 'name', a.name, b.name)) return false; |
| 711 if (b.enclosingClass != null) { |
| 712 return strategy.testElements( |
| 713 a, b, 'enclosingClass', a.enclosingClass, b.enclosingClass); |
| 714 } else { |
| 715 return strategy.testElements( |
| 716 a, b, 'library', a.library, testing.getLibraryForFunction(b)); |
| 717 } |
| 718 } |
| 719 return false; |
| 720 case ElementKind.FIELD: |
| 721 if (b is KField) { |
| 722 if (!strategy.test(a, b, 'name', a.name, b.name)) return false; |
| 723 if (b.enclosingClass != null) { |
| 724 return strategy.testElements( |
| 725 a, b, 'enclosingClass', a.enclosingClass, b.enclosingClass); |
| 726 } else { |
| 727 return strategy.testElements( |
| 728 a, b, 'library', a.library, testing.getLibraryForField(b)); |
| 729 } |
| 730 } |
| 731 return false; |
| 732 case ElementKind.TYPE_VARIABLE: |
| 733 if (b is KTypeVariable) { |
| 734 TypeVariableElement aElement = a; |
| 735 return strategy.test(a, b, 'index', aElement.index, b.index) && |
| 736 strategy.testElements(a, b, 'typeDeclaration', |
| 737 aElement.typeDeclaration, b.typeDeclaration); |
| 738 } |
| 739 return false; |
| 740 default: |
| 741 throw new UnsupportedError('Unsupported equivalence: ' |
| 742 '$a (${a.runtimeType}) vs $b (${b.runtimeType})'); |
| 743 } |
| 744 } |
| 745 |
| 746 bool typeEquivalence(ResolutionDartType a, DartType b, |
| 747 {TestStrategy strategy}) { |
| 748 if (identical(a, b)) return true; |
| 749 if (a == null || b == null) return false; |
| 750 strategy ??= defaultStrategy; |
| 751 switch (a.kind) { |
| 752 case ResolutionTypeKind.DYNAMIC: |
| 753 return b is DynamicType; |
| 754 case ResolutionTypeKind.VOID: |
| 755 return b is VoidType; |
| 756 case ResolutionTypeKind.INTERFACE: |
| 757 if (b is InterfaceType) { |
| 758 ResolutionInterfaceType aType = a; |
| 759 return strategy.testElements(a, b, 'element', a.element, b.element) && |
| 760 strategy.testTypeLists( |
| 761 a, b, 'typeArguments', aType.typeArguments, b.typeArguments); |
| 762 } |
| 763 return false; |
| 764 case ResolutionTypeKind.TYPE_VARIABLE: |
| 765 if (b is TypeVariableType) { |
| 766 return strategy.testElements(a, b, 'element', a.element, b.element); |
| 767 } |
| 768 return false; |
| 769 case ResolutionTypeKind.FUNCTION: |
| 770 if (b is FunctionType) { |
| 771 ResolutionFunctionType aType = a; |
| 772 return strategy.testTypes( |
| 773 a, b, 'returnType', aType.returnType, b.returnType) && |
| 774 strategy.testTypeLists(a, b, 'parameterTypes', |
| 775 aType.parameterTypes, b.parameterTypes) && |
| 776 strategy.testTypeLists(a, b, 'optionalParameterTypes', |
| 777 aType.optionalParameterTypes, b.optionalParameterTypes) && |
| 778 strategy.testLists(a, b, 'namedParameters', aType.namedParameters, |
| 779 b.namedParameters) && |
| 780 strategy.testTypeLists(a, b, 'namedParameterTypes', |
| 781 aType.namedParameterTypes, b.namedParameterTypes); |
| 782 } |
| 783 return false; |
| 784 default: |
| 785 throw new UnsupportedError('Unsupported equivalence: ' |
| 786 '$a (${a.runtimeType}) vs $b (${b.runtimeType})'); |
| 787 } |
| 788 } |
| 789 } |
| OLD | NEW |