diff --git a/lib/src/generator/templates.aot_renderers_for_html.dart b/lib/src/generator/templates.aot_renderers_for_html.dart
index e57ebbd9b8..203c8e3756 100644
--- a/lib/src/generator/templates.aot_renderers_for_html.dart
+++ b/lib/src/generator/templates.aot_renderers_for_html.dart
@@ -322,12 +322,12 @@ String renderClass(ClassTemplateData context0) {
buffer.write('\n ');
buffer.write(_renderClass_partial_mixed_in_types_7(context2));
buffer.writeln();
- if (context2.hasPublicImplementors) {
+ if (context2.hasPublicImplementers) {
buffer.writeln();
buffer.write('''
Implementers
''');
- var context3 = context2.publicImplementorsSorted;
+ var context3 = context2.publicImplementersSorted;
for (var context4 in context3) {
buffer.writeln();
buffer.write('''
@@ -865,6 +865,24 @@ String renderExtensionType(
''');
buffer.write(_renderExtensionType_partial_interfaces_5(context2));
buffer.writeln();
+ if (context2.hasPublicImplementers) {
+ buffer.writeln();
+ buffer.write('''
+ - Implementers
+ ''');
+ var context4 = context2.publicImplementersSorted;
+ for (var context5 in context4) {
+ buffer.writeln();
+ buffer.write('''
+ - ''');
+ buffer.write(context5.linkedName);
+ buffer.write('''
''');
+ }
+ buffer.writeln();
+ buffer.write('''
+
''');
+ }
+ buffer.writeln();
buffer.write('''
''');
@@ -883,10 +901,10 @@ String renderExtensionType(
Properties
''');
- var context4 = context2.publicInstanceFieldsSorted;
- for (var context5 in context4) {
+ var context6 = context2.publicInstanceFieldsSorted;
+ for (var context7 in context6) {
buffer.write('\n ');
- buffer.write(_renderExtensionType_partial_property_8(context5));
+ buffer.write(_renderExtensionType_partial_property_8(context7));
}
buffer.writeln();
buffer.write('''
@@ -1528,13 +1546,13 @@ String renderMixin(MixinTemplateData context0) {
buffer.write('\n ');
buffer.write(_renderMixin_partial_interfaces_6(context2));
buffer.writeln();
- if (context2.hasPublicImplementors) {
+ if (context2.hasPublicImplementers) {
buffer.writeln();
buffer.write('''
- Mixin Applications
-
''');
- var context5 = context2.publicImplementorsSorted;
+ var context5 = context2.publicImplementersSorted;
for (var context6 in context5) {
buffer.writeln();
buffer.write('''
diff --git a/lib/src/generator/templates.runtime_renderers.dart b/lib/src/generator/templates.runtime_renderers.dart
index 4d784f34bc..ffa4ebe3c9 100644
--- a/lib/src/generator/templates.runtime_renderers.dart
+++ b/lib/src/generator/templates.runtime_renderers.dart
@@ -15225,12 +15225,12 @@ class _Renderer_TypeImplementing extends RendererBase {
self.renderSimpleVariable(c, remainingNames, 'bool'),
getBool: (CT_ c) => c.hasModifiers,
),
- 'hasPublicImplementors': Property(
- getValue: (CT_ c) => c.hasPublicImplementors,
+ 'hasPublicImplementers': Property(
+ getValue: (CT_ c) => c.hasPublicImplementers,
renderVariable: (CT_ c, Property self,
List remainingNames) =>
self.renderSimpleVariable(c, remainingNames, 'bool'),
- getBool: (CT_ c) => c.hasPublicImplementors,
+ getBool: (CT_ c) => c.hasPublicImplementers,
),
'hasPublicInterfaces': Property(
getValue: (CT_ c) => c.hasPublicInterfaces,
@@ -15265,28 +15265,28 @@ class _Renderer_TypeImplementing extends RendererBase {
parent: r));
},
),
- 'publicImplementors': Property(
- getValue: (CT_ c) => c.publicImplementors,
+ 'publicImplementers': Property(
+ getValue: (CT_ c) => c.publicImplementers,
renderVariable: (CT_ c, Property self,
List remainingNames) =>
self.renderSimpleVariable(
c, remainingNames, 'Iterable'),
renderIterable: (CT_ c, RendererBase r,
List ast, StringSink sink) {
- return c.publicImplementors.map((e) =>
+ return c.publicImplementers.map((e) =>
_render_InheritingContainer(e, ast, r.template, sink,
parent: r));
},
),
- 'publicImplementorsSorted': Property(
- getValue: (CT_ c) => c.publicImplementorsSorted,
+ 'publicImplementersSorted': Property(
+ getValue: (CT_ c) => c.publicImplementersSorted,
renderVariable: (CT_ c, Property self,
List remainingNames) =>
self.renderSimpleVariable(
c, remainingNames, 'List'),
renderIterable: (CT_ c, RendererBase r,
List ast, StringSink sink) {
- return c.publicImplementorsSorted.map((e) =>
+ return c.publicImplementersSorted.map((e) =>
_render_InheritingContainer(e, ast, r.template, sink,
parent: r));
},
@@ -16846,7 +16846,7 @@ const _invisibleGetters = {
'allConstructedModelElements',
'allExtensionsAdded',
'allHrefs',
- 'allImplementorsAdded',
+ 'allImplementersAdded',
'allInheritableElements',
'allLibraries',
'allLibrariesAdded',
@@ -16862,7 +16862,7 @@ const _invisibleGetters = {
'hasEmbedderSdk',
'hasFooterVersion',
'hashCode',
- 'implementors',
+ 'implementers',
'inheritThrough',
'inheritanceManager',
'libraries',
diff --git a/lib/src/model/inheriting_container.dart b/lib/src/model/inheriting_container.dart
index fca8dd0038..5ca54ac93a 100644
--- a/lib/src/model/inheriting_container.dart
+++ b/lib/src/model/inheriting_container.dart
@@ -503,14 +503,14 @@ mixin TypeImplementing on InheritingContainer {
getTypeFor(interface, library) as DefinedElementType
];
- late final List publicImplementorsSorted =
- publicImplementors.toList(growable: false)..sort(byName);
+ late final List publicImplementersSorted =
+ publicImplementers.toList(growable: false)..sort(byName);
@override
bool get hasModifiers =>
- super.hasModifiers || hasPublicInterfaces || hasPublicImplementors;
+ super.hasModifiers || hasPublicInterfaces || hasPublicImplementers;
- bool get hasPublicImplementors => publicImplementors.isNotEmpty;
+ bool get hasPublicImplementers => publicImplementers.isNotEmpty;
bool get hasPublicInterfaces => publicInterfaces.isNotEmpty;
@@ -522,34 +522,34 @@ mixin TypeImplementing on InheritingContainer {
interface.modelElement as InheritingContainer,
];
- /// All the "immediate" public implementors of this [TypeImplementing].
+ /// All the "immediate" public implementers of this [TypeImplementing].
///
/// For a [Mixin], this is actually the mixin applications using the [Mixin].
///
- /// If this [InheritingContainer] has a private implementor, then that is
- /// counted as a proxy for any public implementors of that private container.
- Iterable get publicImplementors {
+ /// If this [InheritingContainer] has a private implementer, then that is
+ /// counted as a proxy for any public implementers of that private container.
+ Iterable get publicImplementers {
var result = {};
var seen = {};
- // Recursively adds [implementor] if public, or the implementors of
- // [implementor] if not.
- void addToResult(InheritingContainer implementor) {
- if (seen.contains(implementor)) return;
- seen.add(implementor);
- if (implementor.isPublicAndPackageDocumented) {
- result.add(implementor);
+ // Recursively adds [implementer] if public, or the implementers of
+ // [implementer] if not.
+ void addToResult(InheritingContainer implementer) {
+ if (seen.contains(implementer)) return;
+ seen.add(implementer);
+ if (implementer.isPublicAndPackageDocumented) {
+ result.add(implementer);
} else {
- var implementors = packageGraph.implementors[implementor];
- if (implementors != null) {
- model_utils.findCanonicalFor(implementors).forEach(addToResult);
+ var implementers = packageGraph.implementers[implementer];
+ if (implementers != null) {
+ model_utils.findCanonicalFor(implementers).forEach(addToResult);
}
}
}
- var immediateImplementors = packageGraph.implementors[this];
- if (immediateImplementors != null) {
- model_utils.findCanonicalFor(immediateImplementors).forEach(addToResult);
+ var immediateImplementers = packageGraph.implementers[this];
+ if (immediateImplementers != null) {
+ model_utils.findCanonicalFor(immediateImplementers).forEach(addToResult);
}
return result;
}
diff --git a/lib/src/model/package_graph.dart b/lib/src/model/package_graph.dart
index e6168f1f7b..102cb2e397 100644
--- a/lib/src/model/package_graph.dart
+++ b/lib/src/model/package_graph.dart
@@ -145,7 +145,7 @@ class PackageGraph with CommentReferable, Nameable {
package.warn(PackageWarning.noDocumentableLibrariesInPackage);
}
}
- allImplementorsAdded = true;
+ allImplementersAdded = true;
allExtensionsAdded = true;
// We should have found all special classes by now.
@@ -280,17 +280,17 @@ class PackageGraph with CommentReferable, Nameable {
ModelNode? getModelNodeFor(Element element) => _modelNodes[element];
- /// It is safe to cache values derived from the [_implementors] table if this
+ /// It is safe to cache values derived from the [_implementers] table if this
/// is true.
- bool allImplementorsAdded = false;
+ bool allImplementersAdded = false;
/// It is safe to cache values derived from the [_extensions] table if this
/// is true.
bool allExtensionsAdded = false;
- Map> get implementors {
- assert(allImplementorsAdded);
- return _implementors;
+ Map> get implementers {
+ assert(allImplementersAdded);
+ return _implementers;
}
Iterable get documentedExtensions =>
@@ -323,8 +323,12 @@ class PackageGraph with CommentReferable, Nameable {
final Map> allInheritableElements =
{};
- /// A mapping of the list of classes which implement each class.
- final Map> _implementors =
+ /// A mapping of the list of classes, enums, mixins, and extension types which
+ /// "implement" each class, mixin, and extension type.
+ ///
+ /// For the purposes of the "Implementers" section in the output, this
+ /// includes elements that "implement" or "extend" another element.
+ final Map> _implementers =
LinkedHashMap>(
equals: (InheritingContainer a, InheritingContainer b) =>
a.definingContainer == b.definingContainer,
@@ -575,7 +579,7 @@ class PackageGraph with CommentReferable, Nameable {
}
void _addToImplementers(Iterable containers) {
- assert(!allImplementorsAdded);
+ assert(!allImplementersAdded);
// Private containers may not be included in documentation, but may still be
// necessary links in the implementation chain. They are added here as they
@@ -589,7 +593,7 @@ class PackageGraph with CommentReferable, Nameable {
}
implemented = implemented.canonicalModelElement as InheritingContainer? ??
implemented;
- var list = _implementors.putIfAbsent(implemented, () => []);
+ var list = _implementers.putIfAbsent(implemented, () => []);
// TODO(srawlins): This would be more efficient if we created a
// SplayTreeSet keyed off of `.element`.
if (!list.any((l) => l.element == implementer.element)) {
diff --git a/lib/templates/class.html b/lib/templates/class.html
index 4431de77f9..8dfe36f107 100644
--- a/lib/templates/class.html
+++ b/lib/templates/class.html
@@ -19,14 +19,14 @@
{{ >interfaces }}
{{ >mixed_in_types }}
- {{ #hasPublicImplementors }}
+ {{ #hasPublicImplementers }}
- Implementers
- {{ #publicImplementorsSorted }}
+ {{ #publicImplementersSorted }}
- {{{ linkedName }}}
- {{ /publicImplementorsSorted }}
+ {{ /publicImplementersSorted }}
- {{ /hasPublicImplementors }}
+ {{ /hasPublicImplementers }}
{{ #hasPotentiallyApplicableExtensions }}
- Available Extensions
diff --git a/lib/templates/extension_type.html b/lib/templates/extension_type.html
index 4e65170e22..121bd6b971 100644
--- a/lib/templates/extension_type.html
+++ b/lib/templates/extension_type.html
@@ -22,6 +22,15 @@
{{ >interfaces }}
+
+ {{ #hasPublicImplementers }}
+ - Implementers
+
+ {{ #publicImplementersSorted }}
+ - {{{ linkedName }}}
+ {{ /publicImplementersSorted }}
+
+ {{ /hasPublicImplementers }}
{{ >container_annotations }}
diff --git a/lib/templates/mixin.html b/lib/templates/mixin.html
index 5fb8614faf..e9c1e29f1b 100644
--- a/lib/templates/mixin.html
+++ b/lib/templates/mixin.html
@@ -27,16 +27,16 @@
{{ >super_chain }}
{{ >interfaces }}
- {{ #hasPublicImplementors }}
+ {{ #hasPublicImplementers }}
- Mixin Applications
-
- {{ #publicImplementorsSorted }}
+ {{ #publicImplementersSorted }}
- {{{ linkedName }}}
- {{ /publicImplementorsSorted }}
+ {{ /publicImplementersSorted }}
- {{ /hasPublicImplementors }}
+ {{ /hasPublicImplementers }}
{{ >annotations }}
diff --git a/test/end2end/model_test.dart b/test/end2end/model_test.dart
index c1772cfe0a..60112e61ea 100644
--- a/test/end2end/model_test.dart
+++ b/test/end2end/model_test.dart
@@ -1695,9 +1695,9 @@ void main() async {
.publicInterfaces.first.modelElement,
equals(ImplementBase));
- expect(ImplementBase.publicImplementors,
+ expect(ImplementBase.publicImplementers,
contains(ImplementerOfDeclaredPrivateClasses));
- expect(ImplementBase.publicImplementors, contains(ImplementerOfThings));
+ expect(ImplementBase.publicImplementers, contains(ImplementerOfThings));
});
test('Overrides from intermediate abstract classes are picked up correctly',
@@ -1801,9 +1801,9 @@ void main() async {
expect(ThingToImplementInMixin.hasModifiers, isTrue);
expect(MixInImplementation.hasModifiers, isTrue);
expect(MixedInImplementation.hasModifiers, isTrue);
- expect(ThingToImplementInMixin.publicImplementors,
+ expect(ThingToImplementInMixin.publicImplementers,
orderedEquals([MixInImplementation]));
- expect(MixInImplementation.publicImplementors,
+ expect(MixInImplementation.publicImplementers,
orderedEquals([MixedInImplementation]));
expect(
MixedInImplementation.allFields
@@ -4695,16 +4695,16 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans,
setUpAll(() {
apple = exLibrary.classes.firstWhere((c) => c.name == 'Apple');
b = exLibrary.classes.firstWhere((c) => c.name == 'B');
- implA = apple.publicImplementors.toList();
+ implA = apple.publicImplementers.toList();
implC = exLibrary.classes
.firstWhere((c) => c.name == 'Cat')
- .publicImplementors
+ .publicImplementers
.toList();
});
test('private classes do not break the implementor chain', () {
var Super1 = fakeLibrary.classes.singleWhere((c) => c.name == 'Super1');
- var publicImplementors = Super1.publicImplementors.map((i) => i.name);
+ var publicImplementors = Super1.publicImplementers.map((i) => i.name);
expect(publicImplementors, hasLength(3));
// A direct implementor.
expect(publicImplementors, contains('Super4'));
@@ -4720,7 +4720,7 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans,
var GenericSuperProperty = fakeLibrary.classes
.singleWhere((c) => c.name == 'GenericSuperProperty');
var publicImplementors =
- GenericSuperProperty.publicImplementors.map((i) => i.name);
+ GenericSuperProperty.publicImplementers.map((i) => i.name);
expect(publicImplementors, hasLength(1));
// A direct implementor.
expect(publicImplementors, contains('GenericSuperValue'));
@@ -4728,7 +4728,7 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans,
var GenericSuperValue =
fakeLibrary.classes.singleWhere((c) => c.name == 'GenericSuperValue');
publicImplementors =
- GenericSuperValue.publicImplementors.map((i) => i.name);
+ GenericSuperValue.publicImplementers.map((i) => i.name);
expect(publicImplementors, hasLength(1));
// A direct implementor.
expect(publicImplementors, contains('GenericSuperNum'));
@@ -4736,7 +4736,7 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans,
var GenericSuperNum =
fakeLibrary.classes.singleWhere((c) => c.name == 'GenericSuperNum');
publicImplementors =
- GenericSuperNum.publicImplementors.map((i) => i.name);
+ GenericSuperNum.publicImplementers.map((i) => i.name);
expect(publicImplementors, hasLength(1));
expect(publicImplementors, contains('GenericSuperInt'));
});
@@ -4746,7 +4746,7 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans,
});
test('apple has some implementors', () {
- expect(apple.hasPublicImplementors, isTrue);
+ expect(apple.hasPublicImplementers, isTrue);
expect(implA, isNotNull);
expect(implA, hasLength(1));
expect(implA[0].name, equals('B'));
@@ -4763,7 +4763,7 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans,
test('B does not have implementors', () {
expect(b, isNotNull);
expect(b.name, equals('B'));
- expect(b.publicImplementors, hasLength(0));
+ expect(b.publicImplementers, hasLength(0));
});
});
diff --git a/test/templates/extension_type_test.dart b/test/templates/extension_type_test.dart
index d9cb148589..266e22c88f 100644
--- a/test/templates/extension_type_test.dart
+++ b/test/templates/extension_type_test.dart
@@ -112,6 +112,21 @@ extension type Two(List it) implements One {}
]);
}
+ void test_implementers() async {
+ await createPackageWithLibrary('''
+extension type One(List it) {}
+extension type Two(List it) implements One {}
+''');
+ var htmlLines = readLines(['lib', 'One-extension-type.html']);
+
+ htmlLines.expectMainContentContainsAllInOrder([
+ matches('- Implementers
'),
+ matches(''),
+ matches('- Two
'),
+ matches('
'),
+ ]);
+ }
+
void test_constructors() async {
await createPackageWithLibrary('''
extension type One(int it) {