Chromium Code Reviews| 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 import 'package:kernel/ast.dart'; | 5 import 'package:kernel/ast.dart'; |
| 6 import 'package:kernel/class_hierarchy.dart'; | 6 import 'package:kernel/class_hierarchy.dart'; |
| 7 import 'package:kernel/core_types.dart'; | 7 import 'package:kernel/core_types.dart'; |
| 8 import 'package:kernel/src/incremental_class_hierarchy.dart'; | 8 import 'package:kernel/src/incremental_class_hierarchy.dart'; |
| 9 import 'package:kernel/testing/mock_sdk_program.dart'; | 9 import 'package:kernel/testing/mock_sdk_program.dart'; |
| 10 import 'package:kernel/text/ast_to_text.dart'; | 10 import 'package:kernel/text/ast_to_text.dart'; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 Class addImplementsClass(String name, List<Class> implements_) { | 123 Class addImplementsClass(String name, List<Class> implements_) { |
| 124 return addClass(new Class( | 124 return addClass(new Class( |
| 125 name: name, | 125 name: name, |
| 126 supertype: objectSuper, | 126 supertype: objectSuper, |
| 127 implementedTypes: implements_.map((c) => c.asThisSupertype).toList())); | 127 implementedTypes: implements_.map((c) => c.asThisSupertype).toList())); |
| 128 } | 128 } |
| 129 | 129 |
| 130 ClassHierarchy createClassHierarchy(Program program); | 130 ClassHierarchy createClassHierarchy(Program program); |
| 131 | 131 |
| 132 Procedure newEmptyGetter(String name, | 132 Procedure newEmptyGetter(String name, |
| 133 {DartType returnType: const DynamicType()}) { | 133 {DartType returnType: const DynamicType(), bool isAbstract: false}) { |
| 134 var body = new Block([new ReturnStatement(new NullLiteral())]); | 134 var body = |
| 135 isAbstract ? null : new Block([new ReturnStatement(new NullLiteral())]); | |
| 135 return new Procedure(new Name(name), ProcedureKind.Getter, | 136 return new Procedure(new Name(name), ProcedureKind.Getter, |
| 136 new FunctionNode(body, returnType: returnType)); | 137 new FunctionNode(body, returnType: returnType)); |
| 137 } | 138 } |
| 138 | 139 |
| 139 Procedure newEmptyMethod(String name, {bool isAbstract: false}) { | 140 Procedure newEmptyMethod(String name, {bool isAbstract: false}) { |
| 140 var body = isAbstract ? null : new Block([]); | 141 var body = isAbstract ? null : new Block([]); |
| 141 return new Procedure(new Name(name), ProcedureKind.Method, | 142 return new Procedure(new Name(name), ProcedureKind.Method, |
| 142 new FunctionNode(body, returnType: const VoidType()), | 143 new FunctionNode(body, returnType: const VoidType()), |
| 143 isAbstract: isAbstract); | 144 isAbstract: isAbstract); |
| 144 } | 145 } |
| 145 | 146 |
| 146 Procedure newEmptySetter(String name, | 147 Procedure newEmptySetter(String name, |
| 147 {bool abstract: false, DartType type: const DynamicType()}) { | 148 {bool isAbstract: false, DartType type: const DynamicType()}) { |
| 148 var body = abstract ? null : new Block([]); | 149 var body = isAbstract ? null : new Block([]); |
| 149 return new Procedure( | 150 return new Procedure( |
| 150 new Name(name), | 151 new Name(name), |
| 151 ProcedureKind.Setter, | 152 ProcedureKind.Setter, |
| 152 new FunctionNode(body, | 153 new FunctionNode(body, |
| 153 returnType: const VoidType(), | 154 returnType: const VoidType(), |
| 154 positionalParameters: [new VariableDeclaration('_', type: type)])); | 155 positionalParameters: [new VariableDeclaration('_', type: type)])); |
| 155 } | 156 } |
| 156 | 157 |
| 157 void setUp() { | 158 void setUp() { |
| 158 // Start with mock SDK libraries. | 159 // Start with mock SDK libraries. |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 915 expect(hierarchy.getInterfaceMember(b, aMethodName), aMethod); | 916 expect(hierarchy.getInterfaceMember(b, aMethodName), aMethod); |
| 916 expect(hierarchy.getInterfaceMember(b, bMethodName), bMethod); | 917 expect(hierarchy.getInterfaceMember(b, bMethodName), bMethod); |
| 917 expect(hierarchy.getInterfaceMember(b, aSetterName, setter: true), aSetter); | 918 expect(hierarchy.getInterfaceMember(b, aSetterName, setter: true), aSetter); |
| 918 expect(hierarchy.getInterfaceMember(b, bSetterName, setter: true), bSetter); | 919 expect(hierarchy.getInterfaceMember(b, bSetterName, setter: true), bSetter); |
| 919 expect(hierarchy.getInterfaceMember(c, aMethodName), aMethod); | 920 expect(hierarchy.getInterfaceMember(c, aMethodName), aMethod); |
| 920 expect(hierarchy.getInterfaceMember(c, bMethodName), bMethod); | 921 expect(hierarchy.getInterfaceMember(c, bMethodName), bMethod); |
| 921 expect(hierarchy.getInterfaceMember(c, aSetterName, setter: true), aSetter); | 922 expect(hierarchy.getInterfaceMember(c, aSetterName, setter: true), aSetter); |
| 922 expect(hierarchy.getInterfaceMember(c, bSetterName, setter: true), bSetter); | 923 expect(hierarchy.getInterfaceMember(c, bSetterName, setter: true), bSetter); |
| 923 } | 924 } |
| 924 | 925 |
| 926 void test_getInterfaceMembers_in_class() { | |
| 927 var method = newEmptyMethod('method'); | |
| 928 var getter = newEmptyGetter('getter'); | |
| 929 var setter = newEmptySetter('setter'); | |
| 930 var abstractMethod = newEmptyMethod('abstractMethod', isAbstract: true); | |
| 931 var abstractGetter = newEmptyGetter('abstractGetter', isAbstract: true); | |
| 932 var abstractSetter = newEmptySetter('abstractSetter', isAbstract: true); | |
| 933 var nonFinalField = new Field(new Name('nonFinalField')); | |
| 934 var finalField = new Field(new Name('finalField'), isFinal: true); | |
| 935 var a = addClass(new Class( | |
| 936 isAbstract: true, | |
| 937 name: 'A', | |
| 938 supertype: objectSuper, | |
| 939 fields: [ | |
| 940 nonFinalField, | |
| 941 finalField | |
| 942 ], | |
| 943 procedures: [ | |
| 944 method, | |
| 945 getter, | |
| 946 setter, | |
| 947 abstractMethod, | |
| 948 abstractGetter, | |
| 949 abstractSetter | |
| 950 ])); | |
| 951 | |
| 952 _assertTestLibraryText(''' | |
| 953 abstract class A { | |
| 954 field dynamic nonFinalField; | |
| 955 final field dynamic finalField; | |
| 956 method method() → void {} | |
| 957 get getter() → dynamic { | |
| 958 return null; | |
| 959 } | |
| 960 set setter(dynamic _) → void {} | |
| 961 abstract method abstractMethod() → void; | |
| 962 get abstractGetter() → dynamic; | |
| 963 set abstractSetter(dynamic _) → void; | |
| 964 } | |
| 965 '''); | |
| 966 | |
| 967 expect( | |
| 968 hierarchy.getInterfaceMembers(a), | |
| 969 unorderedEquals([ | |
| 970 method, | |
| 971 getter, | |
| 972 abstractMethod, | |
| 973 abstractGetter, | |
| 974 nonFinalField, | |
| 975 finalField | |
| 976 ])); | |
| 977 expect(hierarchy.getInterfaceMembers(a, setters: true), | |
| 978 unorderedEquals([setter, abstractSetter, nonFinalField])); | |
| 979 } | |
| 980 | |
| 981 void test_getInterfaceMembers_inherited() { | |
| 982 var method = newEmptyMethod('method'); | |
| 983 var getter = newEmptyGetter('getter'); | |
| 984 var setter = newEmptySetter('setter'); | |
| 985 var abstractMethod = newEmptyMethod('abstractMethod', isAbstract: true); | |
| 986 var abstractGetter = newEmptyGetter('abstractGetter', isAbstract: true); | |
| 987 var abstractSetter = newEmptySetter('abstractSetter', isAbstract: true); | |
| 988 var nonFinalField = new Field(new Name('nonFinalField')); | |
| 989 var finalField = new Field(new Name('finalField'), isFinal: true); | |
| 990 | |
| 991 var a = addClass(new Class(name: 'A', supertype: objectSuper, fields: [ | |
| 992 nonFinalField, | |
| 993 finalField | |
| 994 ], procedures: [ | |
| 995 method, | |
| 996 getter, | |
| 997 setter, | |
| 998 abstractMethod, | |
| 999 abstractGetter, | |
| 1000 abstractSetter | |
| 1001 ])); | |
| 1002 var b = addClass(new Class(name: 'B', supertype: a.asThisSupertype)); | |
| 1003 var c = addClass(new Class( | |
| 1004 isAbstract: true, | |
| 1005 name: 'C', | |
| 1006 supertype: objectSuper, | |
| 1007 implementedTypes: [a.asThisSupertype])); | |
| 1008 | |
| 1009 _assertTestLibraryText(''' | |
| 1010 class A { | |
| 1011 field dynamic nonFinalField; | |
| 1012 final field dynamic finalField; | |
| 1013 method method() → void {} | |
| 1014 get getter() → dynamic { | |
| 1015 return null; | |
| 1016 } | |
| 1017 set setter(dynamic _) → void {} | |
| 1018 abstract method abstractMethod() → void; | |
| 1019 get abstractGetter() → dynamic; | |
| 1020 set abstractSetter(dynamic _) → void; | |
| 1021 } | |
| 1022 class B extends self::A {} | |
| 1023 abstract class C implements self::A {} | |
| 1024 '''); | |
| 1025 | |
| 1026 expect( | |
| 1027 hierarchy.getInterfaceMembers(b), | |
| 1028 unorderedEquals([ | |
|
scheglov
2017/08/25 20:15:20
We could extract the lists of super getters/setter
Paul Berry
2017/08/25 20:56:39
Done.
| |
| 1029 method, | |
| 1030 getter, | |
| 1031 abstractMethod, | |
| 1032 abstractGetter, | |
| 1033 nonFinalField, | |
| 1034 finalField | |
| 1035 ])); | |
| 1036 expect(hierarchy.getInterfaceMembers(b, setters: true), | |
| 1037 unorderedEquals([setter, abstractSetter, nonFinalField])); | |
| 1038 expect( | |
| 1039 hierarchy.getInterfaceMembers(c), | |
| 1040 unorderedEquals([ | |
| 1041 method, | |
| 1042 getter, | |
| 1043 abstractMethod, | |
| 1044 abstractGetter, | |
| 1045 nonFinalField, | |
| 1046 finalField | |
| 1047 ])); | |
| 1048 expect(hierarchy.getInterfaceMembers(c, setters: true), | |
| 1049 unorderedEquals([setter, abstractSetter, nonFinalField])); | |
| 1050 } | |
| 1051 | |
| 1052 void test_getInterfaceMembers_mixed_in() { | |
|
scheglov
2017/08/25 20:15:20
Do you expect that mixing-in and extends/implement
Paul Berry
2017/08/25 20:56:39
Good point. I've merged it into the previous test
| |
| 1053 var method = newEmptyMethod('method'); | |
| 1054 var getter = newEmptyGetter('getter'); | |
| 1055 var setter = newEmptySetter('setter'); | |
| 1056 var abstractMethod = newEmptyMethod('abstractMethod', isAbstract: true); | |
| 1057 var abstractGetter = newEmptyGetter('abstractGetter', isAbstract: true); | |
| 1058 var abstractSetter = newEmptySetter('abstractSetter', isAbstract: true); | |
| 1059 var nonFinalField = new Field(new Name('nonFinalField')); | |
| 1060 var finalField = new Field(new Name('finalField'), isFinal: true); | |
| 1061 | |
| 1062 var a = addClass(new Class(name: 'A', supertype: objectSuper, fields: [ | |
| 1063 nonFinalField, | |
| 1064 finalField | |
| 1065 ], procedures: [ | |
| 1066 method, | |
| 1067 getter, | |
| 1068 setter, | |
| 1069 abstractMethod, | |
| 1070 abstractGetter, | |
| 1071 abstractSetter | |
| 1072 ])); | |
| 1073 var b = addClass(new Class( | |
| 1074 name: 'B', supertype: objectSuper, mixedInType: a.asThisSupertype)); | |
| 1075 | |
| 1076 _assertTestLibraryText(''' | |
| 1077 class A { | |
| 1078 field dynamic nonFinalField; | |
| 1079 final field dynamic finalField; | |
| 1080 method method() → void {} | |
| 1081 get getter() → dynamic { | |
| 1082 return null; | |
| 1083 } | |
| 1084 set setter(dynamic _) → void {} | |
| 1085 abstract method abstractMethod() → void; | |
| 1086 get abstractGetter() → dynamic; | |
| 1087 set abstractSetter(dynamic _) → void; | |
| 1088 } | |
| 1089 class B = core::Object with self::A {} | |
| 1090 '''); | |
| 1091 | |
| 1092 expect( | |
| 1093 hierarchy.getInterfaceMembers(b), | |
| 1094 unorderedEquals([ | |
| 1095 method, | |
| 1096 getter, | |
| 1097 abstractMethod, | |
| 1098 abstractGetter, | |
| 1099 nonFinalField, | |
| 1100 finalField | |
| 1101 ])); | |
| 1102 expect(hierarchy.getInterfaceMembers(b, setters: true), | |
| 1103 unorderedEquals([setter, abstractSetter, nonFinalField])); | |
| 1104 } | |
| 1105 | |
| 1106 void test_getInterfaceMembers_multiple() { | |
| 1107 var method_a = newEmptyMethod('method'); | |
| 1108 var getter_a = newEmptyGetter('getter'); | |
| 1109 var setter_a = newEmptySetter('setter'); | |
| 1110 var nonFinalField_a = new Field(new Name('nonFinalField')); | |
| 1111 var finalField_a = new Field(new Name('finalField'), isFinal: true); | |
| 1112 var method_b = newEmptyMethod('method'); | |
| 1113 var getter_b = newEmptyGetter('getter'); | |
| 1114 var setter_b = newEmptySetter('setter'); | |
| 1115 var nonFinalField_b = new Field(new Name('nonFinalField')); | |
| 1116 var finalField_b = new Field(new Name('finalField'), isFinal: true); | |
| 1117 | |
| 1118 var a = addClass(new Class( | |
| 1119 name: 'A', | |
| 1120 supertype: objectSuper, | |
| 1121 fields: [nonFinalField_a, finalField_a], | |
| 1122 procedures: [method_a, getter_a, setter_a])); | |
| 1123 var b = addClass(new Class( | |
| 1124 name: 'B', | |
| 1125 supertype: objectSuper, | |
| 1126 fields: [nonFinalField_b, finalField_b], | |
| 1127 procedures: [method_b, getter_b, setter_b])); | |
| 1128 var c = addClass(new Class( | |
| 1129 isAbstract: true, | |
| 1130 name: 'C', | |
| 1131 supertype: objectSuper, | |
| 1132 implementedTypes: [a.asThisSupertype, b.asThisSupertype])); | |
| 1133 | |
| 1134 _assertTestLibraryText(''' | |
| 1135 class A { | |
| 1136 field dynamic nonFinalField; | |
| 1137 final field dynamic finalField; | |
| 1138 method method() → void {} | |
| 1139 get getter() → dynamic { | |
| 1140 return null; | |
| 1141 } | |
| 1142 set setter(dynamic _) → void {} | |
| 1143 } | |
| 1144 class B { | |
| 1145 field dynamic nonFinalField; | |
| 1146 final field dynamic finalField; | |
| 1147 method method() → void {} | |
| 1148 get getter() → dynamic { | |
| 1149 return null; | |
| 1150 } | |
| 1151 set setter(dynamic _) → void {} | |
| 1152 } | |
| 1153 abstract class C implements self::A, self::B {} | |
| 1154 '''); | |
| 1155 | |
| 1156 expect( | |
| 1157 hierarchy.getInterfaceMembers(c), | |
| 1158 unorderedEquals([ | |
| 1159 method_a, | |
| 1160 getter_a, | |
| 1161 nonFinalField_a, | |
| 1162 finalField_a, | |
| 1163 method_b, | |
| 1164 getter_b, | |
| 1165 nonFinalField_b, | |
| 1166 finalField_b | |
| 1167 ])); | |
| 1168 expect( | |
| 1169 hierarchy.getInterfaceMembers(c, setters: true), | |
| 1170 unorderedEquals( | |
| 1171 [setter_a, nonFinalField_a, setter_b, nonFinalField_b])); | |
| 1172 } | |
| 1173 | |
| 1174 void test_getInterfaceMembers_shadowed() { | |
| 1175 var method_a = newEmptyMethod('method'); | |
| 1176 var getter_a = newEmptyGetter('getter'); | |
| 1177 var setter_a = newEmptySetter('setter'); | |
| 1178 var nonFinalField_a = new Field(new Name('nonFinalField')); | |
| 1179 var finalField_a = new Field(new Name('finalField'), isFinal: true); | |
| 1180 var method_b = newEmptyMethod('method'); | |
| 1181 var getter_b = newEmptyGetter('getter'); | |
| 1182 var setter_b = newEmptySetter('setter'); | |
| 1183 var nonFinalField_b = new Field(new Name('nonFinalField')); | |
| 1184 var finalField_b = new Field(new Name('finalField'), isFinal: true); | |
| 1185 | |
| 1186 var a = addClass(new Class( | |
| 1187 name: 'A', | |
| 1188 supertype: objectSuper, | |
| 1189 fields: [nonFinalField_a, finalField_a], | |
| 1190 procedures: [method_a, getter_a, setter_a])); | |
| 1191 var b = addClass(new Class( | |
| 1192 name: 'B', | |
| 1193 supertype: a.asThisSupertype, | |
| 1194 fields: [nonFinalField_b, finalField_b], | |
| 1195 procedures: [method_b, getter_b, setter_b])); | |
| 1196 | |
| 1197 _assertTestLibraryText(''' | |
| 1198 class A { | |
| 1199 field dynamic nonFinalField; | |
| 1200 final field dynamic finalField; | |
| 1201 method method() → void {} | |
| 1202 get getter() → dynamic { | |
| 1203 return null; | |
| 1204 } | |
| 1205 set setter(dynamic _) → void {} | |
| 1206 } | |
| 1207 class B extends self::A { | |
| 1208 field dynamic nonFinalField; | |
| 1209 final field dynamic finalField; | |
| 1210 method method() → void {} | |
| 1211 get getter() → dynamic { | |
| 1212 return null; | |
| 1213 } | |
| 1214 set setter(dynamic _) → void {} | |
| 1215 } | |
| 1216 '''); | |
| 1217 | |
| 1218 expect(hierarchy.getInterfaceMembers(b), | |
| 1219 unorderedEquals([method_b, getter_b, nonFinalField_b, finalField_b])); | |
| 1220 expect(hierarchy.getInterfaceMembers(b, setters: true), | |
| 1221 unorderedEquals([setter_b, nonFinalField_b])); | |
|
scheglov
2017/08/25 20:15:20
Maybe add one non-shadowed method from A?
There is
Paul Berry
2017/08/25 20:56:40
Done.
| |
| 1222 } | |
| 1223 | |
| 925 void test_getOrderedClasses() { | 1224 void test_getOrderedClasses() { |
| 926 var a = addClass(new Class(name: 'A', supertype: objectSuper)); | 1225 var a = addClass(new Class(name: 'A', supertype: objectSuper)); |
| 927 var b = addClass(new Class(name: 'B', supertype: a.asThisSupertype)); | 1226 var b = addClass(new Class(name: 'B', supertype: a.asThisSupertype)); |
| 928 var c = addClass(new Class(name: 'C', supertype: b.asThisSupertype)); | 1227 var c = addClass(new Class(name: 'C', supertype: b.asThisSupertype)); |
| 929 | 1228 |
| 930 void assertOrderOfClasses(List<Class> unordered, List<Class> expected) { | 1229 void assertOrderOfClasses(List<Class> unordered, List<Class> expected) { |
| 931 var ordered = hierarchy.getOrderedClasses(unordered); | 1230 var ordered = hierarchy.getOrderedClasses(unordered); |
| 932 expect(ordered, expected); | 1231 expect(ordered, expected); |
| 933 } | 1232 } |
| 934 | 1233 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1042 actualText = actualText.replaceAll(' extends core::Object', ''); | 1341 actualText = actualText.replaceAll(' extends core::Object', ''); |
| 1043 | 1342 |
| 1044 if (actualText != expectedText) { | 1343 if (actualText != expectedText) { |
| 1045 print('-------- Actual --------'); | 1344 print('-------- Actual --------'); |
| 1046 print(actualText + '------------------------'); | 1345 print(actualText + '------------------------'); |
| 1047 } | 1346 } |
| 1048 | 1347 |
| 1049 expect(actualText, expectedText); | 1348 expect(actualText, expectedText); |
| 1050 } | 1349 } |
| 1051 } | 1350 } |
| OLD | NEW |