OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 /// Equivalence test functions for data objects. | 5 /// Equivalence test functions for data objects. |
6 | 6 |
7 library dart2js.equivalence.functions; | 7 library dart2js.equivalence.functions; |
8 | 8 |
9 import 'package:expect/expect.dart'; | 9 import 'package:expect/expect.dart'; |
10 import 'package:compiler/src/common/resolution.dart'; | 10 import 'package:compiler/src/common/resolution.dart'; |
(...skipping 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
796 checkMaps( | 796 checkMaps( |
797 worldBuilder1.instanceMemberUsageForTesting, | 797 worldBuilder1.instanceMemberUsageForTesting, |
798 worldBuilder2.instanceMemberUsageForTesting, | 798 worldBuilder2.instanceMemberUsageForTesting, |
799 'instanceMemberUsageForTesting', | 799 'instanceMemberUsageForTesting', |
800 elementEquivalence, | 800 elementEquivalence, |
801 areAbstractUsagesEquivalent, | 801 areAbstractUsagesEquivalent, |
802 verbose: verbose); | 802 verbose: verbose); |
803 } | 803 } |
804 | 804 |
805 // TODO(johnniwinther): Check all emitter properties. | 805 // TODO(johnniwinther): Check all emitter properties. |
806 void checkEmitters(CodeEmitterTask emitter1, CodeEmitterTask emitter2, | 806 void checkEmitters( |
| 807 CodeEmitterTask emitter1, CodeEmitterTask emitter2, TestStrategy strategy, |
807 {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent, | 808 {bool elementEquivalence(Entity a, Entity b): _areEntitiesEquivalent, |
808 bool typeEquivalence(DartType a, DartType b): areTypesEquivalent, | 809 bool typeEquivalence(DartType a, DartType b): areTypesEquivalent, |
809 bool elementFilter(Element element), | 810 bool elementFilter(Element element), |
810 bool verbose: false}) { | 811 bool verbose: false}) { |
811 checkEmitterPrograms( | 812 checkEmitterPrograms(emitter1.emitter.programForTesting, |
812 emitter1.emitter.programForTesting, emitter2.emitter.programForTesting); | 813 emitter2.emitter.programForTesting, strategy); |
813 | 814 |
814 checkSets( | 815 checkSets( |
815 emitter1.typeTestRegistry.rtiNeededClasses, | 816 emitter1.typeTestRegistry.rtiNeededClasses, |
816 emitter2.typeTestRegistry.rtiNeededClasses, | 817 emitter2.typeTestRegistry.rtiNeededClasses, |
817 "TypeTestRegistry rti needed classes mismatch", | 818 "TypeTestRegistry rti needed classes mismatch", |
818 elementEquivalence, | 819 strategy.elementEquivalence, |
819 verbose: verbose); | 820 verbose: verbose); |
820 | 821 |
821 checkSets( | 822 checkSets( |
822 emitter1.typeTestRegistry.checkedFunctionTypes, | 823 emitter1.typeTestRegistry.checkedFunctionTypes, |
823 emitter2.typeTestRegistry.checkedFunctionTypes, | 824 emitter2.typeTestRegistry.checkedFunctionTypes, |
824 "TypeTestRegistry checked function types mismatch", | 825 "TypeTestRegistry checked function types mismatch", |
825 typeEquivalence, | 826 strategy.typeEquivalence, |
826 verbose: verbose); | 827 verbose: verbose); |
827 | 828 |
828 checkSets( | 829 checkSets( |
829 emitter1.typeTestRegistry.checkedClasses, | 830 emitter1.typeTestRegistry.checkedClasses, |
830 emitter2.typeTestRegistry.checkedClasses, | 831 emitter2.typeTestRegistry.checkedClasses, |
831 "TypeTestRegistry checked classes mismatch", | 832 "TypeTestRegistry checked classes mismatch", |
832 elementEquivalence, | 833 strategy.elementEquivalence, |
833 verbose: verbose); | 834 verbose: verbose); |
834 } | 835 } |
835 | 836 |
836 void checkEmitterPrograms(Program program1, Program program2) { | 837 void checkEmitterPrograms( |
| 838 Program program1, Program program2, TestStrategy strategy) { |
837 checkLists(program1.fragments, program2.fragments, 'fragments', | 839 checkLists(program1.fragments, program2.fragments, 'fragments', |
838 (a, b) => a.outputFileName == b.outputFileName, | 840 (a, b) => a.outputFileName == b.outputFileName, |
839 onSameElement: checkEmitterFragments); | 841 onSameElement: (a, b) => checkEmitterFragments(a, b, strategy)); |
840 checkLists( | 842 checkLists( |
841 program1.holders, program2.holders, 'holders', (a, b) => a.name == b.name, | 843 program1.holders, program2.holders, 'holders', (a, b) => a.name == b.name, |
842 onSameElement: checkEmitterHolders); | 844 onSameElement: checkEmitterHolders); |
843 check(program1, program2, 'outputContainsConstantList', | 845 check(program1, program2, 'outputContainsConstantList', |
844 program1.outputContainsConstantList, program2.outputContainsConstantList); | 846 program1.outputContainsConstantList, program2.outputContainsConstantList); |
845 check(program1, program2, 'needsNativeSupport', program1.needsNativeSupport, | 847 check(program1, program2, 'needsNativeSupport', program1.needsNativeSupport, |
846 program2.needsNativeSupport); | 848 program2.needsNativeSupport); |
847 check(program1, program2, 'hasIsolateSupport', program1.hasIsolateSupport, | 849 check(program1, program2, 'hasIsolateSupport', program1.hasIsolateSupport, |
848 program2.hasIsolateSupport); | 850 program2.hasIsolateSupport); |
849 check(program1, program2, 'hasSoftDeferredClasses', | 851 check(program1, program2, 'hasSoftDeferredClasses', |
(...skipping 12 matching lines...) Expand all Loading... |
862 program1, | 864 program1, |
863 program2, | 865 program2, |
864 'typeToInterceptorMap', | 866 'typeToInterceptorMap', |
865 program1.typeToInterceptorMap, | 867 program1.typeToInterceptorMap, |
866 program2.typeToInterceptorMap, | 868 program2.typeToInterceptorMap, |
867 areJsNodesEquivalent); | 869 areJsNodesEquivalent); |
868 check(program1, program2, 'metadata', program1.metadata, program2.metadata, | 870 check(program1, program2, 'metadata', program1.metadata, program2.metadata, |
869 areJsNodesEquivalent); | 871 areJsNodesEquivalent); |
870 } | 872 } |
871 | 873 |
872 void checkEmitterFragments(Fragment fragment1, Fragment fragment2) { | 874 void checkEmitterFragments( |
| 875 Fragment fragment1, Fragment fragment2, TestStrategy strategy) { |
873 // TODO(johnniwinther): Check outputUnit. | 876 // TODO(johnniwinther): Check outputUnit. |
874 checkLists(fragment1.libraries, fragment2.libraries, 'libraries', | 877 checkLists(fragment1.libraries, fragment2.libraries, 'libraries', |
875 (a, b) => a.element.canonicalUri == b.element.canonicalUri, | 878 (a, b) => a.element.canonicalUri == b.element.canonicalUri, |
876 onSameElement: checkEmitterLibraries); | 879 onSameElement: (a, b) => checkEmitterLibraries(a, b, strategy)); |
877 checkLists(fragment1.constants, fragment2.constants, 'constants', | 880 checkLists(fragment1.constants, fragment2.constants, 'constants', |
878 (a, b) => a.name.key == b.name.key, | 881 (a, b) => a.name.key == b.name.key, |
879 onSameElement: checkEmitterConstants); | 882 onSameElement: (a, b) => checkEmitterConstants(a, b, strategy)); |
880 checkLists(fragment1.staticNonFinalFields, fragment2.staticNonFinalFields, | 883 checkLists(fragment1.staticNonFinalFields, fragment2.staticNonFinalFields, |
881 'staticNonFinalFields', (a, b) => a.name.key == b.name.key, | 884 'staticNonFinalFields', (a, b) => a.name.key == b.name.key, |
882 onSameElement: checkEmitterStaticFields); | 885 onSameElement: checkEmitterStaticFields); |
883 checkLists( | 886 checkLists( |
884 fragment1.staticLazilyInitializedFields, | 887 fragment1.staticLazilyInitializedFields, |
885 fragment2.staticLazilyInitializedFields, | 888 fragment2.staticLazilyInitializedFields, |
886 'staticLazilyInitializedFields', | 889 'staticLazilyInitializedFields', |
887 (a, b) => a.name.key == b.name.key, | 890 (a, b) => a.name.key == b.name.key, |
888 onSameElement: checkEmitterStaticFields); | 891 onSameElement: checkEmitterStaticFields); |
889 check(fragment1, fragment2, 'isMainFragment', fragment1.isMainFragment, | 892 check(fragment1, fragment2, 'isMainFragment', fragment1.isMainFragment, |
890 fragment2.isMainFragment); | 893 fragment2.isMainFragment); |
891 if (fragment1 is MainFragment && fragment2 is MainFragment) { | 894 if (fragment1 is MainFragment && fragment2 is MainFragment) { |
892 check(fragment1, fragment2, 'invokeMain', fragment1.invokeMain, | 895 check(fragment1, fragment2, 'invokeMain', fragment1.invokeMain, |
893 fragment2.invokeMain, areJsNodesEquivalent); | 896 fragment2.invokeMain, areJsNodesEquivalent); |
894 } | 897 } |
895 } | 898 } |
896 | 899 |
897 void checkEmitterLibraries(Library library1, Library library2) { | 900 void checkEmitterLibraries( |
| 901 Library library1, Library library2, TestStrategy strategy) { |
898 check(library1, library2, 'uri', library1.uri, library2.uri); | 902 check(library1, library2, 'uri', library1.uri, library2.uri); |
899 checkLists(library1.classes, library2.classes, 'classes', | 903 checkLists(library1.classes, library2.classes, 'classes', |
900 (a, b) => a.element.name == b.element.name, | 904 (a, b) => a.element.name == b.element.name, |
901 onSameElement: checkEmitterClasses); | 905 onSameElement: (a, b) => checkEmitterClasses(a, b, strategy)); |
902 checkLists(library1.statics, library2.statics, 'statics', | 906 checkLists(library1.statics, library2.statics, 'statics', |
903 (a, b) => a.name.key == b.name.key, | 907 (a, b) => a.name.key == b.name.key, |
904 onSameElement: checkEmitterMethods); | 908 onSameElement: (a, b) => checkEmitterMethods(a, b, strategy)); |
905 checkLists( | 909 checkLists( |
906 library1.staticFieldsForReflection, | 910 library1.staticFieldsForReflection, |
907 library2.staticFieldsForReflection, | 911 library2.staticFieldsForReflection, |
908 'staticFieldsForReflection', | 912 'staticFieldsForReflection', |
909 (a, b) => a.name.key == b.name.key, | 913 (a, b) => a.name.key == b.name.key, |
910 onSameElement: checkEmitterFields); | 914 onSameElement: checkEmitterFields); |
911 } | 915 } |
912 | 916 |
913 void checkEmitterClasses(Class class1, Class class2) { | 917 void checkEmitterClasses(Class class1, Class class2, TestStrategy strategy) { |
914 checkLists(class1.methods, class2.methods, 'methods', | 918 checkLists(class1.methods, class2.methods, 'methods', |
915 (a, b) => a.name.key == b.name.key, | 919 (a, b) => a.name.key == b.name.key, |
916 onSameElement: checkEmitterMethods); | 920 onSameElement: (a, b) => checkEmitterMethods(a, b, strategy)); |
917 checkLists(class1.fields, class2.fields, 'fields', | 921 checkLists(class1.fields, class2.fields, 'fields', |
918 (a, b) => a.name.key == b.name.key, | 922 (a, b) => a.name.key == b.name.key, |
919 onSameElement: checkEmitterFields); | 923 onSameElement: checkEmitterFields); |
920 checkLists(class1.isChecks, class2.isChecks, 'isChecks', | 924 checkLists(class1.isChecks, class2.isChecks, 'isChecks', |
921 (a, b) => a.name.key == b.name.key, | 925 (a, b) => a.name.key == b.name.key, |
922 onSameElement: checkEmitterMethods); | 926 onSameElement: (a, b) => checkEmitterMethods(a, b, strategy)); |
923 checkLists(class1.checkedSetters, class2.checkedSetters, 'checkedSetters', | 927 checkLists(class1.checkedSetters, class2.checkedSetters, 'checkedSetters', |
924 (a, b) => a.name.key == b.name.key, | 928 (a, b) => a.name.key == b.name.key, |
925 onSameElement: checkEmitterMethods); | 929 onSameElement: (a, b) => checkEmitterMethods(a, b, strategy)); |
926 checkLists(class1.callStubs, class2.callStubs, 'callStubs', | 930 checkLists(class1.callStubs, class2.callStubs, 'callStubs', |
927 (a, b) => a.name.key == b.name.key, | 931 (a, b) => a.name.key == b.name.key, |
928 onSameElement: checkEmitterMethods); | 932 onSameElement: (a, b) => checkEmitterMethods(a, b, strategy)); |
929 checkLists(class1.noSuchMethodStubs, class2.noSuchMethodStubs, | 933 checkLists(class1.noSuchMethodStubs, class2.noSuchMethodStubs, |
930 'noSuchMethodStubs', (a, b) => a.name.key == b.name.key, | 934 'noSuchMethodStubs', (a, b) => a.name.key == b.name.key, |
931 onSameElement: checkEmitterMethods); | 935 onSameElement: (a, b) => checkEmitterMethods(a, b, strategy)); |
932 checkLists(class1.staticFieldsForReflection, class2.staticFieldsForReflection, | 936 checkLists(class1.staticFieldsForReflection, class2.staticFieldsForReflection, |
933 'staticFieldsForReflection', (a, b) => a.name.key == b.name.key, | 937 'staticFieldsForReflection', (a, b) => a.name.key == b.name.key, |
934 onSameElement: checkEmitterFields); | 938 onSameElement: checkEmitterFields); |
935 | 939 |
936 check(class1, class2, 'superclassName', class1.superclassName?.key, | 940 check(class1, class2, 'superclassName', class1.superclassName?.key, |
937 class2.superclassName?.key); | 941 class2.superclassName?.key); |
938 check(class1, class2, 'isMixinApplication', class1.isMixinApplication, | 942 check(class1, class2, 'isMixinApplication', class1.isMixinApplication, |
939 class2.isMixinApplication); | 943 class2.isMixinApplication); |
940 check(class1, class2, 'hasRtiField', class1.hasRtiField, class2.hasRtiField); | 944 check(class1, class2, 'hasRtiField', class1.hasRtiField, class2.hasRtiField); |
941 check(class1, class2, 'onlyForRti', class1.onlyForRti, class2.onlyForRti); | 945 check(class1, class2, 'onlyForRti', class1.onlyForRti, class2.onlyForRti); |
942 check(class1, class2, 'isDirectlyInstantiated', class1.isDirectlyInstantiated, | 946 check(class1, class2, 'isDirectlyInstantiated', class1.isDirectlyInstantiated, |
943 class2.isDirectlyInstantiated); | 947 class2.isDirectlyInstantiated); |
944 check(class1, class2, 'isNative', class1.isNative, class2.isNative); | 948 check(class1, class2, 'isNative', class1.isNative, class2.isNative); |
945 check(class1, class2, 'isClosureBaseClass', class1.isClosureBaseClass, | 949 check(class1, class2, 'isClosureBaseClass', class1.isClosureBaseClass, |
946 class2.isClosureBaseClass); | 950 class2.isClosureBaseClass); |
947 check(class1, class2, 'isSoftDeferred', class1.isSoftDeferred, | 951 check(class1, class2, 'isSoftDeferred', class1.isSoftDeferred, |
948 class2.isSoftDeferred); | 952 class2.isSoftDeferred); |
949 check(class1, class2, 'isEager', class1.isEager, class2.isEager); | 953 check(class1, class2, 'isEager', class1.isEager, class2.isEager); |
950 checkEmitterHolders(class1.holder, class2.holder); | 954 checkEmitterHolders(class1.holder, class2.holder); |
951 } | 955 } |
952 | 956 |
953 void checkEmitterMethods(Method method1, Method method2) { | 957 void checkEmitterMethods( |
| 958 Method method1, Method method2, TestStrategy strategy) { |
954 check(method1, method2, 'code', method1.code, method2.code, | 959 check(method1, method2, 'code', method1.code, method2.code, |
955 areJsNodesEquivalent); | 960 areJsNodesEquivalent); |
956 check(method1, method2, 'is ParameterStubMethod', | 961 check(method1, method2, 'is ParameterStubMethod', |
957 method1 is ParameterStubMethod, method2 is ParameterStubMethod); | 962 method1 is ParameterStubMethod, method2 is ParameterStubMethod); |
958 if (method1 is ParameterStubMethod && method2 is ParameterStubMethod) { | 963 if (method1 is ParameterStubMethod && method2 is ParameterStubMethod) { |
959 check(method1, method2, 'callName', method1.callName?.key, | 964 check(method1, method2, 'callName', method1.callName?.key, |
960 method2.callName?.key); | 965 method2.callName?.key); |
961 } | 966 } |
962 check(method1, method2, 'is DartMethod', method1 is DartMethod, | 967 check(method1, method2, 'is DartMethod', method1 is DartMethod, |
963 method2 is DartMethod); | 968 method2 is DartMethod); |
964 if (method1 is DartMethod && method2 is DartMethod) { | 969 if (method1 is DartMethod && method2 is DartMethod) { |
965 check(method1, method2, 'callName', method1.callName?.key, | 970 check(method1, method2, 'callName', method1.callName?.key, |
966 method2.callName?.key); | 971 method2.callName?.key); |
967 check(method1, method2, 'needsTearOff', method1.needsTearOff, | 972 check(method1, method2, 'needsTearOff', method1.needsTearOff, |
968 method2.needsTearOff); | 973 method2.needsTearOff); |
969 // TODO(johnniwinther): Fix teadOffName mismatch. | 974 check(method1, method2, 'tearOffName', method1.tearOffName?.key, |
970 //check(method1, method2, 'tearOffName', | 975 method2.tearOffName?.key); |
971 // method1.tearOffName?.key, method2.tearOffName?.key); | |
972 checkLists(method1.parameterStubs, method2.parameterStubs, 'parameterStubs', | 976 checkLists(method1.parameterStubs, method2.parameterStubs, 'parameterStubs', |
973 (a, b) => a.name.key == b.name.key, | 977 (a, b) => a.name.key == b.name.key, |
974 onSameElement: checkEmitterMethods); | 978 onSameElement: (a, b) => checkEmitterMethods(a, b, strategy)); |
975 check(method1, method2, 'canBeApplied', method1.canBeApplied, | 979 check(method1, method2, 'canBeApplied', method1.canBeApplied, |
976 method2.canBeApplied); | 980 method2.canBeApplied); |
977 check(method1, method2, 'canBeReflected', method1.canBeReflected, | 981 check(method1, method2, 'canBeReflected', method1.canBeReflected, |
978 method2.canBeReflected); | 982 method2.canBeReflected); |
979 check(method1, method2, 'functionType', method1.functionType, | 983 check(method1, method2, 'functionType', method1.functionType, |
980 method2.functionType, areJsNodesEquivalent); | 984 method2.functionType, areJsNodesEquivalent); |
981 check(method1, method2, 'requiredParameterCount', | 985 check(method1, method2, 'requiredParameterCount', |
982 method1.requiredParameterCount, method2.requiredParameterCount); | 986 method1.requiredParameterCount, method2.requiredParameterCount); |
983 // TODO(johnniwinther): Check optionalParameterDefaultValues. | 987 if (method1.optionalParameterDefaultValues == null && |
| 988 method2.optionalParameterDefaultValues == null) { |
| 989 // Nothing to test. |
| 990 } else if (method1.optionalParameterDefaultValues is List && |
| 991 method2.optionalParameterDefaultValues is List) { |
| 992 checkLists( |
| 993 method1.optionalParameterDefaultValues, |
| 994 method2.optionalParameterDefaultValues, |
| 995 'optionalParameterDefaultValues', |
| 996 strategy.constantValueEquivalence); |
| 997 } else if (method1.optionalParameterDefaultValues is Map && |
| 998 method2.optionalParameterDefaultValues is Map) { |
| 999 checkMaps( |
| 1000 method1.optionalParameterDefaultValues, |
| 1001 method2.optionalParameterDefaultValues, |
| 1002 'optionalParameterDefaultValues', |
| 1003 equality, |
| 1004 strategy.constantValueEquivalence); |
| 1005 } else { |
| 1006 check( |
| 1007 method1, |
| 1008 method2, |
| 1009 'optionalParameterDefaultValues', |
| 1010 method1.optionalParameterDefaultValues, |
| 1011 method2.optionalParameterDefaultValues); |
| 1012 } |
984 } | 1013 } |
985 } | 1014 } |
986 | 1015 |
987 void checkEmitterFields(Field field1, Field field2) { | 1016 void checkEmitterFields(Field field1, Field field2) { |
988 check(field1, field2, 'accessorName', field1.accessorName?.key, | 1017 check(field1, field2, 'accessorName', field1.accessorName?.key, |
989 field2.accessorName?.key); | 1018 field2.accessorName?.key); |
990 check(field1, field2, 'getterFlags', field1.getterFlags, field2.getterFlags); | 1019 check(field1, field2, 'getterFlags', field1.getterFlags, field2.getterFlags); |
991 check(field1, field2, 'setterFlags', field1.setterFlags, field2.setterFlags); | 1020 check(field1, field2, 'setterFlags', field1.setterFlags, field2.setterFlags); |
992 check(field1, field2, 'needsCheckedSetter', field1.needsCheckedSetter, | 1021 check(field1, field2, 'needsCheckedSetter', field1.needsCheckedSetter, |
993 field2.needsCheckedSetter); | 1022 field2.needsCheckedSetter); |
994 } | 1023 } |
995 | 1024 |
996 void checkEmitterConstants(Constant constant1, Constant constant2) { | 1025 void checkEmitterConstants( |
997 // TODO(johnniwinther): Check value. | 1026 Constant constant1, Constant constant2, TestStrategy strategy) { |
998 checkEmitterHolders(constant1.holder, constant2.holder); | 1027 checkEmitterHolders(constant1.holder, constant2.holder); |
| 1028 check(constant1, constant2, 'value', constant1.value, constant2.value, |
| 1029 strategy.constantValueEquivalence); |
999 } | 1030 } |
1000 | 1031 |
1001 void checkEmitterStaticFields(StaticField field1, StaticField field2) { | 1032 void checkEmitterStaticFields(StaticField field1, StaticField field2) { |
1002 check(field1, field2, 'code', field1.code, field2.code, areJsNodesEquivalent); | 1033 check(field1, field2, 'code', field1.code, field2.code, areJsNodesEquivalent); |
1003 check(field1, field2, 'isFinal', field1.isFinal, field2.isFinal); | 1034 check(field1, field2, 'isFinal', field1.isFinal, field2.isFinal); |
1004 check(field1, field2, 'isLazy', field1.isLazy, field2.isLazy); | 1035 check(field1, field2, 'isLazy', field1.isLazy, field2.isLazy); |
1005 checkEmitterHolders(field1.holder, field2.holder); | 1036 checkEmitterHolders(field1.holder, field2.holder); |
1006 } | 1037 } |
1007 | 1038 |
1008 void checkEmitterHolders(Holder holder1, Holder holder2) { | 1039 void checkEmitterHolders(Holder holder1, Holder holder2) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1063 print(' ${js.nodeToString(node1)}'); | 1094 print(' ${js.nodeToString(node1)}'); |
1064 print(' ${js.nodeToString(node2)}'); | 1095 print(' ${js.nodeToString(node2)}'); |
1065 } | 1096 } |
1066 return expectedValue == label2; | 1097 return expectedValue == label2; |
1067 } else { | 1098 } else { |
1068 labelsMap[label1] = label2; | 1099 labelsMap[label1] = label2; |
1069 return true; | 1100 return true; |
1070 } | 1101 } |
1071 } | 1102 } |
1072 } | 1103 } |
OLD | NEW |