Skip to content

Commit a1d3a0a

Browse files
committed
Display indirectly implemented types via extended and mixed-in types
1 parent b47a0c2 commit a1d3a0a

File tree

2 files changed

+69
-7
lines changed

2 files changed

+69
-7
lines changed

lib/src/model/inheriting_container.dart

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -453,13 +453,13 @@ abstract class InheritingContainer extends Container {
453453
}
454454
}
455455

456-
for (var interface in directInterfaces) {
457-
var interfaceElement = interface.modelElement;
456+
void addFromSupertype(DefinedElementType supertype) {
457+
var interfaceElement = supertype.modelElement;
458458

459459
/// Do not recurse if we can find an element here.
460460
if (interfaceElement.canonicalModelElement != null) {
461-
addInterfaceIfUnique(interface);
462-
continue;
461+
addInterfaceIfUnique(supertype);
462+
return;
463463
}
464464
// Public types used to be unconditionally exposed here. However,
465465
// if the packages are [DocumentLocation.missing] we generally treat types
@@ -474,18 +474,30 @@ abstract class InheritingContainer extends Container {
474474
if (interfaceElement is! InheritingContainer) {
475475
assert(
476476
false,
477-
'Can not handle intermediate non-public interfaces created by '
477+
'Cannot handle intermediate non-public interfaces created by '
478478
"ModelElements that are not classes or mixins: '$fullyQualifiedName' "
479-
"contains an interface '$interface', defined by '$interfaceElement'",
479+
"contains a supertype '$supertype', defined by '$interfaceElement'",
480480
);
481-
continue;
481+
return;
482482
}
483483
var publicSuperChain = interfaceElement.superChain.wherePublic;
484484
if (publicSuperChain.isNotEmpty) {
485485
addInterfaceIfUnique(publicSuperChain.first);
486486
}
487487
interfaceElement.publicInterfaces.forEach(addInterfaceIfUnique);
488488
}
489+
490+
for (var interface in directInterfaces) {
491+
addFromSupertype(interface);
492+
}
493+
for (var supertype in superChain) {
494+
addFromSupertype(supertype);
495+
}
496+
if (this case Class(:var mixedInTypes) || Enum(:var mixedInTypes)) {
497+
for (var mixin in mixedInTypes) {
498+
addFromSupertype(mixin);
499+
}
500+
}
489501
return interfaces;
490502
}
491503

test/classes_test.dart

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,56 @@ class C implements _B {}
109109
expect(c.publicInterfaces.first.modelElement, library.classes.named('A'));
110110
}
111111

112+
void test_publicInterfaces_indirectViaPrivate2() async {
113+
var library = await bootPackageWithLibrary('''
114+
class A {}
115+
class _B implements A {}
116+
class _C implements _B {}
117+
class D implements _C {}
118+
''');
119+
120+
var c = library.classes.named('D');
121+
expect(c.publicInterfaces, hasLength(1));
122+
expect(c.publicInterfaces.first.modelElement, library.classes.named('A'));
123+
}
124+
125+
void test_publicInterfaces_indirectViaPrivateExtendedClass() async {
126+
var library = await bootPackageWithLibrary('''
127+
class A {}
128+
class _B implements A {}
129+
class C extends _B {}
130+
''');
131+
132+
var c = library.classes.named('C');
133+
expect(c.publicInterfaces, hasLength(1));
134+
expect(c.publicInterfaces.first.modelElement, library.classes.named('A'));
135+
}
136+
137+
void test_publicInterfaces_indirectViaPrivateExtendedClass2() async {
138+
var library = await bootPackageWithLibrary('''
139+
class A {}
140+
class _B implements A {}
141+
class _C extends _B {}
142+
class D extends _C {}
143+
''');
144+
145+
var c = library.classes.named('D');
146+
expect(c.publicInterfaces, hasLength(1));
147+
expect(c.publicInterfaces.first.modelElement, library.classes.named('A'));
148+
}
149+
150+
void test_publicInterfaces_indirectViaPrivateMixedInMixin() async {
151+
var library = await bootPackageWithLibrary('''
152+
class A {}
153+
mixin _M implements A {}
154+
class C with _M {}
155+
''');
156+
157+
var c = library.classes.named('C');
158+
expect(c.publicInterfaces, hasLength(1));
159+
expect(c.publicInterfaces.first.modelElement, library.classes.named('A'));
160+
}
161+
112162
void test_publicInterfaces_indirectViaPrivate_multiply() async {
113163
var library = await bootPackageWithLibrary('''
114164
class A<T> {}

0 commit comments

Comments
 (0)