diff --git a/lib/src/generator/templates.runtime_renderers.dart b/lib/src/generator/templates.runtime_renderers.dart index a054eb4405..5c6dea08e1 100644 --- a/lib/src/generator/templates.runtime_renderers.dart +++ b/lib/src/generator/templates.runtime_renderers.dart @@ -9568,17 +9568,17 @@ class _Renderer_MixedInTypes extends RendererBase { self.renderSimpleVariable(c, remainingNames, 'bool'), getBool: (CT_ c) => c.hasPublicMixedInTypes, ), - 'mixedInElements': Property( - getValue: (CT_ c) => c.mixedInElements, + 'mixedInTypes': Property( + getValue: (CT_ c) => c.mixedInTypes, renderVariable: (CT_ c, Property self, List remainingNames) => self.renderSimpleVariable( - c, remainingNames, 'List'), + c, remainingNames, 'List'), renderIterable: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.mixedInElements.map((e) => - _render_InheritingContainer(e, ast, r.template, sink, - parent: r)); + return c.mixedInTypes.map((e) => _render_DefinedElementType( + e, ast, r.template, sink, + parent: r)); }, ), 'publicMixedInTypes': Property( diff --git a/lib/src/model/class.dart b/lib/src/model/class.dart index acbbb19a0a..8a0701a5c9 100644 --- a/lib/src/model/class.dart +++ b/lib/src/model/class.dart @@ -31,7 +31,7 @@ class Class extends InheritingContainer with Constructable, MixedInTypes { this, // Caching should make this recursion a little less painful. - for (var container in mixedInElements.reversed) + for (var container in mixedInTypes.modelElements.reversed) ...container.inheritanceChain, for (var container in superChain.modelElements) diff --git a/lib/src/model/enum.dart b/lib/src/model/enum.dart index 914240b258..3d7f2797c0 100644 --- a/lib/src/model/enum.dart +++ b/lib/src/model/enum.dart @@ -23,7 +23,7 @@ class Enum extends InheritingContainer with Constructable, MixedInTypes { @override late final List inheritanceChain = [ this, - for (var container in mixedInElements.reversed) + for (var container in mixedInTypes.modelElements.reversed) ...container.inheritanceChain, for (var container in superChain.modelElements) ...container.inheritanceChain, diff --git a/lib/src/model/inheriting_container.dart b/lib/src/model/inheriting_container.dart index 98a9df6fa6..beeed784b7 100644 --- a/lib/src/model/inheriting_container.dart +++ b/lib/src/model/inheriting_container.dart @@ -382,7 +382,8 @@ abstract class InheritingContainer extends Container { /// All the "immediate" public implementers of this container. /// - /// For a [Mixin], this is actually the mixin applications using the [Mixin]. + /// For a [Mixin], this is actually the mixin applications that use the + /// [Mixin]. /// /// If this container has a private implementer, then that is counted as a /// proxy for any public implementers of that private container. @@ -580,15 +581,10 @@ abstract class InheritingContainer extends Container { /// Add the ability to support mixed-in types to an [InheritingContainer]. mixin MixedInTypes on InheritingContainer { - @visibleForTesting late final List mixedInTypes = element.mixins .map((f) => getTypeFor(f, library) as DefinedElementType) .toList(growable: false); - List get mixedInElements => [ - for (var t in mixedInTypes) t.modelElement as InheritingContainer, - ]; - @override bool get hasModifiers => super.hasModifiers || hasPublicMixedInTypes; @@ -604,8 +600,8 @@ extension on InterfaceElement { extension DefinedElementTypeIterableExtension on Iterable { /// The [ModelElement] for each element. - Iterable get modelElements => - map((e) => e.modelElement as InheritingContainer); + List get modelElements => + map((e) => e.modelElement as InheritingContainer).toList(); } extension InheritingContainerIterableExtension diff --git a/lib/src/model/package_graph.dart b/lib/src/model/package_graph.dart index 07fbf18440..63ce7055d4 100644 --- a/lib/src/model/package_graph.dart +++ b/lib/src/model/package_graph.dart @@ -643,14 +643,11 @@ class PackageGraph with CommentReferable, Nameable { supertype.modelElement as InheritingContainer, container); } if (container is Class) { - for (var element in container.mixedInElements) { + for (var element in container.mixedInTypes.modelElements) { checkAndAddContainer(element, container); } - for (var element in container.interfaceElements) { - checkAndAddContainer(element, container); - } - } else if (container is ExtensionType) { - for (var element in container.interfaceElements) { + } else if (container is Mixin) { + for (var element in container.superclassConstraints.modelElements) { checkAndAddContainer(element, container); } } diff --git a/test/end2end/model_test.dart b/test/end2end/model_test.dart index a4ec522094..d891aaf011 100644 --- a/test/end2end/model_test.dart +++ b/test/end2end/model_test.dart @@ -1763,7 +1763,7 @@ void main() async { test('Verify inheritance/mixin structure and type inference', () { expect( - TypeInferenceMixedIn.mixedInElements + TypeInferenceMixedIn.mixedInTypes .map((element) => element.name), orderedEquals(['GenericMixin'])); expect( @@ -1928,11 +1928,11 @@ void main() async { }); test('mixins', () { - expect(Apple.mixedInElements, hasLength(0)); + expect(Apple.mixedInTypes, hasLength(0)); }); test('mixins private', () { - expect(F.mixedInElements, hasLength(1)); + expect(F.mixedInTypes, hasLength(1)); }); test('interfaces', () { @@ -4487,30 +4487,6 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans, }); group('Implementors', () { - late final Class apple; - late final Class b; - late final List implA, implC; - - setUpAll(() { - apple = exLibrary.classes.named('Apple'); - b = exLibrary.classes.named('B'); - implA = apple.publicImplementersSorted; - implC = exLibrary.classes.named('Cat').publicImplementersSorted; - }); - - test('private classes do not break the implementor chain', () { - var Super1 = fakeLibrary.classes.named('Super1'); - var publicImplementors = - Super1.publicImplementersSorted.map((i) => i.name); - expect(publicImplementors, hasLength(3)); - // A direct implementor. - expect(publicImplementors, contains('Super4')); - // An implementor through _Super2. - expect(publicImplementors, contains('Super3')); - // An implementor through _Super5 and _Super2. - expect(publicImplementors, contains('Super6')); - }); - test( 'private classes in internal libraries do not break the implementor chain', () { @@ -4535,31 +4511,6 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans, expect(publicImplementors, hasLength(1)); expect(publicImplementors, contains('GenericSuperInt')); }); - - test('the first class is Apple', () { - expect(apple.name, equals('Apple')); - }); - - test('apple has some implementors', () { - expect(apple.hasPublicImplementers, isTrue); - expect(implA, isNotNull); - expect(implA, hasLength(1)); - expect(implA[0].name, equals('B')); - }); - - test('Cat has implementors', () { - expect(implC, hasLength(3)); - var implementors = ['B', 'Dog', 'ConstantCat']; - expect(implementors, contains(implC[0].name)); - expect(implementors, contains(implC[1].name)); - expect(implementors, contains(implC[2].name)); - }); - - test('B does not have implementors', () { - expect(b, isNotNull); - expect(b.name, equals('B')); - expect(b.publicImplementersSorted, hasLength(0)); - }); }); group('Errors and exceptions', () { @@ -4569,6 +4520,7 @@ String? topLevelFunction(int param1, bool param2, Cool coolBeans, 'MyErrorImplements', 'MyExceptionImplements' ]; + test('library has the exact errors/exceptions we expect', () { expect(exLibrary.exceptions.map((e) => e.name), unorderedEquals(expectedNames)); diff --git a/test/enums_test.dart b/test/enums_test.dart index 6fc4640ddb..e52324ccd4 100644 --- a/test/enums_test.dart +++ b/test/enums_test.dart @@ -214,8 +214,11 @@ enum E with M, N { one, two, three; } '''); var eEnum = library.enums.named('E'); - expect(eEnum.mixedInElements, hasLength(2)); - expect(eEnum.mixedInElements.map((e) => e.name), equals(['M', 'N'])); + expect(eEnum.mixedInTypes.modelElements, hasLength(2)); + expect( + eEnum.mixedInTypes.modelElements.map((e) => e.name), + equals(['M', 'N']), + ); } void test_operatorsAreDocumented() async { diff --git a/test/templates/class_test.dart b/test/templates/class_test.dart index 6d712e4de6..84c0edf856 100644 --- a/test/templates/class_test.dart +++ b/test/templates/class_test.dart @@ -25,7 +25,8 @@ class ClassTest extends TemplateTestBase { void test_implementers_class_extends() async { await createPackageWithLibrary(''' class Base {} -class Foo extends Base {} +class _Foo extends Base {} +class Foo extends _Foo {} '''); var baseLines = readLines(['lib', 'Base-class.html']); @@ -40,7 +41,8 @@ class Foo extends Base {} void test_implementers_class_implements() async { await createPackageWithLibrary(''' class Base {} -class Foo implements Base {} +class _Foo implements Base {} +class Foo implements _Foo {} '''); var baseLines = readLines(['lib', 'Base-class.html']); @@ -82,6 +84,22 @@ class Foo implements Base {} ]); } + void test_implementers_class_mixesIn() async { + await createPackageWithLibrary(''' +class Base {} +class _Foo with Base {} +class Foo with _Foo {} +'''); + var baseLines = readLines(['lib', 'Base-class.html']); + + baseLines.expectMainContentContainsAllInOrder([ + matches('
Implementers
'), + matches('
    '), + matches('
  • Foo
  • '), + matches('
'), + ]); + } + void test_implementers_extensionType_implements() async { await createPackageWithLibrary(''' class Base1 {} @@ -102,7 +120,8 @@ extension type ET(Base2 base) implements Base1 {} void test_implementers_mixin_implements() async { await createPackageWithLibrary(''' class Base {} -mixin M implements Base {} +mixin _M implements Base {} +mixin M implements _M {} '''); var baseLines = readLines(['lib', 'Base-class.html']); @@ -114,11 +133,11 @@ mixin M implements Base {} ]); } - @FailingTest(reason: 'Not implemented yet; should be?') void test_implementers_mixin_superclassConstraint() async { await createPackageWithLibrary(''' class Base {} -mixin M on Base {} +mixin _M on Base {} +mixin M on _M {} '''); var baseLines = readLines(['lib', 'Base-class.html']); diff --git a/testing/test_package/lib/fake.dart b/testing/test_package/lib/fake.dart index 458cb2c3b1..e869f0568b 100644 --- a/testing/test_package/lib/fake.dart +++ b/testing/test_package/lib/fake.dart @@ -1214,18 +1214,6 @@ extension ExtensionOnTypeParameter on T { T aFunctionReturningT(T other) => other; } -class Super1 {} - -class _Super2 implements Super1 {} - -class Super3 implements _Super2 {} - -class Super4 implements Super1 {} - -class _Super5 implements _Super2 {} - -class Super6 implements _Super5 {} - abstract class IntermediateAbstract extends Object { /// This is an override. @override