From 39a0774e569d30385f24b250404883e67e3afe74 Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Tue, 12 Oct 2021 10:19:05 -0700 Subject: [PATCH 1/2] Migrate element_type to nnbd --- lib/src/element_type.dart | 199 +++++++++--------- .../templates.runtime_renderers.dart | 73 ++++++- lib/src/model/comment_referable.dart | 7 +- lib/src/model/model_element.dart | 6 + lib/src/model/package_graph.dart | 3 - lib/src/render/element_type_renderer.dart | 28 ++- lib/src/warnings.dart | 1 - .../comment_referable_test.dart | 4 - test/src/utils.dart | 11 +- 9 files changed, 188 insertions(+), 144 deletions(-) diff --git a/lib/src/element_type.dart b/lib/src/element_type.dart index cdf04f88bf..4bdcb5ebd0 100644 --- a/lib/src/element_type.dart +++ b/lib/src/element_type.dart @@ -2,8 +2,6 @@ // 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. -// @dart=2.9 - /// The models used to represent Dart code. library dartdoc.element_type; @@ -14,13 +12,14 @@ import 'package:dartdoc/src/model/comment_referable.dart'; 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'; +import 'package:meta/meta.dart'; mixin ElementTypeBuilderImpl implements ElementTypeBuilder { PackageGraph get packageGraph; @override ElementType typeFrom(DartType f, Library library, - {ElementType returnedFrom}) => + {ElementType? returnedFrom}) => ElementType._from(f, library, packageGraph, returnedFrom: returnedFrom); } @@ -28,21 +27,22 @@ mixin ElementTypeBuilderImpl implements ElementTypeBuilder { /// may link to a [ModelElement]. abstract class ElementType extends Privacy with CommentReferable, Nameable, ModelBuilder { - final DartType _type; + final DartType type; @override final PackageGraph packageGraph; - final ElementType returnedFrom; + final ElementType? returnedFrom; @override final Library library; - ElementType(this._type, this.library, this.packageGraph, this.returnedFrom); + ElementType(this.type, this.library, this.packageGraph, this.returnedFrom); factory ElementType._from( DartType f, Library library, PackageGraph packageGraph, - {ElementType returnedFrom}) { - if (f.element == null || - f.element.kind == ElementKind.DYNAMIC || - f.element.kind == ElementKind.NEVER) { + {ElementType? returnedFrom}) { + var fElement = f.element; + if (fElement == null || + fElement.kind == ElementKind.DYNAMIC || + fElement.kind == ElementKind.NEVER) { if (f is FunctionType) { if (f.alias?.element != null) { return AliasedFunctionTypeElementType( @@ -52,14 +52,14 @@ abstract class ElementType extends Privacy } return UndefinedElementType(f, library, packageGraph, returnedFrom); } else { - var element = packageGraph.modelBuilder.fromElement(f.element); + var element = packageGraph.modelBuilder.fromElement(fElement); // [TypeAliasElement.aliasElement] has different implications. // In that case it is an actual type alias of some kind (generic // or otherwise. Here however aliasElement signals that this is a // type referring to an alias. if (f is! TypeAliasElement && f.alias?.element != null) { - return AliasedElementType( - f, library, packageGraph, element, returnedFrom); + return AliasedElementType(f as ParameterizedType, library, packageGraph, + element, returnedFrom); } assert(f is ParameterizedType || f is TypeParameterType); // TODO(jcollins-g): strip out all the cruft that's accumulated @@ -77,8 +77,8 @@ abstract class ElementType extends Privacy return CallableElementType( f, library, packageGraph, element, returnedFrom); } else if (isGenericTypeAlias) { - return GenericTypeAliasElementType( - f, library, packageGraph, element, returnedFrom); + return GenericTypeAliasElementType(f as TypeParameterType, library, + packageGraph, element, returnedFrom); } if (f is TypeParameterType) { return TypeParameterElementType( @@ -86,7 +86,7 @@ abstract class ElementType extends Privacy } assert(f is ParameterizedType); return ParameterizedElementType( - f, library, packageGraph, element, returnedFrom); + f as ParameterizedType, library, packageGraph, element, returnedFrom); } } @@ -122,29 +122,24 @@ abstract class ElementType extends Privacy @override String toString() => '$type'; - - DartType get type => _type; } /// An [ElementType] that isn't pinned to an Element (or one that is, but whose /// element is irrelevant). class UndefinedElementType extends ElementType { UndefinedElementType(DartType f, Library library, PackageGraph packageGraph, - ElementType returnedFrom) + ElementType? returnedFrom) : super(f, library, packageGraph, returnedFrom); - @override - Element get element => null; - @override bool get isPublic => true; @override String get name { if (type.isVoid) return 'void'; - assert({'Never', 'void', 'dynamic'}.contains(type.element.name), + assert({'Never', 'void', 'dynamic'}.contains(type.element!.name), 'Unrecognized type for UndefinedElementType: ${type.toString()}'); - return type.element.name; + return type.element!.name!; } @override @@ -173,14 +168,14 @@ class UndefinedElementType extends ElementType { Iterable get referenceParents => []; @override - Iterable get referenceGrandparentOverrides => null; + Iterable? get referenceGrandparentOverrides => null; } /// A FunctionType that does not have an underpinning Element. class FunctionTypeElementType extends UndefinedElementType with Rendered, Callable { FunctionTypeElementType(FunctionType f, Library library, - PackageGraph packageGraph, ElementType returnedFrom) + PackageGraph packageGraph, ElementType? returnedFrom) : super(f, library, packageGraph, returnedFrom); /// An unmodifiable list of this function element's type parameters. @@ -199,7 +194,7 @@ class FunctionTypeElementType extends UndefinedElementType class AliasedFunctionTypeElementType extends FunctionTypeElementType with Aliased { AliasedFunctionTypeElementType(FunctionType f, Library library, - PackageGraph packageGraph, ElementType returnedFrom) + PackageGraph packageGraph, ElementType? returnedFrom) : super(f, library, packageGraph, returnedFrom) { assert(type.alias?.element != null); assert(type.alias?.typeArguments != null); @@ -211,47 +206,52 @@ class AliasedFunctionTypeElementType extends FunctionTypeElementType } class ParameterizedElementType extends DefinedElementType with Rendered { - ParameterizedElementType(ParameterizedType type, Library library, - PackageGraph packageGraph, ModelElement element, ElementType returnedFrom) + ParameterizedElementType( + ParameterizedType type, + Library library, + PackageGraph packageGraph, + ModelElement element, + ElementType? returnedFrom) : super(type, library, packageGraph, element, returnedFrom); @override - ParameterizedType get type => super.type; + ParameterizedType get type => super.type as ParameterizedType; @override ElementTypeRenderer get _renderer => packageGraph.rendererFactory.parameterizedElementTypeRenderer; - Iterable _typeArguments; @override - Iterable get typeArguments => - _typeArguments ??= type.typeArguments - .map((f) => modelBuilder.typeFrom(f, library)) - .toList(growable: false); + late final Iterable typeArguments = type.typeArguments + .map((f) => modelBuilder.typeFrom(f, library)) + .toList(growable: false); } /// A [ElementType] whose underlying type was referrred to by a type alias. mixin Aliased implements ElementType, ModelBuilderInterface { + late final Element typeAliasElement = type.alias!.element; + @override - String get name => type.alias.element.name; + String get name => typeAliasElement.name!; @override bool get isTypedef => true; - ModelElement _aliasElement; - ModelElement get aliasElement => - _aliasElement ??= modelBuilder.fromElement(type.alias.element); + late final ModelElement aliasElement = + modelBuilder.fromElement(typeAliasElement); - Iterable _aliasArguments; - Iterable get aliasArguments => - _aliasArguments ??= type.alias.typeArguments - .map((f) => modelBuilder.typeFrom(f, library)) - .toList(growable: false); + late final Iterable aliasArguments = type.alias!.typeArguments + .map((f) => modelBuilder.typeFrom(f, library)) + .toList(growable: false); } class AliasedElementType extends ParameterizedElementType with Aliased { - AliasedElementType(ParameterizedType type, Library library, - PackageGraph packageGraph, ModelElement element, ElementType returnedFrom) + AliasedElementType( + ParameterizedType type, + Library library, + PackageGraph packageGraph, + ModelElement element, + ElementType? returnedFrom) : super(type, library, packageGraph, element, returnedFrom) { assert(type.alias?.element != null); } @@ -269,12 +269,16 @@ class AliasedElementType extends ParameterizedElementType with Aliased { } class TypeParameterElementType extends DefinedElementType { - TypeParameterElementType(TypeParameterType type, Library library, - PackageGraph packageGraph, ModelElement element, ElementType returnedFrom) + TypeParameterElementType( + TypeParameterType type, + Library library, + PackageGraph packageGraph, + ModelElement element, + ElementType? returnedFrom) : super(type, library, packageGraph, element, returnedFrom); @override - TypeParameterType get type => super.type; + TypeParameterType get type => super.type as TypeParameterType; @override String get linkedName => '$name$nullabilitySuffix'; @@ -288,22 +292,16 @@ class TypeParameterElementType extends DefinedElementType { /// An [ElementType] associated with an [Element]. abstract class DefinedElementType extends ElementType { - final ModelElement _modelElement; + final ModelElement modelElement; DefinedElementType(DartType type, Library library, PackageGraph packageGraph, - this._modelElement, ElementType returnedFrom) + this.modelElement, ElementType? returnedFrom) : super(type, library, packageGraph, returnedFrom); - @override Element get element => modelElement.element; - ModelElement get modelElement { - assert(_modelElement != null); - return _modelElement; - } - @override - String get name => type.element.name; + String get name => type.element!.name!; @override String get fullyQualifiedName => modelElement.fullyQualifiedName; @@ -315,34 +313,29 @@ abstract class DefinedElementType extends ElementType { /// would ordinarily do. @override bool get isPublic { - Container canonicalClass = modelElement.packageGraph + var canonicalClass = modelElement.packageGraph .findCanonicalModelElementFor(modelElement.element) ?? modelElement; - return canonicalClass?.isPublic ?? false; + return canonicalClass.isPublic; } DartType get _bound => type; - DartType _instantiatedType; - /// Return this type, instantiated to bounds if it isn't already. @override - DartType get instantiatedType { - if (_instantiatedType == null) { - if (_bound is InterfaceType && - !(_bound as InterfaceType) - .typeArguments - .every((t) => t is InterfaceType)) { - var typeSystem = library.element.typeSystem; - _instantiatedType = typeSystem.instantiateToBounds2( - classElement: _bound.element as ClassElement, - nullabilitySuffix: _bound.nullabilitySuffix); - } else { - _instantiatedType = _bound; - } + late final DartType instantiatedType = () { + if (_bound is InterfaceType && + !(_bound as InterfaceType) + .typeArguments + .every((t) => t is InterfaceType)) { + var typeSystem = library.element.typeSystem; + return typeSystem.instantiateToBounds2( + classElement: _bound.element as ClassElement, + nullabilitySuffix: _bound.nullabilitySuffix); + } else { + return _bound; } - return _instantiatedType; - } + }(); /// The instantiated to bounds type of this type is a subtype of /// [t]. @@ -381,45 +374,39 @@ abstract class DefinedElementType extends ElementType { @override Iterable get referenceGrandparentOverrides => modelElement.referenceGrandparentOverrides; + + @internal + @override + CommentReferable get definingCommentReferable => + modelBuilder.fromElement(element); } /// Any callable ElementType will mix-in this class, whether anonymous or not, /// unless it is an alias reference. -mixin Callable implements ElementType { +mixin Callable on ElementType { List get parameters => type.parameters .map((p) => modelBuilder.from(p, library) as Parameter) .toList(growable: false); - ElementType _returnType; - ElementType get returnType { - _returnType ??= modelBuilder.typeFrom(type.returnType, library); - return _returnType; - } + late final ElementType returnType = + modelBuilder.typeFrom(type.returnType, library); @override // TODO(jcollins-g): mustachio should not require this String get linkedName; @override - FunctionType get type => _type; + FunctionType get type => super.type as FunctionType; } /// This [ElementType] uses an [ElementTypeRenderer] to generate /// some of its parameters. mixin Rendered implements ElementType { - String _linkedName; @override - String get linkedName { - _linkedName ??= _renderer.renderLinkedName(this); - return _linkedName; - } + late final String linkedName = _renderer.renderLinkedName(this); - String _nameWithGenerics; @override - String get nameWithGenerics { - _nameWithGenerics ??= _renderer.renderNameWithGenerics(this); - return _nameWithGenerics; - } + late final String nameWithGenerics = _renderer.renderNameWithGenerics(this); ElementTypeRenderer get _renderer; } @@ -427,29 +414,35 @@ mixin Rendered implements ElementType { /// A callable type that may or may not be backed by a declaration using the generic /// function syntax. class CallableElementType extends DefinedElementType with Rendered, Callable { - CallableElementType(FunctionType t, Library library, - PackageGraph packageGraph, ModelElement element, ElementType returnedFrom) + CallableElementType( + FunctionType t, + Library library, + PackageGraph packageGraph, + ModelElement element, + ElementType? returnedFrom) : super(t, library, packageGraph, element, returnedFrom); @override - String get name => - super.name != null && super.name.isNotEmpty ? super.name : 'Function'; + String get name => super.name.isNotEmpty ? super.name : 'Function'; @override ElementTypeRenderer get _renderer => packageGraph.rendererFactory.callableElementTypeRenderer; - Iterable _typeArguments; @override - Iterable get typeArguments => - _typeArguments ??= (type.alias?.typeArguments ?? []) + late final Iterable typeArguments = + (type.alias?.typeArguments ?? []) .map((f) => modelBuilder.typeFrom(f, library)) .toList(growable: false); } /// A non-callable type backed by a [GenericTypeAliasElement]. class GenericTypeAliasElementType extends TypeParameterElementType { - GenericTypeAliasElementType(TypeParameterType t, Library library, - PackageGraph packageGraph, ModelElement element, ElementType returnedFrom) + GenericTypeAliasElementType( + TypeParameterType t, + Library library, + PackageGraph packageGraph, + ModelElement element, + ElementType? returnedFrom) : super(t, library, packageGraph, element, returnedFrom); } diff --git a/lib/src/generator/templates.runtime_renderers.dart b/lib/src/generator/templates.runtime_renderers.dart index 6ff52c170e..16816e4561 100644 --- a/lib/src/generator/templates.runtime_renderers.dart +++ b/lib/src/generator/templates.runtime_renderers.dart @@ -1883,16 +1883,26 @@ class _Renderer_CommentReferable extends RendererBase { _propertyMapCache.putIfAbsent( CT_, () => { - 'element': Property( - getValue: (CT_ c) => c.element, - renderVariable: (CT_ c, Property self, - List remainingNames) => - self.renderSimpleVariable(c, remainingNames, 'Element'), - isNullValue: (CT_ c) => c.element == null, + 'definingCommentReferable': Property( + getValue: (CT_ c) => c.definingCommentReferable, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_CommentReferable.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.definingCommentReferable == null, renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - renderSimple(c.element, ast, r.template, sink, - parent: r, getters: _invisibleGetters['Element']); + renderSimple( + c.definingCommentReferable, ast, r.template, sink, + parent: r, + getters: _invisibleGetters['CommentReferable']); }, ), 'href': Property( @@ -3556,6 +3566,28 @@ class _Renderer_DefinedElementType extends RendererBase { CT_, () => { ..._Renderer_ElementType.propertyMap(), + 'definingCommentReferable': Property( + getValue: (CT_ c) => c.definingCommentReferable, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_CommentReferable.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.definingCommentReferable == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + renderSimple( + c.definingCommentReferable, ast, r.template, sink, + parent: r, + getters: _invisibleGetters['CommentReferable']); + }, + ), 'element': Property( getValue: (CT_ c) => c.element, renderVariable: (CT_ c, Property self, @@ -9511,6 +9543,28 @@ class _Renderer_ModelElement extends RendererBase { getters: _invisibleGetters['DartdocOptionContext']); }, ), + 'definingCommentReferable': Property( + getValue: (CT_ c) => c.definingCommentReferable, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_CommentReferable.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.definingCommentReferable == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + renderSimple( + c.definingCommentReferable, ast, r.template, sink, + parent: r, + getters: _invisibleGetters['CommentReferable']); + }, + ), 'definingLibrary': Property( getValue: (CT_ c) => c.definingLibrary, renderVariable: @@ -15177,7 +15231,7 @@ const _invisibleGetters = { 'referenceGrandparentOverrides', 'referenceName', 'library', - 'element' + 'definingCommentReferable' }, 'CompilationUnitElement': { 'hashCode', @@ -15672,7 +15726,6 @@ const _invisibleGetters = { 'sdk', 'allLibrariesAdded', 'name', - 'element', 'implementors', 'documentedExtensions', 'extensions', diff --git a/lib/src/model/comment_referable.dart b/lib/src/model/comment_referable.dart index 2f0f15be4c..7c3f022b04 100644 --- a/lib/src/model/comment_referable.dart +++ b/lib/src/model/comment_referable.dart @@ -225,6 +225,9 @@ mixin CommentReferable implements Nameable, ModelBuilderInterface { // TODO(jcollins-g): Eliminate need for this in markdown_processor. Library? get library => null; - // TODO(jcollins-g): Eliminate need for this in markdown_processor. - Element? get element; + @internal + + /// For testing / comparison only, get the comment referable from where this + /// [ElementType] was defined. Override where an [Element] is available. + CommentReferable get definingCommentReferable => this; } diff --git a/lib/src/model/model_element.dart b/lib/src/model/model_element.dart index 096e3ee33c..b9e9b9a07d 100644 --- a/lib/src/model/model_element.dart +++ b/lib/src/model/model_element.dart @@ -996,4 +996,10 @@ abstract class ModelElement extends Canonicalization return modelElementRenderer.renderLinkedName(this); } + + @internal + @override + CommentReferable get definingCommentReferable => element == null + ? super.definingCommentReferable + : modelBuilder.fromElement(element); } diff --git a/lib/src/model/package_graph.dart b/lib/src/model/package_graph.dart index a0c1b0ad04..be9690206c 100644 --- a/lib/src/model/package_graph.dart +++ b/lib/src/model/package_graph.dart @@ -54,9 +54,6 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { @override String get name => null; - @override - Element get element => null; - /// Call during initialization to add a library to this [PackageGraph]. /// /// Libraries added in this manner are assumed to be part of documented diff --git a/lib/src/render/element_type_renderer.dart b/lib/src/render/element_type_renderer.dart index cba7493157..93dad025ea 100644 --- a/lib/src/render/element_type_renderer.dart +++ b/lib/src/render/element_type_renderer.dart @@ -182,14 +182,12 @@ class CallableElementTypeRendererHtml String renderNameWithGenerics(CallableElementType elementType) { var buf = StringBuffer(); buf.write(elementType.name); - if (elementType.typeArguments != null) { - if (elementType.typeArguments.isNotEmpty && - !elementType.typeArguments.every((t) => t.name == 'dynamic')) { - buf.write('<'); - buf.writeAll( - elementType.typeArguments.map((t) => t.nameWithGenerics), ', '); - buf.write('>'); - } + if (elementType.typeArguments.isNotEmpty && + !elementType.typeArguments.every((t) => t.name == 'dynamic')) { + buf.write('<'); + buf.writeAll( + elementType.typeArguments.map((t) => t.nameWithGenerics), ', '); + buf.write('>'); } return wrapNullability(elementType, buf.toString()); } @@ -345,14 +343,12 @@ class CallableElementTypeRendererMd String renderNameWithGenerics(CallableElementType elementType) { var buf = StringBuffer(); buf.write(elementType.name); - if (elementType.typeArguments != null) { - if (elementType.typeArguments.isNotEmpty && - !elementType.typeArguments.every((t) => t.name == 'dynamic')) { - buf.write('<'); - buf.writeAll( - elementType.typeArguments.map((t) => t.nameWithGenerics), ', '); - buf.write('>'); - } + if (elementType.typeArguments.isNotEmpty && + !elementType.typeArguments.every((t) => t.name == 'dynamic')) { + buf.write('<'); + buf.writeAll( + elementType.typeArguments.map((t) => t.nameWithGenerics), ', '); + buf.write('>'); } return wrapNullability(elementType, buf.toString()); } diff --git a/lib/src/warnings.dart b/lib/src/warnings.dart index 7d6a005d3f..36cbe48661 100644 --- a/lib/src/warnings.dart +++ b/lib/src/warnings.dart @@ -282,7 +282,6 @@ const Map packageWarningDefinitions = /// Something that package warnings can be called on. Optionally associated /// with an analyzer [element]. mixin Warnable implements Canonicalization, CommentReferable { - @override Element? get element; Warnable? get enclosingElement; diff --git a/test/comment_referable/comment_referable_test.dart b/test/comment_referable/comment_referable_test.dart index 84c2465a12..74afa135ee 100644 --- a/test/comment_referable/comment_referable_test.dart +++ b/test/comment_referable/comment_referable_test.dart @@ -6,7 +6,6 @@ library dartdoc.comment_reference_test; -import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/model/comment_referable.dart'; import 'package:dartdoc/src/model/model_object_builder.dart'; import 'package:dartdoc/src/model/nameable.dart'; @@ -34,9 +33,6 @@ abstract class Base extends Nameable with CommentReferable { referenceBy(value.split(_separator), allowTree: allowTree ?? (_) => true, filter: filter ?? (_) => true); - @override - Element get element => throw UnimplementedError(); - @override Iterable get referenceGrandparentOverrides => null; } diff --git a/test/src/utils.dart b/test/src/utils.dart index f902569de1..bf3e3c4b42 100644 --- a/test/src/utils.dart +++ b/test/src/utils.dart @@ -204,11 +204,12 @@ two:lib/ /// as the original lookup code returns canonicalized results and the /// new lookup code is only guaranteed to return equivalent results. MatchingLinkResult definingLinkResult(MatchingLinkResult originalResult) { - if (originalResult.commentReferable?.element != null) { - return MatchingLinkResult( - originalResult.commentReferable.modelBuilder - .fromElement(originalResult.commentReferable.element), - warn: originalResult.warn); + var definingReferable = + originalResult.commentReferable?.definingCommentReferable; + + if (definingReferable != null && + definingReferable != originalResult.commentReferable) { + return MatchingLinkResult(definingReferable, warn: originalResult.warn); } return originalResult; } From c2ac41e8d65289803c558588b01b5b84dbd5b1b6 Mon Sep 17 00:00:00 2001 From: Janice Collins Date: Tue, 12 Oct 2021 11:09:11 -0700 Subject: [PATCH 2/2] Migrate markdown_processor and matching_link_result --- lib/src/markdown_processor.dart | 60 ++++++++++--------- lib/src/matching_link_result.dart | 4 +- lib/src/quiver.dart | 6 +- .../lib/constructor_tearoffs.dart | 9 +-- 4 files changed, 40 insertions(+), 39 deletions(-) diff --git a/lib/src/markdown_processor.dart b/lib/src/markdown_processor.dart index 8e0f842aea..0f86c5e8ea 100644 --- a/lib/src/markdown_processor.dart +++ b/lib/src/markdown_processor.dart @@ -2,8 +2,6 @@ // 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. -// @dart=2.9 - /// Utility code to convert markdown comments to html. library dartdoc.markdown_processor; @@ -162,7 +160,7 @@ class _IterableBlockParser extends md.BlockParser { /// Return false if the passed [referable] is an unnamed [Constructor], /// or if it is shadowing another type of element, or is a parameter of /// one of the above. -bool _rejectUnnamedAndShadowingConstructors(CommentReferable referable) { +bool _rejectUnnamedAndShadowingConstructors(CommentReferable? referable) { if (referable is Constructor) { if (referable.isUnnamedConstructor) return false; if (referable.enclosingElement @@ -175,11 +173,11 @@ bool _rejectUnnamedAndShadowingConstructors(CommentReferable referable) { /// Return false unless the passed [referable] represents a callable object. /// Allows constructors but does not require them. -bool _requireCallable(CommentReferable referable) => +bool _requireCallable(CommentReferable? referable) => referable is ModelElement && referable.isCallable; /// Return false unless the passed [referable] represents a constructor. -bool _requireConstructor(CommentReferable referable) => +bool _requireConstructor(CommentReferable? referable) => referable is Constructor; /// Implements _getMatchingLinkElement via [CommentReferable.referenceBy]. @@ -188,8 +186,8 @@ MatchingLinkResult _getMatchingLinkElementCommentReferable( var commentReference = warnable.commentRefs[codeRef] ?? ModelCommentReference.synthetic(codeRef); - bool Function(CommentReferable) filter; - bool Function(CommentReferable) allowTree; + late final bool Function(CommentReferable?) filter; + late final bool Function(CommentReferable?) allowTree; // Constructor references are pretty ambiguous by nature since they can be // declared with the same name as the class they are constructing, and even @@ -197,31 +195,33 @@ MatchingLinkResult _getMatchingLinkElementCommentReferable( // named the same as members. // Maybe clean this up with inspiration from constructor tear-off syntax? if (commentReference.allowUnnamedConstructor) { + allowTree = (_) => true; // Neither reject, nor require, a default constructor in the event // the comment reference structure implies one. (We can not require it // in case a library name is the same as a member class name and the class // is the intended lookup). For example, [FooClass.FooClass] structurally // "looks like" a default constructor, so we should allow it here. - filter = commentReference.hasCallableHint ? _requireCallable : null; + filter = commentReference.hasCallableHint ? _requireCallable : (_) => true; } else if (commentReference.hasConstructorHint && commentReference.hasCallableHint) { + allowTree = (_) => true; // This takes precedence over the callable hint if both are present -- // pick a constructor if and only constructor if we see `new`. filter = _requireConstructor; } else if (commentReference.hasCallableHint) { + allowTree = (_) => true; // Trailing parens indicate we are looking for a callable. filter = _requireCallable; } else { - // Without hints, reject unnamed constructors and their parameters to force - // resolution to the class. - filter = _rejectUnnamedAndShadowingConstructors; - if (!commentReference.allowUnnamedConstructorParameter) { allowTree = _rejectUnnamedAndShadowingConstructors; + } else { + allowTree = (_) => true; } + // Without hints, reject unnamed constructors and their parameters to force + // resolution to the class. + filter = _rejectUnnamedAndShadowingConstructors; } - allowTree ??= (_) => true; - filter ??= (_) => true; var lookupResult = warnable.referenceBy(commentReference.referenceBy, allowTree: allowTree, filter: filter); @@ -239,7 +239,10 @@ md.Node _makeLinkNode(String codeRef, Warnable warnable) { if (linkedElement is ModelElement && linkedElement.isDeprecated) { anchor.attributes['class'] = 'deprecated'; } - anchor.attributes['href'] = linkedElement.href; + var href = linkedElement.href; + if (href != null) { + anchor.attributes['href'] = href; + } return anchor; } // else this would be linkedElement.linkedName, but link bodies are slightly @@ -250,9 +253,8 @@ md.Node _makeLinkNode(String codeRef, Warnable warnable) { // current element. warnable.warn(PackageWarning.unresolvedDocReference, message: codeRef, - referredFrom: warnable.documentationIsLocal - ? null - : warnable.documentationFrom); + referredFrom: + warnable.documentationIsLocal ? [] : warnable.documentationFrom); } } @@ -328,8 +330,8 @@ Iterable findFreeHangingGenericsPositions(String string) sync* { } class MarkdownDocument extends md.Document { - factory MarkdownDocument.withElementLinkResolver(Canonicalization element) { - md.Node /*?*/ linkResolver(String name, [String /*?*/ _]) { + factory MarkdownDocument.withElementLinkResolver(Warnable element) { + md.Node? linkResolver(String name, [String? _]) { if (name.isEmpty) { return null; } @@ -343,11 +345,11 @@ class MarkdownDocument extends md.Document { } MarkdownDocument( - {Iterable blockSyntaxes, - Iterable inlineSyntaxes, - md.ExtensionSet extensionSet, - md.Resolver linkResolver, - md.Resolver imageLinkResolver}) + {Iterable? blockSyntaxes, + Iterable? inlineSyntaxes, + md.ExtensionSet? extensionSet, + md.Resolver? linkResolver, + md.Resolver? imageLinkResolver}) : super( blockSyntaxes: blockSyntaxes, inlineSyntaxes: inlineSyntaxes, @@ -362,7 +364,7 @@ class MarkdownDocument extends md.Document { String text, bool processFullText) { var hasExtendedContent = false; var lines = LineSplitter.split(text).toList(); - md.Node firstNode; + md.Node? firstNode; var nodes = []; for (var node in _IterableBlockParser(lines, this).parseLinesGenerator()) { if (firstNode != null) { @@ -387,7 +389,7 @@ class MarkdownDocument extends md.Document { nodes.insertAll(i, inlineNodes); i += inlineNodes.length - 1; } else if (node is md.Element && node.children != null) { - _parseInlineContent(node.children); + _parseInlineContent(node.children!); } } } @@ -407,7 +409,7 @@ class _InlineCodeSyntax extends md.InlineSyntax { @override bool onMatch(md.InlineParser parser, Match match) { - var element = md.Element.text('code', _htmlEscape.convert(match[1] /*!*/)); + var element = md.Element.text('code', _htmlEscape.convert(match[1]!)); parser.addNode(element); return true; } @@ -416,7 +418,7 @@ class _InlineCodeSyntax extends md.InlineSyntax { class _AutolinkWithoutScheme extends md.AutolinkSyntax { @override bool onMatch(md.InlineParser parser, Match match) { - var url = match[1] /*!*/; + var url = match[1]!; var text = _htmlEscape.convert(url).replaceFirst(_hideSchemes, ''); var anchor = md.Element.text('a', text); anchor.attributes['href'] = url; diff --git a/lib/src/matching_link_result.dart b/lib/src/matching_link_result.dart index ad18a8f2d6..615d28b850 100644 --- a/lib/src/matching_link_result.dart +++ b/lib/src/matching_link_result.dart @@ -2,14 +2,12 @@ // 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. -// @dart=2.9 - import 'package:dartdoc/src/model/comment_referable.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/quiver.dart'; class MatchingLinkResult { - final CommentReferable commentReferable; + final CommentReferable? commentReferable; final bool warn; MatchingLinkResult(this.commentReferable, {this.warn = true}); diff --git a/lib/src/quiver.dart b/lib/src/quiver.dart index dd36843303..614d58b937 100644 --- a/lib/src/quiver.dart +++ b/lib/src/quiver.dart @@ -15,15 +15,15 @@ Iterable concat(Iterable> iterables) => // From lib/src/core/hash.dart: /// Generates a hash code for two objects. -int hash2(Object a, Object b) => +int hash2(Object? a, Object? b) => _finish(_combine(_combine(0, a.hashCode), b.hashCode)); /// Generates a hash code for three objects. -int hash3(Object a, Object b, Object c) => _finish( +int hash3(Object? a, Object? b, Object? c) => _finish( _combine(_combine(_combine(0, a.hashCode), b.hashCode), c.hashCode)); /// Generates a hash code for four objects. -int hash4(Object a, Object b, Object c, Object d) => _finish(_combine( +int hash4(Object? a, Object? b, Object? c, Object? d) => _finish(_combine( _combine(_combine(_combine(0, a.hashCode), b.hashCode), c.hashCode), d.hashCode)); diff --git a/testing/test_package_experiments/lib/constructor_tearoffs.dart b/testing/test_package_experiments/lib/constructor_tearoffs.dart index eb6d4b50bf..6c9df04cf7 100644 --- a/testing/test_package_experiments/lib/constructor_tearoffs.dart +++ b/testing/test_package_experiments/lib/constructor_tearoffs.dart @@ -11,6 +11,7 @@ library constructor_tearoffs; abstract class A { final int number; + /// Even though this is abstract, dartdoc should still allow referring to /// [A.new]. A.new(this.number); @@ -59,11 +60,11 @@ typedef Fstring = F; typedef NotAClass = Function; /// Mixins don't have constructors either, so disallow `M.new`. -mixin M on C { -} +mixin M on C {} void func() {} -void funcTypeParams(T something, U different) {} +void funcTypeParams( + T something, U different) {} const aFunc = func; const aFuncParams = funcTypeParams; @@ -78,4 +79,4 @@ const aTearOffDefaultConstructorArgs = F.new; const aTearOffDefaultConstructorTypedef = Fstring.new; // TODO(jcollins-g): does not work @ analyzer 2.2 -//const aTearOffDefaultConstructorArgsTypedef = Ft.new; \ No newline at end of file +//const aTearOffDefaultConstructorArgsTypedef = Ft.new;