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

Side by Side Diff: pkg/kernel/test/class_hierarchy_test.dart

Issue 2941363002: Add the 'crossGettersSetters' flag to ClassHierarchy.forEachOverridePair(). (Closed)
Patch Set: Fixes for review comments. Created 3 years, 6 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 | « pkg/kernel/lib/src/incremental_class_hierarchy.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
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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 /// [implements_] the given classes. 122 /// [implements_] the given classes.
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,
133 {DartType returnType: const DynamicType()}) {
134 var body = new Block([new ReturnStatement(new NullLiteral())]);
135 return new Procedure(new Name(name), ProcedureKind.Getter,
136 new FunctionNode(body, returnType: returnType));
137 }
138
132 Procedure newEmptyMethod(String name, {bool isAbstract: false}) { 139 Procedure newEmptyMethod(String name, {bool isAbstract: false}) {
133 var body = isAbstract ? null : new Block([]); 140 var body = isAbstract ? null : new Block([]);
134 return new Procedure(new Name(name), ProcedureKind.Method, 141 return new Procedure(new Name(name), ProcedureKind.Method,
135 new FunctionNode(body, returnType: const VoidType()), 142 new FunctionNode(body, returnType: const VoidType()),
136 isAbstract: isAbstract); 143 isAbstract: isAbstract);
137 } 144 }
138 145
139 Procedure newEmptySetter(String name, {bool abstract: false}) { 146 Procedure newEmptySetter(String name,
147 {bool abstract: false, DartType type: const DynamicType()}) {
140 var body = abstract ? null : new Block([]); 148 var body = abstract ? null : new Block([]);
141 return new Procedure( 149 return new Procedure(
142 new Name(name), 150 new Name(name),
143 ProcedureKind.Setter, 151 ProcedureKind.Setter,
144 new FunctionNode(body, 152 new FunctionNode(body,
145 returnType: const VoidType(), 153 returnType: const VoidType(),
146 positionalParameters: [new VariableDeclaration('_')])); 154 positionalParameters: [new VariableDeclaration('_', type: type)]));
147 } 155 }
148 156
149 void setUp() { 157 void setUp() {
150 // Start with mock SDK libraries. 158 // Start with mock SDK libraries.
151 program = createMockSdkProgram(); 159 program = createMockSdkProgram();
152 coreTypes = new CoreTypes(program); 160 coreTypes = new CoreTypes(program);
153 161
154 // Add the test library. 162 // Add the test library.
155 library = new Library(Uri.parse('org-dartlang:///test.dart'), name: 'test'); 163 library = new Library(Uri.parse('org-dartlang:///test.dart'), name: 'test');
156 library.parent = program; 164 library.parent = program;
157 program.libraries.add(library); 165 program.libraries.add(library);
158 } 166 }
159 167
168 void test_forEachOverridePair_crossGetterSetter_extends() {
169 var int = coreTypes.intClass.rawType;
170 var a = addClass(new Class(name: 'A', supertype: objectSuper, procedures: [
171 newEmptySetter('foo', type: int),
172 newEmptyGetter('bar', returnType: int)
173 ]));
174 var b = addClass(new Class(
175 name: 'B',
176 supertype: a.asThisSupertype,
177 procedures: [newEmptyGetter('foo'), newEmptySetter('bar')]));
178
179 _assertTestLibraryText('''
180 class A {
181 set foo(core::int _) → void {}
182 get bar() → core::int {
183 return null;
184 }
185 }
186 class B extends self::A {
187 get foo() → dynamic {
188 return null;
189 }
190 set bar(dynamic _) → void {}
191 }
192 ''');
193
194 // No overrides of getters with getters, or setters with setters.
195 _assertOverridePairs(b, []);
196
197 // Has cross-overrides between getters and setters.
198 _assertOverridePairs(
199 b,
200 [
201 'test::B::foo overrides test::A::foo=',
202 'test::B::bar= overrides test::A::bar'
203 ],
204 crossGettersSetters: true);
205 }
206
207 void test_forEachOverridePair_crossGetterSetter_implements() {
208 var int = coreTypes.intClass.rawType;
209 var double = coreTypes.doubleClass.rawType;
210 var a = addClass(new Class(name: 'A', supertype: objectSuper, procedures: [
211 newEmptySetter('foo', type: int),
212 ]));
213 var b = addClass(new Class(name: 'B', supertype: objectSuper, procedures: [
214 newEmptySetter('foo', type: double),
215 ]));
216 var c = addClass(new Class(
217 name: 'C',
218 supertype: objectSuper,
219 implementedTypes: [a.asThisSupertype, b.asThisSupertype],
220 procedures: [newEmptyGetter('foo')]));
221
222 _assertTestLibraryText('''
223 class A {
224 set foo(core::int _) → void {}
225 }
226 class B {
227 set foo(core::double _) → void {}
228 }
229 class C implements self::A, self::B {
230 get foo() → dynamic {
231 return null;
232 }
233 }
234 ''');
235
236 // No overrides of getters with getters, or setters with setters.
237 _assertOverridePairs(c, []);
238
239 // Has cross-overrides between getters and setters.
240 // Even if these overrides are incompatible with each other.
241 _assertOverridePairs(
242 c,
243 [
244 'test::C::foo overrides test::A::foo=',
245 'test::C::foo overrides test::B::foo=',
246 ],
247 crossGettersSetters: true);
248 }
249
160 /// 2. A non-abstract member is inherited from a superclass, and in the 250 /// 2. A non-abstract member is inherited from a superclass, and in the
161 /// context of this class, it overrides an abstract member inheritable through 251 /// context of this class, it overrides an abstract member inheritable through
162 /// one of its superinterfaces. 252 /// one of its superinterfaces.
163 void test_forEachOverridePair_supertypeOverridesInterface() { 253 void test_forEachOverridePair_supertypeOverridesInterface() {
164 var a = addClass(new Class( 254 var a = addClass(new Class(
165 name: 'A', 255 name: 'A',
166 supertype: objectSuper, 256 supertype: objectSuper,
167 procedures: [newEmptyMethod('foo'), newEmptyMethod('bar')])); 257 procedures: [newEmptyMethod('foo'), newEmptyMethod('bar')]));
168 var b = addClass(new Class( 258 var b = addClass(new Class(
169 name: 'B', 259 name: 'B',
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 class B<T> extends self::A<self::B::T, core::bool> {} 985 class B<T> extends self::A<self::B::T, core::bool> {}
896 '''); 986 ''');
897 987
898 var b_int = new InterfaceType(b, [int]); 988 var b_int = new InterfaceType(b, [int]);
899 expect(hierarchy.getTypeAsInstanceOf(b_int, a), 989 expect(hierarchy.getTypeAsInstanceOf(b_int, a),
900 new InterfaceType(a, [int, bool])); 990 new InterfaceType(a, [int, bool]));
901 expect(hierarchy.getTypeAsInstanceOf(b_int, objectClass), 991 expect(hierarchy.getTypeAsInstanceOf(b_int, objectClass),
902 new InterfaceType(objectClass)); 992 new InterfaceType(objectClass));
903 } 993 }
904 994
905 void _assertOverridePairs(Class class_, List<String> expected) { 995 void _assertOverridePairs(Class class_, List<String> expected,
996 {bool crossGettersSetters: false}) {
906 List<String> overrideDescriptions = []; 997 List<String> overrideDescriptions = [];
907 hierarchy.forEachOverridePair(class_, 998 hierarchy.forEachOverridePair(class_,
908 (Member declaredMember, Member interfaceMember, bool isSetter) { 999 (Member declaredMember, Member interfaceMember, bool isSetter) {
909 String declaredName = '$declaredMember${isSetter ? '=': ''}'; 1000 String declaredSuffix;
910 String interfaceName = '$interfaceMember${isSetter ? '=': ''}'; 1001 String interfaceSuffix;
1002 if (crossGettersSetters) {
1003 declaredSuffix = _isSetter(declaredMember) ? '=' : '';
1004 interfaceSuffix = _isSetter(interfaceMember) ? '=' : '';
1005 } else {
1006 declaredSuffix = isSetter ? '=' : '';
1007 interfaceSuffix = isSetter ? '=' : '';
1008 }
1009 String declaredName = '$declaredMember$declaredSuffix';
1010 String interfaceName = '$interfaceMember$interfaceSuffix';
911 var desc = '$declaredName overrides $interfaceName'; 1011 var desc = '$declaredName overrides $interfaceName';
912 overrideDescriptions.add(desc); 1012 overrideDescriptions.add(desc);
913 }); 1013 }, crossGettersSetters: crossGettersSetters);
914 expect(overrideDescriptions, unorderedEquals(expected)); 1014 expect(overrideDescriptions, unorderedEquals(expected));
915 } 1015 }
916 1016
917 /// Assert that the test [library] has the [expectedText] presentation. 1017 /// Assert that the test [library] has the [expectedText] presentation.
918 /// The presentation is close, but not identical to the normal Kernel one. 1018 /// The presentation is close, but not identical to the normal Kernel one.
919 void _assertTestLibraryText(String expectedText) { 1019 void _assertTestLibraryText(String expectedText) {
920 StringBuffer sb = new StringBuffer(); 1020 StringBuffer sb = new StringBuffer();
921 Printer printer = new Printer(sb); 1021 Printer printer = new Printer(sb);
922 printer.writeLibraryFile(library); 1022 printer.writeLibraryFile(library);
923 1023
924 String actualText = sb.toString(); 1024 String actualText = sb.toString();
925 1025
926 // Clean up the text a bit. 1026 // Clean up the text a bit.
927 const oftenUsedPrefix = ''' 1027 const oftenUsedPrefix = '''
928 library test; 1028 library test;
929 import self as self; 1029 import self as self;
930 import "dart:core" as core; 1030 import "dart:core" as core;
931 1031
932 '''; 1032 ''';
933 if (actualText.startsWith(oftenUsedPrefix)) { 1033 if (actualText.startsWith(oftenUsedPrefix)) {
934 actualText = actualText.substring(oftenUsedPrefix.length); 1034 actualText = actualText.substring(oftenUsedPrefix.length);
935 } 1035 }
936 actualText = actualText.replaceAll('{\n}', '{}'); 1036 actualText = actualText.replaceAll('{\n}', '{}');
937 actualText = actualText.replaceAll(' extends core::Object', ''); 1037 actualText = actualText.replaceAll(' extends core::Object', '');
938 1038
939 // if (actualText != expectedText) { 1039 if (actualText != expectedText) {
940 // print('-------- Actual --------'); 1040 print('-------- Actual --------');
941 // print(actualText + '------------------------'); 1041 print(actualText + '------------------------');
942 // } 1042 }
943 1043
944 expect(actualText, expectedText); 1044 expect(actualText, expectedText);
945 } 1045 }
1046
1047 static bool _isSetter(Member member) {
1048 return member is Procedure && member.kind == ProcedureKind.Setter;
1049 }
946 } 1050 }
OLDNEW
« no previous file with comments | « pkg/kernel/lib/src/incremental_class_hierarchy.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698