diff --git a/lib/dartdoc.dart b/lib/dartdoc.dart index e3fbeb5f03..6d74a3fdb1 100644 --- a/lib/dartdoc.dart +++ b/lib/dartdoc.dart @@ -4,8 +4,8 @@ /// A documentation generator for Dart. /// -/// Library interface is currently under heavy construction and may change -/// drastically between minor revisions. +/// Library interface is still experimental. +@experimental library dartdoc; import 'dart:async'; diff --git a/lib/src/element_type.dart b/lib/src/element_type.dart index 6b289c8133..e7b6e948da 100644 --- a/lib/src/element_type.dart +++ b/lib/src/element_type.dart @@ -13,6 +13,15 @@ import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/model/model_object_builder.dart'; import 'package:dartdoc/src/render/element_type_renderer.dart'; +mixin ElementTypeBuilderImpl implements ElementTypeBuilder { + PackageGraph get packageGraph; + + @override + ElementType typeFrom(DartType f, Library library, + {ElementType returnedFrom}) => + ElementType._from(f, library, packageGraph, returnedFrom: returnedFrom); +} + /// Base class representing a type in Dartdoc. It wraps a [DartType], and /// may link to a [ModelElement]. abstract class ElementType extends Privacy @@ -26,7 +35,7 @@ abstract class ElementType extends Privacy ElementType(this._type, this.library, this.packageGraph, this.returnedFrom); - factory ElementType.from( + factory ElementType._from( DartType f, Library library, PackageGraph packageGraph, {ElementType returnedFrom}) { if (f.element == null || @@ -215,7 +224,7 @@ class ParameterizedElementType extends DefinedElementType with Rendered { @override Iterable get typeArguments => _typeArguments ??= type.typeArguments - .map((f) => ElementType.from(f, library, packageGraph)) + .map((f) => modelBuilder.typeFrom(f, library)) .toList(growable: false); } @@ -234,7 +243,7 @@ mixin Aliased implements ElementType, ModelBuilderInterface { Iterable _aliasArguments; Iterable get aliasArguments => _aliasArguments ??= type.alias.typeArguments - .map((f) => ElementType.from(f, library, packageGraph)) + .map((f) => modelBuilder.typeFrom(f, library)) .toList(growable: false); } @@ -381,7 +390,7 @@ mixin Callable implements ElementType { ElementType _returnType; ElementType get returnType { - _returnType ??= ElementType.from(type.returnType, library, packageGraph); + _returnType ??= modelBuilder.typeFrom(type.returnType, library); return _returnType; } @@ -432,7 +441,7 @@ class CallableElementType extends DefinedElementType with Rendered, Callable { @override Iterable get typeArguments => _typeArguments ??= (type.alias?.typeArguments ?? []) - .map((f) => ElementType.from(f, library, packageGraph)) + .map((f) => modelBuilder.typeFrom(f, library)) .toList(growable: false); } diff --git a/lib/src/model/accessor.dart b/lib/src/model/accessor.dart index eafe811454..9bab382cf9 100644 --- a/lib/src/model/accessor.dart +++ b/lib/src/model/accessor.dart @@ -39,7 +39,7 @@ class Accessor extends ModelElement implements EnclosedElement { Callable _modelType; Callable get modelType => _modelType ??= - ElementType.from((originalMember ?? element).type, library, packageGraph); + modelBuilder.typeFrom((originalMember ?? element).type, library); bool get isSynthetic => element.isSynthetic; @@ -137,8 +137,8 @@ class Accessor extends ModelElement implements EnclosedElement { @override ModelElement get enclosingElement { if (element.enclosingElement is CompilationUnitElement) { - return packageGraph.findButDoNotCreateLibraryFor( - element.enclosingElement.enclosingElement); + return modelBuilder + .fromElement(element.enclosingElement.enclosingElement); } return modelBuilder.from(element.enclosingElement, library); diff --git a/lib/src/model/annotation.dart b/lib/src/model/annotation.dart index 6017d74c84..3ef6de260e 100644 --- a/lib/src/model/annotation.dart +++ b/lib/src/model/annotation.dart @@ -38,8 +38,7 @@ class Annotation extends Feature with ModelBuilder { if (_modelType == null) { var annotatedWith = annotation.element; if (annotatedWith is ConstructorElement) { - _modelType = - ElementType.from(annotatedWith.returnType, library, packageGraph); + _modelType = modelBuilder.typeFrom(annotatedWith.returnType, library); } else if (annotatedWith is PropertyAccessorElement) { _modelType = (modelBuilder.fromElement(annotatedWith.variable) as GetterSetterCombo) diff --git a/lib/src/model/constructor.dart b/lib/src/model/constructor.dart index 1cac5f19a9..63b8829a8d 100644 --- a/lib/src/model/constructor.dart +++ b/lib/src/model/constructor.dart @@ -79,7 +79,7 @@ class Constructor extends ModelElement Callable _modelType; Callable get modelType => - _modelType ??= ElementType.from(element.type, library, packageGraph); + _modelType ??= modelBuilder.typeFrom(element.type, library); String _name; diff --git a/lib/src/model/extension.dart b/lib/src/model/extension.dart index 17ed365e76..92f87fb131 100644 --- a/lib/src/model/extension.dart +++ b/lib/src/model/extension.dart @@ -16,8 +16,7 @@ class Extension extends Container implements EnclosedElement { Extension( ExtensionElement element, Library library, PackageGraph packageGraph) : super(element, library, packageGraph) { - extendedType = - ElementType.from(_extension.extendedType, library, packageGraph); + extendedType = modelBuilder.typeFrom(_extension.extendedType, library); } /// Detect if this extension applies to every object. diff --git a/lib/src/model/inheriting_container.dart b/lib/src/model/inheriting_container.dart index c4cc033014..598fcba1b2 100644 --- a/lib/src/model/inheriting_container.dart +++ b/lib/src/model/inheriting_container.dart @@ -96,8 +96,7 @@ mixin MixedInTypes on InheritingContainer { _mixedInTypes ?? [ ...element.mixins - .map( - (f) => ElementType.from(f, library, packageGraph)) + .map((f) => modelBuilder.typeFrom(f, library)) .where((mixin) => mixin != null) ]; @@ -118,8 +117,7 @@ mixin TypeImplementing on InheritingContainer { _directInterfaces ?? [ ...element.interfaces - .map( - (f) => ElementType.from(f, library, packageGraph)) + .map((f) => modelBuilder.typeFrom(f, library)) .toList(growable: false) ]; @@ -224,14 +222,15 @@ abstract class InheritingContainer extends Container /// [ClassElement] is analogous to [InheritingContainer]. ClassElement get element => super.element; - final DefinedElementType supertype; + DefinedElementType _supertype; + DefinedElementType get supertype => + _supertype ??= element.supertype?.element?.supertype == null + ? null + : modelBuilder.typeFrom(element.supertype, library); InheritingContainer( ClassElement element, Library library, PackageGraph packageGraph) - : supertype = element.supertype?.element?.supertype == null - ? null - : ElementType.from(element.supertype, library, packageGraph), - super(element, library, packageGraph); + : super(element, library, packageGraph); @override Iterable get instanceMethods => @@ -361,7 +360,7 @@ abstract class InheritingContainer extends Container @override DefinedElementType get modelType => - _modelType ??= ElementType.from(element.thisType, library, packageGraph); + _modelType ??= modelBuilder.typeFrom(element.thisType, library); /// Not the same as superChain as it may include mixins. /// It's really not even the same as ordinary Dart inheritance, either, @@ -381,8 +380,8 @@ abstract class InheritingContainer extends Container if ((parent.type as InterfaceType)?.superclass?.superclass == null) { parent = null; } else { - parent = ElementType.from( - (parent.type as InterfaceType).superclass, library, packageGraph); + parent = modelBuilder.typeFrom( + (parent.type as InterfaceType).superclass, library); } } else { parent = (parent.modelElement as Class).supertype; diff --git a/lib/src/model/library.dart b/lib/src/model/library.dart index 3fd276edbb..a1edfe8dcb 100644 --- a/lib/src/model/library.dart +++ b/lib/src/model/library.dart @@ -252,7 +252,7 @@ class Library extends ModelElement with Categorization, TopLevelContainer { importedExportedLibraryElements.addAll(element.importedLibraries); importedExportedLibraryElements.addAll(element.exportedLibraries); for (var l in importedExportedLibraryElements) { - var lib = packageGraph.findButDoNotCreateLibraryFor(l); + var lib = modelBuilder.fromElement(l) as Library; _importedExportedLibraries.add(lib); _importedExportedLibraries.addAll(lib.importedExportedLibraries); } diff --git a/lib/src/model/method.dart b/lib/src/model/method.dart index cd5d2f49fd..3bc0c20d05 100644 --- a/lib/src/model/method.dart +++ b/lib/src/model/method.dart @@ -99,7 +99,7 @@ class Method extends ModelElement Callable _modelType; Callable get modelType => _modelType ??= - ElementType.from((originalMember ?? element).type, library, packageGraph); + modelBuilder.typeFrom((originalMember ?? element).type, library); @override Method get overriddenElement { diff --git a/lib/src/model/mixin.dart b/lib/src/model/mixin.dart index 204c2b3ab8..021c533547 100644 --- a/lib/src/model/mixin.dart +++ b/lib/src/model/mixin.dart @@ -21,7 +21,7 @@ class Mixin extends InheritingContainer with TypeImplementing { _superclassConstraints ??= [ ...element.superclassConstraints .map( - (InterfaceType i) => ElementType.from(i, library, packageGraph)) + (InterfaceType i) => modelBuilder.typeFrom(i, library)) .where((t) => t.modelElement != packageGraph.specialClasses[SpecialClass.object]) diff --git a/lib/src/model/model_element.dart b/lib/src/model/model_element.dart index c1bf97ad62..e95b02f8c0 100644 --- a/lib/src/model/model_element.dart +++ b/lib/src/model/model_element.dart @@ -59,25 +59,23 @@ ModelElement resolveMultiplyInheritedElement( enclosingContainer: enclosingClass); } -class ModelElementBuilderImpl implements ModelObjectBuilder { - final PackageGraph _packageGraph; - - ModelElementBuilderImpl(this._packageGraph); +mixin ModelElementBuilderImpl implements ModelElementBuilder { + PackageGraph get packageGraph; @override ModelElement from(Element e, Library library, {Container enclosingContainer}) => - ModelElement._from(e, library, _packageGraph, + ModelElement._from(e, library, packageGraph, enclosingContainer: enclosingContainer); @override ModelElement fromElement(Element e) => - ModelElement._fromElement(e, _packageGraph); + ModelElement._fromElement(e, packageGraph); @override ModelElement fromPropertyInducingElement(Element e, Library l, {Container enclosingContainer, Accessor getter, Accessor setter}) => - ModelElement._fromPropertyInducingElement(e, l, _packageGraph, + ModelElement._fromPropertyInducingElement(e, l, packageGraph, enclosingContainer: enclosingContainer, getter: getter, setter: setter); @@ -150,7 +148,7 @@ abstract class ModelElement extends Canonicalization return ModelElement._from(e, lib, p); } - /// Creates a [ModelElement] from [PropertyInducingElement] [e]. + /// Creates a [ModelElement] from [PropertyInducingElement] [e]. /// /// Do not construct any ModelElements except from this constructor or /// [ModelElement._from]. Specify [enclosingContainer] @@ -525,7 +523,7 @@ abstract class ModelElement extends Canonicalization } Library get definingLibrary { - var library = packageGraph.findButDoNotCreateLibraryFor(element); + Library library = modelBuilder.fromElement(element.library); if (library == null) { warn(PackageWarning.noDefiningLibraryFound); } diff --git a/lib/src/model/model_function.dart b/lib/src/model/model_function.dart index 3025183465..db14433b3f 100644 --- a/lib/src/model/model_function.dart +++ b/lib/src/model/model_function.dart @@ -90,5 +90,5 @@ class ModelFunctionTyped extends ModelElement Callable _modelType; Callable get modelType => - _modelType ??= ElementType.from(element.type, library, packageGraph); + _modelType ??= modelBuilder.typeFrom(element.type, library); } diff --git a/lib/src/model/model_object_builder.dart b/lib/src/model/model_object_builder.dart index 6ad909ae94..347cd107d0 100644 --- a/lib/src/model/model_object_builder.dart +++ b/lib/src/model/model_object_builder.dart @@ -3,6 +3,8 @@ // 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/accessor.dart'; import 'package:dartdoc/src/model/container.dart'; import 'package:dartdoc/src/model/library.dart'; @@ -10,7 +12,10 @@ import 'package:dartdoc/src/model/model_element.dart'; import 'package:dartdoc/src/model/package_graph.dart'; import 'package:meta/meta.dart'; -abstract class ModelObjectBuilder { +abstract class ModelObjectBuilder + implements ModelElementBuilder, ElementTypeBuilder {} + +abstract class ModelElementBuilder { ModelElement from(Element e, Library library, {Container enclosingContainer}); ModelElement fromElement(Element e); @@ -21,12 +26,24 @@ abstract class ModelObjectBuilder { @required Accessor setter}); } +abstract class ElementTypeBuilder { + ElementType typeFrom(DartType f, Library library, {ElementType returnedFrom}); +} + abstract class ModelBuilderInterface { /// Override implementations in unit tests to avoid requiring literal /// [ModelElement]s. ModelObjectBuilder get modelBuilder; } +class ModelObjectBuilderImpl extends ModelObjectBuilder + with ModelElementBuilderImpl, ElementTypeBuilderImpl { + @override + final PackageGraph packageGraph; + + ModelObjectBuilderImpl(this.packageGraph); +} + /// Default implementation of the ModelBuilderInterface, requiring a /// [PackageGraph]. mixin ModelBuilder implements ModelBuilderInterface { @@ -35,5 +52,5 @@ mixin ModelBuilder implements ModelBuilderInterface { ModelObjectBuilder _modelBuilder; @override ModelObjectBuilder get modelBuilder => - _modelBuilder ??= ModelElementBuilderImpl(packageGraph); + _modelBuilder ??= ModelObjectBuilderImpl(packageGraph); } diff --git a/lib/src/model/parameter.dart b/lib/src/model/parameter.dart index aca7d2f94a..6b8d9905e6 100644 --- a/lib/src/model/parameter.dart +++ b/lib/src/model/parameter.dart @@ -109,5 +109,5 @@ class Parameter extends ModelElement implements EnclosedElement { ElementType _modelType; ElementType get modelType => _modelType ??= - ElementType.from((originalMember ?? element).type, library, packageGraph); + modelBuilder.typeFrom((originalMember ?? element).type, library); } diff --git a/lib/src/model/type_parameter.dart b/lib/src/model/type_parameter.dart index 6eb556701f..ec11176c88 100644 --- a/lib/src/model/type_parameter.dart +++ b/lib/src/model/type_parameter.dart @@ -36,7 +36,7 @@ class TypeParameter extends ModelElement { if (_boundType == null) { var bound = element.bound; if (bound != null) { - _boundType = ElementType.from(bound, library, packageGraph); + _boundType = modelBuilder.typeFrom(bound, library); } } return _boundType; diff --git a/lib/src/model/typedef.dart b/lib/src/model/typedef.dart index 791937c327..201b0d0c76 100644 --- a/lib/src/model/typedef.dart +++ b/lib/src/model/typedef.dart @@ -21,8 +21,8 @@ abstract class Typedef extends ModelElement TypeAliasElement get element => super.element; ElementType _modelType; - ElementType get modelType => _modelType ??= - ElementType.from(element.aliasedType, library, packageGraph); + ElementType get modelType => + _modelType ??= modelBuilder.typeFrom(element.aliasedType, library); @override Library get enclosingElement => library;