blob: 021c533547515d3a3fd667ee03763bbd07c3959b [file] [log] [blame]
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:dartdoc/src/element_type.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/model_utils.dart' as model_utils;
import 'package:dartdoc/src/special_elements.dart';
/// Implements the Dart 2.1 "mixin" style of mixin declarations.
class Mixin extends InheritingContainer with TypeImplementing {
Mixin(ClassElement element, Library library, PackageGraph packageGraph)
: super(element, library, packageGraph);
List<ParameterizedElementType> _superclassConstraints;
/// Returns a list of superclass constraints for this mixin.
Iterable<ParameterizedElementType> get superclassConstraints {
_superclassConstraints ??= [
...element.superclassConstraints
.map<ParameterizedElementType>(
(InterfaceType i) => modelBuilder.typeFrom(i, library))
.where((t) =>
t.modelElement !=
packageGraph.specialClasses[SpecialClass.object])
];
return _superclassConstraints;
}
bool get hasPublicSuperclassConstraints =>
publicSuperclassConstraints.isNotEmpty;
Iterable<ParameterizedElementType> get publicSuperclassConstraints =>
model_utils.filterNonPublic(superclassConstraints);
@override
bool get hasModifiers => super.hasModifiers || hasPublicSuperclassConstraints;
@override
String get fileName => '$name-mixin.$fileType';
@override
String get kind => 'mixin';
List<InheritingContainer> _inheritanceChain;
@override
List<InheritingContainer> get inheritanceChain {
if (_inheritanceChain == null) {
_inheritanceChain = [];
_inheritanceChain.add(this);
// Mix-in interfaces come before other interfaces.
_inheritanceChain.addAll(superclassConstraints.expand(
(ParameterizedElementType i) =>
(i.modelElement as InheritingContainer).inheritanceChain));
for (var c
in superChain.map((e) => (e.modelElement as InheritingContainer))) {
_inheritanceChain.addAll(c.inheritanceChain);
}
/// Interfaces need to come last, because classes in the superChain might
/// implement them even when they aren't mentioned.
_inheritanceChain.addAll(interfaces.expand(
(e) => (e.modelElement as InheritingContainer).inheritanceChain));
}
return _inheritanceChain.toList(growable: false);
}
}