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

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

Issue 2912173002: Start adding unit tests for ClassHierarchy. (Closed)
Patch Set: Fix for _runTest(). 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 | « no previous file | pkg/kernel/test/lub_test.dart » ('j') | 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) 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
3 // BSD-style license that can be found in the LICENSE file.
4
5 import 'package:kernel/ast.dart';
6 import 'package:kernel/class_hierarchy.dart';
7 import 'package:kernel/core_types.dart';
8 import 'package:kernel/testing/mock_sdk_program.dart';
9 import 'package:test/test.dart';
10
11 main() {
12 group('ClosedWorldClassHierarchyTest', () {
13 _ClassHierarchyTest._runTests(() => new ClosedWorldClassHierarchyTest());
14 });
15 }
16
17 class ClosedWorldClassHierarchyTest extends _ClassHierarchyTest {
18 ClassHierarchy createClassHierarchy(Program program) {
19 return new ClosedWorldClassHierarchy(program);
20 }
21 }
22
23 abstract class _ClassHierarchyTest {
24 Program program;
25 CoreTypes coreTypes;
26
27 /// The test library.
28 Library library;
29
30 ClassHierarchy _hierarchy;
31
32 /// Return the new or existing instance of [ClassHierarchy].
33 ClassHierarchy get hierarchy {
34 return _hierarchy ??= createClassHierarchy(program);
35 }
36
37 Class get objectClass => coreTypes.objectClass;
38
39 Supertype get objectSuper => coreTypes.objectClass.asThisSupertype;
40
41 Class addClass(Class c) {
42 if (_hierarchy != null) {
43 fail('The class hierarchy has already been created.');
44 }
45 library.addClass(c);
46 return c;
47 }
48
49 /// Add a new generic class with the given [name] and [typeParameterNames].
50 /// The [TypeParameterType]s corresponding to [typeParameterNames] are
51 /// passed to optional [extends_] and [implements_] callbacks.
52 Class addGenericClass(String name, List<String> typeParameterNames,
53 {Supertype extends_(List<DartType> typeParameterTypes),
54 List<Supertype> implements_(List<DartType> typeParameterTypes)}) {
55 var typeParameters = typeParameterNames
56 .map((name) => new TypeParameter(name, objectClass.rawType))
57 .toList();
58 var typeParameterTypes = typeParameters
59 .map((parameter) => new TypeParameterType(parameter))
60 .toList();
61 var supertype =
62 extends_ != null ? extends_(typeParameterTypes) : objectSuper;
63 var implementedTypes =
64 implements_ != null ? implements_(typeParameterTypes) : [];
65 return addClass(new Class(
66 name: name,
67 typeParameters: typeParameters,
68 supertype: supertype,
69 implementedTypes: implementedTypes));
70 }
71
72 /// Add a new class with the given [name] that extends `Object` and
73 /// [implements_] the given classes.
74 Class addImplementsClass(String name, List<Class> implements_) {
75 return addClass(new Class(
76 name: name,
77 supertype: objectSuper,
78 implementedTypes: implements_.map((c) => c.asThisSupertype).toList()));
79 }
80
81 ClassHierarchy createClassHierarchy(Program program);
82
83 Procedure newEmptyMethod(String name, {bool abstract: false}) {
84 var body = abstract ? null : new Block([]);
85 return new Procedure(
86 new Name(name), ProcedureKind.Method, new FunctionNode(body));
87 }
88
89 Procedure newEmptySetter(String name) {
90 return new Procedure(
91 new Name(name),
92 ProcedureKind.Setter,
93 new FunctionNode(new Block([]),
94 positionalParameters: [new VariableDeclaration('_')]));
95 }
96
97 void setUp() {
98 // Start with mock SDK libraries.
99 program = createMockSdkProgram();
100 coreTypes = new CoreTypes(program);
101
102 // Add the test library.
103 library = new Library(Uri.parse('org-dartlang:///test.dart'), name: 'test');
104 library.parent = program;
105 program.libraries.add(library);
106 }
107
108 void tearDown() {}
109
110 void test_forEachOverridePair_overrideSupertype() {
111 // Create the class hierarchy:
112 //
113 // abstract class A extends Object {
114 // foo() {}
115 // bar() {}
116 // }
117 // class B extends A {
118 // foo() {}
119 // }
120 // class C extends B {
121 // bar() {}
122 // }
123 var aFoo = newEmptyMethod('foo');
124 var aBar = newEmptyMethod('bar');
125 var bFoo = newEmptyMethod('foo');
126 var cBar = newEmptyMethod('bar');
127 var a = addClass(
128 new Class(name: 'A', supertype: objectSuper, procedures: [aFoo, aBar]));
129 var b = addClass(
130 new Class(name: 'B', supertype: a.asThisSupertype, procedures: [bFoo]));
131 var c = addClass(
132 new Class(name: 'C', supertype: b.asThisSupertype, procedures: [cBar]));
133
134 _assertOverridePairs(b, ['test::B::foo overrides test::A::foo']);
135 _assertOverridePairs(c, ['test::C::bar overrides test::A::bar']);
136 }
137
138 void test_getClassAsInstanceOf_generic_extends() {
139 // Create the class hierarchy:
140 //
141 // class A<T, U> extends Object {}
142 // class B<T> extends A<T, bool> {}
143 // class C extends B<int> {}
144 var int = coreTypes.intClass.rawType;
145 var bool = coreTypes.boolClass.rawType;
146
147 var a = addGenericClass('A', ['T', 'U']);
148
149 var bT = new TypeParameter('T', objectClass.rawType);
150 var bTT = new TypeParameterType(bT);
151 var b = addClass(new Class(
152 name: 'B',
153 typeParameters: [bT],
154 supertype: new Supertype(a, [bTT, bool])));
155
156 var c = addClass(new Class(name: 'C', supertype: new Supertype(b, [int])));
157
158 expect(hierarchy.getClassAsInstanceOf(a, objectClass), objectSuper);
159 expect(hierarchy.getClassAsInstanceOf(a, a), a.asThisSupertype);
160 expect(hierarchy.getClassAsInstanceOf(b, a), new Supertype(a, [bTT, bool]));
161 expect(hierarchy.getClassAsInstanceOf(c, b), new Supertype(b, [int]));
162 expect(hierarchy.getClassAsInstanceOf(c, a), new Supertype(a, [int, bool]));
163 }
164
165 void test_getClassAsInstanceOf_generic_implements() {
166 // Create the class hierarchy:
167 //
168 // class A<T, U> extends Object {}
169 // class B<T> extends Object implements A<T, bool> {}
170 // class C extends Object implements B<int> {}
171 var int = coreTypes.intClass.rawType;
172 var bool = coreTypes.boolClass.rawType;
173
174 var a = addGenericClass('A', ['T', 'U']);
175
176 var bT = new TypeParameter('T', objectClass.rawType);
177 var bTT = new TypeParameterType(bT);
178 var b = addClass(new Class(
179 name: 'B',
180 typeParameters: [bT],
181 supertype: objectSuper,
182 implementedTypes: [
183 new Supertype(a, [bTT, bool])
184 ]));
185
186 var c = addClass(
187 new Class(name: 'C', supertype: objectSuper, implementedTypes: [
188 new Supertype(b, [int])
189 ]));
190
191 expect(hierarchy.getClassAsInstanceOf(a, objectClass), objectSuper);
192 expect(hierarchy.getClassAsInstanceOf(a, a), a.asThisSupertype);
193 expect(hierarchy.getClassAsInstanceOf(b, a), new Supertype(a, [bTT, bool]));
194 expect(hierarchy.getClassAsInstanceOf(c, b), new Supertype(b, [int]));
195 expect(hierarchy.getClassAsInstanceOf(c, a), new Supertype(a, [int, bool]));
196 }
197
198 void test_getClassAsInstanceOf_generic_with() {
199 // Create the class hierarchy:
200 //
201 // class A<T, U> extends Object {}
202 // class B<T> extends Object with A<T, bool> {}
203 // class C extends Object with B<int> {}
ahe 2017/05/31 17:33:49 Instead of all these comments, I'd take advantage
scheglov 2017/05/31 17:53:27 That's an interesting idea. I will do this in the
204 var int = coreTypes.intClass.rawType;
205 var bool = coreTypes.boolClass.rawType;
206
207 var a = addGenericClass('A', ['T', 'U']);
208
209 var bT = new TypeParameter('T', objectClass.rawType);
210 var bTT = new TypeParameterType(bT);
211 var b = addClass(new Class(
212 name: 'B',
213 typeParameters: [bT],
214 supertype: objectSuper,
215 mixedInType: new Supertype(a, [bTT, bool])));
216
217 var c = addClass(new Class(
218 name: 'C',
219 supertype: objectSuper,
220 mixedInType: new Supertype(b, [int])));
221
222 expect(hierarchy.getClassAsInstanceOf(a, objectClass), objectSuper);
223 expect(hierarchy.getClassAsInstanceOf(a, a), a.asThisSupertype);
224 expect(hierarchy.getClassAsInstanceOf(b, a), new Supertype(a, [bTT, bool]));
225 expect(hierarchy.getClassAsInstanceOf(c, b), new Supertype(b, [int]));
226 expect(hierarchy.getClassAsInstanceOf(c, a), new Supertype(a, [int, bool]));
227 }
228
229 void test_getClassAsInstanceOf_notGeneric_extends() {
230 // Create the class hierarchy:
231 //
232 // class A extends Object {}
233 // class B extends A {}
234 // class C extends B {}
235 // class Z extends Object {}
236 var a = addClass(new Class(name: 'A', supertype: objectSuper));
237 var b = addClass(new Class(name: 'B', supertype: a.asThisSupertype));
238 var c = addClass(new Class(name: 'C', supertype: b.asThisSupertype));
239 var z = addClass(new Class(name: 'Z', supertype: objectSuper));
240
241 expect(hierarchy.getClassAsInstanceOf(a, objectClass), objectSuper);
242 expect(hierarchy.getClassAsInstanceOf(a, a), a.asThisSupertype);
243 expect(hierarchy.getClassAsInstanceOf(b, a), a.asThisSupertype);
244 expect(hierarchy.getClassAsInstanceOf(c, a), a.asThisSupertype);
245 expect(hierarchy.getClassAsInstanceOf(c, b), b.asThisSupertype);
246 expect(hierarchy.getClassAsInstanceOf(z, a), null);
247 expect(hierarchy.getClassAsInstanceOf(z, objectClass), objectSuper);
248 }
249
250 void test_getClassAsInstanceOf_notGeneric_implements() {
251 // Create the class hierarchy:
252 //
253 // class A extends Object {}
254 // class B extends Object {}
255 // class C extends Object implements A {}
256 // class D extends Object implements C {}
257 // class E extends A implements B {}
258 // class Z extends Object {}
259 var a = addClass(new Class(name: 'A', supertype: objectSuper));
260 var b = addClass(new Class(name: 'B', supertype: objectSuper));
261 var c = addClass(new Class(
262 name: 'C',
263 supertype: objectSuper,
264 implementedTypes: [a.asThisSupertype]));
265 var d = addClass(new Class(
266 name: 'D',
267 supertype: objectSuper,
268 implementedTypes: [c.asThisSupertype]));
269 var e = addClass(new Class(
270 name: 'D',
271 supertype: a.asThisSupertype,
272 implementedTypes: [b.asThisSupertype]));
273 var z = addClass(new Class(name: 'Z', supertype: objectSuper));
274
275 expect(hierarchy.getClassAsInstanceOf(c, a), a.asThisSupertype);
276 expect(hierarchy.getClassAsInstanceOf(d, a), a.asThisSupertype);
277 expect(hierarchy.getClassAsInstanceOf(d, c), c.asThisSupertype);
278 expect(hierarchy.getClassAsInstanceOf(e, a), a.asThisSupertype);
279 expect(hierarchy.getClassAsInstanceOf(e, b), b.asThisSupertype);
280 expect(hierarchy.getClassAsInstanceOf(z, a), null);
281 }
282
283 void test_getClassAsInstanceOf_notGeneric_with() {
284 // Create the class hierarchy:
285 //
286 // class A extends Object {}
287 // class B extends Object with A {}
288 // class Z extends Object {}
289 var a = addClass(new Class(name: 'A', supertype: objectSuper));
290 var b = addClass(new Class(
291 name: 'B', supertype: objectSuper, mixedInType: a.asThisSupertype));
292 var z = addClass(new Class(name: 'Z', supertype: objectSuper));
293
294 expect(hierarchy.getClassAsInstanceOf(b, objectClass), objectSuper);
295 expect(hierarchy.getClassAsInstanceOf(b, a), a.asThisSupertype);
296 expect(hierarchy.getClassAsInstanceOf(z, a), null);
297 }
298
299 void test_getClassDepth() {
300 var base = addClass(new Class(name: 'base', supertype: objectSuper));
301 var extends_ =
302 addClass(new Class(name: 'extends_', supertype: base.asThisSupertype));
303 var with_ = addClass(new Class(
304 name: 'with_',
305 supertype: objectSuper,
306 mixedInType: base.asThisSupertype));
307 var implements_ = addClass(new Class(
308 name: 'implements_',
309 supertype: objectSuper,
310 implementedTypes: [base.asThisSupertype]));
311
312 expect(hierarchy.getClassDepth(objectClass), 0);
313 expect(hierarchy.getClassDepth(base), 1);
314 expect(hierarchy.getClassDepth(extends_), 2);
315 expect(hierarchy.getClassDepth(with_), 2);
316 expect(hierarchy.getClassDepth(implements_), 2);
317 }
318
319 void test_getClassicLeastUpperBound_generic() {
320 var int = coreTypes.intClass.rawType;
321 var double = coreTypes.doubleClass.rawType;
322 var bool = coreTypes.boolClass.rawType;
323
324 // Create the class hierarchy:
325 //
326 // Object
327 // |
328 // A
329 // / \
330 // B<T> C<U>
331 // \ /
332 // D<T,U>
333 // / \
334 // E F
335 //
336 // Where E implements D<int, double> and F implements D<int, bool>.
337 var a = addGenericClass('A', []);
338 var b =
339 addGenericClass('B', ['T'], implements_: (_) => [a.asThisSupertype]);
340 var c =
341 addGenericClass('C', ['U'], implements_: (_) => [a.asThisSupertype]);
342 var d = addGenericClass('D', ['T', 'U'], implements_: (typeParameterTypes) {
343 var t = typeParameterTypes[0];
344 var u = typeParameterTypes[1];
345 return [
346 new Supertype(b, [t]),
347 new Supertype(c, [u])
348 ];
349 });
350 var e = addGenericClass('E', [],
351 implements_: (_) => [
352 new Supertype(d, [int, double])
353 ]);
354 var f = addGenericClass('F', [],
355 implements_: (_) => [
356 new Supertype(d, [int, bool])
357 ]);
358
359 expect(
360 hierarchy.getClassicLeastUpperBound(new InterfaceType(d, [int, double]),
361 new InterfaceType(d, [int, double])),
362 new InterfaceType(d, [int, double]));
363 expect(
364 hierarchy.getClassicLeastUpperBound(new InterfaceType(d, [int, double]),
365 new InterfaceType(d, [int, bool])),
366 new InterfaceType(b, [int]));
367 expect(
368 hierarchy.getClassicLeastUpperBound(new InterfaceType(d, [int, double]),
369 new InterfaceType(d, [bool, double])),
370 new InterfaceType(c, [double]));
371 expect(
372 hierarchy.getClassicLeastUpperBound(new InterfaceType(d, [int, double]),
373 new InterfaceType(d, [bool, int])),
374 a.rawType);
375 expect(hierarchy.getClassicLeastUpperBound(e.rawType, f.rawType),
376 new InterfaceType(b, [int]));
377 }
378
379 void test_getClassicLeastUpperBound_nonGeneric() {
380 // Create the class hierarchy:
381 //
382 // Object
383 // / \
384 // A B
385 // /|\
386 // C D E
387 // |X|/
388 // FG HI
389 //
390 // (F and G both implement (C, D); H and I both implement (C, D, E).
391 var a = addImplementsClass('A', []);
392 var b = addImplementsClass('B', []);
393 var c = addImplementsClass('C', [a]);
394 var d = addImplementsClass('D', [a]);
395 var e = addImplementsClass('E', [a]);
396 var f = addImplementsClass('F', [c, d]);
397 var g = addImplementsClass('G', [c, d]);
398 var h = addImplementsClass('H', [c, d, e]);
399 var i = addImplementsClass('I', [c, d, e]);
400 var hierarchy = new ClassHierarchy(program);
401
402 expect(hierarchy.getClassicLeastUpperBound(a.rawType, b.rawType),
403 objectClass.rawType);
404 expect(hierarchy.getClassicLeastUpperBound(a.rawType, objectClass.rawType),
405 objectClass.rawType);
406 expect(hierarchy.getClassicLeastUpperBound(objectClass.rawType, b.rawType),
407 objectClass.rawType);
408 expect(
409 hierarchy.getClassicLeastUpperBound(c.rawType, d.rawType), a.rawType);
410 expect(
411 hierarchy.getClassicLeastUpperBound(c.rawType, a.rawType), a.rawType);
412 expect(
413 hierarchy.getClassicLeastUpperBound(a.rawType, d.rawType), a.rawType);
414 expect(
415 hierarchy.getClassicLeastUpperBound(f.rawType, g.rawType), a.rawType);
416 expect(
417 hierarchy.getClassicLeastUpperBound(h.rawType, i.rawType), a.rawType);
418 }
419
420 void test_getDispatchTarget() {
421 // Create the class hierarchy:
422 //
423 // class A extends Object {
424 // aMethod() {}
425 // void set aSetter(_) {}
426 // }
427 // class B extends A {
428 // bMethod() {}
429 // void set bSetter(_) {}
430 // }
431 // class C extends B {}
432 var aMethod = newEmptyMethod('aMethod');
433 var aSetter = newEmptySetter('aSetter');
434 var bMethod = newEmptyMethod('bMethod');
435 var bSetter = newEmptySetter('bSetter');
436 var a = addClass(new Class(
437 name: 'A', supertype: objectSuper, procedures: [aMethod, aSetter]));
438 var b = addClass(new Class(
439 name: 'B',
440 supertype: a.asThisSupertype,
441 procedures: [bMethod, bSetter]));
442 var c = addClass(new Class(name: 'C', supertype: b.asThisSupertype));
443
444 var aMethodName = new Name('aMethod');
445 var aSetterName = new Name('aSetter');
446 var bMethodName = new Name('bMethod');
447 var bSetterName = new Name('bSetter');
448 expect(hierarchy.getDispatchTarget(a, aMethodName), aMethod);
449 expect(hierarchy.getDispatchTarget(a, bMethodName), isNull);
450 expect(hierarchy.getDispatchTarget(a, aSetterName, setter: true), aSetter);
451 expect(hierarchy.getDispatchTarget(a, bSetterName, setter: true), isNull);
452 expect(hierarchy.getDispatchTarget(b, aMethodName), aMethod);
453 expect(hierarchy.getDispatchTarget(b, bMethodName), bMethod);
454 expect(hierarchy.getDispatchTarget(b, aSetterName, setter: true), aSetter);
455 expect(hierarchy.getDispatchTarget(b, bSetterName, setter: true), bSetter);
456 expect(hierarchy.getDispatchTarget(c, aMethodName), aMethod);
457 expect(hierarchy.getDispatchTarget(c, bMethodName), bMethod);
458 expect(hierarchy.getDispatchTarget(c, aSetterName, setter: true), aSetter);
459 expect(hierarchy.getDispatchTarget(c, bSetterName, setter: true), bSetter);
460 }
461
462 void test_getDispatchTarget_abstract() {
463 // Create the class hierarchy:
464 //
465 // abstract class A extends Object {
466 // aMethodAbstract();
467 // aMethodConcrete() {}
468 // }
469 // abstract class B extends A {
470 // aMethodConcrete();
471 // bMethodAbstract();
472 // bMethodConcrete() {}
473 // }
474 // class C extends B {}
475 var aMethodConcrete = newEmptyMethod('aMethodConcrete');
476 var bMethodConcrete = newEmptyMethod('aMethodConcrete');
477 var a = addClass(new Class(name: 'A', supertype: objectSuper, procedures: [
478 newEmptyMethod('aMethodAbstract', abstract: true),
479 aMethodConcrete
480 ]));
481 var b = addClass(
482 new Class(name: 'B', supertype: a.asThisSupertype, procedures: [
483 newEmptyMethod('aMethodConcrete', abstract: true),
484 newEmptyMethod('bMethodAbstract', abstract: true),
485 bMethodConcrete
486 ]));
487 addClass(new Class(name: 'C', supertype: b.asThisSupertype));
488
489 expect(hierarchy.getDispatchTarget(a, new Name('aMethodConcrete')),
490 aMethodConcrete);
491 // TODO(scheglov) The next two commented statements verify the behavior
ahe 2017/05/31 17:33:49 Add colon after ")".
scheglov 2017/05/31 17:53:27 Done.
492 // documented as "If the class is abstract, abstract members are ignored and
493 // the dispatch is resolved if the class was not abstract.". Unfortunately
494 // the implementation does not follow the documentation. We need to fix
495 // either documentation, or implementation.
ahe 2017/05/31 17:33:49 Since Fasta uses this method, it would be interest
scheglov 2017/05/31 17:53:28 I hope that Kevin will able to shed some light.
496 // expect(hierarchy.getDispatchTarget(c, new Name('aMethodConcrete')),
497 // aMethodConcrete);
498 // expect(hierarchy.getDispatchTarget(b, new Name('aMethodConcrete')),
499 // aMethodConcrete);
500 }
501
502 void test_getInterfaceMember_extends() {
503 // Create the class hierarchy:
504 //
505 // class A extends Object {
506 // aMethod() {}
507 // void set aSetter(_) {}
508 // }
509 // class B extends A {
510 // bMethod() {}
511 // void set bSetter(_) {}
512 // }
513 // class C extends B {}
514 var aMethod = newEmptyMethod('aMethod');
515 var aSetter = newEmptySetter('aSetter');
516 var bMethod = newEmptyMethod('bMethod');
517 var bSetter = newEmptySetter('bSetter');
518 var a = addClass(new Class(
519 name: 'A', supertype: objectSuper, procedures: [aMethod, aSetter]));
520 var b = addClass(new Class(
521 name: 'B',
522 supertype: a.asThisSupertype,
523 procedures: [bMethod, bSetter]));
524 var c = addClass(new Class(name: 'C', supertype: b.asThisSupertype));
525
526 var aMethodName = new Name('aMethod');
527 var aSetterName = new Name('aSetter');
528 var bMethodName = new Name('bMethod');
529 var bSetterName = new Name('bSetter');
530 expect(hierarchy.getInterfaceMember(a, aMethodName), aMethod);
531 expect(hierarchy.getInterfaceMember(a, bMethodName), isNull);
532 expect(hierarchy.getInterfaceMember(a, aSetterName, setter: true), aSetter);
533 expect(hierarchy.getInterfaceMember(a, bSetterName, setter: true), isNull);
534 expect(hierarchy.getInterfaceMember(b, aMethodName), aMethod);
535 expect(hierarchy.getInterfaceMember(b, bMethodName), bMethod);
536 expect(hierarchy.getInterfaceMember(b, aSetterName, setter: true), aSetter);
537 expect(hierarchy.getInterfaceMember(b, bSetterName, setter: true), bSetter);
538 expect(hierarchy.getInterfaceMember(c, aMethodName), aMethod);
539 expect(hierarchy.getInterfaceMember(c, bMethodName), bMethod);
540 expect(hierarchy.getInterfaceMember(c, aSetterName, setter: true), aSetter);
541 expect(hierarchy.getInterfaceMember(c, bSetterName, setter: true), bSetter);
542 }
543
544 void test_getInterfaceMember_implements() {
545 // Create the class hierarchy:
546 //
547 // class A extends Object {
548 // aMethod() {}
549 // void set aSetter(_) {}
550 // }
551 // class B extends Object implements A {
552 // bMethod() {}
553 // void set bSetter(_) {}
554 // }
555 // class C extends Object implements B {}
556 var aMethod = newEmptyMethod('aMethod');
557 var aSetter = newEmptySetter('aSetter');
558 var bMethod = newEmptyMethod('bMethod');
559 var bSetter = newEmptySetter('bSetter');
560 var a = addClass(new Class(
561 name: 'A', supertype: objectSuper, procedures: [aMethod, aSetter]));
562 var b = addClass(new Class(
563 name: 'B',
564 supertype: objectSuper,
565 implementedTypes: [a.asThisSupertype],
566 procedures: [bMethod, bSetter]));
567 var c = addClass(new Class(
568 name: 'C',
569 supertype: objectSuper,
570 implementedTypes: [b.asThisSupertype]));
571
572 var aMethodName = new Name('aMethod');
573 var aSetterName = new Name('aSetter');
574 var bMethodName = new Name('bMethod');
575 var bSetterName = new Name('bSetter');
576 expect(hierarchy.getInterfaceMember(a, aMethodName), aMethod);
577 expect(hierarchy.getInterfaceMember(a, bMethodName), isNull);
578 expect(hierarchy.getInterfaceMember(a, aSetterName, setter: true), aSetter);
579 expect(hierarchy.getInterfaceMember(a, bSetterName, setter: true), isNull);
580 expect(hierarchy.getInterfaceMember(b, aMethodName), aMethod);
581 expect(hierarchy.getInterfaceMember(b, bMethodName), bMethod);
582 expect(hierarchy.getInterfaceMember(b, aSetterName, setter: true), aSetter);
583 expect(hierarchy.getInterfaceMember(b, bSetterName, setter: true), bSetter);
584 expect(hierarchy.getInterfaceMember(c, aMethodName), aMethod);
585 expect(hierarchy.getInterfaceMember(c, bMethodName), bMethod);
586 expect(hierarchy.getInterfaceMember(c, aSetterName, setter: true), aSetter);
587 expect(hierarchy.getInterfaceMember(c, bSetterName, setter: true), bSetter);
588 }
589
590 void test_getRankedSuperclasses() {
591 // Create the class hierarchy:
592 //
593 // Object
594 // |
595 // A
596 // / \
597 // B C
598 // | |
599 // | D
600 // \ /
601 // E
ahe 2017/05/31 17:33:49 I'm thinking it might be a good idea to add more c
scheglov 2017/05/31 17:53:27 Sounds good to me. Anything specific you have in m
ahe 2017/05/31 18:33:06 I'll discuss it with Johnni tomorrow. I can't reme
602 var a = addImplementsClass('A', []);
603 var b = addImplementsClass('B', [a]);
604 var c = addImplementsClass('C', [a]);
605 var d = addImplementsClass('D', [c]);
606 var e = addImplementsClass('E', [b, d]);
607
608 expect(hierarchy.getRankedSuperclasses(a), [a, objectClass]);
609 expect(hierarchy.getRankedSuperclasses(b), [b, a, objectClass]);
610 expect(hierarchy.getRankedSuperclasses(c), [c, a, objectClass]);
611 expect(hierarchy.getRankedSuperclasses(d), [d, c, a, objectClass]);
612 if (hierarchy.getClassIndex(b) < hierarchy.getClassIndex(c)) {
613 expect(hierarchy.getRankedSuperclasses(e), [e, d, b, c, a, objectClass]);
614 } else {
615 expect(hierarchy.getRankedSuperclasses(e), [e, d, c, b, a, objectClass]);
616 }
617 }
618
619 void test_getTypeAsInstanceOf_generic_extends() {
620 // Create the class hierarchy:
621 //
622 // class A<T, U> extends Object {}
623 // class B<T> extends A<T, bool> {}
624 var int = coreTypes.intClass.rawType;
625 var bool = coreTypes.boolClass.rawType;
626
627 var a = addGenericClass('A', ['T', 'U']);
628
629 var bT = new TypeParameter('T', objectClass.rawType);
630 var bTT = new TypeParameterType(bT);
631 var b = addClass(new Class(
632 name: 'B',
633 typeParameters: [bT],
634 supertype: new Supertype(a, [bTT, bool])));
635
636 var b_int = new InterfaceType(b, [int]);
637 expect(hierarchy.getTypeAsInstanceOf(b_int, a),
638 new InterfaceType(a, [int, bool]));
639 expect(hierarchy.getTypeAsInstanceOf(b_int, objectClass),
640 new InterfaceType(objectClass));
641 }
642
643 void test_rootClass() {
644 addClass(new Class(name: 'A', supertype: objectSuper));
645 expect(hierarchy.rootClass, objectClass);
646 }
647
648 void _assertOverridePairs(Class class_, List<String> expected) {
649 List<String> overrideDescriptions = [];
650 hierarchy.forEachOverridePair(class_,
651 (Member declaredMember, Member interfaceMember, bool isSetter) {
652 var desc = '$declaredMember overrides $interfaceMember';
653 overrideDescriptions.add(desc);
654 });
655 expect(overrideDescriptions, unorderedEquals(expected));
656 }
657
658 /// Create a new [_ClassHierarchyTest] using [newInstance] and run [test]
659 /// with the given [description] and [doRun] with the test instance.
660 static void _runTest(_ClassHierarchyTest newInstance(), String description,
661 void doRun(_ClassHierarchyTest instance)) {
662 test(description, () {
663 var instance = newInstance();
664 instance.setUp();
665 try {
666 doRun(instance);
667 } finally {
668 instance.tearDown();
669 }
670 });
671 }
672
673 /// Run all tests declared in [_ClassHierarchyTest]. This method must be
674 /// updated when a new `test_XYZ` method is added, renamed or deleted.
675 static void _runTests(_ClassHierarchyTest newInstance()) {
scheglov 2017/05/31 17:53:27 Given that this is considered as not an optimal so
ahe 2017/05/31 18:33:06 I agree.
676 _runTest(newInstance, 'test_forEachOverridePair_overrideSupertype',
677 (i) => i.test_forEachOverridePair_overrideSupertype());
678 _runTest(newInstance, 'test_getClassAsInstanceOf_generic_extends',
679 (i) => i.test_getClassAsInstanceOf_generic_extends());
680 _runTest(newInstance, 'test_getClassAsInstanceOf_generic_implements',
681 (i) => i.test_getClassAsInstanceOf_generic_implements());
682 _runTest(newInstance, 'test_getClassAsInstanceOf_generic_with',
683 (i) => i.test_getClassAsInstanceOf_generic_with());
684 _runTest(newInstance, 'test_getClassAsInstanceOf_notGeneric_extends',
685 (i) => i.test_getClassAsInstanceOf_notGeneric_extends());
686 _runTest(newInstance, 'test_getClassAsInstanceOf_notGeneric_implements',
687 (i) => i.test_getClassAsInstanceOf_notGeneric_implements());
688 _runTest(newInstance, 'test_getClassAsInstanceOf_notGeneric_with',
689 (i) => i.test_getClassAsInstanceOf_notGeneric_with());
690 _runTest(newInstance, 'test_getClassDepth', (i) => i.test_getClassDepth());
691 _runTest(newInstance, 'test_getClassicLeastUpperBound_generic',
692 (i) => i.test_getClassicLeastUpperBound_generic());
693 _runTest(newInstance, 'test_getClassicLeastUpperBound_nonGeneric',
694 (i) => i.test_getClassicLeastUpperBound_nonGeneric());
695 _runTest(newInstance, 'test_getDispatchTarget',
696 (i) => i.test_getDispatchTarget());
697 _runTest(newInstance, 'test_getDispatchTarget_abstract',
698 (i) => i.test_getDispatchTarget_abstract());
699 _runTest(newInstance, 'test_getInterfaceMember_extends',
700 (i) => i.test_getInterfaceMember_extends());
701 _runTest(newInstance, 'test_getInterfaceMember_implements',
702 (i) => i.test_getInterfaceMember_implements());
703 _runTest(newInstance, 'test_getRankedSuperclasses',
704 (i) => i.test_getRankedSuperclasses());
705 _runTest(newInstance, 'test_getTypeAsInstanceOf_generic_extends',
706 (i) => i.test_getTypeAsInstanceOf_generic_extends());
707 _runTest(newInstance, 'test_rootClass', (i) => i.test_rootClass());
708 }
709 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/test/lub_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698