diff --git a/lib/dartdoc.dart b/lib/dartdoc.dart index 453897966f..00564432aa 100644 --- a/lib/dartdoc.dart +++ b/lib/dartdoc.dart @@ -2,7 +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 /// A documentation generator for Dart. /// /// Library interface is still experimental. diff --git a/lib/src/dartdoc_options.dart b/lib/src/dartdoc_options.dart index 561e6d7ef0..43720516f2 100644 --- a/lib/src/dartdoc_options.dart +++ b/lib/src/dartdoc_options.dart @@ -58,8 +58,8 @@ class DartdocFileMissing extends DartdocOptionError { /// the 'categories' keyword in the options file, and populated by the /// [CategoryConfiguration] class. class CategoryDefinition { - /// Internal name of the category. - final String name; + /// Internal name of the category, or null for the default category. + final String? name; /// Displayed name of the category in docs, or null if there is none. final String? _displayName; @@ -71,7 +71,7 @@ class CategoryDefinition { CategoryDefinition(this.name, this._displayName, this.documentationMarkdown); /// Returns the [_displayName], if available, or else simply [name]. - String get displayName => _displayName ?? name; + String get displayName => _displayName ?? name ?? ''; } /// A configuration class that can interpret category definitions from a YAML @@ -1246,7 +1246,7 @@ class DartdocOptionContext extends DartdocOptionContextBase List get dropTextFrom => optionSet['dropTextFrom'].valueAt(context); - String get examplePathPrefix => + String? get examplePathPrefix => optionSet['examplePathPrefix'].valueAt(context); // TODO(srawlins): This memoization saved a lot of time in unit testing, but diff --git a/lib/src/element_type.dart b/lib/src/element_type.dart index 4bdcb5ebd0..4779815ab7 100644 --- a/lib/src/element_type.dart +++ b/lib/src/element_type.dart @@ -43,6 +43,7 @@ abstract class ElementType extends Privacy if (fElement == null || fElement.kind == ElementKind.DYNAMIC || fElement.kind == ElementKind.NEVER) { + // [UndefinedElementType]s. if (f is FunctionType) { if (f.alias?.element != null) { return AliasedFunctionTypeElementType( @@ -51,43 +52,42 @@ abstract class ElementType extends Privacy return FunctionTypeElementType(f, library, packageGraph, returnedFrom); } return UndefinedElementType(f, library, packageGraph, returnedFrom); - } else { - 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 as ParameterizedType, library, packageGraph, - element, returnedFrom); - } - assert(f is ParameterizedType || f is TypeParameterType); - // TODO(jcollins-g): strip out all the cruft that's accumulated - // here for non-generic type aliases. - var isGenericTypeAlias = f.alias?.element != null && f is! InterfaceType; - if (f is FunctionType) { - assert(f is ParameterizedType); - // This is an indication we have an extremely out of date analyzer.... - assert( - !isGenericTypeAlias, 'should never occur: out of date analyzer?'); - // And finally, delete this case and its associated class - // after https://dart-review.googlesource.com/c/sdk/+/201520 - // is in all published versions of analyzer this version of dartdoc - // is compatible with. - return CallableElementType( - f, library, packageGraph, element, returnedFrom); - } else if (isGenericTypeAlias) { - return GenericTypeAliasElementType(f as TypeParameterType, library, - packageGraph, element, returnedFrom); - } - if (f is TypeParameterType) { - return TypeParameterElementType( - f, library, packageGraph, element, returnedFrom); - } - assert(f is ParameterizedType); - return ParameterizedElementType( + } + // [DefinedElementType]s. + 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 as ParameterizedType, library, packageGraph, element, returnedFrom); } + assert(f is ParameterizedType || f is TypeParameterType); + // TODO(jcollins-g): strip out all the cruft that's accumulated + // here for non-generic type aliases. + var isGenericTypeAlias = f.alias?.element != null && f is! InterfaceType; + if (f is FunctionType) { + assert(f is ParameterizedType); + // This is an indication we have an extremely out of date analyzer.... + assert(!isGenericTypeAlias, 'should never occur: out of date analyzer?'); + // And finally, delete this case and its associated class + // after https://dart-review.googlesource.com/c/sdk/+/201520 + // is in all published versions of analyzer this version of dartdoc + // is compatible with. + return CallableElementType( + f, library, packageGraph, element, returnedFrom); + } else if (isGenericTypeAlias) { + return GenericTypeAliasElementType( + f as TypeParameterType, library, packageGraph, element, returnedFrom); + } + if (f is TypeParameterType) { + return TypeParameterElementType( + f, library, packageGraph, element, returnedFrom); + } + assert(f is ParameterizedType); + return ParameterizedElementType( + f as ParameterizedType, library, packageGraph, element, returnedFrom); } bool get canHaveParameters => false; @@ -260,7 +260,7 @@ class AliasedElementType extends ParameterizedElementType with Aliased { ParameterizedType get type; /// Parameters, if available, for the underlying typedef. - List get aliasedParameters => + late final List aliasedParameters = modelElement.isCallable ? modelElement.parameters : []; @override @@ -298,7 +298,7 @@ abstract class DefinedElementType extends ElementType { this.modelElement, ElementType? returnedFrom) : super(type, library, packageGraph, returnedFrom); - Element get element => modelElement.element; + Element get element => modelElement.element!; @override String get name => type.element!.name!; @@ -372,7 +372,7 @@ abstract class DefinedElementType extends ElementType { modelElement.referenceParents; @override - Iterable get referenceGrandparentOverrides => + Iterable? get referenceGrandparentOverrides => modelElement.referenceGrandparentOverrides; @internal diff --git a/lib/src/generator/generator_utils.dart b/lib/src/generator/generator_utils.dart index 23a5173440..1be0c621d2 100644 --- a/lib/src/generator/generator_utils.dart +++ b/lib/src/generator/generator_utils.dart @@ -14,9 +14,9 @@ import 'package:dartdoc/src/model/model_element.dart'; /// will likely want the same content for this. String generateCategoryJson(Iterable categories, bool pretty) { // ignore: omit_local_variable_types - final List> indexItems = + final List> indexItems = categories.map((Categorization categorization) { - final data = { + final data = { 'name': categorization.name, 'qualifiedName': categorization.fullyQualifiedName, 'href': categorization.href, @@ -49,7 +49,7 @@ String generateCategoryJson(Iterable categories, bool pretty) { String generateSearchIndexJson( Iterable indexedElements, bool pretty) { final indexItems = indexedElements.map((Indexable indexable) { - final data = { + final data = { 'name': indexable.name, 'qualifiedName': indexable.fullyQualifiedName, 'href': indexable.href, @@ -57,13 +57,13 @@ String generateSearchIndexJson( 'overriddenDepth': indexable.overriddenDepth, }; if (indexable is ModelElement) { - data['packageName'] = indexable.package.name; + data['packageName'] = indexable.package?.name; } if (indexable is EnclosedElement) { final ee = indexable as EnclosedElement; - data['enclosedBy'] = { - 'name': ee.enclosingElement.name, - 'type': ee.enclosingElement.kind + data['enclosedBy'] = { + 'name': ee.enclosingElement!.name, + 'type': ee.enclosingElement!.kind }; data['qualifiedName'] = indexable.fullyQualifiedName; diff --git a/lib/src/generator/template_data.dart b/lib/src/generator/template_data.dart index 95b58832d5..3d553b621e 100644 --- a/lib/src/generator/template_data.dart +++ b/lib/src/generator/template_data.dart @@ -51,7 +51,8 @@ abstract class TemplateData { String get bareHref { if (self is Indexable) { - return (self as Indexable).href.replaceAll(htmlBasePlaceholder, ''); + var selfHref = (self as Indexable).href ?? ''; + return selfHref.replaceAll(htmlBasePlaceholder, ''); } return ''; } diff --git a/lib/src/generator/templates.aot_renderers_for_md.dart b/lib/src/generator/templates.aot_renderers_for_md.dart index 7abba63417..7aef7ce29d 100644 --- a/lib/src/generator/templates.aot_renderers_for_md.dart +++ b/lib/src/generator/templates.aot_renderers_for_md.dart @@ -712,12 +712,10 @@ String renderClass(_i1.ClassTemplateData context0) { '''); var context11 = context2.potentiallyApplicableExtensions; if (context11 != null) { - for (var context12 in context11) { - buffer.writeln(); - buffer.write(''' + buffer.writeln(); + buffer.write(''' - '''); - buffer.write(context12.linkedName.toString()); - } + buffer.write(context2.linkedName.toString()); } } buffer.writeln(); @@ -726,13 +724,13 @@ String renderClass(_i1.ClassTemplateData context0) { buffer.write(''' **Annotations** '''); - var context13 = context2.annotations; - if (context13 != null) { - for (var context14 in context13) { + var context12 = context2.annotations; + if (context12 != null) { + for (var context13 in context12) { buffer.writeln(); buffer.write(''' - '''); - buffer.write(context14.linkedNameWithParameters.toString()); + buffer.write(context13.linkedNameWithParameters.toString()); } } } @@ -743,25 +741,25 @@ String renderClass(_i1.ClassTemplateData context0) { buffer.write(''' ## Constructors '''); - var context15 = context2.publicConstructorsSorted; - if (context15 != null) { - for (var context16 in context15) { + var context14 = context2.publicConstructorsSorted; + if (context14 != null) { + for (var context15 in context14) { buffer.writeln(); - buffer.write(context16.linkedName.toString()); + buffer.write(context15.linkedName.toString()); buffer.write(''' ('''); - buffer.write(context16.linkedParams.toString()); + buffer.write(context15.linkedParams.toString()); buffer.write(''') '''); - buffer.write(context16.oneLineDoc.toString()); + buffer.write(context15.oneLineDoc.toString()); buffer.write(' '); - buffer.write(context16.extendedDocLink.toString()); + buffer.write(context15.extendedDocLink.toString()); buffer.write(' '); - if (context16.isConst == true) { + if (context15.isConst == true) { buffer.write('''_const_'''); } buffer.write(' '); - if (context16.isFactory == true) { + if (context15.isFactory == true) { buffer.write('''_factory_'''); } buffer.writeln(); @@ -774,12 +772,12 @@ String renderClass(_i1.ClassTemplateData context0) { buffer.write(''' ## Properties '''); - var context17 = context2.publicInstanceFieldsSorted; - if (context17 != null) { - for (var context18 in context17) { + var context16 = context2.publicInstanceFieldsSorted; + if (context16 != null) { + for (var context17 in context16) { buffer.writeln(); buffer.write( - _renderClass_partial_property_5(context18, context2, context0)); + _renderClass_partial_property_5(context17, context2, context0)); buffer.writeln(); } } @@ -790,12 +788,12 @@ String renderClass(_i1.ClassTemplateData context0) { buffer.write(''' ## Methods '''); - var context19 = context2.publicInstanceMethodsSorted; - if (context19 != null) { - for (var context20 in context19) { + var context18 = context2.publicInstanceMethodsSorted; + if (context18 != null) { + for (var context19 in context18) { buffer.writeln(); buffer.write( - _renderClass_partial_callable_6(context20, context2, context0)); + _renderClass_partial_callable_6(context19, context2, context0)); buffer.writeln(); } } @@ -806,12 +804,12 @@ String renderClass(_i1.ClassTemplateData context0) { buffer.write(''' ## Operators '''); - var context21 = context2.publicInstanceOperatorsSorted; - if (context21 != null) { - for (var context22 in context21) { + var context20 = context2.publicInstanceOperatorsSorted; + if (context20 != null) { + for (var context21 in context20) { buffer.writeln(); buffer.write( - _renderClass_partial_callable_6(context22, context2, context0)); + _renderClass_partial_callable_6(context21, context2, context0)); buffer.writeln(); } } @@ -822,12 +820,12 @@ String renderClass(_i1.ClassTemplateData context0) { buffer.write(''' ## Static Properties '''); - var context23 = context2.publicVariableStaticFieldsSorted; - if (context23 != null) { - for (var context24 in context23) { + var context22 = context2.publicVariableStaticFieldsSorted; + if (context22 != null) { + for (var context23 in context22) { buffer.writeln(); buffer.write( - _renderClass_partial_property_5(context24, context2, context0)); + _renderClass_partial_property_5(context23, context2, context0)); buffer.writeln(); } } @@ -838,12 +836,12 @@ String renderClass(_i1.ClassTemplateData context0) { buffer.write(''' ## Static Methods '''); - var context25 = context2.publicStaticMethodsSorted; - if (context25 != null) { - for (var context26 in context25) { + var context24 = context2.publicStaticMethodsSorted; + if (context24 != null) { + for (var context25 in context24) { buffer.writeln(); buffer.write( - _renderClass_partial_callable_6(context26, context2, context0)); + _renderClass_partial_callable_6(context25, context2, context0)); buffer.writeln(); } } @@ -854,12 +852,12 @@ String renderClass(_i1.ClassTemplateData context0) { buffer.write(''' ## Constants '''); - var context27 = context2.publicConstantFieldsSorted; - if (context27 != null) { - for (var context28 in context27) { + var context26 = context2.publicConstantFieldsSorted; + if (context26 != null) { + for (var context27 in context26) { buffer.writeln(); buffer.write( - _renderClass_partial_constant_7(context28, context2, context0)); + _renderClass_partial_constant_7(context27, context2, context0)); buffer.writeln(); } } diff --git a/lib/src/generator/templates.runtime_renderers.dart b/lib/src/generator/templates.runtime_renderers.dart index 01c2f5ab52..56508a6a6f 100644 --- a/lib/src/generator/templates.runtime_renderers.dart +++ b/lib/src/generator/templates.runtime_renderers.dart @@ -731,10 +731,11 @@ class _Renderer_Categorization extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'List'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.categoryNames == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.categoryNames.map((e) => - _render_String(e, ast, r.template, sink, parent: r)); + renderSimple(c.categoryNames, ast, r.template, sink, + parent: r, getters: _invisibleGetters['List']); }, ), 'displayedCategories': Property( @@ -828,10 +829,11 @@ class _Renderer_Categorization extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'List'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.subCategoryNames == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.subCategoryNames.map((e) => - _render_String(e, ast, r.template, sink, parent: r)); + renderSimple(c.subCategoryNames, ast, r.template, sink, + parent: r, getters: _invisibleGetters['List']); }, ), }); @@ -1599,11 +1601,11 @@ class _Renderer_Class extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'List'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.allModelElements == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.allModelElements.map((e) => _render_ModelElement( - e, ast, r.template, sink, - parent: r)); + renderSimple(c.allModelElements, ast, r.template, sink, + parent: r, getters: _invisibleGetters['List']); }, ), 'constantFields': Property( @@ -2269,25 +2271,6 @@ class _Renderer_Constructor extends RendererBase { parent: r); }, ), - 'href': Property( - getValue: (CT_ c) => c.href, - renderVariable: - (CT_ c, Property self, List remainingNames) { - if (remainingNames.isEmpty) { - return self.getValue(c).toString(); - } - var name = remainingNames.first; - var nextProperty = - _Renderer_String.propertyMap().getValue(name); - return nextProperty.renderVariable(self.getValue(c), - nextProperty, [...remainingNames.skip(1)]); - }, - isNullValue: (CT_ c) => c.href == null, - renderValue: (CT_ c, RendererBase r, - List ast, StringSink sink) { - _render_String(c.href, ast, r.template, sink, parent: r); - }, - ), 'isConst': Property( getValue: (CT_ c) => c.isConst, renderVariable: (CT_ c, Property self, @@ -2786,11 +2769,11 @@ class _Renderer_Container extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'Iterable'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.allModelElements == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.allModelElements.map((e) => _render_ModelElement( - e, ast, r.template, sink, - parent: r)); + renderSimple(c.allModelElements, ast, r.template, sink, + parent: r, getters: _invisibleGetters['Iterable']); }, ), 'constantFields': Property( @@ -2811,10 +2794,11 @@ class _Renderer_Container extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'Iterable'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.declaredFields == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.declaredFields.map((e) => - _render_Field(e, ast, r.template, sink, parent: r)); + renderSimple(c.declaredFields, ast, r.template, sink, + parent: r, getters: _invisibleGetters['Iterable']); }, ), 'declaredMethods': Property( @@ -2823,10 +2807,11 @@ class _Renderer_Container extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'Iterable'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.declaredMethods == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.declaredMethods.map((e) => - _render_Method(e, ast, r.template, sink, parent: r)); + renderSimple(c.declaredMethods, ast, r.template, sink, + parent: r, getters: _invisibleGetters['Iterable']); }, ), 'declaredOperators': Property( @@ -3035,6 +3020,46 @@ class _Renderer_Container extends RendererBase { self.renderSimpleVariable(c, remainingNames, 'bool'), getBool: (CT_ c) => c.isMixin == true, ), + 'library': Property( + getValue: (CT_ c) => c.library, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_Library.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.library == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_Library(c.library, ast, r.template, sink, + parent: r); + }, + ), + 'package': Property( + getValue: (CT_ c) => c.package, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_Package.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.package == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_Package(c.package, ast, r.template, sink, + parent: r); + }, + ), 'publicConstantFields': Property( getValue: (CT_ c) => c.publicConstantFields, renderVariable: (CT_ c, Property self, @@ -3705,12 +3730,13 @@ class _Renderer_DefinedElementType extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'Iterable'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => + c.referenceGrandparentOverrides == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.referenceGrandparentOverrides.map((e) => - renderSimple(e, ast, r.template, sink, - parent: r, - getters: _invisibleGetters['CommentReferable'])); + renderSimple( + c.referenceGrandparentOverrides, ast, r.template, sink, + parent: r, getters: _invisibleGetters['Iterable']); }, ), 'referenceParents': Property( @@ -4489,11 +4515,11 @@ class _Renderer_Extension extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'List'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.allModelElements == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.allModelElements.map((e) => _render_ModelElement( - e, ast, r.template, sink, - parent: r)); + renderSimple(c.allModelElements, ast, r.template, sink, + parent: r, getters: _invisibleGetters['List']); }, ), 'alwaysApplies': Property( @@ -4509,10 +4535,11 @@ class _Renderer_Extension extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'List'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.declaredFields == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.declaredFields.map((e) => - _render_Field(e, ast, r.template, sink, parent: r)); + renderSimple(c.declaredFields, ast, r.template, sink, + parent: r, getters: _invisibleGetters['List']); }, ), 'declaredMethods': Property( @@ -4521,10 +4548,25 @@ class _Renderer_Extension extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'List'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.declaredMethods == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.declaredMethods.map((e) => - _render_Method(e, ast, r.template, sink, parent: r)); + renderSimple(c.declaredMethods, ast, r.template, sink, + parent: r, getters: _invisibleGetters['List']); + }, + ), + 'element': Property( + getValue: (CT_ c) => c.element, + renderVariable: (CT_ c, Property self, + List remainingNames) => + self.renderSimpleVariable( + c, remainingNames, 'ExtensionElement'), + isNullValue: (CT_ c) => c.element == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + renderSimple(c.element, ast, r.template, sink, + parent: r, + getters: _invisibleGetters['ExtensionElement']); }, ), 'enclosingElement': Property( @@ -4588,25 +4630,6 @@ class _Renderer_Extension extends RendererBase { parent: r); }, ), - 'href': Property( - getValue: (CT_ c) => c.href, - renderVariable: - (CT_ c, Property self, List remainingNames) { - if (remainingNames.isEmpty) { - return self.getValue(c).toString(); - } - var name = remainingNames.first; - var nextProperty = - _Renderer_String.propertyMap().getValue(name); - return nextProperty.renderVariable(self.getValue(c), - nextProperty, [...remainingNames.skip(1)]); - }, - isNullValue: (CT_ c) => c.href == null, - renderValue: (CT_ c, RendererBase r, - List ast, StringSink sink) { - _render_String(c.href, ast, r.template, sink, parent: r); - }, - ), 'kind': Property( getValue: (CT_ c) => c.kind, renderVariable: @@ -4735,10 +4758,13 @@ class _Renderer_ExtensionTarget extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'Iterable'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => + c.potentiallyApplicableExtensions == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.potentiallyApplicableExtensions.map((e) => - _render_Extension(e, ast, r.template, sink, parent: r)); + renderSimple(c.potentiallyApplicableExtensions, ast, + r.template, sink, + parent: r, getters: _invisibleGetters['Iterable']); }, ), 'potentiallyApplicableExtensionsSorted': Property( @@ -5463,6 +5489,26 @@ class _Renderer_Field extends RendererBase { _render_String(c.kind, ast, r.template, sink, parent: r); }, ), + 'library': Property( + getValue: (CT_ c) => c.library, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_Library.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.library == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_Library(c.library, ast, r.template, sink, + parent: r); + }, + ), 'overriddenElement': Property( getValue: (CT_ c) => c.overriddenElement, renderVariable: @@ -5483,6 +5529,26 @@ class _Renderer_Field extends RendererBase { parent: r, getters: _invisibleGetters['Inheritable']); }, ), + 'package': Property( + getValue: (CT_ c) => c.package, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_Package.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.package == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_Package(c.package, ast, r.template, sink, + parent: r); + }, + ), 'setter': Property( getValue: (CT_ c) => c.setter, renderVariable: @@ -6500,10 +6566,11 @@ class _Renderer_InheritingContainer extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'List'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.allFields == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.allFields.map((e) => - _render_Field(e, ast, r.template, sink, parent: r)); + renderSimple(c.allFields, ast, r.template, sink, + parent: r, getters: _invisibleGetters['List']); }, ), 'allModelElements': Property( @@ -6512,11 +6579,11 @@ class _Renderer_InheritingContainer extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'List'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.allModelElements == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.allModelElements.map((e) => _render_ModelElement( - e, ast, r.template, sink, - parent: r)); + renderSimple(c.allModelElements, ast, r.template, sink, + parent: r, getters: _invisibleGetters['List']); }, ), 'constantFields': Property( @@ -6672,25 +6739,6 @@ class _Renderer_InheritingContainer extends RendererBase { self.renderSimpleVariable(c, remainingNames, 'bool'), getBool: (CT_ c) => c.hasPublicSuperChainReversed == true, ), - 'href': Property( - getValue: (CT_ c) => c.href, - renderVariable: - (CT_ c, Property self, List remainingNames) { - if (remainingNames.isEmpty) { - return self.getValue(c).toString(); - } - var name = remainingNames.first; - var nextProperty = - _Renderer_String.propertyMap().getValue(name); - return nextProperty.renderVariable(self.getValue(c), - nextProperty, [...remainingNames.skip(1)]); - }, - isNullValue: (CT_ c) => c.href == null, - renderValue: (CT_ c, RendererBase r, - List ast, StringSink sink) { - _render_String(c.href, ast, r.template, sink, parent: r); - }, - ), 'inheritanceChain': Property( getValue: (CT_ c) => c.inheritanceChain, renderVariable: (CT_ c, Property self, @@ -6722,10 +6770,11 @@ class _Renderer_InheritingContainer extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'Iterable'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.inheritedMethods == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.inheritedMethods.map((e) => - _render_Method(e, ast, r.template, sink, parent: r)); + renderSimple(c.inheritedMethods, ast, r.template, sink, + parent: r, getters: _invisibleGetters['Iterable']); }, ), 'inheritedOperators': Property( @@ -6734,10 +6783,11 @@ class _Renderer_InheritingContainer extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'Iterable'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.inheritedOperators == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.inheritedOperators.map((e) => - _render_Operator(e, ast, r.template, sink, parent: r)); + renderSimple(c.inheritedOperators, ast, r.template, sink, + parent: r, getters: _invisibleGetters['Iterable']); }, ), 'instanceFields': Property( @@ -7628,18 +7678,6 @@ class _Renderer_Library extends RendererBase { _render_String(c.href, ast, r.template, sink, parent: r); }, ), - 'importedExportedLibraries': Property( - getValue: (CT_ c) => c.importedExportedLibraries, - renderVariable: (CT_ c, Property self, - List remainingNames) => - self.renderSimpleVariable( - c, remainingNames, 'Set'), - renderIterable: (CT_ c, RendererBase r, - List ast, StringSink sink) { - return c.importedExportedLibraries.map((e) => - _render_Library(e, ast, r.template, sink, parent: r)); - }, - ), 'inheritanceManager': Property( getValue: (CT_ c) => c.inheritanceManager, renderVariable: (CT_ c, Property self, @@ -7805,18 +7843,6 @@ class _Renderer_Library extends RendererBase { parent: r); }, ), - 'packageImportedExportedLibraries': Property( - getValue: (CT_ c) => c.packageImportedExportedLibraries, - renderVariable: (CT_ c, Property self, - List remainingNames) => - self.renderSimpleVariable( - c, remainingNames, 'Set'), - renderIterable: (CT_ c, RendererBase r, - List ast, StringSink sink) { - return c.packageImportedExportedLibraries.map((e) => - _render_Library(e, ast, r.template, sink, parent: r)); - }, - ), 'packageMeta': Property( getValue: (CT_ c) => c.packageMeta, renderVariable: (CT_ c, Property self, @@ -9249,12 +9275,11 @@ class _Renderer_Mixin extends RendererBase { List remainingNames) => self.renderSimpleVariable(c, remainingNames, 'Iterable'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.superclassConstraints == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.superclassConstraints.map((e) => - _render_ParameterizedElementType( - e, ast, r.template, sink, - parent: r)); + renderSimple(c.superclassConstraints, ast, r.template, sink, + parent: r, getters: _invisibleGetters['Iterable']); }, ), }); @@ -9428,10 +9453,11 @@ class _Renderer_ModelElement extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'List'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.allParameters == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.allParameters.map((e) => - _render_Parameter(e, ast, r.template, sink, parent: r)); + renderSimple(c.allParameters, ast, r.template, sink, + parent: r, getters: _invisibleGetters['List']); }, ), 'annotations': Property( @@ -9657,10 +9683,11 @@ class _Renderer_ModelElement extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'Set'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.exportedInLibraries == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.exportedInLibraries.map((e) => - _render_Library(e, ast, r.template, sink, parent: r)); + renderSimple(c.exportedInLibraries, ast, r.template, sink, + parent: r, getters: _invisibleGetters['Set']); }, ), 'extendedDocLink': Property( @@ -10594,6 +10621,26 @@ class _Renderer_ModelFunctionTyped extends RendererBase { parent: r); }, ), + 'package': Property( + getValue: (CT_ c) => c.package, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_Package.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.package == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_Package(c.package, ast, r.template, sink, + parent: r); + }, + ), 'referenceChildren': Property( getValue: (CT_ c) => c.referenceChildren, renderVariable: (CT_ c, Property self, @@ -10722,10 +10769,11 @@ class _Renderer_Nameable extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'Set'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.namePieces == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.namePieces.map((e) => - _render_String(e, ast, r.template, sink, parent: r)); + renderSimple(c.namePieces, ast, r.template, sink, + parent: r, getters: _invisibleGetters['Set']); }, ), }); @@ -13333,11 +13381,11 @@ class _Renderer_TopLevelContainer extends RendererBase { List remainingNames) => self.renderSimpleVariable( c, remainingNames, 'Iterable'), - renderIterable: (CT_ c, RendererBase r, + isNullValue: (CT_ c) => c.functions == null, + renderValue: (CT_ c, RendererBase r, List ast, StringSink sink) { - return c.functions.map((e) => _render_ModelFunction( - e, ast, r.template, sink, - parent: r)); + renderSimple(c.functions, ast, r.template, sink, + parent: r, getters: _invisibleGetters['Iterable']); }, ), 'hasPublicClasses': Property( @@ -14087,6 +14135,46 @@ class _Renderer_TopLevelVariable extends RendererBase { _render_String(c.kind, ast, r.template, sink, parent: r); }, ), + 'library': Property( + getValue: (CT_ c) => c.library, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_Library.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.library == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_Library(c.library, ast, r.template, sink, + parent: r); + }, + ), + 'package': Property( + getValue: (CT_ c) => c.package, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_Package.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.package == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_Package(c.package, ast, r.template, sink, + parent: r); + }, + ), 'referenceParents': Property( getValue: (CT_ c) => c.referenceParents, renderVariable: (CT_ c, Property self, @@ -14773,6 +14861,26 @@ class _Renderer_Typedef extends RendererBase { _render_String(c.kind, ast, r.template, sink, parent: r); }, ), + 'library': Property( + getValue: (CT_ c) => c.library, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_Library.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.library == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_Library(c.library, ast, r.template, sink, + parent: r); + }, + ), 'linkedGenericParameters': Property( getValue: (CT_ c) => c.linkedGenericParameters, renderVariable: @@ -14834,6 +14942,26 @@ class _Renderer_Typedef extends RendererBase { parent: r); }, ), + 'package': Property( + getValue: (CT_ c) => c.package, + renderVariable: + (CT_ c, Property self, List remainingNames) { + if (remainingNames.isEmpty) { + return self.getValue(c).toString(); + } + var name = remainingNames.first; + var nextProperty = + _Renderer_Package.propertyMap().getValue(name); + return nextProperty.renderVariable(self.getValue(c), + nextProperty, [...remainingNames.skip(1)]); + }, + isNullValue: (CT_ c) => c.package == null, + renderValue: (CT_ c, RendererBase r, + List ast, StringSink sink) { + _render_Package(c.package, ast, r.template, sink, + parent: r); + }, + ), 'referenceChildren': Property( getValue: (CT_ c) => c.referenceChildren, renderVariable: (CT_ c, Property self, @@ -15489,6 +15617,15 @@ const _invisibleGetters = { 'staticType', 'unParenthesized' }, + 'ExtensionElement': { + 'hashCode', + 'runtimeType', + 'accessors', + 'enclosingElement', + 'extendedType', + 'fields', + 'methods' + }, 'Feature': { 'hashCode', 'runtimeType', @@ -15538,6 +15675,7 @@ const _invisibleGetters = { }, 'GetterSetterCombo': { 'enclosingElement', + 'documentationFrom', 'getter', 'setter', 'annotations', @@ -15552,7 +15690,6 @@ const _invisibleGetters = { 'hasPublicGetter', 'hasPublicSetter', 'isPublic', - 'documentationFrom', 'hasAccessorsWithDocs', 'getterSetterBothAvailable', 'oneLineDoc', @@ -15578,14 +15715,14 @@ const _invisibleGetters = { }, 'HashMap': {'hashCode', 'runtimeType'}, 'Inheritable': { + 'overriddenDepth', 'isInherited', 'isCovariant', 'features', 'canonicalLibrary', 'inheritance', 'overriddenElement', - 'isOverride', - 'overriddenDepth' + 'isOverride' }, 'InheritanceManager3': {'hashCode', 'runtimeType'}, 'Iterable': { @@ -15632,6 +15769,7 @@ const _invisibleGetters = { 'typeSystem', 'units' }, + 'List': {'hashCode', 'runtimeType', 'length', 'reversed'}, 'Locatable': { 'hashCode', 'runtimeType', @@ -15726,6 +15864,8 @@ const _invisibleGetters = { 'packageMap', 'sdk', 'allLibrariesAdded', + 'packageWarningCounter', + 'localPublicLibraries', 'name', 'implementors', 'documentedExtensions', @@ -15736,7 +15876,6 @@ const _invisibleGetters = { 'packageGraph', 'resourceProvider', 'sdkLibrarySources', - 'packageWarningCounter', 'packages', 'publicPackages', 'localPackages', @@ -15746,7 +15885,6 @@ const _invisibleGetters = { 'libraries', 'publicLibraries', 'localLibraries', - 'localPublicLibraries', 'inheritThrough', 'invisibleAnnotations', 'allModelElements', @@ -15879,6 +16017,17 @@ const _invisibleGetters = { 'path', 'shortName' }, + 'Set': { + 'hashCode', + 'runtimeType', + 'iterator', + 'length', + 'isEmpty', + 'isNotEmpty', + 'first', + 'last', + 'single' + }, 'TemplateOptions': { 'hashCode', 'runtimeType', diff --git a/lib/src/logging.dart b/lib/src/logging.dart index ddce9f144d..02a255d6cb 100644 --- a/lib/src/logging.dart +++ b/lib/src/logging.dart @@ -23,23 +23,23 @@ const Level progressLevel = Level('PROGRESS', 501); /// Has a value of `1201` – one more than [Level.SHOUT]. const Level printLevel = Level('PRINT', 1201); -void logWarning(Object message) { +void logWarning(String? message) { _logger.log(Level.WARNING, message); } -void logInfo(Object message) { +void logInfo(String? message) { _logger.log(Level.INFO, message); } -void logDebug(Object message) { +void logDebug(String? message) { _logger.log(Level.FINE, message); } -void logProgress(Object message) { +void logProgress(String? message) { _logger.log(progressLevel, message); } -void logPrint(Object message) { +void logPrint(String? message) { _logger.log(printLevel, message); } diff --git a/lib/src/model/accessor.dart b/lib/src/model/accessor.dart index 8fe507ba71..2364570c82 100644 --- a/lib/src/model/accessor.dart +++ b/lib/src/model/accessor.dart @@ -2,12 +2,11 @@ // 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:analyzer/dart/element/element.dart'; import 'package:analyzer/source/line_info.dart'; // ignore: implementation_imports import 'package:analyzer/src/dart/element/member.dart' show ExecutableMember; +import 'package:collection/collection.dart' show IterableExtension; import 'package:dartdoc/src/element_type.dart'; import 'package:dartdoc/src/model/comment_referable.dart'; import 'package:dartdoc/src/model/model.dart'; @@ -17,15 +16,17 @@ import 'package:dartdoc/src/warnings.dart'; /// Getters and setters. class Accessor extends ModelElement implements EnclosedElement { - GetterSetterCombo enclosingCombo; + /// The combo ([Field] or [TopLevelVariable]) containing this accessor. + /// Initialized by the combo's constructor. + late final GetterSetterCombo enclosingCombo; - Accessor(PropertyAccessorElement element, Library library, + Accessor(PropertyAccessorElement? element, Library? library, PackageGraph packageGraph, - [ExecutableMember /*?*/ originalMember]) + [ExecutableMember? originalMember]) : super(element, library, packageGraph, originalMember); @override - CharacterLocation get characterLocation { + CharacterLocation? get characterLocation { if (element.nameOffset < 0) { assert(element.isSynthetic, 'Invalid offset for non-synthetic element'); // TODO(jcollins-g): switch to [element.nonSynthetic] after analyzer 1.8 @@ -35,39 +36,33 @@ class Accessor extends ModelElement implements EnclosedElement { } @override - PropertyAccessorElement get element => super.element; + PropertyAccessorElement get element => + super.element as PropertyAccessorElement; @override - ExecutableMember get originalMember => super.originalMember; + ExecutableMember? get originalMember => + super.originalMember as ExecutableMember?; - Callable _modelType; - Callable get modelType => _modelType ??= - modelBuilder.typeFrom((originalMember ?? element).type, library); + late final Callable modelType = modelBuilder.typeFrom( + (originalMember ?? element).type, library) as Callable; bool get isSynthetic => element.isSynthetic; SourceCodeRenderer get _sourceCodeRenderer => packageGraph.rendererFactory.sourceCodeRenderer; - GetterSetterCombo _definingCombo; // The [enclosingCombo] where this element was defined. - GetterSetterCombo get definingCombo { - if (_definingCombo == null) { - var variable = element.variable; - _definingCombo = modelBuilder.fromElement(variable); - assert(_definingCombo != null, 'Unable to find defining combo'); - } - return _definingCombo; - } + late final GetterSetterCombo definingCombo = + modelBuilder.fromElement(element.variable) as GetterSetterCombo; - String _sourceCode; + String? _sourceCode; @override - String get sourceCode { + String? get sourceCode { if (_sourceCode == null) { if (isSynthetic) { _sourceCode = _sourceCodeRenderer.renderSourceCode( - packageGraph.getModelNodeFor(definingCombo.element).sourceCode); + packageGraph.getModelNodeFor(definingCombo.element)!.sourceCode!); } else { _sourceCode = super.sourceCode; } @@ -76,10 +71,10 @@ class Accessor extends ModelElement implements EnclosedElement { } bool _documentationCommentComputed = false; - String _documentationComment; + String? _documentationComment; @override String get documentationComment => _documentationCommentComputed - ? _documentationComment + ? _documentationComment! : _documentationComment ??= () { _documentationCommentComputed = true; if (isSynthetic) { @@ -88,24 +83,21 @@ class Accessor extends ModelElement implements EnclosedElement { return stripComments(super.documentationComment); }(); - String /*!*/ __syntheticDocumentationComment; - /// Build a documentation comment for this accessor assuming it is synthetic. /// Value here is not useful if [isSynthetic] is false. - String /*!*/ get _syntheticDocumentationComment => - __syntheticDocumentationComment ??= () { - if (_hasSyntheticDocumentationComment) { - return definingCombo.documentationComment ?? ''; - } - return ''; - }(); + late final String _syntheticDocumentationComment = () { + if (_hasSyntheticDocumentationComment) { + return definingCombo.documentationComment; + } + return ''; + }(); /// If this is a getter, assume we want synthetic documentation. /// If the definingCombo has a nodoc tag, we want synthetic documentation /// for a synthetic accessor just in case it is inherited somewhere /// down the line due to split inheritance. bool get _hasSyntheticDocumentationComment => - (isGetter || definingCombo.hasNodoc || _comboDocsAreIndependent()) && + (isGetter || definingCombo.hasNodoc! || _comboDocsAreIndependent()) && definingCombo.hasDocumentationComment; // If we're a setter, and a getter exists, do not add synthetic @@ -113,7 +105,7 @@ class Accessor extends ModelElement implements EnclosedElement { // from that getter. bool _comboDocsAreIndependent() { if (isSetter && definingCombo.hasGetter) { - if (definingCombo.getter.isSynthetic || + if (definingCombo.getter!.isSynthetic || !definingCombo.documentationFrom.contains(this)) { return true; } @@ -129,7 +121,7 @@ class Accessor extends ModelElement implements EnclosedElement { @override void warn( PackageWarning kind, { - String message, + String? message, Iterable referredFrom = const [], Iterable extendedDebug = const [], }) { @@ -140,23 +132,23 @@ class Accessor extends ModelElement implements EnclosedElement { } @override - ModelElement get enclosingElement { + ModelElement? get enclosingElement { if (element.enclosingElement is CompilationUnitElement) { return modelBuilder - .fromElement(element.enclosingElement.enclosingElement); + .fromElement(element.enclosingElement.enclosingElement!); } return modelBuilder.from(element.enclosingElement, library); } @override - String get filePath => enclosingCombo.filePath; + String? get filePath => enclosingCombo.filePath; @override bool get isCanonical => enclosingCombo.isCanonical; @override - String get href { + String? get href { return enclosingCombo.href; } @@ -167,14 +159,17 @@ class Accessor extends ModelElement implements EnclosedElement { @override String get kind => 'accessor'; - String _namePart; + String? _namePart; @override - String get namePart { - _namePart ??= super.namePart.split('=').first; + String? get namePart { + _namePart ??= super.namePart!.split('=').first; return _namePart; } + @override + Library get library => super.library!; + @override /// Accessors should never be participating directly in comment reference @@ -192,51 +187,32 @@ class Accessor extends ModelElement implements EnclosedElement { /// A getter or setter that is a member of a [Container]. class ContainerAccessor extends Accessor with ContainerMember, Inheritable { - /// Factory will return an [ContainerAccessor] with isInherited = true - /// if [element] is in [inheritedAccessors]. - factory ContainerAccessor.from( - PropertyAccessorElement element, - Set inheritedAccessors, - Container enclosingContainer) { - ContainerAccessor accessor; - if (element == null) return null; - if (inheritedAccessors.contains(element)) { - accessor = enclosingContainer.packageGraph.modelBuilder.from( - element, enclosingContainer.library, - enclosingContainer: enclosingContainer); - } else { - accessor = enclosingContainer.packageGraph.modelBuilder - .from(element, enclosingContainer.library); - } - return accessor; - } - /// The index and values fields are never declared, and must be special cased. bool get _isEnumSynthetic => enclosingCombo is EnumField && (name == 'index' || name == 'values'); @override - CharacterLocation get characterLocation { - if (_isEnumSynthetic) return enclosingElement.characterLocation; + CharacterLocation? get characterLocation { + if (_isEnumSynthetic) return enclosingElement!.characterLocation; // TODO(jcollins-g): Remove the enclosingCombo case below once // https://github.com/dart-lang/sdk/issues/46154 is fixed. if (enclosingCombo is EnumField) return enclosingCombo.characterLocation; return super.characterLocation; } - ModelElement _enclosingElement; + ModelElement? _enclosingElement; bool _isInherited = false; @override bool get isCovariant => isSetter && parameters.first.isCovariant; - ContainerAccessor(PropertyAccessorElement element, Library library, + ContainerAccessor(PropertyAccessorElement? element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); - ContainerAccessor.inherited(PropertyAccessorElement element, Library library, + ContainerAccessor.inherited(PropertyAccessorElement element, Library? library, PackageGraph packageGraph, this._enclosingElement, - {ExecutableMember originalMember}) + {ExecutableMember? originalMember}) : super(element, library, packageGraph, originalMember) { _isInherited = true; } @@ -245,35 +221,34 @@ class ContainerAccessor extends Accessor with ContainerMember, Inheritable { bool get isInherited => _isInherited; @override - Container get enclosingElement { + Container? get enclosingElement { _enclosingElement ??= super.enclosingElement; - return _enclosingElement; + return _enclosingElement as Container?; } bool _overriddenElementIsSet = false; - ModelElement _overriddenElement; + ModelElement? _overriddenElement; @override - ContainerAccessor get overriddenElement { + ContainerAccessor? get overriddenElement { assert(packageGraph.allLibrariesAdded); if (!_overriddenElementIsSet) { _overriddenElementIsSet = true; var parent = element.enclosingElement; if (parent is ClassElement) { for (var t in parent.allSupertypes) { - Element accessor = + Element? accessor = isGetter ? t.getGetter(element.name) : t.getSetter(element.name); if (accessor != null) { accessor = accessor.declaration; InheritingContainer parentContainer = - modelBuilder.fromElement(t.element); + modelBuilder.fromElement(t.element) as InheritingContainer; var possibleFields = []; possibleFields.addAll(parentContainer.instanceFields); possibleFields.addAll(parentContainer.staticFields); - var fieldName = accessor.name.replaceFirst('=', ''); - var foundField = possibleFields.firstWhere( - (f) => f.element.name == fieldName, - orElse: () => null); + var fieldName = accessor!.name!.replaceFirst('=', ''); + var foundField = possibleFields + .firstWhereOrNull((f) => f.element!.name == fieldName); if (foundField != null) { if (isGetter) { _overriddenElement = foundField.getter; @@ -287,6 +262,6 @@ class ContainerAccessor extends Accessor with ContainerMember, Inheritable { } } } - return _overriddenElement; + return _overriddenElement as ContainerAccessor?; } } diff --git a/lib/src/model/annotation.dart b/lib/src/model/annotation.dart index cc0bb678f0..8a4a203a8d 100644 --- a/lib/src/model/annotation.dart +++ b/lib/src/model/annotation.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/element_type.dart'; import 'package:dartdoc/src/model/feature.dart'; @@ -16,14 +14,14 @@ import 'package:dartdoc/src/model/package_graph.dart'; /// `@`. class Annotation extends Feature with ModelBuilder { final ElementAnnotation annotation; - final Library library; + final Library? library; @override final PackageGraph packageGraph; Annotation(this.annotation, this.library, this.packageGraph) - : super(annotation.element.name); + : super(annotation.element!.name); - String _linkedNameWithParameters; + String? _linkedNameWithParameters; @override String get linkedNameWithParameters => _linkedNameWithParameters ??= packageGraph.rendererFactory.featureRenderer.renderAnnotation(this); @@ -31,16 +29,16 @@ class Annotation extends Feature with ModelBuilder { /// Return the linked name of the annotation. @override String get linkedName => annotation.element is PropertyAccessorElement - ? modelBuilder.fromElement(annotation.element).linkedName + ? modelBuilder.fromElement(annotation.element!).linkedName // TODO(jcollins-g): consider linking to constructor instead of type? - : modelType.linkedName; + : modelType!.linkedName; - ElementType _modelType; - ElementType get modelType { + ElementType? _modelType; + ElementType? get modelType { if (_modelType == null) { var annotatedWith = annotation.element; if (annotatedWith is ConstructorElement) { - _modelType = modelBuilder.typeFrom(annotatedWith.returnType, library); + _modelType = modelBuilder.typeFrom(annotatedWith.returnType, library!); } else if (annotatedWith is PropertyAccessorElement) { _modelType = (modelBuilder.fromElement(annotatedWith.variable) as GetterSetterCombo) @@ -53,7 +51,7 @@ class Annotation extends Feature with ModelBuilder { return _modelType; } - String _parameterText; + String? _parameterText; String get parameterText { // TODO(srawlins): Attempt to revive constructor arguments in an annotation, // akin to source_gen's Reviver, in order to link to inner components. For @@ -65,12 +63,12 @@ class Annotation extends Feature with ModelBuilder { _parameterText = source.substring(startIndex == -1 ? source.length : startIndex); } - return _parameterText; + return _parameterText!; } @override bool get isPublic => - modelType.isPublic && + modelType!.isPublic && modelType is DefinedElementType && !packageGraph.invisibleAnnotations .contains((modelType as DefinedElementType).modelElement); diff --git a/lib/src/model/canonicalization.dart b/lib/src/model/canonicalization.dart index 152db508ec..7099eab5dc 100644 --- a/lib/src/model/canonicalization.dart +++ b/lib/src/model/canonicalization.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 - import 'package:dartdoc/src/comment_references/model_comment_reference.dart'; import 'package:dartdoc/src/model/model.dart'; @@ -11,7 +9,7 @@ import 'package:dartdoc/src/model/model.dart'; abstract class Canonicalization implements Locatable, Documentable { bool get isCanonical; - Library get canonicalLibrary; + Library? get canonicalLibrary; /// A map of [ModelCommentReference.codeRef] to [ModelCommentReference]. /// This map deduplicates comment references as all identical reference @@ -44,25 +42,25 @@ abstract class Canonicalization implements Locatable, Documentable { // Penalty for deprecated libraries. if (lib.isDeprecated) scoredCandidate._alterScore(-1.0, 'is deprecated'); // Give a big boost if the library has the package name embedded in it. - if (lib.package.namePieces.intersection(lib.namePieces).isEmpty) { + if (lib.package.namePieces!.intersection(lib.namePieces!).isEmpty) { scoredCandidate._alterScore(1.0, 'embeds package name'); } // Give a tiny boost for libraries with long names, assuming they're // more specific (and therefore more likely to be the owner of this symbol). - scoredCandidate._alterScore(.01 * lib.namePieces.length, 'name is long'); + scoredCandidate._alterScore(.01 * lib.namePieces!.length, 'name is long'); // If we don't know the location of this element, return our best guess. // TODO(jcollins-g): is that even possible? assert(locationPieces.isNotEmpty); if (locationPieces.isEmpty) return scoredCandidate; // The more pieces we have of the location in our library name, the more we should boost our score. scoredCandidate._alterScore( - lib.namePieces.intersection(locationPieces).length.toDouble() / + lib.namePieces!.intersection(locationPieces).length.toDouble() / locationPieces.length.toDouble(), 'element location shares parts with name'); // If pieces of location at least start with elements of our library name, boost the score a little bit. var scoreBoost = 0.0; for (var piece in resplit(locationPieces)) { - for (var namePiece in lib.namePieces) { + for (var namePiece in lib.namePieces!) { if (piece.startsWith(namePiece)) { scoreBoost += 0.001; } diff --git a/lib/src/model/categorization.dart b/lib/src/model/categorization.dart index 08c190a120..2ecea4edf7 100644 --- a/lib/src/model/categorization.dart +++ b/lib/src/model/categorization.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 - import 'package:dartdoc/src/model/model.dart'; final RegExp _categoryRegExp = RegExp( @@ -13,7 +11,7 @@ final RegExp _categoryRegExp = RegExp( /// Mixin implementing dartdoc categorization for ModelElements. abstract class Categorization implements ModelElement { @override - String buildDocumentationAddition(String rawDocs) => + String buildDocumentationAddition(String? rawDocs) => _stripAndSetDartdocCategories(rawDocs ??= ''); /// Parse `{@category ...}` and related information in API comments, stripping @@ -29,16 +27,16 @@ abstract class Categorization implements ModelElement { switch (match[1]) { case 'category': case 'api': - categorySet.add(match[2].trim()); + categorySet.add(match[2]!.trim()); break; case 'subCategory': - subCategorySet.add(match[2].trim()); + subCategorySet.add(match[2]!.trim()); break; case 'image': - _image = match[2].trim(); + _image = match[2]!.trim(); break; case 'samples': - _samples = match[2].trim(); + _samples = match[2]!.trim(); break; } return ''; @@ -51,74 +49,74 @@ abstract class Categorization implements ModelElement { return rawDocs; } - bool get hasSubCategoryNames => subCategoryNames.isNotEmpty; - List _subCategoryNames; + bool get hasSubCategoryNames => subCategoryNames!.isNotEmpty; + List? _subCategoryNames; /// Either a set of strings containing all declared subcategories for this symbol, /// or a set containing Null if none were declared. - List get subCategoryNames { + List? get subCategoryNames { // TODO(jcollins-g): avoid side-effect dependency if (_subCategoryNames == null) documentationLocal; return _subCategoryNames; } @override - bool get hasCategoryNames => categoryNames.isNotEmpty; - List _categoryNames; + bool get hasCategoryNames => categoryNames!.isNotEmpty; + List? _categoryNames; /// Either a set of strings containing all declared categories for this symbol, /// or a set containing Null if none were declared. - List get categoryNames { + List? get categoryNames { // TODO(jcollins-g): avoid side-effect dependency if (_categoryNames == null) documentationLocal; return _categoryNames; } - bool get hasImage => image.isNotEmpty; - String _image; + bool get hasImage => image!.isNotEmpty; + String? _image; /// Either a URI to a defined image, or the empty string if none /// was declared. - String get image { + String? get image { // TODO(jcollins-g): avoid side-effect dependency if (_image == null) documentationLocal; return _image; } - bool get hasSamples => samples.isNotEmpty; - String _samples; + bool get hasSamples => samples!.isNotEmpty; + String? _samples; /// Either a URI to documentation with samples, or the empty string if none /// was declared. - String get samples { + String? get samples { // TODO(jcollins-g): avoid side-effect dependency if (_samples == null) documentationLocal; return _samples; } - bool _hasCategorization; - - Iterable _categories; + Iterable? _categories; - Iterable get categories { - _categories ??= categoryNames - .map((n) => package.nameToCategory[n]) + Iterable get categories { + _categories ??= categoryNames! + .map((n) => package?.nameToCategory[n]) .where((c) => c != null) .toList() ..sort(); - return _categories; + return _categories!; } @override - Iterable get displayedCategories { + Iterable get displayedCategories { if (config.showUndocumentedCategories) return categories; - return categories.where((c) => c.isDocumented); + return categories.where((c) => c!.isDocumented); } + bool? _hasCategorization; + /// True if categories, subcategories, a documentation icon, or samples were /// declared. - bool get hasCategorization { + late final bool hasCategorization = () { if (_hasCategorization == null) documentationLocal; - return _hasCategorization; - } + return _hasCategorization!; + }(); } diff --git a/lib/src/model/category.dart b/lib/src/model/category.dart index 65c5b38a10..9df98fa039 100644 --- a/lib/src/model/category.dart +++ b/lib/src/model/category.dart @@ -32,7 +32,7 @@ class Category extends Nameable @override Package get package => _package; - final String _name; + final String? _name; final DartdocOptionContext _config; @@ -95,7 +95,7 @@ class Category extends Nameable String get name => categoryDefinition.displayName; @override - String get sortKey => _name; + String get sortKey => _name ?? ''; @override List get containerOrder => config.categoryOrder; diff --git a/lib/src/model/class.dart b/lib/src/model/class.dart index 41cff0ff9b..c17143769d 100644 --- a/lib/src/model/class.dart +++ b/lib/src/model/class.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/model/model.dart'; @@ -18,17 +16,17 @@ import 'comment_referable.dart'; /// **inherited**: Filtered getters giving only inherited children. class Class extends InheritingContainer with Constructable, TypeImplementing, MixedInTypes { - Class(ClassElement element, Library library, PackageGraph packageGraph) + Class(ClassElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph) { packageGraph.specialClasses.addSpecial(this); } - List _allModelElements; + List? _allModelElements; @override - List get allModelElements { + List? get allModelElements { _allModelElements ??= [ - ...super.allModelElements, + ...super.allModelElements!, ...constructors, ]; return _allModelElements; @@ -36,7 +34,7 @@ class Class extends InheritingContainer /// Returns the library that encloses this element. @override - ModelElement get enclosingElement => library; + ModelElement? get enclosingElement => library; @override String get fileName => '$name-class.$fileType'; @@ -51,16 +49,20 @@ class Class extends InheritingContainer } @override - String get href { + String? get href { if (!identical(canonicalModelElement, this)) { return canonicalModelElement?.href; } assert(canonicalLibrary != null); assert(canonicalLibrary == library); - return '${package.baseHref}$filePath'; + var packageBaseHref = package.baseHref; + if (packageBaseHref != null) { + return '$packageBaseHref$filePath'; + } + return null; } - bool get isAbstract => element.isAbstract; + bool get isAbstract => element!.isAbstract; @override bool get isCanonical => super.isCanonical && isPublic; @@ -72,15 +74,15 @@ class Class extends InheritingContainer } // if this class is itself Error or Exception, return true - if (_doCheck(element)) return true; + if (_doCheck(element!)) return true; - return element.allSupertypes.map((t) => t.element).any(_doCheck); + return element!.allSupertypes.map((t) => t.element).any(_doCheck); } @override String get kind => 'class'; - List _inheritanceChain; + List? _inheritanceChain; /// Not the same as superChain as it may include mixins. /// It's really not even the same as ordinary Dart inheritance, either, @@ -88,42 +90,42 @@ class Class extends InheritingContainer /// to include them in the set of things we might link to for documentation /// purposes in abstract classes. @override - List get inheritanceChain { + List get inheritanceChain { if (_inheritanceChain == null) { _inheritanceChain = []; - _inheritanceChain.add(this); + _inheritanceChain!.add(this); /// Caching should make this recursion a little less painful. for (var c in mixedInTypes.reversed .map((e) => (e.modelElement as InheritingContainer))) { - _inheritanceChain.addAll(c.inheritanceChain); + _inheritanceChain!.addAll(c.inheritanceChain); } for (var c in superChain.map((e) => (e.modelElement as InheritingContainer))) { - _inheritanceChain.addAll(c.inheritanceChain); + _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( + _inheritanceChain!.addAll(interfaces.expand( (e) => (e.modelElement as InheritingContainer).inheritanceChain)); } - return _inheritanceChain.toList(growable: false); + return _inheritanceChain!.toList(growable: false); } - Iterable _instanceFields; + Iterable? _instanceFields; @override Iterable get instanceFields => - _instanceFields ??= allFields.where((f) => !f.isStatic); + _instanceFields ??= allFields!.where((f) => !f.isStatic); @override bool get publicInheritedInstanceFields => publicInstanceFields.every((f) => f.isInherited); @override - Iterable get constantFields => allFields.where((f) => f.isConst); + Iterable get constantFields => allFields!.where((f) => f.isConst); static Iterable> _constructorGenerator( Iterable source) sync* { diff --git a/lib/src/model/constructor.dart b/lib/src/model/constructor.dart index a46b2ec78f..4b5f39b1e5 100644 --- a/lib/src/model/constructor.dart +++ b/lib/src/model/constructor.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/source/line_info.dart'; import 'package:dartdoc/src/element_type.dart'; @@ -14,12 +12,12 @@ class Constructor extends ModelElement with TypeParameters, ContainerMember implements EnclosedElement { Constructor( - ConstructorElement element, Library library, PackageGraph packageGraph) + ConstructorElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); @override - CharacterLocation get characterLocation { - if (element.isSynthetic) { + CharacterLocation? get characterLocation { + if (element!.isSynthetic) { // Make warnings for a synthetic constructor refer to somewhere reasonable // since a synthetic constructor has no definition independent of the // parent class. @@ -29,7 +27,7 @@ class Constructor extends ModelElement } @override - ConstructorElement get element => super.element; + ConstructorElement? get element => super.element as ConstructorElement?; @override // TODO(jcollins-g): Revisit this when dart-lang/sdk#31517 is implemented. @@ -38,11 +36,11 @@ class Constructor extends ModelElement @override ModelElement get enclosingElement => - modelBuilder.from(element.enclosingElement, library); + modelBuilder.from(element!.enclosingElement, library!); @override String get filePath => - '${enclosingElement.library.dirName}/${enclosingElement.name}/$fileName'; + '${enclosingElement.library!.dirName}/${enclosingElement.name}/$fileName'; String get fullKind { if (isConst) return 'const $kind'; @@ -53,96 +51,73 @@ class Constructor extends ModelElement @override String get fullyQualifiedName { if (isUnnamedConstructor) return super.fullyQualifiedName; - return '${library.name}.$name'; - } - - @override - String get href { - if (!identical(canonicalModelElement, this)) { - return canonicalModelElement?.href; - } - assert(canonicalLibrary != null); - assert(canonicalLibrary == library); - return '${package.baseHref}$filePath'; + return '${library!.name}.$name'; } @override - bool get isConst => element.isConst; + bool get isConst => element!.isConst; bool get isUnnamedConstructor => name == enclosingElement.name; bool get isDefaultConstructor => name == '${enclosingElement.name}.new' || isUnnamedConstructor; - bool get isFactory => element.isFactory; + bool get isFactory => element!.isFactory; @override String get kind => 'constructor'; - Callable _modelType; - Callable get modelType => - _modelType ??= modelBuilder.typeFrom(element.type, library); - - String _name; + Callable? _modelType; + Callable get modelType => (_modelType ??= + modelBuilder.typeFrom(element!.type, library!) as Callable?)!; @override - String get name { - if (_name == null) { - // TODO(jcollins-g): After the old lookup code is retired, rationalize - // [name] around the conventions used in referenceChildren and replace - // code there and elsewhere with simple references to the name. - var constructorName = element.name; - if (constructorName.isEmpty) { - _name = enclosingElement.name; - } else { - _name = '${enclosingElement.name}.$constructorName'; - } + late final String name = () { + // TODO(jcollins-g): After the old lookup code is retired, rationalize + // [name] around the conventions used in referenceChildren and replace + // code there and elsewhere with simple references to the name. + var constructorName = element!.name; + if (constructorName.isEmpty) { + return enclosingElement.name; } - return _name; - } - - String _nameWithGenerics; + return '${enclosingElement.name}.$constructorName'; + }(); @override - String get nameWithGenerics { - if (_nameWithGenerics == null) { - var constructorName = element.name; - if (constructorName.isEmpty) { - _nameWithGenerics = '${enclosingElement.name}$genericParameters'; - } else { - _nameWithGenerics = - '${enclosingElement.name}$genericParameters.$constructorName'; - } + late final String nameWithGenerics = () { + var constructorName = element!.name; + if (constructorName.isEmpty) { + return '${enclosingElement.name}$genericParameters'; } - return _nameWithGenerics; - } + return '${enclosingElement.name}$genericParameters.$constructorName'; + }(); - String get shortName { + String? get shortName { if (name.contains('.')) { - return name.substring(element.enclosingElement.name.length + 1); + return name.substring(element!.enclosingElement.name.length + 1); } else { return name; } } - Map _referenceChildren; + Map? _referenceChildren; @override Map get referenceChildren { if (_referenceChildren == null) { _referenceChildren = {}; - _referenceChildren.addEntries(allParameters.map((param) { + _referenceChildren!.addEntries(allParameters!.map((param) { var paramElement = param.element; if (paramElement is FieldFormalParameterElement) { - return modelBuilder.fromElement(paramElement.field); + return modelBuilder.fromElement(paramElement.field!); } return param; }).generateEntries()); - _referenceChildren.addEntries(typeParameters.generateEntries()); + _referenceChildren!.addEntries(typeParameters.generateEntries()); } - return _referenceChildren; + return _referenceChildren!; } @override String get referenceName => - isUnnamedConstructor ? enclosingElement.name : element.name; + isUnnamedConstructor ? enclosingElement.name : element!.name; } diff --git a/lib/src/model/container.dart b/lib/src/model/container.dart index f4ae78af47..dfeed70aa5 100644 --- a/lib/src/model/container.dart +++ b/lib/src/model/container.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/scope.dart'; import 'package:dartdoc/src/model/comment_referable.dart'; @@ -33,12 +31,20 @@ import 'package:meta/meta.dart'; /// **all** : Referring to all children. abstract class Container extends ModelElement with Categorization, TypeParameters { - Container(Element element, Library library, PackageGraph packageGraph) + Container(Element element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); + /// Containers must have associated libraries. + @override + Library get library => super.library!; + + /// Containers must have associated packages. + @override + Package get package => super.package!; + // TODO(jcollins-g): Implement a ContainerScope that flattens supertypes? @override - Scope get scope => null; + Scope? get scope => null; @override bool get hasParameters => false; @@ -58,7 +64,7 @@ abstract class Container extends ModelElement element is ClassElement && (element as ClassElement).isMixin; @mustCallSuper - Iterable get allModelElements => quiver.concat([ + Iterable? get allModelElements => quiver.concat([ instanceMethods, instanceFields, instanceOperators, @@ -68,19 +74,19 @@ abstract class Container extends ModelElement staticMethods, ]); - List _allCanonicalModelElements; + List? _allCanonicalModelElements; List get allCanonicalModelElements { return (_allCanonicalModelElements ??= - allModelElements.where((e) => e.isCanonical).toList()); + allModelElements!.where((e) => e.isCanonical).toList()); } /// All methods, including operators and statics, declared as part of this /// [Container]. [declaredMethods] must be the union of [instanceMethods], /// [staticMethods], and [instanceOperators]. - Iterable get declaredMethods; + Iterable? get declaredMethods; - Iterable get instanceMethods => declaredMethods + Iterable get instanceMethods => declaredMethods! .where((m) => !m.isStatic && !m.isOperator) .toList(growable: false); @@ -105,21 +111,17 @@ abstract class Container extends ModelElement Iterable get publicInstanceMethods => model_utils.filterNonPublic(instanceMethods); - List _publicInstanceMethodsSorted; + List? _publicInstanceMethodsSorted; List get publicInstanceMethodsSorted => _publicInstanceMethodsSorted ?? publicInstanceMethods.toList() ..sort(byName); - Iterable _declaredOperators; @nonVirtual - Iterable get declaredOperators { - _declaredOperators ??= - declaredMethods.whereType().toList(growable: false); - return _declaredOperators; - } + late final Iterable declaredOperators = + declaredMethods!.whereType().toList(growable: false); @override - ModelElement get enclosingElement; + ModelElement? get enclosingElement; Iterable get instanceOperators => declaredOperators; @@ -131,17 +133,17 @@ abstract class Container extends ModelElement Iterable get publicInstanceOperators => model_utils.filterNonPublic(instanceOperators); - List _publicInstanceOperatorsSorted; + List? _publicInstanceOperatorsSorted; List get publicInstanceOperatorsSorted => _publicInstanceOperatorsSorted ??= publicInstanceOperators.toList() ..sort(byName); /// Fields fully declared in this [Container]. - Iterable get declaredFields; + Iterable? get declaredFields; /// All fields accessible in this instance that are not static. Iterable get instanceFields => - declaredFields.where((f) => !f.isStatic); + declaredFields!.where((f) => !f.isStatic); bool get hasInstanceFields => instanceFields.isNotEmpty; @@ -152,18 +154,18 @@ abstract class Container extends ModelElement @nonVirtual bool get hasPublicInstanceFields => publicInstanceFields.isNotEmpty; - List _publicInstanceFieldsSorted; + List? _publicInstanceFieldsSorted; List get publicInstanceFieldsSorted => _publicInstanceFieldsSorted ??= publicInstanceFields.toList()..sort(byName); - Iterable get constantFields => declaredFields.where((f) => f.isConst); + Iterable get constantFields => declaredFields!.where((f) => f.isConst); Iterable get publicConstantFields => model_utils.filterNonPublic(constantFields); bool get hasPublicConstantFields => publicConstantFieldsSorted.isNotEmpty; - List _publicConstantFieldsSorted; + List? _publicConstantFieldsSorted; List get publicConstantFieldsSorted => _publicConstantFieldsSorted ??= publicConstantFields.toList()..sort(byName); @@ -175,13 +177,13 @@ abstract class Container extends ModelElement /// This container might be canonical for elements it does not contain. /// See [Inheritable.canonicalEnclosingContainer]. - bool containsElement(Element element) => allElements.contains(element); + bool containsElement(Element? element) => allElements.contains(element); - Set _allElements; - Set get allElements => - _allElements ??= allModelElements.map((e) => e.element).toSet(); + Set? _allElements; + Set get allElements => + _allElements ??= allModelElements!.map((e) => e.element).toSet(); - Map> _membersByName; + Map>? _membersByName; /// Given a ModelElement that is a member of some other class, return /// the member of this class that has the same name and runtime type. @@ -191,18 +193,18 @@ abstract class Container extends ModelElement T memberByExample(T example) { if (_membersByName == null) { _membersByName = {}; - for (var me in allModelElements) { - if (!_membersByName.containsKey(me.name)) { - _membersByName[me.name] = []; + for (var me in allModelElements!) { + if (!_membersByName!.containsKey(me.name)) { + _membersByName![me.name] = []; } - _membersByName[me.name].add(me); + _membersByName![me.name]!.add(me); } } ModelElement member; // [T] is insufficiently specific to disambiguate between different // subtypes of [Inheritable] or other mixins/implementations of // [ModelElement] via [Iterable.whereType]. - var possibleMembers = _membersByName[example.name] + var possibleMembers = _membersByName![example.name]! .where((e) => e.runtimeType == example.runtimeType); if (example is Accessor) { possibleMembers = possibleMembers @@ -210,7 +212,7 @@ abstract class Container extends ModelElement } member = possibleMembers.first; assert(possibleMembers.length == 1); - return member; + return member as T; } bool get hasPublicStaticFields => publicStaticFieldsSorted.isNotEmpty; @@ -218,11 +220,11 @@ abstract class Container extends ModelElement Iterable get publicStaticFields => model_utils.filterNonPublic(staticFields); - List _publicStaticFieldsSorted; + List? _publicStaticFieldsSorted; List get publicStaticFieldsSorted => _publicStaticFieldsSorted ??= publicStaticFields.toList()..sort(byName); - Iterable get staticFields => declaredFields.where((f) => f.isStatic); + Iterable get staticFields => declaredFields!.where((f) => f.isStatic); Iterable get variableStaticFields => staticFields.where((f) => !f.isConst); @@ -233,13 +235,13 @@ abstract class Container extends ModelElement Iterable get publicVariableStaticFields => model_utils.filterNonPublic(variableStaticFields); - List _publicVariableStaticFieldsSorted; + List? _publicVariableStaticFieldsSorted; List get publicVariableStaticFieldsSorted => _publicVariableStaticFieldsSorted ??= publicVariableStaticFields.toList() ..sort(byName); Iterable get staticMethods => - declaredMethods.where((m) => m.isStatic); + declaredMethods!.where((m) => m.isStatic); bool get hasPublicStaticMethods => model_utils.filterNonPublic(publicStaticMethodsSorted).isNotEmpty; @@ -247,7 +249,7 @@ abstract class Container extends ModelElement Iterable get publicStaticMethods => model_utils.filterNonPublic(staticMethods); - List _publicStaticMethodsSorted; + List? _publicStaticMethodsSorted; List get publicStaticMethodsSorted => _publicStaticMethodsSorted ??= publicStaticMethods.toList()..sort(byName); @@ -255,33 +257,33 @@ abstract class Container extends ModelElement /// parameter-global. Iterable> get extraReferenceChildren => []; - Map _referenceChildren; + Map? _referenceChildren; @override @mustCallSuper Map get referenceChildren { if (_referenceChildren == null) { _referenceChildren = {}; - _referenceChildren.addEntries(allModelElements + _referenceChildren!.addEntries(allModelElements! .whereNotType() .whereNotType() .generateEntries()); - _referenceChildren.addEntriesIfAbsent(extraReferenceChildren); + _referenceChildren!.addEntriesIfAbsent(extraReferenceChildren); // Process unscoped parameters last to make sure they don't override // other options. - for (var modelElement in allModelElements) { + for (var modelElement in allModelElements!) { // Don't complain about references to parameter names, but prefer // referring to anything else. // TODO(jcollins-g): Figure out something good to do in the ecosystem // here to wean people off the habit of unscoped parameter references. if (modelElement.hasParameters) { - _referenceChildren + _referenceChildren! .addEntriesIfAbsent(modelElement.parameters.generateEntries()); } } - _referenceChildren['this'] = this; + _referenceChildren!['this'] = this; } - return _referenceChildren; + return _referenceChildren!; } @override diff --git a/lib/src/model/container_member.dart b/lib/src/model/container_member.dart index adf5e674ce..4d8daaa594 100644 --- a/lib/src/model/container_member.dart +++ b/lib/src/model/container_member.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 - import 'package:dartdoc/src/model/feature.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:meta/meta.dart'; @@ -20,11 +18,11 @@ mixin ContainerMember on ModelElement implements EnclosedElement { // implemented. bool get isExtended => false; - Container _definingEnclosingContainer; + Container? _definingEnclosingContainer; - Container get definingEnclosingContainer { + Container? get definingEnclosingContainer { _definingEnclosingContainer ??= - modelBuilder.fromElement(element.enclosingElement); + modelBuilder.fromElement(element!.enclosingElement!) as Container?; return _definingEnclosingContainer; } @@ -35,27 +33,27 @@ mixin ContainerMember on ModelElement implements EnclosedElement { }; bool _canonicalEnclosingContainerIsSet = false; - Container _canonicalEnclosingContainer; + Container? _canonicalEnclosingContainer; - Container get canonicalEnclosingContainer { + Container? get canonicalEnclosingContainer { if (!_canonicalEnclosingContainerIsSet) { _canonicalEnclosingContainer = computeCanonicalEnclosingContainer(); _canonicalEnclosingContainerIsSet = true; assert(_canonicalEnclosingContainer == null || - _canonicalEnclosingContainer.isDocumented); + _canonicalEnclosingContainer!.isDocumented); } return _canonicalEnclosingContainer; } - Container computeCanonicalEnclosingContainer() { + Container? computeCanonicalEnclosingContainer() { // TODO(jcollins-g): move Extension specific code to [Extendable] - if (enclosingElement is Extension && enclosingElement.isDocumented) { - return packageGraph - .findCanonicalModelElementFor(enclosingElement.element); + if (enclosingElement is Extension && enclosingElement!.isDocumented) { + return packageGraph.findCanonicalModelElementFor( + enclosingElement!.element) as Container?; } if (enclosingElement is! Extension) { - return packageGraph - .findCanonicalModelElementFor(element.enclosingElement); + return packageGraph.findCanonicalModelElementFor( + element!.enclosingElement) as Container?; } return null; } @@ -68,7 +66,10 @@ mixin ContainerMember on ModelElement implements EnclosedElement { // references are resolved wrt documentation inheritance, // that has to be resolved in the source by not inheriting // documentation. - [enclosingElement, documentationFrom.first.enclosingElement]; + [ + enclosingElement as Container, + documentationFrom.first.enclosingElement as Container + ]; @override Iterable get referenceGrandparentOverrides sync* { @@ -78,6 +79,6 @@ mixin ContainerMember on ModelElement implements EnclosedElement { yield (documentationFrom.first as ModelElement).definingLibrary; // TODO(jcollins-g): Wean users off of depending on canonical library // resolution. dart-lang/dartdoc#2696 - if (canonicalLibrary != null) yield canonicalLibrary; + if (canonicalLibrary != null) yield canonicalLibrary!; } } diff --git a/lib/src/model/documentable.dart b/lib/src/model/documentable.dart index dc773426b8..b3b0aa5211 100644 --- a/lib/src/model/documentable.dart +++ b/lib/src/model/documentable.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 - import 'package:analyzer/file_system/file_system.dart'; import 'package:dartdoc/src/dartdoc_options.dart'; import 'package:dartdoc/src/io_utils.dart'; @@ -13,15 +11,15 @@ import 'model.dart'; /// Bridges the gap between model elements and packages, /// both of which have documentation. abstract class Documentable extends Nameable { - String get documentation; + String? get documentation; - String get documentationAsHtml; + String? get documentationAsHtml; bool get hasDocumentation; bool get hasExtendedDocumentation; - String get oneLineDoc; + String? get oneLineDoc; PackageGraph get packageGraph; @@ -29,7 +27,7 @@ abstract class Documentable extends Nameable { DartdocOptionContext get config; - String get href; + String? get href; String get kind; } @@ -47,43 +45,42 @@ enum DocumentLocation { mixin MarkdownFileDocumentation implements Documentable, Canonicalization { DocumentLocation get documentedWhere; - Documentation __documentation; + Documentation? __documentation; - Documentation get _documentation { + Documentation? get _documentation { if (__documentation != null) return __documentation; __documentation = Documentation.forElement(this); return __documentation; } @override - String get documentationAsHtml => _documentation.asHtml; + String? get documentationAsHtml => _documentation!.asHtml; @override String get documentation { final docFile = documentationFile; return docFile == null - ? null + ? '' : packageGraph.resourceProvider .readAsMalformedAllowedStringSync(docFile); } @override - bool get hasDocumentation => documentation?.isNotEmpty == true; + bool get hasDocumentation => documentation.isNotEmpty == true; @override - bool get hasExtendedDocumentation => - documentation != null && documentation.isNotEmpty; + bool get hasExtendedDocumentation => documentation.isNotEmpty; @override bool get isDocumented; @override - String get oneLineDoc => __documentation.asOneLiner; + String? get oneLineDoc => __documentation!.asOneLiner; - File get documentationFile; + File? get documentationFile; @override - String get location => '(${documentationFile.path})'; + String get location => '(${documentationFile?.path})'; @override Set get locationPieces => {location}; diff --git a/lib/src/model/documentation.dart b/lib/src/model/documentation.dart index 9dcb90e199..eaf1405768 100644 --- a/lib/src/model/documentation.dart +++ b/lib/src/model/documentation.dart @@ -2,12 +2,11 @@ // 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/comment_references/model_comment_reference.dart'; import 'package:dartdoc/src/markdown_processor.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/render/documentation_renderer.dart'; +import 'package:dartdoc/src/warnings.dart'; import 'package:markdown/markdown.dart' as md; class Documentation { @@ -15,18 +14,18 @@ class Documentation { Documentation.forElement(this._element); - bool _hasExtendedDocs; + bool? _hasExtendedDocs; - bool get hasExtendedDocs { + bool? get hasExtendedDocs { if (_hasExtendedDocs == null) { _renderDocumentation(_element.isCanonical && _asHtml == null); } return _hasExtendedDocs; } - String _asHtml; + String? _asHtml; - String get asHtml { + String? get asHtml { if (_asHtml == null) { assert(_asOneLiner == null || _element.isCanonical); _renderDocumentation(true); @@ -34,9 +33,9 @@ class Documentation { return _asHtml; } - String _asOneLiner; + String? _asOneLiner; - String get asOneLiner { + String? get asOneLiner { if (_asOneLiner == null) { assert(_asHtml == null); _renderDocumentation(_element.isCanonical); @@ -44,7 +43,7 @@ class Documentation { return _asOneLiner; } - Map get commentRefs => _element.commentRefs; + Map? get commentRefs => _element.commentRefs; void _renderDocumentation(bool processFullDocs) { var parseResult = _parseDocumentation(processFullDocs); @@ -71,8 +70,10 @@ class Documentation { if (text == null || text.isEmpty) { return DocumentationParseResult.empty; } - showWarningsForGenericsOutsideSquareBracketsBlocks(text, _element); - var document = MarkdownDocument.withElementLinkResolver(_element); + showWarningsForGenericsOutsideSquareBracketsBlocks( + text, _element as Warnable); + var document = + MarkdownDocument.withElementLinkResolver(_element as Warnable); return document.parseMarkdownText(text, processFullDocs); } diff --git a/lib/src/model/documentation_comment.dart b/lib/src/model/documentation_comment.dart index 1a7dea6bcc..0b9fb0832c 100644 --- a/lib/src/model/documentation_comment.dart +++ b/lib/src/model/documentation_comment.dart @@ -1,5 +1,4 @@ -// @dart=2.9 - +import 'package:analyzer/file_system/file_system.dart'; import 'package:args/args.dart'; import 'package:crypto/crypto.dart' as crypto; import 'package:dartdoc/src/model/documentable.dart'; @@ -41,7 +40,7 @@ final RegExp _needsPrecacheRegExp = RegExp(r'{@(template|tool|inject-html)'); /// entrypoints. mixin DocumentationComment on Documentable, Warnable, Locatable, SourceCodeMixin { - List _documentationFrom; + List? _documentationFrom; /// Returns the ModelElement(s) from which we will get documentation. /// Can be more than one if this is a Field composing documentation from @@ -56,41 +55,41 @@ mixin DocumentationComment if (!hasDocumentationComment && this is Inheritable && (this as Inheritable).overriddenElement != null) { - return (this as Inheritable).overriddenElement.documentationFrom; + return (this as Inheritable).overriddenElement!.documentationFrom; } else if (this is Inheritable && (this as Inheritable).isInherited) { - var fromThis = modelBuilder.fromElement(element); + var fromThis = modelBuilder.fromElement(element!); return fromThis.documentationFrom; } else { return [this]; } }(); - String _documentationAsHtml; + String? _documentationAsHtml; @override - String get documentationAsHtml { + String? get documentationAsHtml { if (_documentationAsHtml != null) return _documentationAsHtml; _documentationAsHtml = _injectHtmlFragments(elementDocumentation.asHtml); return _documentationAsHtml; } - Documentation _elementDocumentation; + Documentation? _elementDocumentation; Documentation get elementDocumentation => _elementDocumentation ??= Documentation.forElement(this); - String /*!*/ get documentationComment; + String get documentationComment; /// True if [this] has a synthetic/inherited or local documentation /// comment. False otherwise. bool get hasDocumentationComment; /// Returns true if the raw documentation comment has a nodoc indication. - bool get hasNodoc { + bool? get hasNodoc { if (hasDocumentationComment && (documentationComment.contains('@nodoc') || documentationComment.contains(''))) { return true; } - return packageGraph.configSetsNodocFor(element.source.fullName); + return packageGraph.configSetsNodocFor(element!.source!.fullName); } /// Process a [documentationComment], performing various actions based on @@ -139,9 +138,9 @@ mixin DocumentationComment return docs; } - String get sourceFileName; + String? get sourceFileName; - String get fullyQualifiedNameWithoutLibrary; + String? get fullyQualifiedNameWithoutLibrary; path.Context get pathContext; @@ -260,7 +259,7 @@ mixin DocumentationComment var invocationIndex = 0; return await _replaceAllMappedAsync(rawDocs, _basicToolPattern, (basicMatch) async { - var args = _splitUpQuotedArgs(basicMatch[1]).toList(); + var args = _splitUpQuotedArgs(basicMatch[1]!).toList(); // Tool name must come first. if (args.isEmpty) { warn(PackageWarning.toolError, @@ -270,27 +269,29 @@ mixin DocumentationComment // Count the number of invocations of tools in this dartdoc block, // so that tools can differentiate different blocks from each other. invocationIndex++; - return await config.tools.runner.run(args, content: basicMatch[2], + return await config.tools.runner.run(args, content: basicMatch[2]!, toolErrorCallback: (String message) async { warn(PackageWarning.toolError, message: message); - }, environment: _toolsEnvironment(invocationIndex: invocationIndex)); + }, + environment: _toolsEnvironment(invocationIndex: invocationIndex) + as Map); }); } /// The environment variables to use when running a tool. - Map _toolsEnvironment({@required int invocationIndex}) { + Map _toolsEnvironment({required int invocationIndex}) { return { 'SOURCE_LINE': characterLocation?.lineNumber.toString(), 'SOURCE_COLUMN': characterLocation?.columnNumber.toString(), if (sourceFileName != null && package?.packagePath != null) 'SOURCE_PATH': - pathContext.relative(sourceFileName, from: package.packagePath), + pathContext.relative(sourceFileName!, from: package!.packagePath), 'PACKAGE_PATH': package?.packagePath, 'PACKAGE_NAME': package?.name, 'LIBRARY_NAME': library?.fullyQualifiedName, 'ELEMENT_NAME': fullyQualifiedNameWithoutLibrary, 'INVOCATION_INDEX': invocationIndex.toString(), - 'PACKAGE_INVOCATION_INDEX': (package.toolInvocationIndex++).toString(), + 'PACKAGE_INVOCATION_INDEX': (package?.toolInvocationIndex++).toString(), }..removeWhere((key, value) => value == null); } @@ -311,34 +312,39 @@ mixin DocumentationComment /// {@example abc/def/xyz_component.dart region=template lang=html} /// String _injectExamples(String rawdocs) { - final dirPath = package.packageMeta.dir.path; + final dirPath = package?.packageMeta.dir.path; return rawdocs.replaceAllMapped(_examplePattern, (match) { - var args = _getExampleArgs(match[1]); + var args = _getExampleArgs(match[1]!); if (args == null) { // Already warned about an invalid parameter if this happens. return ''; } var lang = args['lang'] ?? - pathContext.extension(args['src']).replaceFirst('.', ''); + pathContext.extension(args['src']!).replaceFirst('.', ''); var replacement = match[0]; // default to fully matched string. - var fragmentFile = packageGraph.resourceProvider.getFile( - pathContext.canonicalize(pathContext.join(dirPath, args['file']))); - if (fragmentFile.exists) { + File? fragmentFile; + + if (dirPath != null) { + fragmentFile = packageGraph.resourceProvider.getFile( + pathContext.canonicalize(pathContext.join(dirPath, args['file']))); + } + if (fragmentFile != null && fragmentFile.exists == true) { replacement = fragmentFile.readAsStringSync(); if (lang.isNotEmpty) { replacement = replacement.replaceFirst('```', '```$lang'); } } else { - var filePath = element.source.fullName.substring(dirPath.length + 1); + var filePath = + element!.source!.fullName.substring((dirPath?.length ?? -1) + 1); // TODO(srawlins): If a file exists at the location without the // appended 'md' extension, note this. warn(PackageWarning.missingExampleFile, - message: '${fragmentFile.path}; path listed at $filePath'); + message: '${fragmentFile?.path}; path listed at $filePath'); } - return replacement; + return replacement!; }); } @@ -353,7 +359,7 @@ mixin DocumentationComment /// Returns a map of arguments. The first unnamed argument will have key /// 'src'. The computed file path, constructed from 'src' and 'region' will /// have key 'file'. - Map _getExampleArgs(String argsAsString) { + Map? _getExampleArgs(String argsAsString) { var results = _parseArgs(argsAsString, _exampleArgParser, 'example'); if (results == null) { return null; @@ -363,7 +369,7 @@ mixin DocumentationComment var src = results.rest.isEmpty ? '' : results.rest.first.replaceAll('/', pathContext.separator); - var args = { + var args = { 'src': src, 'lang': results['lang'], 'region': results['region'] ?? '', @@ -379,9 +385,10 @@ mixin DocumentationComment var ext = pathContext.extension(src); file = pathContext.join(dir, '$basename-$region$ext$fragExtension'); } - args['file'] = config.examplePathPrefix == null + var examplePathPrefix = config.examplePathPrefix; + args['file'] = examplePathPrefix == null ? file - : pathContext.join(config.examplePathPrefix, file); + : pathContext.join(examplePathPrefix, file); return args; } @@ -423,7 +430,7 @@ mixin DocumentationComment /// found in the address bar of the browser when viewing a YouTube video. String _injectYouTube(String rawDocs) { return rawDocs.replaceAllMapped(_basicYouTubePattern, (basicMatch) { - var args = _parseArgs(basicMatch[1], _youTubeArgParser, 'youtube'); + var args = _parseArgs(basicMatch[1]!, _youTubeArgParser, 'youtube'); if (args == null) { // Already warned about an invalid parameter if this happens. return ''; @@ -464,7 +471,7 @@ mixin DocumentationComment 'https://www.youtube.com/watch?v=oHg5SJYRHA0.'); return ''; } - var youTubeId = url.group(url.groupCount); + var youTubeId = url.group(url.groupCount)!; var aspectRatio = (height / width * 100).toStringAsFixed(2); return modelElementRenderer.renderYoutubeUrl(youTubeId, aspectRatio); @@ -510,7 +517,7 @@ mixin DocumentationComment var id = '$base$animationIdCount'; // We check for duplicate IDs so that we make sure not to collide with // user-supplied ids on the same page. - while (package.usedAnimationIdsByHref[href].contains(id)) { + while (package!.usedAnimationIdsByHref[href]!.contains(id)) { animationIdCount++; id = '$base$animationIdCount'; } @@ -519,9 +526,9 @@ mixin DocumentationComment return rawDocs.replaceAllMapped(_basicAnimationPattern, (basicMatch) { // Make sure we have a set to keep track of used IDs for this href. - package.usedAnimationIdsByHref[href] ??= {}; + package!.usedAnimationIdsByHref[href] ??= {}; - var args = _parseArgs(basicMatch[1], _animationArgParser, 'animation'); + var args = _parseArgs(basicMatch[1]!, _animationArgParser, 'animation'); if (args == null) { // Already warned about an invalid parameter if this happens. return ''; @@ -551,13 +558,13 @@ mixin DocumentationComment 'and must not begin with a number.'); return ''; } - if (package.usedAnimationIdsByHref[href].contains(uniqueId)) { + if (package!.usedAnimationIdsByHref[href]!.contains(uniqueId)) { warn(PackageWarning.invalidParameter, message: 'An animation has a non-unique identifier, "$uniqueId". ' 'Animation identifiers must be unique.'); return ''; } - package.usedAnimationIdsByHref[href].add(uniqueId); + package!.usedAnimationIdsByHref[href]!.add(uniqueId); int width; try { @@ -616,8 +623,8 @@ mixin DocumentationComment /// String _stripMacroTemplatesAndAddToIndex(String rawDocs) { return rawDocs.replaceAllMapped(_templatePattern, (match) { - var name = match[1].trim(); - var content = match[2].trim(); + var name = match[1]!.trim(); + var content = match[2]!.trim(); var trailingNewline = match[3]; packageGraph.addMacro(name, content); return '{@macro $name}$trailingNewline'; @@ -638,7 +645,7 @@ mixin DocumentationComment String _stripHtmlAndAddToIndex(String rawDocs) { if (!config.injectHtml) return rawDocs; return rawDocs.replaceAllMapped(_htmlPattern, (match) { - var fragment = match[1]; + var fragment = match[1]!; var digest = crypto.sha1.convert(fragment.codeUnits).toString(); packageGraph.addHtmlFragment(digest, fragment); // The newlines are so that Markdown will pass this through without @@ -652,7 +659,7 @@ mixin DocumentationComment /// First, this will split the given [argsAsString] into separate arguments /// with [_splitUpQuotedArgs] it then parses the resulting argument list /// normally with [argParser] and returns the result. - ArgResults _parseArgs( + ArgResults? _parseArgs( String argsAsString, ArgParser argParser, String directiveName) { var args = _splitUpQuotedArgs(argsAsString, convertToArgs: true); try { @@ -711,7 +718,7 @@ mixin DocumentationComment // by an equals sign), add a "--" in front so that they parse as options. return matches.map((Match match) { var option = ''; - if (convertToArgs && match[1] != null && !match[1].startsWith('-')) { + if (convertToArgs && match[1] != null && !match[1]!.startsWith('-')) { option = '--'; } if (match[2] != null) { @@ -736,7 +743,7 @@ mixin DocumentationComment } } for (var element in firstOfPair) { - final result = element.group(2).trim(); + final result = element.group(2)!.trim(); if (result.isEmpty) { warn(PackageWarning.missingCodeBlockLanguage, message: @@ -749,9 +756,9 @@ mixin DocumentationComment /// [config.dropTextFrom] indicates it should not be returned. Macro /// definitions are stripped, but macros themselves are not injected. This /// is a two stage process to avoid ordering problems. - String _documentationLocal; + String? _documentationLocal; - String get documentationLocal => + String? get documentationLocal => _documentationLocal ??= _buildDocumentationLocal(); /// Unconditionally precache local documentation. @@ -761,28 +768,28 @@ mixin DocumentationComment _documentationLocal = await _buildDocumentationBase(); } - bool _needsPrecache; - bool get needsPrecache => _needsPrecache ??= - _needsPrecacheRegExp.hasMatch(documentationComment ?? ''); + bool? _needsPrecache; + bool get needsPrecache => + _needsPrecache ??= _needsPrecacheRegExp.hasMatch(documentationComment); - String _rawDocs; + String? _rawDocs; - String _buildDocumentationLocal() => _buildDocumentationBaseSync(); + String? _buildDocumentationLocal() => _buildDocumentationBaseSync(); /// Override this to add more features to the documentation builder in a /// subclass. - String buildDocumentationAddition(String docs) => docs ?? ''; + String buildDocumentationAddition(String? docs) => docs ?? ''; /// Separate from _buildDocumentationLocal for overriding. - String _buildDocumentationBaseSync() { + String? _buildDocumentationBaseSync() { assert(_rawDocs == null, 'reentrant calls to _buildDocumentation* not allowed'); // Do not use the sync method if we need to evaluate tools or templates. assert(!isCanonical || !needsPrecache); - if (config.dropTextFrom.contains(element.library.name)) { + if (config.dropTextFrom.contains(element!.library!.name)) { _rawDocs = ''; } else { - _rawDocs = _processCommentWithoutTools(documentationComment ?? ''); + _rawDocs = _processCommentWithoutTools(documentationComment); } _rawDocs = buildDocumentationAddition(_rawDocs); return _rawDocs; @@ -790,14 +797,14 @@ mixin DocumentationComment /// Separate from _buildDocumentationLocal for overriding. Can only be /// used as part of [PackageGraph.setUpPackageGraph]. - Future _buildDocumentationBase() async { + Future _buildDocumentationBase() async { assert(_rawDocs == null, 'reentrant calls to _buildDocumentation* not allowed'); // Do not use the sync method if we need to evaluate tools or templates. - if (config.dropTextFrom.contains(element.library.name)) { + if (config.dropTextFrom.contains(element!.library!.name)) { _rawDocs = ''; } else { - _rawDocs = await processComment(documentationComment ?? ''); + _rawDocs = await processComment(documentationComment); } _rawDocs = buildDocumentationAddition(_rawDocs); return _rawDocs; @@ -837,13 +844,14 @@ mixin DocumentationComment /// /// And the HTML fragment will not have been processed or changed by Markdown, /// but just injected verbatim. - String _injectHtmlFragments(String rawDocs) { + String? _injectHtmlFragments(String? rawDocs) { if (!config.injectHtml) return rawDocs; - return rawDocs.replaceAllMapped(_htmlInjectRegExp, (match) { + return rawDocs!.replaceAllMapped(_htmlInjectRegExp, (match) { var fragment = packageGraph.getHtmlFragment(match[1]); if (fragment == null) { warn(PackageWarning.unknownHtmlFragment, message: match[1]); + return ''; } return fragment; }); diff --git a/lib/src/model/dynamic.dart b/lib/src/model/dynamic.dart index 4d130dd65e..9d4b4cee45 100644 --- a/lib/src/model/dynamic.dart +++ b/lib/src/model/dynamic.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/element_type.dart'; import 'package:dartdoc/src/model/comment_referable.dart'; @@ -19,15 +17,15 @@ class Dynamic extends ModelElement { /// [dynamic] is not a real object, and so we can't document it, so there /// can be nothing canonical for it. @override - ModelElement get canonicalModelElement => null; + ModelElement? get canonicalModelElement => null; @override - ModelElement get enclosingElement => null; + ModelElement? get enclosingElement => null; /// And similarly, even if someone references it directly it can have /// no hyperlink. @override - String get href => null; + String? get href => null; @override String get kind => 'dynamic'; @@ -36,7 +34,7 @@ class Dynamic extends ModelElement { String get linkedName => 'dynamic'; @override - String get filePath => null; + String? get filePath => null; @override Map get referenceChildren => {}; diff --git a/lib/src/model/enclosed_element.dart b/lib/src/model/enclosed_element.dart index bc285f4505..579f1ffdae 100644 --- a/lib/src/model/enclosed_element.dart +++ b/lib/src/model/enclosed_element.dart @@ -2,13 +2,11 @@ // 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/model.dart'; /// An element that is enclosed by some other element. /// /// Libraries are not enclosed. abstract class EnclosedElement { - ModelElement get enclosingElement; + ModelElement? get enclosingElement; } diff --git a/lib/src/model/enum.dart b/lib/src/model/enum.dart index a15cfb6fd4..607fef9de7 100644 --- a/lib/src/model/enum.dart +++ b/lib/src/model/enum.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 - // TODO(jcollins-g): Consider Enum as subclass of Container? import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/model/model.dart'; @@ -11,28 +9,28 @@ import 'package:dartdoc/src/render/enum_field_renderer.dart'; import 'package:dartdoc/src/special_elements.dart'; class Enum extends InheritingContainer with TypeImplementing { - Enum(ClassElement element, Library library, PackageGraph packageGraph) + Enum(ClassElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); - List _inheritanceChain; + List? _inheritanceChain; @override - List get inheritanceChain { + List get inheritanceChain { if (_inheritanceChain == null) { _inheritanceChain = []; - _inheritanceChain.add(this); + _inheritanceChain!.add(this); for (var c in superChain.map((e) => (e.modelElement as InheritingContainer))) { - _inheritanceChain.addAll(c.inheritanceChain); + _inheritanceChain!.addAll(c.inheritanceChain); } - _inheritanceChain.addAll(interfaces.expand( + _inheritanceChain!.addAll(interfaces.expand( (e) => (e.modelElement as InheritingContainer).inheritanceChain)); - assert(_inheritanceChain + assert(_inheritanceChain! .contains(packageGraph.specialClasses[SpecialClass.enumClass])); } - return _inheritanceChain.toList(growable: false); + return _inheritanceChain!.toList(growable: false); } @override @@ -42,15 +40,17 @@ class Enum extends InheritingContainer with TypeImplementing { /// Enum's fields are virtual, so we do a little work to create /// usable values for the docs. class EnumField extends Field { - int index; + int? index; EnumField(FieldElement element, Library library, PackageGraph packageGraph, - Accessor getter, Accessor setter) - : super(element, library, packageGraph, getter, setter); + Accessor? getter, Accessor? setter) + : super(element, library, packageGraph, getter as ContainerAccessor?, + setter as ContainerAccessor?); EnumField.forConstant(this.index, FieldElement element, Library library, - PackageGraph packageGraph, Accessor getter) - : super(element, library, packageGraph, getter, null); + PackageGraph packageGraph, Accessor? getter) + : super( + element, library, packageGraph, getter as ContainerAccessor?, null); @override String get constantValueBase => _fieldRenderer.renderValue(this); @@ -81,7 +81,7 @@ class EnumField extends Field { } @override - String get href { + String? get href { if (!identical(canonicalModelElement, this)) { return canonicalModelElement?.href; } @@ -109,10 +109,10 @@ class EnumField extends Field { } @override - String get oneLineDoc => documentationAsHtml; + String? get oneLineDoc => documentationAsHtml; @override - Inheritable get overriddenElement => null; + Inheritable? get overriddenElement => null; EnumFieldRenderer get _fieldRenderer => packageGraph.rendererFactory.enumFieldRenderer; diff --git a/lib/src/model/extendable.dart b/lib/src/model/extendable.dart index 909bd30a13..bb496c6b4f 100644 --- a/lib/src/model/extendable.dart +++ b/lib/src/model/extendable.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 - import 'package:dartdoc/src/model/model.dart'; /// Mixin for subclasses of [ModelElement] representing Elements that can be diff --git a/lib/src/model/extension.dart b/lib/src/model/extension.dart index 09cf1a6430..1a031e3cdd 100644 --- a/lib/src/model/extension.dart +++ b/lib/src/model/extension.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/element_type.dart'; import 'package:dartdoc/src/model/comment_referable.dart'; @@ -13,13 +11,12 @@ import 'package:dartdoc/src/quiver.dart' as quiver; /// Extension methods class Extension extends Container implements EnclosedElement { - ElementType extendedType; + late final ElementType extendedType = + modelBuilder.typeFrom(element.extendedType, library); Extension( ExtensionElement element, Library library, PackageGraph packageGraph) - : super(element, library, packageGraph) { - extendedType = modelBuilder.typeFrom(_extension.extendedType, library); - } + : super(element, library, packageGraph); /// Detect if this extension applies to every object. bool get alwaysApplies => @@ -28,7 +25,7 @@ class Extension extends Container implements EnclosedElement { extendedType.instantiatedType.isDartCoreObject; bool couldApplyTo(T c) => - _couldApplyTo(c.modelType); + _couldApplyTo(c.modelType as DefinedElementType); /// Return true if this extension could apply to [t]. bool _couldApplyTo(DefinedElementType t) { @@ -44,32 +41,33 @@ class Extension extends Container implements EnclosedElement { /// Returns the library that encloses this element. @override - ModelElement get enclosingElement => library; - - ExtensionElement get _extension => (element as ExtensionElement); + ModelElement? get enclosingElement => library; @override String get kind => 'extension'; - List _methods; + List? _methods; @override - List get declaredMethods { - _methods ??= _extension.methods.map((e) { + List? get declaredMethods { + _methods ??= element.methods.map((e) { return modelBuilder.from(e, library) as Method; }).toList(growable: false); return _methods; } @override - String get name => super.name ?? ''; + ExtensionElement get element => super.element as ExtensionElement; + + @override + String get name => element.name == null ? '' : super.name; - List _declaredFields; + List? _declaredFields; @override - List get declaredFields { - _declaredFields ??= _extension.fields.map((f) { - Accessor getter, setter; + List? get declaredFields { + _declaredFields ??= element.fields.map((f) { + Accessor? getter, setter; if (f.getter != null) { getter = ContainerAccessor(f.getter, library, packageGraph); } @@ -82,24 +80,24 @@ class Extension extends Container implements EnclosedElement { return _declaredFields; } - List _typeParameters; + List? _typeParameters; // a stronger hash? @override List get typeParameters { - _typeParameters ??= _extension.typeParameters.map((f) { - var lib = modelBuilder.fromElement(f.enclosingElement.library); - return modelBuilder.from(f, lib) as TypeParameter; + _typeParameters ??= element.typeParameters.map((f) { + var lib = modelBuilder.fromElement(f.enclosingElement!.library!); + return modelBuilder.from(f, lib as Library) as TypeParameter; }).toList(); - return _typeParameters; + return _typeParameters!; } - List _allModelElements; + List? _allModelElements; @override - List get allModelElements { + List? get allModelElements { _allModelElements ??= List.from( quiver.concat([ - super.allModelElements, + super.allModelElements!, typeParameters, ]), growable: false); @@ -109,17 +107,7 @@ class Extension extends Container implements EnclosedElement { @override String get filePath => '${library.dirName}/$fileName'; - @override - String get href { - if (!identical(canonicalModelElement, this)) { - return canonicalModelElement?.href; - } - assert(canonicalLibrary != null); - assert(canonicalLibrary == library); - return '${package.baseHref}$filePath'; - } - - Map _referenceChildren; + Map? _referenceChildren; @override Map get referenceChildren { return _referenceChildren ??= { diff --git a/lib/src/model/extension_target.dart b/lib/src/model/extension_target.dart index 3291c2de05..27e7893024 100644 --- a/lib/src/model/extension_target.dart +++ b/lib/src/model/extension_target.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 - import 'package:dartdoc/src/element_type.dart'; import 'package:dartdoc/src/model/model.dart'; @@ -13,17 +11,17 @@ mixin ExtensionTarget on ModelElement { bool get hasModifiers; bool get hasPotentiallyApplicableExtensions => - potentiallyApplicableExtensions.isNotEmpty; + potentiallyApplicableExtensions!.isNotEmpty; - List _potentiallyApplicableExtensions; + List? _potentiallyApplicableExtensions; /// The set of potentiallyApplicableExtensions, for display in templates. /// /// This is defined as those extensions where an instantiation of the type /// defined by [element] can exist where this extension applies, not including /// any extension that applies to every type. - Iterable get potentiallyApplicableExtensions { - _potentiallyApplicableExtensions ??= packageGraph.documentedExtensions + Iterable? get potentiallyApplicableExtensions { + _potentiallyApplicableExtensions ??= packageGraph.documentedExtensions! .where((e) => !e.alwaysApplies) .where((e) => e.couldApplyTo(this)) .toList(growable: false); @@ -33,5 +31,5 @@ mixin ExtensionTarget on ModelElement { ElementType get modelType; List get potentiallyApplicableExtensionsSorted => - potentiallyApplicableExtensions.toList()..sort(byName); + potentiallyApplicableExtensions!.toList()..sort(byName); } diff --git a/lib/src/model/feature.dart b/lib/src/model/feature.dart index eaa2638c8b..5529ce0cc8 100644 --- a/lib/src/model/feature.dart +++ b/lib/src/model/feature.dart @@ -2,19 +2,17 @@ // 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:collection/collection.dart'; import 'package:dartdoc/src/model/privacy.dart'; int byFeatureOrdering(Feature a, Feature b) { if (a.sortGroup < b.sortGroup) return -1; if (a.sortGroup > b.sortGroup) return 1; - return compareAsciiLowerCaseNatural(a.name, b.name); + return compareAsciiLowerCaseNatural(a.name!, b.name!); } class ElementFeatureNotFoundError extends Error { - final String message; + final String? message; ElementFeatureNotFoundError([this.message]); @@ -25,7 +23,7 @@ class ElementFeatureNotFoundError extends Error { /// A "feature" includes both explicit annotations in code (e.g. `deprecated`) /// as well as others added by the documentation system (`read-write`); class Feature implements Privacy { - final String _name; + final String? _name; /// Do not use this except in subclasses, prefer const members of this /// class instead. @@ -33,14 +31,14 @@ class Feature implements Privacy { final String featurePrefix = ''; - String get name => _name; + String? get name => _name; - String get linkedName => name; + String? get linkedName => name; - String get linkedNameWithParameters => linkedName; + String? get linkedNameWithParameters => linkedName; @override - bool get isPublic => !name.startsWith('_'); + bool get isPublic => !name!.startsWith('_'); /// Numerical sort group for this feature. /// Less than zero will sort before custom annotations. diff --git a/lib/src/model/feature_set.dart b/lib/src/model/feature_set.dart index 31b67d84cf..cbfd50b5d3 100644 --- a/lib/src/model/feature_set.dart +++ b/lib/src/model/feature_set.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 - import 'package:dartdoc/src/model/language_feature.dart'; import 'package:dartdoc/src/model/model.dart'; @@ -11,7 +9,7 @@ import 'package:dartdoc/src/model/model.dart'; /// the user interpretation of the interface. mixin FeatureSet { PackageGraph get packageGraph; - Library get library; + Library? get library; /// A list of language features that both apply to this [ModelElement] and /// make sense to display in context. @@ -28,5 +26,5 @@ mixin FeatureSet { // TODO(jcollins-g): This is an approximation and not strictly true for // inheritance/reexports. - bool get isNullSafety => library.isNullSafety; + bool get isNullSafety => library!.isNullSafety; } diff --git a/lib/src/model/field.dart b/lib/src/model/field.dart index 150912e40a..60179047df 100644 --- a/lib/src/model/field.dart +++ b/lib/src/model/field.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/model/feature.dart'; import 'package:dartdoc/src/model/model.dart'; @@ -13,18 +11,18 @@ class Field extends ModelElement with GetterSetterCombo, ContainerMember, Inheritable implements EnclosedElement { bool _isInherited = false; - Container _enclosingContainer; + late final Container _enclosingContainer; @override - final ContainerAccessor getter; + final ContainerAccessor? getter; @override - final ContainerAccessor setter; + final ContainerAccessor? setter; Field(FieldElement element, Library library, PackageGraph packageGraph, this.getter, this.setter) : super(element, library, packageGraph) { assert(getter != null || setter != null); - if (getter != null) getter.enclosingCombo = this; - if (setter != null) setter.enclosingCombo = this; + if (getter != null) getter!.enclosingCombo = this; + if (setter != null) setter!.enclosingCombo = this; } factory Field.inherited( @@ -32,9 +30,10 @@ class Field extends ModelElement Container enclosingContainer, Library library, PackageGraph packageGraph, - Accessor getter, - Accessor setter) { - var newField = Field(element, library, packageGraph, getter, setter); + Accessor? getter, + Accessor? setter) { + var newField = Field(element, library, packageGraph, + getter as ContainerAccessor?, setter as ContainerAccessor?); newField._isInherited = true; newField._enclosingContainer = enclosingContainer; // Can't set _isInherited to true if this is the defining element, because @@ -57,44 +56,39 @@ class Field extends ModelElement } @override - Container get enclosingElement { - _enclosingContainer ??= modelBuilder.from(field.enclosingElement, library); - return _enclosingContainer; - } + Container get enclosingElement => isInherited + ? _enclosingContainer + : modelBuilder.from(field!.enclosingElement, library) as Container; @override String get filePath => '${enclosingElement.library.dirName}/${enclosingElement.name}/$fileName'; @override - String get href { - if (!identical(canonicalModelElement, this)) { - return canonicalModelElement?.href; - } - assert(canonicalLibrary != null); - assert(canonicalEnclosingContainer == enclosingElement); - assert(canonicalLibrary == library); - return '${package.baseHref}$filePath'; + String? get href { + assert(!identical(canonicalModelElement, this) || + canonicalEnclosingContainer == enclosingElement); + return super.href; } @override - bool get isConst => field.isConst; + bool get isConst => field!.isConst; /// Returns true if the FieldElement is covariant, or if the first parameter /// for the setter is covariant. @override - bool get isCovariant => setter?.isCovariant == true || field.isCovariant; + bool get isCovariant => setter?.isCovariant == true || field!.isCovariant; @override bool get isFinal { /// isFinal returns true for the field even if it has an explicit getter /// (which means we should not document it as "final"). if (hasExplicitGetter) return false; - return field.isFinal; + return field!.isFinal; } @override - bool get isLate => isFinal && field.isLate; + bool get isLate => isFinal && field!.isLate; @override bool get isInherited => _isInherited; @@ -103,7 +97,7 @@ class Field extends ModelElement String get kind => isConst ? 'constant' : 'property'; String get fullkind { - if (field.isAbstract) return 'abstract $kind'; + if (field!.isAbstract) return 'abstract $kind'; return kind; } @@ -114,28 +108,28 @@ class Field extends ModelElement // either the getter or setter has one of those properties, but that's not // really specific enough for [Field]s that have public getter/setters. if (hasPublicGetter && hasPublicSetter) { - if (getter.isInherited && setter.isInherited) { + if (getter!.isInherited && setter!.isInherited) { allFeatures.add(Feature.inherited); } else { allFeatures.remove(Feature.inherited); - if (getter.isInherited) allFeatures.add(Feature.inheritedGetter); - if (setter.isInherited) allFeatures.add(Feature.inheritedSetter); + if (getter!.isInherited) allFeatures.add(Feature.inheritedGetter); + if (setter!.isInherited) allFeatures.add(Feature.inheritedSetter); } - if (getter.isOverride && setter.isOverride) { + if (getter!.isOverride! && setter!.isOverride!) { allFeatures.add(Feature.overrideFeature); } else { allFeatures.remove(Feature.overrideFeature); - if (getter.isOverride) allFeatures.add(Feature.overrideGetter); - if (setter.isOverride) allFeatures.add(Feature.overrideSetter); + if (getter!.isOverride!) allFeatures.add(Feature.overrideGetter); + if (setter!.isOverride!) allFeatures.add(Feature.overrideSetter); } } else { if (isInherited) allFeatures.add(Feature.inherited); - if (isOverride) allFeatures.add(Feature.overrideFeature); + if (isOverride!) allFeatures.add(Feature.overrideFeature); } return allFeatures; } - FieldElement get field => (element as FieldElement); + FieldElement? get field => (element as FieldElement?); @override String get fileName => '${isConst ? '$name-constant' : name}.$fileType'; @@ -143,13 +137,13 @@ class Field extends ModelElement SourceCodeRenderer get _sourceCodeRenderer => packageGraph.rendererFactory.sourceCodeRenderer; - String _sourceCode; + String? _sourceCode; @override - String get sourceCode { + String? get sourceCode { if (_sourceCode == null) { // We could use a set to figure the dupes out, but that would lose ordering. - var fieldSourceCode = modelNode.sourceCode ?? ''; + var fieldSourceCode = modelNode!.sourceCode ?? ''; var getterSourceCode = getter?.sourceCode ?? ''; var setterSourceCode = setter?.sourceCode ?? ''; var buffer = StringBuffer(); @@ -173,5 +167,11 @@ class Field extends ModelElement } @override - Inheritable get overriddenElement => null; + Library get library => super.library!; + + @override + Package get package => super.package!; + + @override + Inheritable? get overriddenElement => null; } diff --git a/lib/src/model/getter_setter_combo.dart b/lib/src/model/getter_setter_combo.dart index ffecb26fb1..1ac12f0d03 100644 --- a/lib/src/model/getter_setter_combo.dart +++ b/lib/src/model/getter_setter_combo.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 - import 'dart:convert'; import 'package:analyzer/dart/ast/ast.dart' @@ -24,15 +22,15 @@ import 'package:meta/meta.dart'; /// Mixin for top-level variables and fields (aka properties) mixin GetterSetterCombo on ModelElement { - Accessor get getter; + Accessor? get getter; - Accessor get setter; + Accessor? get setter; @override Iterable get annotations => [ ...super.annotations, - if (hasGetter) ...getter.annotations, - if (hasSetter) ...setter.annotations, + if (hasGetter) ...getter!.annotations, + if (hasSetter) ...setter!.annotations, ]; Iterable get allAccessors sync* { @@ -43,32 +41,32 @@ mixin GetterSetterCombo on ModelElement { @protected Set get comboFeatures => { - if (hasExplicitGetter && hasPublicGetter) ...getter.features, - if (hasExplicitSetter && hasPublicSetter) ...setter.features, + if (hasExplicitGetter && hasPublicGetter) ...getter!.features, + if (hasExplicitSetter && hasPublicSetter) ...setter!.features, if (readOnly && !isFinal && !isConst) Feature.readOnly, if (writeOnly) Feature.writeOnly, if (readWrite && !isLate) Feature.readWrite, }; @override - ModelElement enclosingElement; + ModelElement? enclosingElement; bool get isInherited; - Expression get constantInitializer => + Expression? get constantInitializer => (element as ConstVariableElement).constantInitializer; String linkifyConstantValue(String original) { if (constantInitializer is! InstanceCreationExpression) return original; var creationExpression = constantInitializer as InstanceCreationExpression; var constructorName = creationExpression.constructorName.toString(); - Element staticElement = creationExpression.constructorName.staticElement; + Element? staticElement = creationExpression.constructorName.staticElement; if (staticElement == null) { warn(PackageWarning.missingConstantConstructor, message: constructorName); return original; } - Constructor target = modelBuilder.fromElement(staticElement); - Class targetClass = target.enclosingElement; + Constructor target = modelBuilder.fromElement(staticElement) as Constructor; + Class targetClass = target.enclosingElement as Class; // TODO(jcollins-g): this logic really should be integrated into Constructor, // but that's not trivial because of linkedName's usage. if (targetClass.name == target.name) { @@ -84,14 +82,14 @@ mixin GetterSetterCombo on ModelElement { } @override - CharacterLocation get characterLocation { + CharacterLocation? get characterLocation { // Handle all synthetic possibilities. Ordinarily, warnings for // explicit setters/getters will be handled by those objects, but // if a warning comes up for an enclosing synthetic field we have to // put it somewhere. So pick an accessor. - if (element.isSynthetic) { - if (hasExplicitGetter) return getter.characterLocation; - if (hasExplicitSetter) return setter.characterLocation; + if (element!.isSynthetic) { + if (hasExplicitGetter) return getter!.characterLocation; + if (hasExplicitSetter) return setter!.characterLocation; assert(false, 'Field and accessors can not all be synthetic'); } return super.characterLocation; @@ -101,60 +99,62 @@ mixin GetterSetterCombo on ModelElement { String get constantValueTruncated => linkifyConstantValue(truncateString(constantValueBase, 200)); - String _constantValueBase; + String? _constantValueBase; String get constantValueBase => _constantValueBase ??= _buildConstantValueBase(); - bool get hasPublicGetter => hasGetter && getter.isPublic; + bool get hasPublicGetter => hasGetter && getter!.isPublic; - bool get hasPublicSetter => hasSetter && setter.isPublic; + bool get hasPublicSetter => hasSetter && setter!.isPublic; @override bool get isPublic => hasPublicGetter || hasPublicSetter; - List _documentationFrom; + List get _superDocumentationFrom => + super.documentationFrom; @override - List get documentationFrom { - if (_documentationFrom == null) { - _documentationFrom = []; - if (hasPublicGetter) { - _documentationFrom.addAll(getter.documentationFrom); - } else if (hasPublicSetter) { - _documentationFrom.addAll(setter.documentationFrom); - } - if (_documentationFrom.isEmpty || - _documentationFrom.every((e) => e.documentationComment == '')) { - _documentationFrom = super.documentationFrom; - } + late final List documentationFrom = () { + var toReturn = []; + if (hasPublicGetter) { + toReturn.addAll(getter!.documentationFrom); + } else if (hasPublicSetter) { + toReturn.addAll(setter!.documentationFrom); } - return _documentationFrom; - } + if (toReturn.isEmpty || + toReturn.every((e) => e.documentationComment == '')) { + // TODO(jcollins-g): Remove indirection once analyzer realizes super is + // allowed from from inside a late final variable's anonymous closure call + // (sdk >= 2.15.0-239.0.dev, but possibly earlier dev versions too). + toReturn = _superDocumentationFrom; + } + return toReturn; + }(); bool get hasAccessorsWithDocs => - (hasPublicGetter && !getter.isSynthetic && getter.hasDocumentation || - hasPublicSetter && !setter.isSynthetic && setter.hasDocumentation); + (hasPublicGetter && !getter!.isSynthetic && getter!.hasDocumentation || + hasPublicSetter && !setter!.isSynthetic && setter!.hasDocumentation); bool get getterSetterBothAvailable => (hasPublicGetter && - getter.hasDocumentation && + getter!.hasDocumentation && hasPublicSetter && - setter.hasDocumentation); + setter!.hasDocumentation); - String _oneLineDoc; + String? _oneLineDoc; @override - String get oneLineDoc { + String? get oneLineDoc { if (_oneLineDoc == null) { if (!hasAccessorsWithDocs) { _oneLineDoc = super.oneLineDoc; } else { var buffer = StringBuffer(); - if (hasPublicGetter && getter.oneLineDoc.isNotEmpty) { - buffer.write(getter.oneLineDoc); + if (hasPublicGetter && getter!.oneLineDoc!.isNotEmpty) { + buffer.write(getter!.oneLineDoc); } - if (hasPublicSetter && setter.oneLineDoc.isNotEmpty) { - buffer.write(getterSetterBothAvailable ? "" : setter.oneLineDoc); + if (hasPublicSetter && setter!.oneLineDoc!.isNotEmpty) { + buffer.write(getterSetterBothAvailable ? "" : setter!.oneLineDoc); } _oneLineDoc = buffer.toString(); } @@ -163,47 +163,49 @@ mixin GetterSetterCombo on ModelElement { } bool _documentationCommentComputed = false; - String _documentationComment; + String? _documentationComment; @override - String /*!*/ get documentationComment => _documentationCommentComputed - ? _documentationComment + String get documentationComment => _documentationCommentComputed + ? _documentationComment! : _documentationComment ??= () { _documentationCommentComputed = true; var docs = _getterSetterDocumentationComment; - if (docs.isEmpty) return element.documentationComment ?? ''; + if (docs.isEmpty) return element!.documentationComment ?? ''; return docs; }(); @override bool get hasDocumentationComment => _getterSetterDocumentationComment.isNotEmpty || - element.documentationComment != null; + element!.documentationComment != null; - String __getterSetterDocumentationComment; + String? __getterSetterDocumentationComment; /// Derive a documentation comment for the combo by copying documentation /// from the [getter] and/or [setter]. - String /*!*/ get _getterSetterDocumentationComment => + String get _getterSetterDocumentationComment => __getterSetterDocumentationComment ??= () { var buffer = StringBuffer(); // Check for synthetic before public, always, or stack overflow. - if (hasGetter && !getter.isSynthetic && getter.isPublic) { - assert(getter.documentationFrom.length == 1); - var fromGetter = getter.documentationFrom.first; + if (hasGetter && !getter!.isSynthetic && getter!.isPublic) { + assert(getter!.documentationFrom.length == 1); + var fromGetter = getter!.documentationFrom.first; // We have to check against dropTextFrom here since documentationFrom // doesn't yield the real elements for GetterSetterCombos. - if (!config.dropTextFrom.contains(fromGetter.element.library.name)) { + if (!config.dropTextFrom + .contains(fromGetter.element!.library!.name)) { if (fromGetter.hasDocumentationComment) { buffer.write(fromGetter.documentationComment); } } } - if (hasSetter && !setter.isSynthetic && setter.isPublic) { - assert(setter.documentationFrom.length == 1); - var fromSetter = setter.documentationFrom.first; - if (!config.dropTextFrom.contains(fromSetter.element.library.name)) { + if (hasSetter && !setter!.isSynthetic && setter!.isPublic) { + assert(setter!.documentationFrom.length == 1); + var fromSetter = setter!.documentationFrom.first; + if (!config.dropTextFrom + .contains(fromSetter.element!.library!.name)) { if (fromSetter.hasDocumentationComment) { if (buffer.isNotEmpty) buffer.write('\n\n'); buffer.write(fromSetter.documentationComment); @@ -214,8 +216,8 @@ mixin GetterSetterCombo on ModelElement { }(); ElementType get modelType { - if (hasGetter) return getter.modelType.returnType; - return setter.parameters.first.modelType; + if (hasGetter) return getter!.modelType.returnType; + return setter!.parameters.first.modelType; } @override @@ -225,17 +227,17 @@ mixin GetterSetterCombo on ModelElement { bool get hasParameters => hasSetter; @override - List get parameters => setter.parameters; + List get parameters => setter!.parameters; @override - String get linkedParamsNoMetadata { - if (hasSetter) return setter.linkedParamsNoMetadata; + String? get linkedParamsNoMetadata { + if (hasSetter) return setter!.linkedParamsNoMetadata; return null; } - bool get hasExplicitGetter => hasPublicGetter && !getter.isSynthetic; + bool get hasExplicitGetter => hasPublicGetter && !getter!.isSynthetic; - bool get hasExplicitSetter => hasPublicSetter && !setter.isSynthetic; + bool get hasExplicitSetter => hasPublicSetter && !setter!.isSynthetic; bool get hasGetter => getter != null; @@ -264,17 +266,18 @@ mixin GetterSetterCombo on ModelElement { bool get writeOnly => hasPublicSetter && !hasPublicGetter; - Map _referenceChildren; + Map? _referenceChildren; @override Map get referenceChildren { if (_referenceChildren == null) { _referenceChildren = {}; if (hasParameters) { - _referenceChildren.addEntries(parameters.explicitOnCollisionWith(this)); + _referenceChildren! + .addEntries(parameters.explicitOnCollisionWith(this)); } - _referenceChildren + _referenceChildren! .addEntries(modelType.typeArguments.explicitOnCollisionWith(this)); } - return _referenceChildren; + return _referenceChildren!; } } diff --git a/lib/src/model/indexable.dart b/lib/src/model/indexable.dart index 24d47da254..c96e77cb8c 100644 --- a/lib/src/model/indexable.dart +++ b/lib/src/model/indexable.dart @@ -2,15 +2,13 @@ // 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/model.dart'; /// Something able to be indexed. abstract class Indexable implements Nameable { - String get href; + String? get href; String get kind; - int get overriddenDepth => 0; + int? get overriddenDepth => 0; } diff --git a/lib/src/model/inheritable.dart b/lib/src/model/inheritable.dart index 453606972e..37f0c777a8 100644 --- a/lib/src/model/inheritable.dart +++ b/lib/src/model/inheritable.dart @@ -2,8 +2,7 @@ // 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:collection/collection.dart' show IterableExtension; import 'package:dartdoc/src/model/feature.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/special_elements.dart'; @@ -33,24 +32,25 @@ mixin Inheritable on ContainerMember { @override Set get features => { ...super.features, - if (isOverride) Feature.overrideFeature, + if (isOverride!) Feature.overrideFeature, if (isInherited) Feature.inherited, if (isCovariant) Feature.covariant, }; @override - Library get canonicalLibrary => canonicalEnclosingContainer?.canonicalLibrary; + Library? get canonicalLibrary => + canonicalEnclosingContainer?.canonicalLibrary; @override - ModelElement buildCanonicalModelElement() { + ModelElement? buildCanonicalModelElement() { // TODO(jcollins-g): factor out extension logic into [Extendable] if (canonicalEnclosingContainer is Extension) { return this; } if (canonicalEnclosingContainer is Container) { - return canonicalEnclosingContainer.allCanonicalModelElements.firstWhere( - (m) => m.name == name && m.isPropertyAccessor == isPropertyAccessor, - orElse: () => null); + return canonicalEnclosingContainer!.allCanonicalModelElements + .firstWhereOrNull((m) => + m.name == name && m.isPropertyAccessor == isPropertyAccessor); } if (canonicalEnclosingContainer != null) { throw UnimplementedError('$canonicalEnclosingContainer: unknown type'); @@ -59,27 +59,27 @@ mixin Inheritable on ContainerMember { } @override - Container computeCanonicalEnclosingContainer() { + Container? computeCanonicalEnclosingContainer() { if (isInherited) { - var searchElement = element.declaration; + var searchElement = element!.declaration; // TODO(jcollins-g): generate warning if an inherited element's definition // is in an intermediate non-canonical class in the inheritance chain? - Container previous; - Container previousNonSkippable; - Container found; + Container? previous; + Container? previousNonSkippable; + Container? found; for (var c in inheritance.reversed) { // Filter out mixins. - if (c.containsElement(searchElement)) { - if ((packageGraph.inheritThrough.contains(previous) && + if (c!.containsElement(searchElement)) { + if ((packageGraph.inheritThrough!.contains(previous) && c != definingEnclosingContainer) || - (packageGraph.inheritThrough.contains(c) && + (packageGraph.inheritThrough!.contains(c) && c == definingEnclosingContainer)) { - return previousNonSkippable + return previousNonSkippable! .memberByExample(this) .canonicalEnclosingContainer; } - Container canonicalC = - packageGraph.findCanonicalModelElementFor(c.element); + Container? canonicalC = packageGraph + .findCanonicalModelElementFor(c.element) as Container?; // TODO(jcollins-g): invert this lookup so traversal is recursive // starting from the ModelElement. if (canonicalC != null) { @@ -90,14 +90,14 @@ mixin Inheritable on ContainerMember { } } previous = c; - if (!packageGraph.inheritThrough.contains(c)) { + if (!packageGraph.inheritThrough!.contains(c)) { previousNonSkippable = c; } } // This is still OK because we're never supposed to cloak public // classes. - if (definingEnclosingContainer.isCanonical && - definingEnclosingContainer.isPublic) { + if (definingEnclosingContainer!.isCanonical && + definingEnclosingContainer!.isPublic) { assert(definingEnclosingContainer == found); } if (found != null) { @@ -105,14 +105,14 @@ mixin Inheritable on ContainerMember { } } else if (!isInherited && definingEnclosingContainer is! Extension) { // TODO(jcollins-g): factor out extension logic into [Extendable]. - return packageGraph - .findCanonicalModelElementFor(element.enclosingElement); + return packageGraph.findCanonicalModelElementFor( + element!.enclosingElement) as Container?; } return super.computeCanonicalEnclosingContainer(); } - List get inheritance { - var inheritance = []; + List get inheritance { + var inheritance = []; inheritance .addAll((enclosingElement as InheritingContainer).inheritanceChain); var object = packageGraph.specialClasses[SpecialClass.object]; @@ -129,12 +129,12 @@ mixin Inheritable on ContainerMember { return inheritance; } - Inheritable get overriddenElement; + Inheritable? get overriddenElement; - bool _isOverride; + bool? _isOverride; /// True if this [Inheritable] is overriding a superclass. - bool get isOverride { + bool? get isOverride { if (_isOverride == null) { // The canonical version of the enclosing element -- not canonicalEnclosingElement, // as that is the element enclosing the canonical version of this element, @@ -146,11 +146,11 @@ mixin Inheritable on ContainerMember { _isOverride = false; return _isOverride; } - InheritingContainer enclosingCanonical = - enclosingElement.canonicalModelElement; + InheritingContainer? enclosingCanonical = + enclosingElement!.canonicalModelElement as InheritingContainer?; // The container in which this element was defined, canonical if available. - Container definingCanonical = - definingEnclosingContainer.canonicalModelElement ?? + Container? definingCanonical = + definingEnclosingContainer!.canonicalModelElement as Container? ?? definingEnclosingContainer; // The canonical version of the element we're overriding, if available. var overriddenCanonical = @@ -164,24 +164,20 @@ mixin Inheritable on ContainerMember { enclosingCanonical == definingCanonical && // If the overridden element isn't public, we shouldn't be an // override in most cases. Approximation until #1623 is fixed. - overriddenCanonical.isPublic; - assert(!(_isOverride && isInherited)); + overriddenCanonical!.isPublic; + assert(!(_isOverride! && isInherited)); } return _isOverride; } - int _overriddenDepth; - @override - int get overriddenDepth { - if (_overriddenDepth == null) { - _overriddenDepth = 0; - var e = this; - while (e.overriddenElement != null) { - _overriddenDepth += 1; - e = e.overriddenElement; - } + late final int overriddenDepth = () { + var depth = 0; + Inheritable e = this; + while (e.overriddenElement != null) { + depth += 1; + e = e.overriddenElement!; } - return _overriddenDepth; - } + return depth; + }(); } diff --git a/lib/src/model/inheriting_container.dart b/lib/src/model/inheriting_container.dart index cfe78f4b97..039264ae41 100644 --- a/lib/src/model/inheriting_container.dart +++ b/lib/src/model/inheriting_container.dart @@ -2,10 +2,9 @@ // 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:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; +import 'package:collection/collection.dart' show IterableExtension; import 'package:dartdoc/src/element_type.dart'; import 'package:dartdoc/src/model/comment_referable.dart'; import 'package:dartdoc/src/model/extension_target.dart'; @@ -20,9 +19,9 @@ import 'package:meta/meta.dart'; /// Note that [Constructor]s are not considered to be modifiers so a /// [hasModifier] override is not necessary for this mixin. mixin Constructable on InheritingContainer { - List _constructors; + List? _constructors; Iterable get constructors => _constructors ??= [ - ...element.constructors + ...element!.constructors .map((e) => modelBuilder.from(e, library) as Constructor) ]; @@ -33,24 +32,24 @@ mixin Constructable on InheritingContainer { Iterable get publicConstructors => model_utils.filterNonPublic(constructors); - List _publicConstructorsSorted; + List? _publicConstructorsSorted; @override Iterable get publicConstructorsSorted => _publicConstructorsSorted ??= publicConstructors.toList()..sort(byName); - Constructor _unnamedConstructor; - Constructor get unnamedConstructor { - _unnamedConstructor ??= constructors - .firstWhere((c) => c.isUnnamedConstructor, orElse: () => null); + Constructor? _unnamedConstructor; + Constructor? get unnamedConstructor { + _unnamedConstructor ??= + constructors.firstWhereOrNull((c) => c.isUnnamedConstructor); return _unnamedConstructor; } - Constructor _defaultConstructor; + Constructor? _defaultConstructor; /// With constructor tearoffs, this is no longer equivalent to the unnamed /// constructor and assumptions based on that are incorrect. - Constructor get defaultConstructor { + Constructor? get defaultConstructor { _defaultConstructor ??= unnamedConstructor ?? constructors.firstWhere((c) => c.isDefaultConstructor); return _defaultConstructor; @@ -92,14 +91,13 @@ mixin Constructable on InheritingContainer { /// Add the ability to support mixed-in types to an [InheritingContainer]. mixin MixedInTypes on InheritingContainer { - List _mixedInTypes; + List? _mixedInTypes; List get mixedInTypes => _mixedInTypes ?? [ - ...element.mixins - .map((f) => modelBuilder.typeFrom(f, library)) - .where((mixin) => mixin != null) + ...element!.mixins.map( + (f) => modelBuilder.typeFrom(f, library) as DefinedElementType) ]; bool get hasPublicMixedInTypes => publicMixedInTypes.isNotEmpty; @@ -114,12 +112,13 @@ mixin MixedInTypes on InheritingContainer { /// Add the ability for an [InheritingContainer] to be implemented by other /// InheritingContainers and to reference what it itself implements. mixin TypeImplementing on InheritingContainer { - List _directInterfaces; + List? _directInterfaces; List get directInterfaces => _directInterfaces ?? [ - ...element.interfaces - .map((f) => modelBuilder.typeFrom(f, library)) + ...element!.interfaces + .map( + (f) => modelBuilder.typeFrom(f, library) as DefinedElementType) .toList(growable: false) ]; @@ -203,7 +202,7 @@ mixin TypeImplementing on InheritingContainer { return result; } - List _publicImplementorsSorted; + List? _publicImplementorsSorted; Iterable get publicImplementorsSorted => _publicImplementorsSorted ??= publicImplementors.toList()..sort(byName); @@ -222,21 +221,22 @@ abstract class InheritingContainer extends Container @override /// [ClassElement] is analogous to [InheritingContainer]. - ClassElement get element => super.element; + ClassElement? get element => super.element as ClassElement?; - DefinedElementType _supertype; - DefinedElementType get supertype => - _supertype ??= element.supertype?.element?.supertype == null + DefinedElementType? _supertype; + DefinedElementType? get supertype => + _supertype ??= element!.supertype?.element.supertype == null ? null - : modelBuilder.typeFrom(element.supertype, library); + : modelBuilder.typeFrom(element!.supertype!, library) + as DefinedElementType?; InheritingContainer( - ClassElement element, Library library, PackageGraph packageGraph) + ClassElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); @override Iterable get instanceMethods => - quiver.concat([super.instanceMethods, inheritedMethods]); + quiver.concat([super.instanceMethods, inheritedMethods!]); @override bool get publicInheritedInstanceMethods => @@ -244,19 +244,19 @@ abstract class InheritingContainer extends Container @override Iterable get instanceOperators => - quiver.concat([super.instanceOperators, inheritedOperators]); + quiver.concat([super.instanceOperators, inheritedOperators!]); @override bool get publicInheritedInstanceOperators => publicInstanceOperators.every((f) => f.isInherited); - List _allModelElements; + List? _allModelElements; @override - List get allModelElements { + List? get allModelElements { _allModelElements ??= List.from( quiver.concat([ - super.allModelElements, + super.allModelElements!, typeParameters, ]), growable: false); @@ -265,11 +265,11 @@ abstract class InheritingContainer extends Container /// Returns the [InheritingContainer] with the library in which [element] is defined. InheritingContainer get definingContainer => - modelBuilder.from(element, definingLibrary); + modelBuilder.from(element!, definingLibrary) as InheritingContainer; /// Returns the library that encloses this element. @override - ModelElement get enclosingElement => library; + ModelElement? get enclosingElement => library; @override String get filePath => '${library.dirName}/$fileName'; @@ -284,25 +284,15 @@ abstract class InheritingContainer extends Container bool get hasPublicSuperChainReversed => publicSuperChainReversed.isNotEmpty; - @override - String get href { - if (!identical(canonicalModelElement, this)) { - return canonicalModelElement?.href; - } - assert(canonicalLibrary != null); - assert(canonicalLibrary == library); - return '${package.baseHref}$filePath'; - } - /*lazy final*/ - List _inheritedMethods; + List? _inheritedMethods; - Iterable get inheritedMethods { + Iterable? get inheritedMethods { if (_inheritedMethods == null) { _inheritedMethods = []; - var methodNames = declaredMethods.map((m) => m.element.name).toSet(); + var methodNames = declaredMethods.map((m) => m.element!.name).toSet(); - var inheritedMethodElements = _inheritedElements.where((e) { + var inheritedMethodElements = _inheritedElements!.where((e) { return (e is MethodElement && !e.isOperator && e is! PropertyAccessorElement && @@ -310,40 +300,42 @@ abstract class InheritingContainer extends Container }).toSet(); for (var e in inheritedMethodElements) { - Method m = modelBuilder.from(e, library, enclosingContainer: this); - _inheritedMethods.add(m); + Method m = + modelBuilder.from(e!, library, enclosingContainer: this) as Method; + _inheritedMethods!.add(m); } } return _inheritedMethods; } Iterable get publicInheritedMethods => - model_utils.filterNonPublic(inheritedMethods); + model_utils.filterNonPublic(inheritedMethods!); bool get hasPublicInheritedMethods => publicInheritedMethods.isNotEmpty; /*lazy final*/ - List _inheritedOperators; + List? _inheritedOperators; - Iterable get inheritedOperators { + Iterable? get inheritedOperators { if (_inheritedOperators == null) { _inheritedOperators = []; - var operatorNames = declaredOperators.map((o) => o.element.name).toSet(); + var operatorNames = declaredOperators.map((o) => o.element!.name).toSet(); - var inheritedOperatorElements = _inheritedElements.where((e) { + var inheritedOperatorElements = _inheritedElements!.where((e) { return (e is MethodElement && e.isOperator && !operatorNames.contains(e.name)); }).toSet(); for (var e in inheritedOperatorElements) { - Operator o = modelBuilder.from(e, library, enclosingContainer: this); - _inheritedOperators.add(o); + Operator o = modelBuilder.from(e!, library, enclosingContainer: this) + as Operator; + _inheritedOperators!.add(o); } } return _inheritedOperators; } - Iterable get inheritedFields => allFields.where((f) => f.isInherited); + Iterable get inheritedFields => allFields!.where((f) => f.isInherited); Iterable get publicInterfaces => []; @@ -354,22 +346,23 @@ abstract class InheritingContainer extends Container bool get isCanonical => super.isCanonical && isPublic; /// Returns true if [other] is a parent class for this class. - bool _isInheritingFrom(InheritingContainer other) => superChain + bool _isInheritingFrom(InheritingContainer? other) => superChain .map((et) => (et.modelElement as InheritingContainer)) .contains(other); - DefinedElementType _modelType; + DefinedElementType? _modelType; @override DefinedElementType get modelType => - _modelType ??= modelBuilder.typeFrom(element.thisType, library); + (_modelType ??= modelBuilder.typeFrom(element!.thisType, library) + as DefinedElementType?)!; /// Not the same as superChain as it may include mixins. /// It's really not even the same as ordinary Dart inheritance, either, /// because we pretend that interfaces are part of the inheritance chain /// to include them in the set of things we might link to for documentation /// purposes in abstract classes. - List get inheritanceChain; + List get inheritanceChain; List get superChain { var typeChain = []; @@ -379,11 +372,12 @@ abstract class InheritingContainer extends Container if (parent.type is InterfaceType) { // Avoid adding [Object] to the superChain (_supertype already has this // check) - if ((parent.type as InterfaceType)?.superclass?.superclass == null) { + if ((parent.type as InterfaceType).superclass?.superclass == null) { parent = null; } else { parent = modelBuilder.typeFrom( - (parent.type as InterfaceType).superclass, library); + (parent.type as InterfaceType).superclass!, library) + as DefinedElementType?; } } else { parent = (parent.modelElement as Class).supertype; @@ -398,31 +392,21 @@ abstract class InheritingContainer extends Container Iterable get publicSuperChainReversed => publicSuperChain.toList().reversed; - List __inheritedElements; + List? __inheritedElements; - List get _inheritedElements { + List? get _inheritedElements { if (__inheritedElements == null) { - if (element.isDartCoreObject) { - return __inheritedElements = []; - } - - if (definingLibrary == null) { - // [definingLibrary] may be null if [element] has been imported or - // exported with a non-normalized URI, like "src//a.dart". - // TODO(srawlins): It would be nice to allow references from such - // libraries, but for now, PackageGraph.allLibraries is a Map with - // LibraryElement keys, which include [Element.location] in their - // `==` calculation; I think we should not key off of Elements. + if (element!.isDartCoreObject) { return __inheritedElements = []; } - var inheritance = definingLibrary.inheritanceManager; - var cmap = inheritance.getInheritedConcreteMap2(element); - var imap = inheritance.getInheritedMap2(element); + var inheritance = definingLibrary.inheritanceManager!; + var cmap = inheritance.getInheritedConcreteMap2(element!); + var imap = inheritance.getInheritedMap2(element!); - List inheritanceChainElements; + List? inheritanceChainElements; - var combinedMap = {}; + var combinedMap = {}; for (var nameObj in cmap.keys) { combinedMap[nameObj.name] = cmap[nameObj]; } @@ -431,23 +415,24 @@ abstract class InheritingContainer extends Container // Elements in the inheritance chain starting from [this.element] // down to, but not including, [Object]. inheritanceChainElements ??= - inheritanceChain.map((c) => c.element).toList(); + inheritanceChain.map((c) => c!.element).toList(); // [packageGraph.specialClasses] is not available yet. bool _isDartCoreObject(ClassElement e) => e.name == 'Object' && e.library.name == 'dart.core'; assert(inheritanceChainElements - .contains(imap[nameObj].enclosingElement) || - _isDartCoreObject(imap[nameObj].enclosingElement)); + .contains(imap[nameObj]!.enclosingElement) || + _isDartCoreObject( + imap[nameObj]!.enclosingElement as ClassElement)); // If the concrete object from [InheritanceManager3.getInheritedConcreteMap2] // is farther from this class in the inheritance chain than the one // provided by InheritedMap2, prefer InheritedMap2. This // correctly accounts for intermediate abstract classes that have // method/field implementations. - if (inheritanceChainElements - .indexOf(combinedMap[nameObj.name].enclosingElement) < + if (inheritanceChainElements.indexOf(combinedMap[nameObj.name]! + .enclosingElement as ClassElement?) < inheritanceChainElements - .indexOf(imap[nameObj].enclosingElement)) { + .indexOf(imap[nameObj]!.enclosingElement as ClassElement?)) { combinedMap[nameObj.name] = imap[nameObj]; } } else { @@ -460,13 +445,13 @@ abstract class InheritingContainer extends Container return __inheritedElements; } - List _allFields; + List? _allFields; - List get allFields { + List? get allFields { if (_allFields == null) { _allFields = []; var inheritedAccessorElements = {} - ..addAll(_inheritedElements.whereType()); + ..addAll(_inheritedElements!.whereType()); // This structure keeps track of inherited accessors, allowing lookup // by field name (stripping the '=' from setters). @@ -479,16 +464,16 @@ abstract class InheritingContainer extends Container // For half-inherited fields, the analyzer only links the non-inherited // to the [FieldElement]. Compose our [Field] class by hand by looking up // inherited accessors that may be related. - for (var f in element.fields) { + for (var f in element!.fields) { var getterElement = f.getter; if (getterElement == null && accessorMap.containsKey(f.name)) { - getterElement = accessorMap[f.name] - .firstWhere((e) => e.isGetter, orElse: () => null); + getterElement = + accessorMap[f.name]!.firstWhereOrNull((e) => e.isGetter); } var setterElement = f.setter; if (setterElement == null && accessorMap.containsKey(f.name)) { - setterElement = accessorMap[f.name] - .firstWhere((e) => e.isSetter, orElse: () => null); + setterElement = + accessorMap[f.name]!.firstWhereOrNull((e) => e.isSetter); } _addSingleField( getterElement, setterElement, inheritedAccessorElements, f); @@ -498,11 +483,9 @@ abstract class InheritingContainer extends Container // Now we only have inherited accessors who aren't associated with // anything in cls._fields. for (var fieldName in accessorMap.keys) { - var elements = accessorMap[fieldName].toList(); - var getterElement = - elements.firstWhere((e) => e.isGetter, orElse: () => null); - var setterElement = - elements.firstWhere((e) => e.isSetter, orElse: () => null); + var elements = accessorMap[fieldName]!.toList(); + var getterElement = elements.firstWhereOrNull((e) => e.isGetter); + var setterElement = elements.firstWhereOrNull((e) => e.isSetter); _addSingleField( getterElement, setterElement, inheritedAccessorElements); } @@ -511,7 +494,7 @@ abstract class InheritingContainer extends Container } @override - Iterable get declaredFields => allFields.where((f) => !f.isInherited); + Iterable get declaredFields => allFields!.where((f) => !f.isInherited); /// Add a single Field to _fields. /// @@ -519,23 +502,24 @@ abstract class InheritingContainer extends Container /// whose enclosing class inherits from the other (defaulting to the getter) /// and construct a Field using that. void _addSingleField( - PropertyAccessorElement getterElement, - PropertyAccessorElement setterElement, + PropertyAccessorElement? getterElement, + PropertyAccessorElement? setterElement, Set inheritedAccessors, - [FieldElement f]) { + [FieldElement? f]) { /// Return an [ContainerAccessor] with isInherited = true /// if [element] is in [inheritedAccessors]. - ContainerAccessor containerAccessorFrom( - PropertyAccessorElement element, + ContainerAccessor? containerAccessorFrom( + PropertyAccessorElement? element, Set inheritedAccessors, Container enclosingContainer) { ContainerAccessor accessor; if (element == null) return null; if (inheritedAccessors.contains(element)) { accessor = modelBuilder.from(element, enclosingContainer.library, - enclosingContainer: enclosingContainer); + enclosingContainer: enclosingContainer) as ContainerAccessor; } else { - accessor = modelBuilder.from(element, enclosingContainer.library); + accessor = modelBuilder.from(element, enclosingContainer.library) + as ContainerAccessor; } return accessor; } @@ -551,21 +535,21 @@ abstract class InheritingContainer extends Container // Pick an appropriate FieldElement to represent this element. // Only hard when dealing with a synthetic Field. if (getter != null && setter == null) { - f = getterElement.variable; + f = getterElement!.variable as FieldElement?; } else if (getter == null && setter != null) { - f = setterElement.variable; + f = setterElement!.variable as FieldElement?; } else { /* getter != null && setter != null */ // In cases where a Field is composed of two Accessors defined in // different places in the inheritance chain, there are two FieldElements // for this single Field we're trying to compose. Pick the one closest // to this class on the inheritance chain. - if (setter.enclosingElement is Class && - (setter.enclosingElement as Class) - ._isInheritingFrom(getter.enclosingElement)) { - f = setterElement.variable; + if (setter!.enclosingElement is Class && + (setter.enclosingElement as Class)._isInheritingFrom( + getter!.enclosingElement as InheritingContainer?)) { + f = setterElement!.variable as FieldElement?; } else { - f = getterElement.variable; + f = getterElement!.variable as FieldElement?; } } } @@ -573,48 +557,48 @@ abstract class InheritingContainer extends Container if ((getter == null || getter.isInherited) && (setter == null || setter.isInherited)) { // Field is 100% inherited. - field = modelBuilder.fromPropertyInducingElement(f, library, - enclosingContainer: this, getter: getter, setter: setter); + field = modelBuilder.fromPropertyInducingElement(f!, library, + enclosingContainer: this, getter: getter, setter: setter) as Field; } else { // Field is <100% inherited (could be half-inherited). // TODO(jcollins-g): Navigation is probably still confusing for // half-inherited fields when traversing the inheritance tree. Make // this better, somehow. - field = modelBuilder.fromPropertyInducingElement(f, library, - getter: getter, setter: setter); + field = modelBuilder.fromPropertyInducingElement(f!, library, + getter: getter, setter: setter) as Field; } - _allFields.add(field); + _allFields!.add(field); } - Iterable _declaredMethods; + Iterable? _declaredMethods; @override Iterable get declaredMethods => - _declaredMethods ??= element.methods.map((e) { + _declaredMethods ??= element!.methods.map((e) { return modelBuilder.from(e, library) as Method; }); - List _typeParameters; + List? _typeParameters; @override List get typeParameters { - _typeParameters ??= element.typeParameters.map((f) { - var lib = modelBuilder.fromElement(f.enclosingElement.library); - return modelBuilder.from(f, lib) as TypeParameter; + _typeParameters ??= element!.typeParameters.map((f) { + var lib = modelBuilder.fromElement(f.enclosingElement!.library!); + return modelBuilder.from(f, lib as Library) as TypeParameter; }).toList(); - return _typeParameters; + return _typeParameters!; } - Iterable _instanceFields; + Iterable? _instanceFields; @override Iterable get instanceFields => - _instanceFields ??= allFields.where((f) => !f.isStatic); + _instanceFields ??= allFields!.where((f) => !f.isStatic); @override bool get publicInheritedInstanceFields => publicInstanceFields.every((f) => f.isInherited); @override - Iterable get constantFields => allFields.where((f) => f.isConst); + Iterable get constantFields => allFields!.where((f) => f.isConst); } diff --git a/lib/src/model/library.dart b/lib/src/model/library.dart index 776557bdee..24d60d9cfc 100644 --- a/lib/src/model/library.dart +++ b/lib/src/model/library.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 - import 'dart:collection'; import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit; @@ -17,6 +15,7 @@ import 'package:analyzer/src/dart/element/inheritance_manager3.dart' show InheritanceManager3; // ignore: implementation_imports import 'package:analyzer/src/generated/sdk.dart' show SdkLibrary; +import 'package:collection/collection.dart' show IterableExtension; import 'package:dartdoc/src/model/comment_referable.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/package_meta.dart' show PackageMeta; @@ -63,7 +62,7 @@ class Library extends ModelElement with Categorization, TopLevelContainer { @Deprecated('Use [modelBuilder.fromElement] instead of this factory.') factory Library(LibraryElement element, PackageGraph packageGraph) { - return packageGraph.modelBuilder.fromElement(element); + return packageGraph.modelBuilder.fromElement(element) as Library; } Library._(LibraryElement element, PackageGraph packageGraph, this.package, @@ -73,7 +72,6 @@ class Library extends ModelElement with Categorization, TopLevelContainer { factory Library.fromLibraryResult(DartDocResolvedLibrary resolvedLibrary, PackageGraph packageGraph, Package package) { var element = resolvedLibrary.result.element; - if (element == null) throw ArgumentError.notNull('element'); // Initialize [packageGraph]'s cache of [ModelNode]s for relevant // elements in this library. @@ -117,7 +115,7 @@ class Library extends ModelElement with Categorization, TopLevelContainer { @override Scope get scope => element.scope; - List __allOriginalModelElementNames; + List? __allOriginalModelElementNames; /// Return true if this library is in a package configured to be treated as /// as using Null safety and itself uses Null safety. @@ -137,30 +135,30 @@ class Library extends ModelElement with Categorization, TopLevelContainer { /// documented with this library, but these ModelElements and names correspond /// to the defining library where each originally came from with respect /// to inheritance and reexporting. Most useful for error reporting. - Iterable get _allOriginalModelElementNames { + Iterable? get _allOriginalModelElementNames { __allOriginalModelElementNames ??= allModelElements.map((e) { if (e is GetterSetterCombo) { - Accessor getter; - Accessor setter; + Accessor? getter; + Accessor? setter; if (e.hasGetter) { - getter = modelBuilder.fromElement(e.getter.element); + getter = modelBuilder.fromElement(e.getter!.element) as Accessor; } if (e.hasSetter) { - setter = modelBuilder.fromElement(e.setter.element); + setter = modelBuilder.fromElement(e.setter!.element) as Accessor; } return modelBuilder - .fromPropertyInducingElement( - e.element, modelBuilder.fromElement(e.element.library), + .fromPropertyInducingElement(e.element!, + modelBuilder.fromElement(e.element!.library!) as Library, getter: getter, setter: setter) .fullyQualifiedName; } - return modelBuilder.fromElement(e.element).fullyQualifiedName; + return modelBuilder.fromElement(e.element!).fullyQualifiedName; }).toList(); return __allOriginalModelElementNames; } @override - CharacterLocation get characterLocation { + CharacterLocation? get characterLocation { if (element.nameOffset == -1) { assert(isAnonymous, 'Only anonymous libraries are allowed to have no declared location'); @@ -177,22 +175,17 @@ class Library extends ModelElement with Categorization, TopLevelContainer { Iterable get classes => allClasses.where((c) => !c.isErrorOrException); @override - LibraryElement get element => super.element; - - /*late final*/ List _extensions; + LibraryElement get element => super.element as LibraryElement; @override - Iterable get extensions { - _extensions ??= _exportedAndLocalElements - .whereType() - .map((e) => modelBuilder.from(e, this) as Extension) - .toList(growable: false); - return _extensions; - } - - SdkLibrary get sdkLib { - if (packageGraph.sdkLibrarySources.containsKey(element.librarySource)) { - return packageGraph.sdkLibrarySources[element.librarySource]; + late final Iterable extensions = _exportedAndLocalElements + .whereType() + .map((e) => modelBuilder.from(e, this) as Extension) + .toList(growable: false); + + SdkLibrary? get sdkLib { + if (packageGraph.sdkLibrarySources!.containsKey(element.librarySource)) { + return packageGraph.sdkLibrarySources![element.librarySource]; } return null; } @@ -200,6 +193,7 @@ class Library extends ModelElement with Categorization, TopLevelContainer { @override bool get isPublic { if (!super.isPublic) return false; + var sdkLib = this.sdkLib; if (sdkLib != null && (sdkLib.isInternal || !sdkLib.isDocumented)) { return false; } @@ -210,95 +204,43 @@ class Library extends ModelElement with Categorization, TopLevelContainer { return true; } - /*late final*/ List _constants; - @override - Iterable get constants { - _constants ??= - _getVariables().where((v) => v.isConst).toList(growable: false); - return _constants; - } - - /*late final*/ Set _packageImportedExportedLibraries; - - /// Returns all libraries either imported by or exported by any public library - /// this library's package. (Not [PackageGraph], but sharing a package name). - /// - /// Note: will still contain non-public libraries because those can be - /// imported or exported. - // TODO(jcollins-g): move this to [Package] once it really knows about - // more than one package. - Set get packageImportedExportedLibraries { - if (_packageImportedExportedLibraries == null) { - _packageImportedExportedLibraries = {}; - packageGraph.publicLibraries - .where((l) => l.packageName == packageName) - .forEach((l) { - _packageImportedExportedLibraries.addAll(l.importedExportedLibraries); - }); - } - return _packageImportedExportedLibraries; - } - - /*late final*/ Set _importedExportedLibraries; - - /// Returns all libraries either imported by or exported by this library, - /// recursively. - Set get importedExportedLibraries { - if (_importedExportedLibraries == null) { - _importedExportedLibraries = {}; - var importedExportedLibraryElements = {}; - importedExportedLibraryElements.addAll(element.importedLibraries); - importedExportedLibraryElements.addAll(element.exportedLibraries); - for (var l in importedExportedLibraryElements) { - var lib = modelBuilder.fromElement(l) as Library; - _importedExportedLibraries.add(lib); - _importedExportedLibraries.addAll(lib.importedExportedLibraries); - } - } - return _importedExportedLibraries; - } - - /*late final*/ Map> _prefixToLibrary; + late final Iterable constants = + _variables.where((v) => v.isConst).toList(growable: false); /// Map of import prefixes ('import "foo" as prefix;') to [Library]. - Map> get prefixToLibrary { - if (_prefixToLibrary == null) { - _prefixToLibrary = {}; - // It is possible to have overlapping prefixes. - for (var i in element.imports) { - // Ignore invalid imports. - if (i.prefix?.name != null && i.importedLibrary != null) { - _prefixToLibrary - .putIfAbsent(i.prefix?.name, () => {}) - .add(modelBuilder.from(i.importedLibrary, library)); - } + late final Map> prefixToLibrary = () { + var prefixToLibrary = >{}; + // It is possible to have overlapping prefixes. + for (var i in element.imports) { + var prefixName = i.prefix?.name; + // Ignore invalid imports. + if (prefixName != null && i.importedLibrary != null) { + prefixToLibrary + .putIfAbsent(prefixName, () => {}) + .add(modelBuilder.from(i.importedLibrary!, library) as Library); } } - return _prefixToLibrary; - } + return prefixToLibrary; + }(); - /*late final*/ String _dirName; - - String get dirName { - if (_dirName == null) { - _dirName = name; - if (isAnonymous) { - _dirName = nameFromPath; - } - _dirName = _dirName.replaceAll(':', '-').replaceAll('/', '_'); + late final String dirName = () { + var _dirName = name; + if (isAnonymous) { + _dirName = nameFromPath; } + _dirName = _dirName.replaceAll(':', '-').replaceAll('/', '_'); return _dirName; - } + }(); - /*late final*/ Set _canonicalFor; + Set? _canonicalFor; Set get canonicalFor { if (_canonicalFor == null) { // TODO(jcollins-g): restructure to avoid using side effects. buildDocumentationAddition(documentationComment); } - return _canonicalFor; + return _canonicalFor!; } static final _canonicalRegExp = RegExp(r'{@canonicalFor\s([^}]+)}'); @@ -309,63 +251,48 @@ class Library extends ModelElement with Categorization, TopLevelContainer { /// Example: /// {@canonicalFor libname.ClassName} @override - String buildDocumentationAddition(String rawDocs) { + String buildDocumentationAddition(String? rawDocs) { rawDocs = super.buildDocumentationAddition(rawDocs); - var newCanonicalFor = {}; - var notFoundInAllModelElements = {}; + var newCanonicalFor = {}; + var notFoundInAllModelElements = {}; rawDocs = rawDocs.replaceAllMapped(_canonicalRegExp, (Match match) { newCanonicalFor.add(match.group(1)); notFoundInAllModelElements.add(match.group(1)); return ''; }); if (notFoundInAllModelElements.isNotEmpty) { - notFoundInAllModelElements.removeAll(_allOriginalModelElementNames); + notFoundInAllModelElements.removeAll(_allOriginalModelElementNames!); } for (var notFound in notFoundInAllModelElements) { warn(PackageWarning.ignoredCanonicalFor, message: notFound); } // TODO(jcollins-g): warn if a macro/tool _does_ generate an unexpected // canonicalFor? - _canonicalFor ??= newCanonicalFor; + _canonicalFor ??= newCanonicalFor as Set; return rawDocs; } /// Libraries are not enclosed by anything. @override - ModelElement get enclosingElement => null; - - /*late final*/ List _enums; + ModelElement? get enclosingElement => null; @override - List get enums { - _enums ??= _exportedAndLocalElements - .whereType() - .where((element) => element.isEnum) - .map((e) => modelBuilder.from(e, this) as Enum) - .toList(growable: false); - return _enums; - } - - /*late final*/ List _mixins; + late final List enums = _exportedAndLocalElements + .whereType() + .where((element) => element.isEnum) + .map((e) => modelBuilder.from(e, this) as Enum) + .toList(growable: false); @override - List get mixins { - _mixins ??= _exportedAndLocalElements - .whereType() - .where((ClassElement c) => c.isMixin) - .map((e) => modelBuilder.from(e, this) as Mixin) - .toList(growable: false); - return _mixins; - } - - /*late final*/ List _exceptions; + late final List mixins = _exportedAndLocalElements + .whereType() + .where((ClassElement c) => c.isMixin) + .map((e) => modelBuilder.from(e, this) as Mixin) + .toList(growable: false); @override - List get exceptions { - _exceptions ??= - allClasses.where((c) => c.isErrorOrException).toList(growable: false); - return _exceptions; - } + late final List exceptions = + allClasses.where((c) => c.isErrorOrException).toList(growable: false); @override String get fileName => '$dirName-library.$fileType'; @@ -373,34 +300,29 @@ class Library extends ModelElement with Categorization, TopLevelContainer { @override String get filePath => '${library.dirName}/$fileName'; - List _functions; - @override - List get functions { - _functions ??= - _exportedAndLocalElements.whereType().map((e) { - return modelBuilder.from(e, this) as ModelFunction; - }).toList(growable: false); - return _functions; - } + late final List functions = + _exportedAndLocalElements.whereType().map((e) { + return modelBuilder.from(e, this) as ModelFunction; + }).toList(growable: false); @override - String get href { + String? get href { if (!identical(canonicalModelElement, this)) { return canonicalModelElement?.href; } return '${package.baseHref}$filePath'; } - InheritanceManager3 _inheritanceManager; + InheritanceManager3? _inheritanceManager; // TODO(srawlins): Make a static field, likely on [Class]. - InheritanceManager3 get inheritanceManager { + InheritanceManager3? get inheritanceManager { _inheritanceManager ??= InheritanceManager3(); return _inheritanceManager; } - bool get isAnonymous => element.name == null || element.name.isEmpty; + bool get isAnonymous => element.name.isEmpty; @override String get kind => 'library'; @@ -408,35 +330,25 @@ class Library extends ModelElement with Categorization, TopLevelContainer { @override Library get library => this; - /*late final*/ String _name; - @override - String get name { - if (_name == null) { - var source = element.source; - - if (source.uri.isScheme('dart')) { - // There are inconsistencies in library naming + URIs for the dart - // internal libraries; rationalize them here. - if (source.uri.toString().contains('/')) { - _name = element.name.replaceFirst('dart.', 'dart:'); - } else { - _name = source.uri.toString(); - } - } else if (element.name != null && element.name.isNotEmpty) { - _name = element.name; - } else { - _name = pathContext.basename(source.fullName); - if (_name.endsWith('.dart')) { - _name = _name.substring(0, _name.length - '.dart'.length); - } + late final String name = () { + var source = element.source; + if (source.uri.isScheme('dart')) { + // There are inconsistencies in library naming + URIs for the dart + // internal libraries; rationalize them here. + if (source.uri.toString().contains('/')) { + return element.name.replaceFirst('dart.', 'dart:'); } + return source.uri.toString(); + } else if (element.name.isNotEmpty) { + return element.name; + } + var _name = pathContext.basename(source.fullName); + if (_name.endsWith('.dart')) { + _name = _name.substring(0, _name.length - '.dart'.length); } - return _name; - } - - /*late final*/ String _nameFromPath; + }(); /// Generate a name for this library based on its location. /// @@ -445,18 +357,16 @@ class Library extends ModelElement with Categorization, TopLevelContainer { /// the name calculation. Simple cases (such as an anonymous library in /// 'lib') are the same, but this will include slashes and possibly colons /// for anonymous libraries in subdirectories or other packages. - String get nameFromPath { - _nameFromPath ??= _getNameFromPath(element, package, _restoredUri); - return _nameFromPath; - } + late final String nameFromPath = + _getNameFromPath(element, package, _restoredUri); /// The name of the package we were defined in. String get packageName => packageMeta?.name ?? ''; /// The real packageMeta, as opposed to the package we are documenting with. - PackageMeta _packageMeta; + PackageMeta? _packageMeta; - PackageMeta get packageMeta { + PackageMeta? get packageMeta { _packageMeta ??= packageGraph.packageMetaProvider.fromElement( element, config.sdkDir, @@ -464,71 +374,51 @@ class Library extends ModelElement with Categorization, TopLevelContainer { return _packageMeta; } - /*late final*/ List _properties; - /// All variables ("properties") except constants. @override - Iterable get properties { - _properties ??= - _getVariables().where((v) => !v.isConst).toList(growable: false); - return _properties; - } - - /*late final*/ List _typedefs; + late final Iterable properties = + _variables.where((v) => !v.isConst).toList(growable: false); @override - List get typedefs { - _typedefs ??= _exportedAndLocalElements - .whereType() - .map((e) => modelBuilder.from(e, this) as Typedef) - .toList(growable: false); - return _typedefs; - } + late final List typedefs = _exportedAndLocalElements + .whereType() + .map((e) => modelBuilder.from(e, this) as Typedef) + .toList(growable: false); TypeSystem get typeSystem => element.typeSystem; - List _classes; - - List get allClasses { - _classes ??= _exportedAndLocalElements - .whereType() - .where((e) => !e.isMixin && !e.isEnum) - .map((e) => modelBuilder.from(e, this) as Class) - .toList(growable: false); - return _classes; - } - - Class getClassByName(String name) { - return allClasses.firstWhere((it) => it.name == name, orElse: () => null); - } - - /*late final*/ List _variables; - - List _getVariables() { - if (_variables == null) { - var elements = _exportedAndLocalElements - .whereType() - .toSet(); - elements.addAll(_exportedAndLocalElements - .whereType() - .map((a) => a.variable)); - _variables = []; - for (var element in elements) { - Accessor getter; - if (element.getter != null) { - getter = modelBuilder.from(element.getter, this); - } - Accessor setter; - if (element.setter != null) { - setter = modelBuilder.from(element.setter, this); - } - var me = modelBuilder.fromPropertyInducingElement(element, this, - getter: getter, setter: setter); - _variables.add(me); + late final List allClasses = _exportedAndLocalElements + .whereType() + .where((e) => !e.isMixin && !e.isEnum) + .map((e) => modelBuilder.from(e, this) as Class) + .toList(growable: false); + + Class? getClassByName(String name) { + return allClasses.firstWhereOrNull((it) => it.name == name); + } + + late final List _variables = () { + var elements = + _exportedAndLocalElements.whereType().toSet(); + elements.addAll(_exportedAndLocalElements + .whereType() + .map((a) => a.variable as TopLevelVariableElement)); + var _variables = []; + for (var element in elements) { + Accessor? getter; + if (element.getter != null) { + getter = modelBuilder.from(element.getter!, this) as Accessor; + } + Accessor? setter; + if (element.setter != null) { + setter = modelBuilder.from(element.setter!, this) as Accessor; } + var me = modelBuilder.fromPropertyInducingElement(element, this, + getter: getter, setter: setter); + _variables.add(me as TopLevelVariable); } return _variables; - } + }(); /// Reverses URIs if needed to get a package URI. /// @@ -559,67 +449,42 @@ class Library extends ModelElement with Categorization, TopLevelContainer { return name; } - /*late final*/ HashMap> _modelElementsMap; - - HashMap> get modelElementsMap { - if (_modelElementsMap == null) { - var results = quiver.concat(>[ - library.constants, - library.functions, - library.properties, - library.typedefs, - library.extensions.expand((e) { - return quiver.concat([ - [e], - e.allModelElements - ]); - }), - library.allClasses.expand((c) { - return quiver.concat([ - [c], - c.allModelElements - ]); - }), - library.enums.expand((e) { - return quiver.concat([ - [e], - e.allModelElements - ]); - }), - library.mixins.expand((m) { - return quiver.concat([ - [m], - m.allModelElements - ]); - }), - ]); - _modelElementsMap = HashMap>(); - for (var modelElement in results) { - _modelElementsMap - .putIfAbsent(modelElement.element, () => {}) - .add(modelElement); - } - _modelElementsMap.putIfAbsent(element, () => {}).add(this); + late final HashMap> modelElementsMap = () { + var _modelElementsMap = HashMap>(); + for (var modelElement in [ + ...library.constants, + ...library.functions, + ...library.properties, + ...library.typedefs, + ...library.extensions.expand((e) { + return [e, ...e.allModelElements!]; + }), + ...library.allClasses.expand((c) { + return [c, ...c.allModelElements!]; + }), + ...library.enums.expand((e) { + return [e, ...e.allModelElements!]; + }), + ...library.mixins.expand((m) { + return [m, ...m.allModelElements!]; + }), + ]) { + _modelElementsMap + .putIfAbsent(modelElement.element!, () => {}) + .add(modelElement); } + _modelElementsMap.putIfAbsent(element, () => {}).add(this); return _modelElementsMap; - } + }(); - /*late final*/ List _allModelElements; + late final Iterable allModelElements = [ + for (var modelElements in modelElementsMap.values) ...modelElements, + ]; - Iterable get allModelElements { - return _allModelElements ??= [ - for (var modelElements in modelElementsMap.values) ...modelElements, - ]; - } - - /*late final*/ List _allCanonicalModelElements; - - Iterable get allCanonicalModelElements { - return (_allCanonicalModelElements ??= - allModelElements.where((e) => e.isCanonical).toList()); - } + late final Iterable allCanonicalModelElements = + allModelElements.where((e) => e.isCanonical).toList(); - Map _referenceChildren; + Map? _referenceChildren; @override Map get referenceChildren { if (_referenceChildren == null) { @@ -627,7 +492,7 @@ class Library extends ModelElement with Categorization, TopLevelContainer { var definedNamesModelElements = element .exportNamespace.definedNames.values .map((v) => modelBuilder.fromElement(v)); - _referenceChildren.addEntries( + _referenceChildren!.addEntries( definedNamesModelElements.whereNotType().generateEntries()); /* Map.fromEntries( @@ -644,12 +509,12 @@ class Library extends ModelElement with Categorization, TopLevelContainer { // refer to hidden members via the prefix, because that can be // ambiguous. dart-lang/dartdoc#2683. for (var prefixEntry in prefixToLibrary.entries) { - if (!_referenceChildren.containsKey(prefixEntry.key)) { - _referenceChildren[prefixEntry.key] = prefixEntry.value.first; + if (!_referenceChildren!.containsKey(prefixEntry.key)) { + _referenceChildren![prefixEntry.key] = prefixEntry.value.first; } } } - return _referenceChildren; + return _referenceChildren!; } @override diff --git a/lib/src/model/library_container.dart b/lib/src/model/library_container.dart index 46c94593d5..e8594c94f0 100644 --- a/lib/src/model/library_container.dart +++ b/lib/src/model/library_container.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 - import 'package:collection/collection.dart'; import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/model_utils.dart' as model_utils; @@ -21,7 +19,7 @@ abstract class LibraryContainer Iterable get publicLibraries => model_utils.filterNonPublic(libraries); - List _publicLibrariesSorted; + List? _publicLibrariesSorted; Iterable get publicLibrariesSorted => _publicLibrariesSorted ??= publicLibraries.toList()..sort(byName); @@ -32,10 +30,10 @@ abstract class LibraryContainer String get enclosingName; /// Order by which this container should be sorted. - List get containerOrder; + List get containerOrder; /// Sorting key. [containerOrder] should contain these. - String get sortKey => name; + String? get sortKey => name; /// Does this container represent the SDK? This can be false for containers /// that only represent a part of the SDK. @@ -49,9 +47,9 @@ abstract class LibraryContainer /// * 3 otherwise. int get _group { if (containerOrder.contains(sortKey)) return -1; - if (equalsIgnoreAsciiCase(sortKey, enclosingName)) return 0; + if (equalsIgnoreAsciiCase(sortKey!, enclosingName)) return 0; if (isSdk) return 1; - if (sortKey.toLowerCase().contains(enclosingName.toLowerCase())) return 2; + if (sortKey!.toLowerCase().contains(enclosingName.toLowerCase())) return 2; return 3; } @@ -62,7 +60,7 @@ abstract class LibraryContainer return Comparable.compare(containerOrder.indexOf(sortKey), containerOrder.indexOf(other.sortKey)); } else { - return sortKey.toLowerCase().compareTo(other.sortKey.toLowerCase()); + return sortKey!.toLowerCase().compareTo(other.sortKey!.toLowerCase()); } } return Comparable.compare(_group, other._group); diff --git a/lib/src/model/locatable.dart b/lib/src/model/locatable.dart index 94d03d1ae0..27633b63f9 100644 --- a/lib/src/model/locatable.dart +++ b/lib/src/model/locatable.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 - import 'package:analyzer/dart/element/element.dart' show Element; /// Something that can be located for warning purposes. @@ -16,7 +14,7 @@ abstract class Locatable { String get fullyQualifiedName; - String get href; + String? get href; /// A string indicating the URI of this Locatable, usually derived from /// [Element.location]. diff --git a/lib/src/model/method.dart b/lib/src/model/method.dart index 29a5757559..14e5be8f7e 100644 --- a/lib/src/model/method.dart +++ b/lib/src/model/method.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/source/line_info.dart'; // ignore: implementation_imports @@ -17,67 +15,63 @@ class Method extends ModelElement with ContainerMember, Inheritable, TypeParameters implements EnclosedElement { bool _isInherited = false; - Container _enclosingContainer; + Container? _enclosingContainer; @override List typeParameters = []; - Method(MethodElement element, Library library, PackageGraph packageGraph) + Method(MethodElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph) { _calcTypeParameters(); } Method.inherited(MethodElement element, this._enclosingContainer, - Library library, PackageGraph packageGraph, - {ExecutableMember originalMember}) + Library? library, PackageGraph packageGraph, + {ExecutableMember? originalMember}) : super(element, library, packageGraph, originalMember) { _isInherited = true; _calcTypeParameters(); } void _calcTypeParameters() { - typeParameters = element.typeParameters.map((f) { - return modelBuilder.from(f, library) as TypeParameter; + typeParameters = element!.typeParameters.map((f) { + return modelBuilder.from(f, library!) as TypeParameter; }).toList(); } @override - CharacterLocation get characterLocation { + CharacterLocation? get characterLocation { if (enclosingElement is Enum && name == 'toString') { // The toString() method on Enums is special, treated as not having // a definition location by the analyzer yet not being inherited, either. // Just directly override our location with the Enum definition -- // this is OK because Enums can not inherit from each other nor // have their definitions split between files. - return enclosingElement.characterLocation; + return enclosingElement!.characterLocation; } return super.characterLocation; } @override - ModelElement get enclosingElement { + ModelElement? get enclosingElement { _enclosingContainer ??= - modelBuilder.from(element.enclosingElement, library); + modelBuilder.from(element!.enclosingElement, library!) as Container?; return _enclosingContainer; } @override String get filePath => - '${enclosingElement.library.dirName}/${enclosingElement.name}/$fileName'; + '${enclosingElement!.library!.dirName}/${enclosingElement!.name}/$fileName'; String get fullkind { - if (element.isAbstract) return 'abstract $kind'; + if (element!.isAbstract) return 'abstract $kind'; return kind; } @override - String get href { - if (!identical(canonicalModelElement, this)) { - return canonicalModelElement?.href; - } - assert(!(canonicalLibrary == null || canonicalEnclosingContainer == null)); - assert(canonicalLibrary == library); - assert(canonicalEnclosingContainer == enclosingElement); - return '${package.baseHref}$filePath'; + String? get href { + assert(!identical(canonicalModelElement, this) || + canonicalEnclosingContainer == enclosingElement); + return super.href; } @override @@ -92,42 +86,43 @@ class Method extends ModelElement }; @override - bool get isStatic => element.isStatic; + bool get isStatic => element!.isStatic; @override String get kind => 'method'; @override - ExecutableMember get originalMember => super.originalMember; + ExecutableMember? get originalMember => + super.originalMember as ExecutableMember?; - Callable _modelType; - Callable get modelType => _modelType ??= - modelBuilder.typeFrom((originalMember ?? element).type, library); + Callable? _modelType; + Callable get modelType => (_modelType ??= modelBuilder.typeFrom( + (originalMember ?? element)!.type, library!) as Callable?)!; @override - Method get overriddenElement { + Method? get overriddenElement { if (_enclosingContainer is Extension) { return null; } - ClassElement parent = element.enclosingElement; + ClassElement parent = element!.enclosingElement as ClassElement; for (var t in parent.allSupertypes) { - Element e = t.getMethod(element.name); + Element? e = t.getMethod(element!.name); if (e != null) { assert(e.enclosingElement is ClassElement); - return modelBuilder.fromElement(e); + return modelBuilder.fromElement(e) as Method?; } } return null; } @override - MethodElement get element => super.element; + MethodElement? get element => super.element as MethodElement?; /// Methods can not be covariant; always returns false. @override bool get isCovariant => false; - Map _referenceChildren; + Map? _referenceChildren; @override Map get referenceChildren { var from = documentationFrom.first as Method; @@ -136,13 +131,13 @@ class Method extends ModelElement } if (_referenceChildren == null) { _referenceChildren = {}; - _referenceChildren.addEntriesIfAbsent([ + _referenceChildren!.addEntriesIfAbsent([ ...typeParameters.explicitOnCollisionWith(this), - ...allParameters.explicitOnCollisionWith(this), + ...allParameters!.explicitOnCollisionWith(this), ...modelType.typeArguments.explicitOnCollisionWith(this), ...modelType.returnType.typeArguments.explicitOnCollisionWith(this), ]); } - return _referenceChildren; + return _referenceChildren!; } } diff --git a/lib/src/model/mixin.dart b/lib/src/model/mixin.dart index b5252753dd..35e17c5065 100644 --- a/lib/src/model/mixin.dart +++ b/lib/src/model/mixin.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:dartdoc/src/element_type.dart'; @@ -13,17 +11,17 @@ 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) + Mixin(ClassElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); - List _superclassConstraints; + List? _superclassConstraints; /// Returns a list of superclass constraints for this mixin. - Iterable get superclassConstraints { + Iterable? get superclassConstraints { _superclassConstraints ??= [ - ...element.superclassConstraints - .map( - (InterfaceType i) => modelBuilder.typeFrom(i, library)) + ...element!.superclassConstraints + .map((InterfaceType i) => + modelBuilder.typeFrom(i, library) as ParameterizedElementType) .where((t) => t.modelElement != packageGraph.specialClasses[SpecialClass.object]) @@ -35,7 +33,7 @@ class Mixin extends InheritingContainer with TypeImplementing { publicSuperclassConstraints.isNotEmpty; Iterable get publicSuperclassConstraints => - model_utils.filterNonPublic(superclassConstraints); + model_utils.filterNonPublic(superclassConstraints!); @override bool get hasModifiers => super.hasModifiers || hasPublicSuperclassConstraints; @@ -46,29 +44,29 @@ class Mixin extends InheritingContainer with TypeImplementing { @override String get kind => 'mixin'; - List _inheritanceChain; + List? _inheritanceChain; @override - List get inheritanceChain { + List get inheritanceChain { if (_inheritanceChain == null) { _inheritanceChain = []; - _inheritanceChain.add(this); + _inheritanceChain!.add(this); // Mix-in interfaces come before other interfaces. - _inheritanceChain.addAll(superclassConstraints.expand( + _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); + _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( + _inheritanceChain!.addAll(interfaces.expand( (e) => (e.modelElement as InheritingContainer).inheritanceChain)); } - return _inheritanceChain.toList(growable: false); + return _inheritanceChain!.toList(growable: false); } } diff --git a/lib/src/model/model.dart b/lib/src/model/model.dart index c4507e8ddb..a6d40f3d2f 100644 --- a/lib/src/model/model.dart +++ b/lib/src/model/model.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 - export 'accessor.dart'; export 'canonicalization.dart'; export 'categorization.dart'; diff --git a/lib/src/model/model_element.dart b/lib/src/model/model_element.dart index b9e9b9a07d..ccf9a04b5d 100644 --- a/lib/src/model/model_element.dart +++ b/lib/src/model/model_element.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.models; @@ -14,7 +12,7 @@ import 'package:analyzer/dart/element/type.dart' show FunctionType; import 'package:analyzer/source/line_info.dart'; // ignore: implementation_imports import 'package:analyzer/src/dart/element/member.dart' - show ExecutableMember, Member; + show ExecutableMember, Member, ParameterMember; import 'package:collection/collection.dart'; import 'package:dartdoc/src/comment_references/model_comment_reference.dart'; import 'package:dartdoc/src/dartdoc_options.dart'; @@ -42,22 +40,22 @@ import 'package:path/path.dart' as path show Context; /// the inheritance and interface chains from the analyzer. ModelElement resolveMultiplyInheritedElement( MultiplyInheritedExecutableElement e, - Library library, + Library? library, PackageGraph packageGraph, Class enclosingClass) { var inheritables = e.inheritedElements .map((ee) => ModelElement._fromElement(ee, packageGraph) as Inheritable); - Inheritable foundInheritable; + late Inheritable foundInheritable; var lowIndex = enclosingClass.inheritanceChain.length; for (var inheritable in inheritables) { - var index = - enclosingClass.inheritanceChain.indexOf(inheritable.enclosingElement); + var index = enclosingClass.inheritanceChain + .indexOf(inheritable.enclosingElement as InheritingContainer?); if (index < lowIndex) { foundInheritable = inheritable; lowIndex = index; } } - return ModelElement._from(foundInheritable.element, library, packageGraph, + return ModelElement._from(foundInheritable.element!, library, packageGraph, enclosingContainer: enclosingClass); } @@ -66,7 +64,7 @@ mixin ModelElementBuilderImpl implements ModelElementBuilder { @override ModelElement from(Element e, Library library, - {Container enclosingContainer}) => + {Container? enclosingContainer}) => ModelElement._from(e, library, packageGraph, enclosingContainer: enclosingContainer); @@ -76,8 +74,11 @@ mixin ModelElementBuilderImpl implements ModelElementBuilder { @override ModelElement fromPropertyInducingElement(Element e, Library l, - {Container enclosingContainer, Accessor getter, Accessor setter}) => - ModelElement._fromPropertyInducingElement(e, l, packageGraph, + {Container? enclosingContainer, + Accessor? getter, + Accessor? setter}) => + ModelElement._fromPropertyInducingElement( + e as PropertyInducingElement, l, packageGraph, enclosingContainer: enclosingContainer, getter: getter, setter: setter); @@ -124,14 +125,13 @@ abstract class ModelElement extends Canonicalization DocumentationComment, ModelBuilder implements Comparable, Documentable { - final Element _element; + final Element? _element; // TODO(jcollins-g): This really wants a "member that has a type" class. - final Member /*?*/ _originalMember; - final Library /*?*/ _library; + final Member? _originalMember; + final Library? _library; - UnmodifiableListView _parameters; - String _linkedName; + String? _linkedName; ModelElement(this._element, this._library, this._packageGraph, [this._originalMember]); @@ -141,11 +141,11 @@ abstract class ModelElement extends Canonicalization var lib = p.findButDoNotCreateLibraryFor(e); if (e is PropertyInducingElement) { var getter = - e.getter != null ? ModelElement._from(e.getter, lib, p) : null; + e.getter != null ? ModelElement._from(e.getter!, lib, p) : null; var setter = - e.setter != null ? ModelElement._from(e.setter, lib, p) : null; - return ModelElement._fromPropertyInducingElement(e, lib, p, - getter: getter, setter: setter); + e.setter != null ? ModelElement._from(e.setter!, lib, p) : null; + return ModelElement._fromPropertyInducingElement(e, lib!, p, + getter: getter as Accessor?, setter: setter as Accessor?); } return ModelElement._from(e, lib, p); } @@ -157,40 +157,38 @@ abstract class ModelElement extends Canonicalization /// if and only if this is to be an inherited or extended object. factory ModelElement._fromPropertyInducingElement( PropertyInducingElement e, Library library, PackageGraph packageGraph, - {Container enclosingContainer, - @required Accessor getter, - @required Accessor setter}) { - assert(packageGraph != null); - assert(e != null); - assert(library != null); - + {Container? enclosingContainer, + required Accessor? getter, + required Accessor? setter}) { // TODO(jcollins-g): Refactor object model to instantiate 'ModelMembers' // for members? if (e is Member) { - e = e.declaration; + e = e.declaration as PropertyInducingElement; } // Return the cached ModelElement if it exists. var key = - Tuple3(e, library, enclosingContainer); + Tuple3(e, library, enclosingContainer); if (packageGraph.allConstructedModelElements.containsKey(key)) { - return packageGraph.allConstructedModelElements[key]; + return packageGraph.allConstructedModelElements[key]!; } - ModelElement newModelElement; + ModelElement? newModelElement; if (e is FieldElement) { if (enclosingContainer == null) { if (e.isEnumConstant) { - var index = e.computeConstantValue().getField(e.name).toIntValue(); + var index = e.computeConstantValue()!.getField(e.name)!.toIntValue(); newModelElement = EnumField.forConstant(index, e, library, packageGraph, getter); } else if (e.enclosingElement is ExtensionElement) { - newModelElement = Field(e, library, packageGraph, getter, setter); + newModelElement = Field(e, library, packageGraph, + getter as ContainerAccessor?, setter as ContainerAccessor?); } else if (e.enclosingElement is ClassElement && (e.enclosingElement as ClassElement).isEnum) { newModelElement = EnumField(e, library, packageGraph, getter, setter); } else { - newModelElement = Field(e, library, packageGraph, getter, setter); + newModelElement = Field(e, library, packageGraph, + getter as ContainerAccessor?, setter as ContainerAccessor?); } } else { // EnumFields can't be inherited, so this case is simpler. @@ -208,8 +206,8 @@ abstract class ModelElement extends Canonicalization _cacheNewModelElement(e, newModelElement, library, enclosingContainer: enclosingContainer); - assert(newModelElement.element is! MultiplyInheritedExecutableElement); - return newModelElement; + assert(newModelElement!.element is! MultiplyInheritedExecutableElement); + return newModelElement!; } /// Creates a [ModelElement] from a non-property-inducing [e]. @@ -224,10 +222,8 @@ abstract class ModelElement extends Canonicalization // TODO(jcollins-g): Auto-vivify element's defining library for library // parameter when given a null. factory ModelElement._from( - Element e, Library library, PackageGraph packageGraph, - {Container enclosingContainer}) { - assert(packageGraph != null); - assert(e != null); + Element e, Library? library, PackageGraph packageGraph, + {Container? enclosingContainer}) { assert(library != null || e is ParameterElement || e is TypeParameterElement || @@ -242,7 +238,7 @@ abstract class ModelElement extends Canonicalization return NeverType(e, packageGraph); } - Member originalMember; + Member? originalMember; // TODO(jcollins-g): Refactor object model to instantiate 'ModelMembers' // for members? if (e is Member) { @@ -252,13 +248,15 @@ abstract class ModelElement extends Canonicalization // Return the cached ModelElement if it exists. var key = - Tuple3(e, library, enclosingContainer); + Tuple3(e, library, enclosingContainer); if (packageGraph.allConstructedModelElements.containsKey(key)) { - return packageGraph.allConstructedModelElements[key]; + return packageGraph.allConstructedModelElements[ + key as Tuple3]!; } var newModelElement = ModelElement._fromParameters(e, library, packageGraph, - enclosingContainer: enclosingContainer, originalMember: originalMember); + enclosingContainer: enclosingContainer, + originalMember: originalMember)!; if (enclosingContainer != null) assert(newModelElement is Inheritable); _cacheNewModelElement(e, newModelElement, library, @@ -271,13 +269,13 @@ abstract class ModelElement extends Canonicalization /// Caches a newly-created [ModelElement] from [ModelElement._from] or /// [ModelElement._fromPropertyInducingElement]. static void _cacheNewModelElement( - Element e, ModelElement newModelElement, Library library, - {Container enclosingContainer}) { + Element e, ModelElement? newModelElement, Library? library, + {Container? enclosingContainer}) { // TODO(jcollins-g): Reenable Parameter caching when dart-lang/sdk#30146 // is fixed? if (library != null && newModelElement is! Parameter) { var key = - Tuple3(e, library, enclosingContainer); + Tuple3(e, library, enclosingContainer); library.packageGraph.allConstructedModelElements[key] = newModelElement; if (newModelElement is Inheritable) { var iKey = Tuple2(e, library); @@ -288,12 +286,12 @@ abstract class ModelElement extends Canonicalization } } - static ModelElement _fromParameters( - Element e, Library library, PackageGraph packageGraph, - {Container enclosingContainer, Member originalMember}) { + static ModelElement? _fromParameters( + Element e, Library? library, PackageGraph packageGraph, + {Container? enclosingContainer, Member? originalMember}) { if (e is MultiplyInheritedExecutableElement) { return resolveMultiplyInheritedElement( - e, library, packageGraph, enclosingContainer); + e, library, packageGraph, enclosingContainer as Class); } assert(e is! MultiplyDefinedElement); if (e is LibraryElement) { @@ -312,13 +310,13 @@ abstract class ModelElement extends Canonicalization } } if (e is ExtensionElement) { - return Extension(e, library, packageGraph); + return Extension(e, library!, packageGraph); } if (e is FunctionElement) { return ModelFunction(e, library, packageGraph); } else if (e is GenericFunctionTypeElement) { assert(e.enclosingElement is TypeAliasElement); - assert(e.enclosingElement.name != ''); + assert(e.enclosingElement!.name != ''); return ModelFunctionTypedef(e, library, packageGraph); } if (e is TypeAliasElement) { @@ -346,7 +344,7 @@ abstract class ModelElement extends Canonicalization return Method(e, library, packageGraph); } else { return Method.inherited(e, enclosingContainer, library, packageGraph, - originalMember: originalMember); + originalMember: originalMember as ExecutableMember?); } } if (e is PropertyAccessorElement) { @@ -360,7 +358,7 @@ abstract class ModelElement extends Canonicalization assert(e.enclosingElement is! ExtensionElement); return ContainerAccessor.inherited( e, library, packageGraph, enclosingContainer, - originalMember: originalMember); + originalMember: originalMember as ExecutableMember?); } } else { return Accessor(e, library, packageGraph); @@ -371,7 +369,7 @@ abstract class ModelElement extends Canonicalization } if (e is ParameterElement) { return Parameter(e, library, packageGraph, - originalMember: originalMember); + originalMember: originalMember as ParameterMember?); } throw 'Unknown type ${e.runtimeType}'; } @@ -381,58 +379,55 @@ abstract class ModelElement extends Canonicalization bool get hasCategoryNames => false; // Stub for mustache. - Iterable get displayedCategories => []; + Iterable get displayedCategories => []; - Set get exportedInLibraries { - return library.packageGraph.libraryElementReexportedBy[element.library]; + Set? get exportedInLibraries { + return library!.packageGraph.libraryElementReexportedBy[element!.library!]; } - ModelNode _modelNode; + ModelNode? _modelNode; @override - ModelNode get modelNode => + ModelNode? get modelNode => _modelNode ??= packageGraph.getModelNodeFor(element); - Iterable _annotations; + Iterable? _annotations; // Skips over annotations with null elements or that are otherwise // supposed to be invisible (@pragma). While technically, null elements // indicate invalid code from analyzer's perspective they are present in // sky_engine (@Native) so we don't want to crash here. - Iterable get annotations => _annotations ??= element.metadata + Iterable get annotations => _annotations ??= element!.metadata .whereNot((m) => m.element == null || - packageGraph.specialClasses[SpecialClass.pragma].element.constructors + packageGraph + .specialClasses[SpecialClass.pragma]!.element!.constructors .contains(m.element)) .map((m) => Annotation(m, library, packageGraph)); - bool _isPublic; - - @override - bool get isPublic { - if (_isPublic == null) { - if (name == '') { - _isPublic = false; - } else if (this is! Library && (library == null || !library.isPublic)) { - _isPublic = false; - } else if (enclosingElement is Class && - !(enclosingElement as Class).isPublic) { - _isPublic = false; - } else if (enclosingElement is Extension && - !(enclosingElement as Extension).isPublic) { - _isPublic = false; - } else { - _isPublic = utils.hasPublicName(element) && !hasNodoc; - } + + @override + late final bool isPublic = () { + if (name == '') { + return false; } - return _isPublic; - } + if (this is! Library && (library == null || !library!.isPublic)) { + return false; + } + if (enclosingElement is Class && !(enclosingElement as Class).isPublic) { + return false; + } + if (enclosingElement is Extension && + !(enclosingElement as Extension).isPublic) { + return false; + } + return utils.hasPublicName(element!) && !hasNodoc!; + }(); - Map _commentRefs; @override - Map get commentRefs { - if (_commentRefs == null) { - _commentRefs = {}; - for (var from in documentationFrom) { - var checkReferences = [from]; + late final Map commentRefs = () { + var _commentRefs = {}; + for (var from in documentationFrom) { + if (from is ModelElement) { + var checkReferences = [from]; if (from is Accessor) { checkReferences.add(from.enclosingCombo); } @@ -448,22 +443,18 @@ abstract class ModelElement extends Canonicalization } } return _commentRefs; - } - - DartdocOptionContext _config; + }(); @override - DartdocOptionContext get config { - _config ??= DartdocOptionContext.fromContextElement( - packageGraph.config, library.element, packageGraph.resourceProvider); - return _config; - } + late final DartdocOptionContext config = + DartdocOptionContext.fromContextElement( + packageGraph.config, library!.element, packageGraph.resourceProvider); - Set _locationPieces; + Set? _locationPieces; @override Set get locationPieces => - _locationPieces ??= Set.from(element.location + _locationPieces ??= Set.from(element!.location .toString() .split(locationSplitter) .where((s) => s.isNotEmpty)); @@ -501,52 +492,56 @@ abstract class ModelElement extends Canonicalization (element is TypeAliasElement && (element as TypeAliasElement).aliasedElement is FunctionTypedElement); - ModelElement buildCanonicalModelElement() { - Container preferredClass; + ModelElement? buildCanonicalModelElement() { + Container? preferredClass; if (enclosingElement is Class || enclosingElement is Extension) { - preferredClass = enclosingElement; + preferredClass = enclosingElement as Container?; } return packageGraph.findCanonicalModelElementFor(element, preferredClass: preferredClass); } - ModelElement _canonicalModelElement; + ModelElement? _canonicalModelElement; // Returns the canonical ModelElement for this ModelElement, or null // if there isn't one. - ModelElement get canonicalModelElement => + ModelElement? get canonicalModelElement => _canonicalModelElement ??= buildCanonicalModelElement(); - bool get hasSourceHref => sourceHref.isNotEmpty; - String _sourceHref; + bool get hasSourceHref => sourceHref!.isNotEmpty; + String? _sourceHref; - String get sourceHref { + String? get sourceHref { _sourceHref ??= SourceLinker.fromElement(this).href(); return _sourceHref; } Library get definingLibrary { - Library library = modelBuilder.fromElement(element.library); + Library? library = modelBuilder.fromElement(element!.library!) as Library?; if (library == null) { warn(PackageWarning.noDefiningLibraryFound); } - return library; + Library? fallback; + if (enclosingElement is ModelElement) { + fallback = (enclosingElement as ModelElement).definingLibrary; + } + return library ?? fallback ?? this.library!; } - Library _canonicalLibrary; + Library? _canonicalLibrary; // [_canonicalLibrary] can be null so we can't check against null to see // whether we tried to compute it before. bool _canonicalLibraryIsSet = false; @override - Library get canonicalLibrary { + Library? get canonicalLibrary { if (!_canonicalLibraryIsSet) { // This is not accurate if we are constructing the Package. assert(packageGraph.allLibrariesAdded); // Privately named elements can never have a canonical library, so // just shortcut them out. - if (!utils.hasPublicName(element)) { + if (!utils.hasPublicName(element!)) { _canonicalLibrary = null; } else if (!packageGraph.localPublicLibraries.contains(definingLibrary)) { _canonicalLibrary = _searchForCanonicalLibrary(); @@ -557,7 +552,7 @@ abstract class ModelElement extends Canonicalization if (this is Inheritable && !config.linkToRemote) { if ((this as Inheritable).isInherited && _canonicalLibrary == null && - packageGraph.publicLibraries.contains(library)) { + packageGraph.publicLibraries!.contains(library)) { // In the event we've inherited a field from an object that isn't // directly reexported, we may need to pretend we are canonical for // this. @@ -567,14 +562,11 @@ abstract class ModelElement extends Canonicalization _canonicalLibraryIsSet = true; } assert(_canonicalLibrary == null || - packageGraph.publicLibraries.contains(_canonicalLibrary)); + packageGraph.publicLibraries!.contains(_canonicalLibrary)); return _canonicalLibrary; } - Library _searchForCanonicalLibrary() { - if (definingLibrary == null) { - return null; - } + Library? _searchForCanonicalLibrary() { var thisAndExported = definingLibrary.exportedInLibraries; if (thisAndExported == null) { @@ -596,9 +588,9 @@ abstract class ModelElement extends Canonicalization l.isPublic && l.package.documentedWhere != DocumentLocation.missing) .where((l) { var lookup = - l.element.exportNamespace.definedNames[topLevelElement?.name]; + l.element.exportNamespace.definedNames[topLevelElement?.name!]; if (lookup is PropertyAccessorElement) { - lookup = (lookup as PropertyAccessorElement).variable; + lookup = lookup.variable; } return topLevelElement == lookup; }).toList(); @@ -624,7 +616,7 @@ abstract class ModelElement extends Canonicalization } // Start with our top-level element. - var warnable = ModelElement._fromElement(topLevelElement, packageGraph); + var warnable = ModelElement._fromElement(topLevelElement!, packageGraph); // Heuristic scoring to determine which library a human likely // considers this element to be primarily 'from', and therefore, // canonical. Still warn if the heuristic isn't that confident. @@ -668,7 +660,7 @@ abstract class ModelElement extends Canonicalization } @override - Element get element => _element; + Element? get element => _element; @override String get location { @@ -692,11 +684,11 @@ abstract class ModelElement extends Canonicalization String get fileName => '$name.$fileType'; - String get fileType => package.fileType; + String get fileType => package!.fileType; - String get filePath; + String? get filePath; - String _fullyQualifiedName; + String? _fullyQualifiedName; /// Returns the fully qualified name. /// @@ -706,57 +698,68 @@ abstract class ModelElement extends Canonicalization return (_fullyQualifiedName ??= _buildFullyQualifiedName()); } - String _fullyQualifiedNameWithoutLibrary; + String? _fullyQualifiedNameWithoutLibrary; @override - String get fullyQualifiedNameWithoutLibrary { + String? get fullyQualifiedNameWithoutLibrary { // Remember, periods are legal in library names. _fullyQualifiedNameWithoutLibrary ??= - fullyQualifiedName.replaceFirst('${library.fullyQualifiedName}.', ''); + fullyQualifiedName.replaceFirst('${library!.fullyQualifiedName}.', ''); return _fullyQualifiedNameWithoutLibrary; } @override - String get sourceFileName => element.source.fullName; + String get sourceFileName => element!.source!.fullName; - CharacterLocation _characterLocation; + CharacterLocation? _characterLocation; bool _characterLocationIsSet = false; @override - CharacterLocation get characterLocation { + CharacterLocation? get characterLocation { if (!_characterLocationIsSet) { - var lineInfo = compilationUnitElement.lineInfo; + var lineInfo = compilationUnitElement!.lineInfo; _characterLocationIsSet = true; - assert(element.nameOffset >= 0, + assert(element!.nameOffset >= 0, 'Invalid location data for element: $fullyQualifiedName'); assert(lineInfo != null, 'No lineInfo data available for element: $fullyQualifiedName'); - if (element.nameOffset >= 0) { - _characterLocation = lineInfo?.getLocation(element.nameOffset); + if (element!.nameOffset >= 0) { + _characterLocation = lineInfo?.getLocation(element!.nameOffset); } } return _characterLocation; } - CompilationUnitElement get compilationUnitElement => - element.thisOrAncestorOfType(); + CompilationUnitElement? get compilationUnitElement => + element!.thisOrAncestorOfType(); bool get hasAnnotations => annotations.isNotEmpty; @override - bool get hasDocumentation => documentation?.isNotEmpty == true; + bool get hasDocumentation => documentation.isNotEmpty == true; @override bool get hasExtendedDocumentation => - href != null && elementDocumentation.hasExtendedDocs; + href != null && elementDocumentation.hasExtendedDocs!; bool get hasParameters => parameters.isNotEmpty; /// If canonicalLibrary (or canonicalEnclosingElement, for Inheritable /// subclasses) is null, href should be null. @override - String get href; + String? get href { + if (!identical(canonicalModelElement, this)) { + return canonicalModelElement?.href; + } + assert(canonicalLibrary != null); + assert(canonicalLibrary == library); + var packageBaseHref = package?.baseHref; + if (packageBaseHref != null) { + return '$packageBaseHref$filePath'; + } + return null; + } - String get htmlId => name; + String? get htmlId => name; bool get isAsynchronous => isExecutable && (element as ExecutableElement).isAsynchronous; @@ -766,13 +769,13 @@ abstract class ModelElement extends Canonicalization bool get isDeprecated { // If element.metadata is empty, it might be because this is a property // where the metadata belongs to the individual getter/setter - if (element.metadata.isEmpty && element is PropertyInducingElement) { + if (element!.metadata.isEmpty && element is PropertyInducingElement) { var pie = element as PropertyInducingElement; // The getter or the setter might be null – so the stored value may be // `true`, `false`, or `null` - var getterDeprecated = pie.getter?.metadata?.any((a) => a.isDeprecated); - var setterDeprecated = pie.setter?.metadata?.any((a) => a.isDeprecated); + var getterDeprecated = pie.getter?.metadata.any((a) => a.isDeprecated); + var setterDeprecated = pie.setter?.metadata.any((a) => a.isDeprecated); var deprecatedValues = [getterDeprecated, setterDeprecated].where((a) => a != null).toList(); @@ -782,9 +785,9 @@ abstract class ModelElement extends Canonicalization // If there are both a setter and getter, only show the property as // deprecated if both are deprecated. - return deprecatedValues.every((d) => d); + return deprecatedValues.every((d) => d!); } - return element.metadata.any((a) => a.isDeprecated); + return element!.metadata.any((a) => a.isDeprecated); } @override @@ -814,11 +817,12 @@ abstract class ModelElement extends Canonicalization String get kind; @override - Library get library => _library; + // FIXME(nnbd): library should not have to be nullable just because of dynamic + Library? get library => _library; String get linkedName { _linkedName ??= _calculateLinkedName(); - return _linkedName; + return _linkedName!; } @visibleForTesting @@ -840,21 +844,19 @@ abstract class ModelElement extends Canonicalization String get linkedParamsLines => _parameterRendererDetailed.renderLinkedParams(parameters).trim(); - String get linkedParamsNoMetadata => + String? get linkedParamsNoMetadata => _parameterRenderer.renderLinkedParams(parameters, showMetadata: false); String get linkedParamsNoMetadataOrNames => _parameterRenderer .renderLinkedParams(parameters, showMetadata: false, showNames: false); - String _name; - @override - String get name => _name ??= element.name; + String get name => element!.name!; @override - String get oneLineDoc => elementDocumentation.asOneLiner; + String? get oneLineDoc => elementDocumentation.asOneLiner; - Member get originalMember => _originalMember; + Member? get originalMember => _originalMember; final PackageGraph _packageGraph; @@ -862,21 +864,23 @@ abstract class ModelElement extends Canonicalization PackageGraph get packageGraph => _packageGraph; @override - Package get package => library?.package; + // FIXME(nnbd): package should not have to be nullable just because of dynamic + Package? get package => library?.package; - bool get isPublicAndPackageDocumented => isPublic && package.isDocumented; + bool get isPublicAndPackageDocumented => + isPublic && package?.isDocumented == true; - List _allParameters; + List? _allParameters; // TODO(jcollins-g): This is in the wrong place. Move parts to // [GetterSetterCombo], elsewhere as appropriate? - List get allParameters { + List? get allParameters { if (_allParameters == null) { var recursedParameters = {}; var newParameters = {}; if (this is GetterSetterCombo && (this as GetterSetterCombo).setter != null) { - newParameters.addAll((this as GetterSetterCombo).setter.parameters); + newParameters.addAll((this as GetterSetterCombo).setter!.parameters); } else { if (isCallable) newParameters.addAll(parameters); } @@ -904,55 +908,51 @@ abstract class ModelElement extends Canonicalization @override path.Context get pathContext => packageGraph.resourceProvider.pathContext; - List get parameters { + late final List parameters = () { if (!isCallable) { throw StateError( '$element (${element.runtimeType}) cannot have parameters'); } - if (_parameters == null) { - List params; - - if (element is TypeAliasElement) { - _parameters = ModelElement._fromElement( - (element as TypeAliasElement).aliasedElement, packageGraph) - .parameters; + if (element is TypeAliasElement) { + return ModelElement._fromElement( + (element as TypeAliasElement).aliasedElement!, packageGraph) + .parameters; + } + List? params; + if (element is ExecutableElement) { + if (_originalMember != null) { + assert(_originalMember is ExecutableMember); + params = (_originalMember as ExecutableMember).parameters; } else { - if (element is ExecutableElement) { - if (_originalMember != null) { - assert(_originalMember is ExecutableMember); - params = (_originalMember as ExecutableMember).parameters; - } else { - params = (element as ExecutableElement).parameters; - } - } - if (params == null && element is FunctionTypedElement) { - if (_originalMember != null) { - params = (_originalMember as FunctionTypedElement).parameters; - } else { - params = (element as FunctionTypedElement).parameters; - } - } - _parameters = UnmodifiableListView(params - .map((p) => - ModelElement._from(p, library, packageGraph) as Parameter) - .toList(growable: false)); + params = (element as ExecutableElement).parameters; } } - return _parameters; - } + if (params == null && element is FunctionTypedElement) { + if (_originalMember != null) { + params = (_originalMember as FunctionTypedElement).parameters; + } else { + params = (element as FunctionTypedElement).parameters; + } + } + + return [ + ...params! + .map((p) => ModelElement._from(p, library, packageGraph) as Parameter) + ]; + }(); @override - String /*!*/ get documentationComment => element.documentationComment ?? ''; + String get documentationComment => element!.documentationComment ?? ''; @override - bool get hasDocumentationComment => element.documentationComment != null; + bool get hasDocumentationComment => element!.documentationComment != null; - String _sourceCode; + String? _sourceCode; @override - String get sourceCode { + String? get sourceCode { return _sourceCode ??= - _sourceCodeRenderer.renderSourceCode(super.sourceCode); + _sourceCodeRenderer.renderSourceCode(super.sourceCode!); } @override @@ -967,7 +967,7 @@ abstract class ModelElement extends Canonicalization @override String toString() => '$runtimeType $name'; - String _buildFullyQualifiedName([ModelElement e, String fqName]) { + String _buildFullyQualifiedName([ModelElement? e, String? fqName]) { e ??= this; fqName ??= e.name; @@ -975,8 +975,8 @@ abstract class ModelElement extends Canonicalization return fqName; } - return _buildFullyQualifiedName( - e.enclosingElement, '${e.enclosingElement.name}.$fqName'); + return _buildFullyQualifiedName(e.enclosingElement as ModelElement?, + '${e.enclosingElement!.name}.$fqName'); } String _calculateLinkedName() { @@ -1001,5 +1001,5 @@ abstract class ModelElement extends Canonicalization @override CommentReferable get definingCommentReferable => element == null ? super.definingCommentReferable - : modelBuilder.fromElement(element); + : modelBuilder.fromElement(element!); } diff --git a/lib/src/model/model_function.dart b/lib/src/model/model_function.dart index c614c72b26..f5d33c4872 100644 --- a/lib/src/model/model_function.dart +++ b/lib/src/model/model_function.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/element_type.dart'; import 'package:dartdoc/src/model/comment_referable.dart'; @@ -12,51 +10,52 @@ import 'package:dartdoc/src/model/model.dart'; /// A [ModelElement] for a [FunctionElement] that isn't part of a type definition. class ModelFunction extends ModelFunctionTyped with Categorization { ModelFunction( - FunctionElement element, Library library, PackageGraph packageGraph) + FunctionElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); @override - bool get isStatic => element.isStatic; + bool get isStatic => element!.isStatic; @override - String get name => element.name ?? ''; + String get name => element!.name; @override - FunctionElement get element => super.element; + FunctionElement? get element => super.element as FunctionElement?; } /// A [ModelElement] for a [FunctionTypedElement] that is part of an /// explicit typedef. class ModelFunctionTypedef extends ModelFunctionTyped { ModelFunctionTypedef( - FunctionTypedElement element, Library library, PackageGraph packageGraph) + FunctionTypedElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); @override - String get name => element.enclosingElement.name; + String get name => element!.enclosingElement!.name!; } class ModelFunctionTyped extends ModelElement with TypeParameters implements EnclosedElement { - List _typeParameters; + List? _typeParameters; @override List get typeParameters => _typeParameters ??= [ - for (var p in element.typeParameters) modelBuilder.from(p, library), + for (var p in element!.typeParameters) + modelBuilder.from(p, library!) as TypeParameter, ]; ModelFunctionTyped( - FunctionTypedElement element, Library library, PackageGraph packageGraph) + FunctionTypedElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); @override - ModelElement get enclosingElement => library; + ModelElement? get enclosingElement => library; @override - String get filePath => '${library.dirName}/$fileName'; + String get filePath => '${library!.dirName}/$fileName'; @override - String get href { + String? get href { if (!identical(canonicalModelElement, this)) { return canonicalModelElement?.href; } @@ -71,26 +70,29 @@ class ModelFunctionTyped extends ModelElement // Food for mustache. TODO(jcollins-g): what about enclosing elements? bool get isInherited => false; - Map _referenceChildren; + Map? _referenceChildren; @override Map get referenceChildren { if (_referenceChildren == null) { _referenceChildren = {}; - _referenceChildren + _referenceChildren! .addEntriesIfAbsent(typeParameters.explicitOnCollisionWith(this)); - _referenceChildren + _referenceChildren! .addEntriesIfAbsent(parameters.explicitOnCollisionWith(this)); } - return _referenceChildren; + return _referenceChildren!; } + @override + Package get package => super.package!; + @override Iterable get referenceParents => [definingLibrary]; @override - FunctionTypedElement get element => super.element; + FunctionTypedElement? get element => super.element as FunctionTypedElement?; - Callable _modelType; - Callable get modelType => - _modelType ??= modelBuilder.typeFrom(element.type, library); + Callable? _modelType; + Callable get modelType => (_modelType ??= + modelBuilder.typeFrom(element!.type, library!) as Callable?)!; } diff --git a/lib/src/model/model_node.dart b/lib/src/model/model_node.dart index dbd48274b1..a2d8d568f7 100644 --- a/lib/src/model/model_node.dart +++ b/lib/src/model/model_node.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 - import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/file_system/file_system.dart'; @@ -17,27 +15,27 @@ class ModelNode { final Element element; final ResourceProvider resourceProvider; - final AstNode _sourceNode; + final AstNode? _sourceNode; - ModelNode(AstNode sourceNode, this.element, this.resourceProvider) + ModelNode(AstNode? sourceNode, this.element, this.resourceProvider) : _sourceNode = sourceNode, commentRefs = _commentRefsFor(sourceNode, resourceProvider); static List _commentRefsFor( - AstNode node, ResourceProvider resourceProvider) { + AstNode? node, ResourceProvider resourceProvider) { if (node is AnnotatedNode && - node?.documentationComment?.references != null) { + node.documentationComment?.references != null) { return [ - for (var m in node.documentationComment.references) + for (var m in node.documentationComment!.references) ModelCommentReference(m, resourceProvider), ]; } return []; } - String _sourceCode; + String? _sourceCode; - String get sourceCode { + String? get sourceCode { if (_sourceCode == null) { if (_sourceNode?.offset != null) { var enclosingSourceNode = _sourceNode; @@ -46,12 +44,12 @@ class ModelNode { /// In this case, it is either a [FieldDeclaration] or /// [TopLevelVariableDeclaration]. (#2401) if (_sourceNode is VariableDeclaration) { - enclosingSourceNode = _sourceNode.parent.parent; + enclosingSourceNode = _sourceNode!.parent!.parent; assert(enclosingSourceNode is FieldDeclaration || enclosingSourceNode is TopLevelVariableDeclaration); } - var sourceEnd = enclosingSourceNode.end; + var sourceEnd = enclosingSourceNode!.end; var sourceOffset = enclosingSourceNode.offset; var contents = @@ -60,7 +58,7 @@ class ModelNode { var i = sourceOffset; while (i > 0) { i -= 1; - if (contents[i] == '\n' || contents[i] == '\r') { + if (contents![i] == '\n' || contents[i] == '\r') { i += 1; break; } @@ -68,7 +66,7 @@ class ModelNode { // Trim the common indent from the source snippet. var start = sourceOffset - (sourceOffset - i); - var source = contents.substring(start, sourceEnd); + var source = contents!.substring(start, sourceEnd); source = model_utils.stripIndentFromSource(source); source = model_utils.stripDartdocCommentsFromSource(source); diff --git a/lib/src/model/model_object_builder.dart b/lib/src/model/model_object_builder.dart index 1a7a53a014..c9dafd9d4e 100644 --- a/lib/src/model/model_object_builder.dart +++ b/lib/src/model/model_object_builder.dart @@ -10,7 +10,6 @@ import 'package:dartdoc/src/model/container.dart'; import 'package:dartdoc/src/model/library.dart'; import 'package:dartdoc/src/model/model_element.dart'; import 'package:dartdoc/src/model/package_graph.dart'; -import 'package:meta/meta.dart'; abstract class ModelObjectBuilder implements ModelElementBuilder, ElementTypeBuilder {} @@ -22,8 +21,8 @@ abstract class ModelElementBuilder { ModelElement fromPropertyInducingElement(Element e, Library l, {Container enclosingContainer, - @required Accessor getter, - @required Accessor setter}); + required Accessor? getter, + required Accessor? setter}); } abstract class ElementTypeBuilder { diff --git a/lib/src/model/nameable.dart b/lib/src/model/nameable.dart index 8843244534..b8ead8010d 100644 --- a/lib/src/model/nameable.dart +++ b/lib/src/model/nameable.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 - import 'package:collection/collection.dart'; import 'locatable.dart'; @@ -15,18 +13,18 @@ abstract class Nameable { String get fullyQualifiedName => name; - Set _namePieces; - Set get namePieces { + Set? _namePieces; + Set? get namePieces { _namePieces ??= { ...name.split(locationSplitter).where((s) => s.isNotEmpty) }; return _namePieces; } - String _namePart; + String? _namePart; /// Utility getter/cache for `_MarkdownCommentReference._getResultsForClass`. - String get namePart { + String? get namePart { // TODO(jcollins-g): This should really be the same as 'name', but isn't // because of accessors and operators. _namePart ??= fullyQualifiedName.split('.').last; diff --git a/lib/src/model/never.dart b/lib/src/model/never.dart index ad67fa774e..9b88f0ca95 100644 --- a/lib/src/model/never.dart +++ b/lib/src/model/never.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/model/comment_referable.dart'; import 'package:dartdoc/src/model/model.dart'; @@ -15,7 +13,7 @@ class NeverType extends ModelElement { /// `Never` is not a real object, and so we can't document it, so there /// can be nothing canonical for it. @override - ModelElement get canonicalModelElement => null; + ModelElement? get canonicalModelElement => null; @override ModelElement get enclosingElement => throw UnsupportedError(''); @@ -23,7 +21,7 @@ class NeverType extends ModelElement { /// And similarly, even if someone references it directly it can have /// no hyperlink. @override - String get href => null; + String? get href => null; @override String get kind => 'Never'; @@ -32,7 +30,7 @@ class NeverType extends ModelElement { String get linkedName => 'Never'; @override - String get filePath => null; + String? get filePath => null; @override Map get referenceChildren => {}; diff --git a/lib/src/model/operator.dart b/lib/src/model/operator.dart index 4b989a22d0..4523cfb4b0 100644 --- a/lib/src/model/operator.dart +++ b/lib/src/model/operator.dart @@ -2,22 +2,21 @@ // 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:analyzer/dart/element/element.dart'; // ignore: implementation_imports -import 'package:analyzer/src/dart/element/member.dart' show Member; +import 'package:analyzer/src/dart/element/member.dart' + show ExecutableMember, Member; import 'package:dartdoc/src/comment_references/parser.dart'; import 'package:dartdoc/src/model/model.dart'; class Operator extends Method { - Operator(MethodElement element, Library library, PackageGraph packageGraph) + Operator(MethodElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); Operator.inherited(MethodElement element, Container enclosingContainer, - Library library, PackageGraph packageGraph, {Member originalMember}) + Library? library, PackageGraph packageGraph, {Member? originalMember}) : super.inherited(element, enclosingContainer, library, packageGraph, - originalMember: originalMember); + originalMember: originalMember as ExecutableMember?); @override String get fileName { @@ -30,7 +29,7 @@ class Operator extends Method { @override String get fullyQualifiedName => - '${library.name}.${enclosingElement.name}.${super.name}'; + '${library!.name}.${enclosingElement!.name}.${super.name}'; @override bool get isOperator => true; diff --git a/lib/src/model/package.dart b/lib/src/model/package.dart index f472830407..2c8d4d62e2 100644 --- a/lib/src/model/package.dart +++ b/lib/src/model/package.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/file_system/file_system.dart'; import 'package:dartdoc/src/comment_references/model_comment_reference.dart'; @@ -44,7 +42,7 @@ class Package extends LibraryContainer String _name; PackageGraph _packageGraph; - final Map _nameToCategory = {}; + final Map _nameToCategory = {}; // Creates a package, if necessary, and adds it to the [packageGraph]. factory Package.fromPackageMeta( @@ -63,10 +61,10 @@ class Package extends LibraryContainer // before allLibrariesAdded is true. assert( !(expectNonLocal && - packageGraph.packageMap[packageName].documentedWhere == + packageGraph.packageMap[packageName]!.documentedWhere == DocumentLocation.local), 'Found more libraries to document after allLibrariesAdded was set to true'); - return packageGraph.packageMap[packageName]; + return packageGraph.packageMap[packageName]!; } Package._(this._name, this._packageGraph, this._packageMeta); @@ -75,14 +73,14 @@ class Package extends LibraryContainer bool get isCanonical => true; @override - Library get canonicalLibrary => null; + Library? get canonicalLibrary => null; /// Number of times we have invoked a tool for this package. int toolInvocationIndex = 0; // The animation IDs that have already been used, indexed by the [href] of the // object that contains them. - Map> usedAnimationIdsByHref = {}; + Map> usedAnimationIdsByHref = {}; /// Pieces of the location, split to remove 'package:' and slashes. @override @@ -93,8 +91,7 @@ class Package extends LibraryContainer /// non-documented libraries unless they are all referenced by documented ones. final Set allLibraries = {}; - bool get hasHomepage => - packageMeta.homepage != null && packageMeta.homepage.isNotEmpty; + bool get hasHomepage => packageMeta.homepage.isNotEmpty; String get homepage => packageMeta.homepage; @@ -108,22 +105,22 @@ class Package extends LibraryContainer /// in this package. bool get hasCategories => categories.isNotEmpty; - LibraryContainer get defaultCategory => nameToCategory[null]; + LibraryContainer? get defaultCategory => nameToCategory[null]; - String _documentationAsHtml; + String? _documentationAsHtml; @override - String get documentationAsHtml { + String? get documentationAsHtml { if (_documentationAsHtml != null) return _documentationAsHtml; _documentationAsHtml = Documentation.forElement(this).asHtml; return _documentationAsHtml; } - String /*?*/ _documentation; + String? _documentation; @override - String get documentation { + String? get documentation { if (_documentation == null) { final docFile = documentationFile; if (docFile != null) { @@ -140,9 +137,9 @@ class Package extends LibraryContainer @override bool get hasExtendedDocumentation => hasDocumentation; - File /*?*/ _documentationFile; + File? _documentationFile; - File /*?*/ get documentationFile => + File? get documentationFile => _documentationFile ??= packageMeta.getReadmeContents(); @override @@ -153,70 +150,64 @@ class Package extends LibraryContainer isFirstPackage || documentedWhere != DocumentLocation.missing; @override - Warnable get enclosingElement => null; - - bool _isPublic; + Warnable? get enclosingElement => null; @override - bool get isPublic { - _isPublic ??= libraries.any((l) => l.isPublic); - return _isPublic; - } - bool _isLocal; + /// If we have public libraries, this is the default package, or we are + /// auto-including dependencies, this package is public. + late final bool isPublic = + libraries.any((l) => l.isPublic) || _isLocalPublicByDefault; /// Return true if this is the default package, this is part of an embedder /// SDK, or if [DartdocOptionContext.autoIncludeDependencies] is true -- but /// only if the package was not excluded on the command line. - bool get isLocal { - _isLocal ??= ( - // Document as local if this is the default package. - packageMeta == packageGraph.packageMeta || - // Assume we want to document an embedded SDK as local if - // it has libraries defined in the default package. - // TODO(jcollins-g): Handle case where embedder SDKs can be - // assembled from multiple locations? - packageGraph.hasEmbedderSdk && - packageMeta.isSdk && - libraries.any((l) => _pathContext.isWithin( - packageGraph.packageMeta.dir.path, - (l.element.source.fullName))) || - // autoIncludeDependencies means everything is local. - packageGraph.config.autoIncludeDependencies) && - // Regardless of the above rules, do not document as local if - // we excluded this package by name. - !packageGraph.config.isPackageExcluded(name); - return _isLocal; - } - - /* late */ DocumentLocation _documentedWhere; - - DocumentLocation get documentedWhere { - if (_documentedWhere == null) { - if (isLocal) { - if (isPublic) { - _documentedWhere = DocumentLocation.local; - } - } else { - if (config.linkToRemote && - config.linkToUrl.isNotEmpty && - isPublic && - !packageGraph.config.isPackageExcluded(name)) { - _documentedWhere = DocumentLocation.remote; - } else { - _documentedWhere = DocumentLocation.missing; - } - } + late final bool isLocal = ( + // Document as local if this is the default package. + _isLocalPublicByDefault || + // Assume we want to document an embedded SDK as local if + // it has libraries defined in the default package. + // TODO(jcollins-g): Handle case where embedder SDKs can be + // assembled from multiple locations? + packageGraph.hasEmbedderSdk && + packageMeta.isSdk && + libraries.any((l) => _pathContext.isWithin( + packageGraph.packageMeta.dir.path, + (l.element.source.fullName)))) && + // Regardless of the above rules, do not document as local if + // we excluded this package by name. + !_isExcluded; + + /// True if the global config excludes this package by name. + late final bool _isExcluded = packageGraph.config.isPackageExcluded(name); + + /// True if this is the package being documented by default, or the + /// global config indicates we are auto-including dependencies. + late final bool _isLocalPublicByDefault = + (packageMeta == packageGraph.packageMeta || + packageGraph.config.autoIncludeDependencies); + + /// Returns the location of documentation for this package, for linkToRemote + /// and canonicalization decision making. + late final DocumentLocation documentedWhere = () { + if (isLocal && isPublic) { + return DocumentLocation.local; } - return _documentedWhere; - } + if (config.linkToRemote && + config.linkToUrl.isNotEmpty && + isPublic && + !packageGraph.config.isPackageExcluded(name)) { + return DocumentLocation.remote; + } + return DocumentLocation.missing; + }(); @override String get enclosingName => packageGraph.defaultPackageName; String get filePath => 'index.$fileType'; - String _fileType; + String? _fileType; String get fileType { // TODO(jdkoren): Provide a way to determine file type of a remote package's @@ -232,16 +223,16 @@ class Package extends LibraryContainer @override String get fullyQualifiedName => 'package:$name'; - String _baseHref; + String? _baseHref; - String get baseHref { + String? get baseHref { if (_baseHref != null) { return _baseHref; } if (documentedWhere == DocumentLocation.remote) { _baseHref = _remoteBaseHref; - if (!_baseHref.endsWith('/')) _baseHref = '$_baseHref/'; + if (!_baseHref!.endsWith('/')) _baseHref = '$_baseHref/'; } else { _baseHref = config.useBaseHref ? '' : htmlBasePlaceholder; } @@ -278,7 +269,7 @@ class Package extends LibraryContainer return packageMeta.version; default: assert(false, 'Unsupported case: ${m.group(1)}'); - return null; + return ''; } }); } @@ -309,11 +300,11 @@ class Package extends LibraryContainer } /// A map of category name to the category itself. - Map get nameToCategory { + Map get nameToCategory { if (_nameToCategory.isEmpty) { - Category categoryFor(String category) { + Category? categoryFor(String? category) { _nameToCategory.putIfAbsent( - category, () => Category(category, this, config)); + category, () => Category(category!, this, config)); return _nameToCategory[category]; } @@ -321,25 +312,22 @@ class Package extends LibraryContainer for (var c in libraries.expand( (l) => l.allCanonicalModelElements.whereType())) { if (c.hasCategoryNames) { - for (var category in c.categoryNames) { - categoryFor(category).addItem(c); + for (var category in c.categoryNames!) { + categoryFor(category)!.addItem(c); } } else { // Add to the default category. - categoryFor(null).addItem(c); + categoryFor(null)!.addItem(c); } } } return _nameToCategory; } - List _categories; - - List get categories { - _categories ??= nameToCategory.values.where((c) => c.name != null).toList() + late final List categories = () { + return nameToCategory.values.where((c) => c.name.isNotEmpty).toList() ..sort(); - return _categories; - } + }(); Iterable get categoriesWithPublicLibraries => categories.where((c) => c.publicLibraries.isNotEmpty); @@ -358,16 +346,11 @@ class Package extends LibraryContainer bool get hasDocumentedCategories => documentedCategories.isNotEmpty; - DartdocOptionContext _config; - @override - DartdocOptionContext get config { - _config ??= DartdocOptionContext.fromContext( - packageGraph.config, - packageGraph.resourceProvider.getFolder(packagePath), - packageGraph.resourceProvider); - return _config; - } + late final DartdocOptionContext config = DartdocOptionContext.fromContext( + packageGraph.config, + packageGraph.resourceProvider.getFolder(packagePath!), + packageGraph.resourceProvider); /// Is this the package at the top of the list? We display the first /// package specially (with "Libraries" rather than the package name). @@ -378,39 +361,39 @@ class Package extends LibraryContainer @override bool get isSdk => packageMeta.isSdk; - String _packagePath; + String? _packagePath; - String get packagePath { + String? get packagePath { _packagePath ??= _pathContext.canonicalize(packageMeta.dir.path); return _packagePath; } - String get version => packageMeta.version ?? '0.0.0-unknown'; + String get version => packageMeta.version; final PackageMeta _packageMeta; PackageMeta get packageMeta => _packageMeta; @override - Element get element => null; + Element? get element => null; @override - List get containerOrder => config.packageOrder; + List get containerOrder => config.packageOrder; - Map _referenceChildren; + Map? _referenceChildren; @override Map get referenceChildren { if (_referenceChildren == null) { _referenceChildren = {}; - _referenceChildren.addEntries(publicLibrariesSorted.generateEntries()); + _referenceChildren!.addEntries(publicLibrariesSorted.generateEntries()); // Do not override any preexisting data, and insert based on the // public library sort order. // TODO(jcollins-g): warn when results require package-global // lookups like this. - _referenceChildren.addEntriesIfAbsent( + _referenceChildren!.addEntriesIfAbsent( publicLibrariesSorted.expand((l) => l.referenceChildren.entries)); } - return _referenceChildren; + return _referenceChildren!; } @override diff --git a/lib/src/model/package_builder.dart b/lib/src/model/package_builder.dart index c842c02c3e..ea21b20f74 100644 --- a/lib/src/model/package_builder.dart +++ b/lib/src/model/package_builder.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 - import 'dart:async'; import 'package:analyzer/dart/analysis/analysis_context_collection.dart'; @@ -24,6 +22,7 @@ import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl; import 'package:analyzer/src/generated/java_io.dart' show JavaFile; // ignore: implementation_imports import 'package:analyzer/src/generated/sdk.dart' show DartSdk; +import 'package:collection/collection.dart' show IterableExtension; import 'package:dartdoc/src/dartdoc_options.dart'; import 'package:dartdoc/src/logging.dart'; import 'package:dartdoc/src/model/model.dart' hide Package; @@ -33,7 +32,7 @@ import 'package:dartdoc/src/package_meta.dart' import 'package:dartdoc/src/quiver.dart' as quiver; import 'package:dartdoc/src/render/renderer_factory.dart'; import 'package:dartdoc/src/special_elements.dart'; -import 'package:meta/meta.dart'; +import 'package:package_config/package_config.dart'; import 'package:path/path.dart' as path show Context; /// Everything you need to instantiate a PackageGraph object for documenting. @@ -81,19 +80,13 @@ class PubPackageBuilder implements PackageBuilder { return newGraph; } - /*late final*/ DartSdk _sdk; - - DartSdk get sdk { - _sdk ??= packageMetaProvider.defaultSdk ?? - FolderBasedDartSdk( - resourceProvider, resourceProvider.getFolder(config.sdkDir)); + late final DartSdk sdk = packageMetaProvider.defaultSdk ?? + FolderBasedDartSdk( + resourceProvider, resourceProvider.getFolder(config.sdkDir)); - return _sdk; - } + EmbedderSdk? _embedderSdk; - EmbedderSdk _embedderSdk; - - EmbedderSdk get embedderSdk { + EmbedderSdk? get embedderSdk { if (_embedderSdk == null && !config.topLevelPackageMeta.isSdk) { _embedderSdk = EmbedderSdk( resourceProvider, EmbedderYamlLocator(_packageMap).embedderYamls); @@ -103,10 +96,10 @@ class PubPackageBuilder implements PackageBuilder { ResourceProvider get resourceProvider => packageMetaProvider.resourceProvider; + /// Do not call more than once for a given PackageBuilder. Future _calculatePackageMap() async { - assert(_packageMap == null); _packageMap = >{}; - Folder cwd = resourceProvider.getResource(config.inputDir); + Folder cwd = resourceProvider.getResource(config.inputDir) as Folder; var info = await packageConfigProvider .findPackageConfig(resourceProvider.getFolder(cwd.path)); if (info == null) return; @@ -121,11 +114,11 @@ class PubPackageBuilder implements PackageBuilder { } } - /*late final*/ Map> _packageMap; + late final Map> _packageMap; - AnalysisContextCollection _contextCollection; + AnalysisContextCollection? _contextCollection; - AnalysisContextCollection get contextCollection { + AnalysisContextCollection? get contextCollection { _contextCollection ??= AnalysisContextCollectionImpl( includedPaths: [config.inputDir], // TODO(jcollins-g): should we pass excluded directories here instead of @@ -142,14 +135,14 @@ class PubPackageBuilder implements PackageBuilder { /// Returns an Iterable with the SDK files we should parse. Iterable getSdkFilesToDocument() sync* { for (var sdkLib in sdk.sdkLibraries) { - var source = sdk.mapDartUri(sdkLib.shortName); + var source = sdk.mapDartUri(sdkLib.shortName)!; yield source.fullName; } } /// Parse a single library at [filePath] using the current analysis driver. /// If [filePath] is not a library, returns null. - Future processLibrary(String filePath) async { + Future processLibrary(String filePath) async { var name = filePath; var directoryCurrentPath = resourceProvider.pathContext.current; @@ -162,7 +155,7 @@ class PubPackageBuilder implements PackageBuilder { var javaFile = JavaFile(filePath).getAbsoluteFile(); filePath = javaFile.getPath(); - var analysisContext = contextCollection.contextFor(config.inputDir); + var analysisContext = contextCollection!.contextFor(config.inputDir); var session = analysisContext.currentSession; // Allow dart source files with inappropriate suffixes (#1897). final library = await session.getResolvedLibrary(filePath); @@ -174,11 +167,11 @@ class PubPackageBuilder implements PackageBuilder { return null; } - Set _packageMetasForFiles(Iterable files) => { + Set _packageMetasForFiles(Iterable files) => { for (var filename in files) packageMetaProvider.fromFilename(filename), }; - void _addKnownFiles(LibraryElement element) { + void _addKnownFiles(LibraryElement? element) { if (element != null) { var path = element.source.fullName; if (_knownFiles.add(path)) { @@ -204,10 +197,10 @@ class PubPackageBuilder implements PackageBuilder { void Function(DartDocResolvedLibrary) libraryAdder, Set libraries, Set files, - [bool Function(LibraryElement) isLibraryIncluded]) async { + [bool Function(LibraryElement)? isLibraryIncluded]) async { isLibraryIncluded ??= (_) => true; - var lastPass = {}; - var current = {}; + Set lastPass = {}; + Set current = {}; var knownParts = {}; do { lastPass = current; @@ -239,7 +232,7 @@ class PubPackageBuilder implements PackageBuilder { // discovers some files in a package we haven't seen yet, add files // for that package. for (var meta in current.difference(lastPass)) { - if (meta.isSdk) { + if (meta!.isSdk) { files.addAll(getSdkFilesToDocument()); } else { files.addAll(await findFilesToDocumentInPackage(meta.dir.path, @@ -253,17 +246,18 @@ class PubPackageBuilder implements PackageBuilder { /// Given a package name, explore the directory and pull out all top level /// library files in the "lib" directory to document. Stream findFilesToDocumentInPackage(String basePackageDir, - {@required bool autoIncludeDependencies, + {required bool autoIncludeDependencies, bool filterExcludes = true}) async* { var packageDirs = {basePackageDir}; if (autoIncludeDependencies) { - var info = await packageConfigProvider - .findPackageConfig(resourceProvider.getFolder(basePackageDir)); + var info = await (packageConfigProvider + .findPackageConfig(resourceProvider.getFolder(basePackageDir)) + as FutureOr); for (var package in info.packages) { if (!filterExcludes || !config.exclude.contains(package.name)) { packageDirs.add(_pathContext.dirname( - _pathContext.fromUri(info[package.name].packageUriRoot))); + _pathContext.fromUri(info[package.name]!.packageUriRoot))); } } } @@ -307,7 +301,7 @@ class PubPackageBuilder implements PackageBuilder { /// The returned paths are guaranteed to begin with [dir]. Iterable _listDir(String dir, {bool recursive = false, - Iterable Function(Folder dir) listDir}) { + Iterable Function(Folder dir)? listDir}) { listDir ??= (Folder dir) => dir.getChildren(); return _doList(dir, {}, recursive, listDir); @@ -344,9 +338,7 @@ class PubPackageBuilder implements PackageBuilder { for (var file in files) { var fileContext = DartdocOptionContext.fromContext(config, config.resourceProvider.getFile(file), config.resourceProvider); - if (fileContext.includeExternal != null) { - yield* fileContext.includeExternal; - } + yield* fileContext.includeExternal; } } @@ -371,7 +363,7 @@ class PubPackageBuilder implements PackageBuilder { return [ for (var dartUri in _embedderSdkUris) resourceProvider.pathContext.absolute(resourceProvider - .getFile(embedderSdk.mapDartUri(dartUri).fullName) + .getFile(embedderSdk!.mapDartUri(dartUri)!.fullName) .path), ]; } @@ -381,16 +373,16 @@ class PubPackageBuilder implements PackageBuilder { Iterable get _embedderSdkUris { if (config.topLevelPackageMeta.isSdk) return []; - return embedderSdk?.urlMappings?.keys ?? []; + return embedderSdk?.urlMappings.keys ?? []; } Future getLibraries(PackageGraph uninitializedPackageGraph) async { - var findSpecialsSdk = sdk; - if (embedderSdk != null && embedderSdk.urlMappings.isNotEmpty) { + DartSdk? findSpecialsSdk = sdk; + if (embedderSdk != null && embedderSdk!.urlMappings.isNotEmpty) { findSpecialsSdk = embedderSdk; } var files = await _getFiles(); - var specialFiles = specialLibraryFiles(findSpecialsSdk); + var specialFiles = specialLibraryFiles(findSpecialsSdk!); /// Returns true if this library element should be included according /// to the configuration. @@ -430,13 +422,11 @@ class PubPackageBuilder implements PackageBuilder { var resources = dir.getChildren(); var pathContext = dir.provider.pathContext; - var pubspec = resources.firstWhere( - (e) => e is File && pathContext.basename(e.path) == 'pubspec.yaml', - orElse: () => null); + var pubspec = resources.firstWhereOrNull( + (e) => e is File && pathContext.basename(e.path) == 'pubspec.yaml'); - var libDir = resources.firstWhere( - (e) => e is Folder && pathContext.basename(e.path) == 'lib', - orElse: () => null); + var libDir = resources.firstWhereOrNull( + (e) => e is Folder && pathContext.basename(e.path) == 'lib'); if (pubspec != null && libDir != null) { yield libDir; diff --git a/lib/src/model/package_graph.dart b/lib/src/model/package_graph.dart index cfc76e9d0c..f289a89fe5 100644 --- a/lib/src/model/package_graph.dart +++ b/lib/src/model/package_graph.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 - import 'dart:collection'; import 'package:analyzer/dart/ast/ast.dart' hide CommentReference; @@ -37,7 +35,6 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { this.rendererFactory, this.packageMetaProvider, ) : packageMeta = config.topLevelPackageMeta { - _packageWarningCounter = PackageWarningCounter(this); // Make sure the default package exists, even if it has no libraries. // This can happen for packages that only contain embedder SDKs. Package.fromPackageMeta(packageMeta, this); @@ -52,7 +49,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { } @override - String get name => null; + String get name => ''; /// Call during initialization to add a library to this [PackageGraph]. /// @@ -70,7 +67,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { } var lib = Library.fromLibraryResult( resolvedLibrary, this, Package.fromPackageMeta(packageMeta, this)); - packageMap[packageMeta.name].libraries.add(lib); + packageMap[packageMeta.name]!.libraries.add(lib); allLibraries[libraryElement.source.fullName] = lib; } @@ -126,7 +123,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { for (var d in m.documentationFrom.where((d) => d.hasDocumentationComment)) { if (d.needsPrecache && !precachedElements.contains(d)) { - precachedElements.add(d); + precachedElements.add(d as ModelElement); yield d.precacheLocalDocs(); logProgress(d.name); // TopLevelVariables get their documentation from getters and setters, @@ -140,7 +137,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { } } - for (var m in allModelElements) { + for (var m in allModelElements!) { // Skip if there is a canonicalModelElement somewhere else we can run this // for and we won't need a one line document that is precached. // Not the same as allCanonicalModelElements since we need to run @@ -151,7 +148,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { && !m.isCanonical // This element is not canonical && - !m.enclosingElement + !m.enclosingElement! .isCanonical // The enclosingElement won't need a oneLineDoc from this ) { continue; @@ -174,9 +171,9 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { resourceProvider)); } - ModelNode getModelNodeFor(Element element) => _modelNodes[element]; + ModelNode? getModelNodeFor(Element? element) => _modelNodes[element!]; - SpecialClasses specialClasses; + late SpecialClasses specialClasses; /// It is safe to cache values derived from the [_implementors] table if this /// is true. @@ -191,8 +188,8 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { return _implementors; } - List _documentedExtensions; - Iterable get documentedExtensions { + List? _documentedExtensions; + Iterable? get documentedExtensions { _documentedExtensions ??= utils.filterNonDocumented(extensions).toList(growable: false); return _documentedExtensions; @@ -212,12 +209,10 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { // of differences in the [TimestampedData] timestamps. final allLibraries = {}; - /// Keep track of warnings - PackageWarningCounter _packageWarningCounter; - /// All ModelElements constructed for this package; a superset of [allModelElements]. - final allConstructedModelElements = - HashMap, ModelElement>(); + final HashMap, ModelElement?> + allConstructedModelElements = + HashMap, ModelElement?>(); /// Anything that might be inheritable, place here for later lookup. final allInheritableElements = @@ -249,7 +244,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { /// PackageMeta Provider for building [PackageMeta]s. final PackageMetaProvider packageMetaProvider; - Package _defaultPackage; + Package? _defaultPackage; Package get defaultPackage => _defaultPackage ??= Package.fromPackageMeta(packageMeta, this); @@ -268,13 +263,13 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { final DartSdk sdk; - Map _sdkLibrarySources; + Map? _sdkLibrarySources; - Map get sdkLibrarySources { + Map? get sdkLibrarySources { if (_sdkLibrarySources == null) { _sdkLibrarySources = {}; - for (var lib in sdk?.sdkLibraries) { - _sdkLibrarySources[sdk.mapDartUri(lib.shortName)] = lib; + for (var lib in sdk.sdkLibraries) { + _sdkLibrarySources![sdk.mapDartUri(lib.shortName)] = lib; } } return _sdkLibrarySources; @@ -285,14 +280,16 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { bool allLibrariesAdded = false; bool _localDocumentationBuilt = false; - PackageWarningCounter get packageWarningCounter => _packageWarningCounter; + /// Keep track of warnings. + late final PackageWarningCounter packageWarningCounter = + PackageWarningCounter(this); - final Set> _warnAlreadySeen = {}; + final Set> _warnAlreadySeen = {}; - void warnOnElement(Warnable warnable, PackageWarning kind, - {String message, - Iterable referredFrom, - Iterable extendedDebug}) { + void warnOnElement(Warnable? warnable, PackageWarning kind, + {String? message, + Iterable? referredFrom, + Iterable? extendedDebug}) { var newEntry = Tuple3(warnable?.element, kind, message); if (_warnAlreadySeen.contains(newEntry)) { return; @@ -301,29 +298,29 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { // don't allow warnings we're already working on to get in there. _warnAlreadySeen.add(newEntry); _warnOnElement(warnable, kind, - message: message, + message: message ?? '', referredFrom: referredFrom, extendedDebug: extendedDebug); _warnAlreadySeen.remove(newEntry); } - void _warnOnElement(Warnable warnable, PackageWarning kind, - {String message, - Iterable referredFrom, - Iterable extendedDebug}) { + void _warnOnElement(Warnable? warnable, PackageWarning kind, + {required String message, + Iterable? referredFrom, + Iterable? extendedDebug}) { if (warnable != null) { // This sort of warning is only applicable to top level elements. if (kind == PackageWarning.ambiguousReexport) { - while (warnable.enclosingElement is! Library && + while (warnable!.enclosingElement is! Library && warnable.enclosingElement != null) { warnable = warnable.enclosingElement; } } } else { // If we don't have an element, we need a message to disambiguate. - assert(message != null); + assert(message.isNotEmpty); } - if (_packageWarningCounter.hasWarning(warnable, kind, message)) { + if (packageWarningCounter.hasWarning(warnable, kind, message)) { return; } // Some kinds of warnings it is OK to drop if we're not documenting them. @@ -344,7 +341,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { var warnablePrefix = 'from'; var referredFromPrefix = 'referred to by'; - String warningMessage; + String? warningMessage; switch (kind) { case PackageWarning.noCanonicalFound: // Fix these warnings by adding libraries with --include, or by using @@ -369,11 +366,11 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { break; case PackageWarning.noLibraryLevelDocs: warningMessage = - '${warnable.fullyQualifiedName} has no library level documentation comments'; + '${warnable!.fullyQualifiedName} has no library level documentation comments'; break; case PackageWarning.noDocumentableLibrariesInPackage: warningMessage = - '${warnable.fullyQualifiedName} has no documentable libraries'; + '${warnable!.fullyQualifiedName} has no documentable libraries'; break; case PackageWarning.ambiguousDocReference: warningMessage = 'ambiguous doc reference $message'; @@ -455,7 +452,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { break; } - var messageParts = [warningMessage]; + var messageParts = [warningMessage]; if (warnable != null) { messageParts.add('$warnablePrefix $warnableName: ${warnable.location}'); } @@ -476,7 +473,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { packageWarningCounter.addWarning(warnable, kind, message, fullMessage); } - String _safeWarnableName(Locatable locatable) { + String _safeWarnableName(Locatable? locatable) { if (locatable == null) { return ''; } @@ -486,9 +483,9 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { List get packages => packageMap.values.toList(); - List _publicPackages; + List? _publicPackages; - List get publicPackages { + List? get publicPackages { if (_publicPackages == null) { assert(allLibrariesAdded); // Help the user if they pass us a package that doesn't exist. @@ -507,7 +504,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { /// Local packages are to be documented locally vs. remote or not at all. List get localPackages => - publicPackages.where((p) => p.isLocal).toList(); + publicPackages!.where((p) => p.isLocal).toList(); /// Documented packages are documented somewhere (local or remote). Iterable get documentedPackages => @@ -516,12 +513,12 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { Map> _libraryElementReexportedBy = {}; /// Prevent cycles from breaking our stack. - Set> _reexportsTagged = {}; + Set> _reexportsTagged = {}; void _tagReexportsFor( - final Library topLevelLibrary, final LibraryElement libraryElement, - [ExportElement lastExportedElement]) { - var key = Tuple2(topLevelLibrary, libraryElement); + final Library topLevelLibrary, final LibraryElement? libraryElement, + [ExportElement? lastExportedElement]) { + var key = Tuple2(topLevelLibrary, libraryElement); if (_reexportsTagged.contains(key)) { return; } @@ -530,7 +527,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { // The first call to _tagReexportFor should not have a null libraryElement. assert(lastExportedElement != null); warnOnElement( - findButDoNotCreateLibraryFor(lastExportedElement.enclosingElement), + findButDoNotCreateLibraryFor(lastExportedElement!.enclosingElement!), PackageWarning.unresolvedExport, message: '"${lastExportedElement.uri}"', referredFrom: [topLevelLibrary]); @@ -553,7 +550,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { _lastSizeOfAllLibraries = allLibraries.keys.length; _libraryElementReexportedBy = >{}; _reexportsTagged = {}; - for (var library in publicLibraries) { + for (var library in publicLibraries!) { _tagReexportsFor(library, library.element); } } @@ -577,7 +574,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { if (modelElement is Dynamic) continue; // TODO: see [Accessor.enclosingCombo] if (modelElement is Accessor) continue; - final href = modelElement.href; + final href = modelElement!.href; if (href == null) continue; hrefMap.putIfAbsent(href, () => {}).add(modelElement); @@ -604,9 +601,10 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { if (!implemented.isPublic) { privates.add(implemented); } - implemented = implemented.canonicalModelElement ?? implemented; + implemented = implemented.canonicalModelElement as InheritingContainer? ?? + implemented; _implementors.putIfAbsent(implemented, () => []); - var list = _implementors[implemented]; + var list = _implementors[implemented]!; // TODO(srawlins): This would be more efficient if we created a // SplayTreeSet keyed off of `.element`. if (!list.any((l) => l.element == implementor.element)) { @@ -616,18 +614,19 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { void addImplementor(InheritingContainer clazz) { if (clazz.supertype != null) { - checkAndAddContainer(clazz.supertype.modelElement, clazz); + checkAndAddContainer( + clazz.supertype!.modelElement as InheritingContainer, clazz); } if (clazz is Class) { for (var type in clazz.mixedInTypes) { - checkAndAddContainer(type.modelElement, clazz); + checkAndAddContainer(type.modelElement as InheritingContainer, clazz); } for (var type in clazz.interfaces) { - checkAndAddContainer(type.modelElement, clazz); + checkAndAddContainer(type.modelElement as InheritingContainer, clazz); } } for (var type in clazz.publicInterfaces) { - checkAndAddContainer(type.modelElement, clazz); + checkAndAddContainer(type.modelElement as InheritingContainer, clazz); } } @@ -643,9 +642,9 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { Iterable get libraries => packages.expand((p) => p.libraries).toList()..sort(); - List _publicLibraries; + List? _publicLibraries; - Iterable get publicLibraries { + Iterable? get publicLibraries { if (_publicLibraries == null) { assert(allLibrariesAdded); _publicLibraries = utils.filterNonPublic(libraries).toList(); @@ -653,9 +652,9 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { return _publicLibraries; } - List _localLibraries; + List? _localLibraries; - Iterable get localLibraries { + Iterable? get localLibraries { if (_localLibraries == null) { assert(allLibrariesAdded); _localLibraries = localPackages.expand((p) => p.libraries).toList() @@ -664,36 +663,31 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { return _localLibraries; } - List _localPublicLibraries; - - Iterable get localPublicLibraries { - if (_localPublicLibraries == null) { - assert(allLibrariesAdded); - _localPublicLibraries = utils.filterNonPublic(localLibraries).toList(); - } - return _localPublicLibraries; - } + late final Iterable localPublicLibraries = () { + assert(allLibrariesAdded); + return utils.filterNonPublic(localLibraries!).toList(); + }(); - Set _inheritThrough; + Set? _inheritThrough; /// Return the set of [Class]es objects should inherit through if they /// show up in the inheritance chain. Do not call before interceptorElement is /// found. Add classes here if they are similar to Interceptor in that they /// are to be ignored even when they are the implementors of [Inheritable]s, /// and the class these inherit from should instead claim implementation. - Set get inheritThrough { + Set? get inheritThrough { if (_inheritThrough == null) { _inheritThrough = {}; - _inheritThrough.add(specialClasses[SpecialClass.interceptor]); + _inheritThrough!.add(specialClasses[SpecialClass.interceptor]); } return _inheritThrough; } - Set _invisibleAnnotations; + Set? _invisibleAnnotations; /// Returns the set of [Class] objects that are similar to pragma /// in that we should never count them as documentable annotations. - Set get invisibleAnnotations => + Set get invisibleAnnotations => _invisibleAnnotations ??= {specialClasses[SpecialClass.pragma]}; bool isAnnotationVisible(Class clazz) => @@ -707,7 +701,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { buffer.writeln(divider); buffer.writeln(); for (final name in packageMap.keys) { - final package = packageMap[name]; + final package = packageMap[name]!; buffer.write('Package $name documented at ${package.documentedWhere} ' 'with libraries: '); buffer.writeAll(package.allLibraries); @@ -717,10 +711,10 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { return buffer.toString(); } - final Map _canonicalLibraryFor = {}; + final Map _canonicalLibraryFor = {}; /// Tries to find a top level library that references this element. - Library findCanonicalLibraryFor(Element e) { + Library? findCanonicalLibraryFor(Element? e) { assert(allLibrariesAdded); var searchElement = e; if (e is PropertyAccessorElement) { @@ -734,9 +728,9 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { return _canonicalLibraryFor[e]; } _canonicalLibraryFor[e] = null; - for (var library in publicLibraries) { + for (var library in publicLibraries!) { if (library.modelElementsMap.containsKey(searchElement)) { - for (var modelElement in library.modelElementsMap[searchElement]) { + for (var modelElement in library.modelElementsMap[searchElement!]!) { if (modelElement.isCanonical) { return _canonicalLibraryFor[e] = library; } @@ -753,27 +747,27 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { /// This doesn't know anything about [PackageGraph.inheritThrough] and probably /// shouldn't, so using it with [Inheritable]s without special casing is /// not advised. - // FIXME(nnbd): remove null check ignore in model_utils after migration - ModelElement /*?*/ findCanonicalModelElementFor(Element e, - {Container preferredClass}) { + ModelElement? findCanonicalModelElementFor(Element? e, + {Container? preferredClass}) { assert(allLibrariesAdded); var lib = findCanonicalLibraryFor(e); - if (preferredClass != null && preferredClass is Container) { - Container canonicalClass = - findCanonicalModelElementFor(preferredClass.element); + if (preferredClass != null) { + Container? canonicalClass = + findCanonicalModelElementFor(preferredClass.element) as Container?; if (canonicalClass != null) preferredClass = canonicalClass; } if (lib == null && preferredClass != null) { lib = findCanonicalLibraryFor(preferredClass.element); } - ModelElement modelElement; + ModelElement? modelElement; // For elements defined in extensions, they are canonical. if (e?.enclosingElement is ExtensionElement) { - lib ??= modelBuilder.fromElement(e.enclosingElement.library); + lib ??= + modelBuilder.fromElement(e!.enclosingElement!.library!) as Library?; // (TODO:keertip) Find a better way to exclude members of extensions // when libraries are specified using the "--include" flag if (lib?.isDocumented == true) { - return modelBuilder.from(e, lib); + return modelBuilder.from(e!, lib!); } } // TODO(jcollins-g): Special cases are pretty large here. Refactor to split @@ -781,30 +775,36 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { // TODO(jcollins-g): The data structures should be changed to eliminate guesswork // with member elements. if (e is ClassMemberElement || e is PropertyAccessorElement) { - e = e.declaration; - var candidates = {}; - var iKey = Tuple2(e, lib); + e = e!.declaration; + var candidates = {}; + var iKey = Tuple2(e, lib); var key = - Tuple4(e, lib, null, null); - var keyWithClass = Tuple4( - e, lib, preferredClass, null); + Tuple4(e, lib, null, null); + var keyWithClass = Tuple4( + e, lib, preferredClass as Class?, null); if (allConstructedModelElements.containsKey(key)) { - candidates.add(allConstructedModelElements[key]); + candidates.add(allConstructedModelElements[ + key as Tuple3]); } if (allConstructedModelElements.containsKey(keyWithClass)) { - candidates.add(allConstructedModelElements[keyWithClass]); + candidates.add(allConstructedModelElements[ + keyWithClass as Tuple3]); } if (candidates.isEmpty && allInheritableElements.containsKey(iKey)) { - candidates - .addAll(allInheritableElements[iKey].where((me) => me.isCanonical)); + candidates.addAll( + allInheritableElements[iKey as Tuple2]! + .where((me) => me.isCanonical)); } - Class canonicalClass = findCanonicalModelElementFor(e.enclosingElement); + Class? canonicalClass = + findCanonicalModelElementFor(e!.enclosingElement) as Class?; if (canonicalClass != null) { candidates.addAll(canonicalClass.allCanonicalModelElements.where((m) { return m.element == e; })); } - var matches = {...candidates.where((me) => me.isCanonical)}; + var matches = { + ...candidates.where((me) => me!.isCanonical) + }; // It's possible to find accessors but no combos. Be sure that if we // have Accessors, we find their combos too. @@ -817,9 +817,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { // This is for situations where multiple classes may actually be canonical // for an inherited element whose defining Class is not canonical. - if (matches.length > 1 && - preferredClass != null && - preferredClass is Class) { + if (matches.length > 1 && preferredClass != null) { // Search for matches inside our superchain. var superChain = preferredClass.superChain .map((et) => et.modelElement) @@ -832,7 +830,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { // preferredClass. var enclosingElements = { ...matches - .map((me) => (me as EnclosedElement).enclosingElement as Class) + .map((me) => (me as EnclosedElement).enclosingElement as Class?) }; for (var c in superChain.reversed) { if (enclosingElements.contains(c)) { @@ -856,13 +854,13 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { if (lib != null) { if (e is PropertyInducingElement) { var getter = - e.getter != null ? modelBuilder.from(e.getter, lib) : null; + e.getter != null ? modelBuilder.from(e.getter!, lib) : null; var setter = - e.setter != null ? modelBuilder.from(e.setter, lib) : null; + e.setter != null ? modelBuilder.from(e.setter!, lib) : null; modelElement = modelBuilder.fromPropertyInducingElement(e, lib, - getter: getter, setter: setter); + getter: getter as Accessor, setter: setter as Accessor); } else { - modelElement = modelBuilder.from(e, lib); + modelElement = modelBuilder.from(e!, lib); } } assert(modelElement is! Inheritable); @@ -872,7 +870,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { } // Prefer Fields. if (e is PropertyAccessorElement && modelElement is Accessor) { - modelElement = (modelElement as Accessor).enclosingCombo; + modelElement = modelElement.enclosingCombo; } return modelElement; } @@ -880,9 +878,9 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { /// This is used when we might need a Library object that isn't actually /// a documentation entry point (for elements that have no Library within the /// set of canonical Libraries). - Library findButDoNotCreateLibraryFor(Element e) { + Library? findButDoNotCreateLibraryFor(Element e) { // This is just a cache to avoid creating lots of libraries over and over. - return allLibraries[e.library?.source?.fullName]; + return allLibraries[e.library?.source.fullName]; } /// This is used when we might need a Library object that isn't actually @@ -890,10 +888,6 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { /// set of canonical Libraries). Library findOrCreateLibraryFor(DartDocResolvedLibrary resolvedLibrary) { final libraryElement = resolvedLibrary.library; - // can be null if e is for dynamic - if (libraryElement == null) { - return null; - } var foundLibrary = findButDoNotCreateLibraryFor(libraryElement); if (foundLibrary != null) return foundLibrary; @@ -901,15 +895,15 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { resolvedLibrary, this, Package.fromPackageMeta( - packageMetaProvider.fromElement(libraryElement, config.sdkDir), + packageMetaProvider.fromElement(libraryElement, config.sdkDir)!, packageGraph)); allLibraries[libraryElement.source.fullName] = foundLibrary; return foundLibrary; } - List _allModelElements; + List? _allModelElements; - Iterable get allModelElements { + Iterable? get allModelElements { assert(allLibrariesAdded); if (_allModelElements == null) { _allModelElements = []; @@ -923,7 +917,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { librariesToDo .difference(completedLibraries) .forEach((Library library) { - _allModelElements.addAll(library.allModelElements); + _allModelElements!.addAll(library.allModelElements); completedLibraries.add(library); }); librariesToDo.addAll(p.allLibraries); @@ -936,24 +930,24 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { return _allModelElements; } - List _allLocalModelElements; + List? _allLocalModelElements; - Iterable get allLocalModelElements { + Iterable? get allLocalModelElements { assert(allLibrariesAdded); if (_allLocalModelElements == null) { _allLocalModelElements = []; - for (var library in localLibraries) { - _allLocalModelElements.addAll(library.allModelElements); + for (var library in localLibraries!) { + _allLocalModelElements!.addAll(library.allModelElements); } } return _allLocalModelElements; } - List _allCanonicalModelElements; + List? _allCanonicalModelElements; Iterable get allCanonicalModelElements { return _allCanonicalModelElements ??= - allLocalModelElements.where((e) => e.isCanonical).toList(); + allLocalModelElements!.where((e) => e.isCanonical).toList(); } /// Glob lookups can be expensive. Cache per filename. @@ -961,7 +955,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { /// Given an element's location, look up the nodoc configuration data and /// determine whether to unconditionally treat the element as "nodoc". - bool configSetsNodocFor(String fullName) { + bool? configSetsNodocFor(String fullName) { if (!_configSetsNodocFor.containsKey(fullName)) { var file = resourceProvider.getFile(fullName); // Direct lookup instead of generating a custom context will save some @@ -975,9 +969,9 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { return _configSetsNodocFor[fullName]; } - String getMacro(String name) { + String? getMacro(String? name) { assert(_localDocumentationBuilt); - return _macros[name]; + return _macros[name!]; } void addMacro(String name, String content) { @@ -989,9 +983,9 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { _macros[name] = content; } - String getHtmlFragment(String name) { + String? getHtmlFragment(String? name) { assert(_localDocumentationBuilt); - return _htmlFragments[name]; + return _htmlFragments[name!]; } void addHtmlFragment(String name, String content) { @@ -1003,7 +997,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { _htmlFragments[name] = content; } - Map _referenceChildren; + Map? _referenceChildren; @override Map get referenceChildren { if (_referenceChildren == null) { @@ -1014,20 +1008,20 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { var sortedPackages = packages.toList()..sort(byName); var sortedDocumentedPackages = documentedPackages.toList()..sort(byName); // Packages are the top priority. - _referenceChildren.addEntries(sortedPackages.generateEntries()); + _referenceChildren!.addEntries(sortedPackages.generateEntries()); // Libraries are next. // TODO(jcollins-g): Warn about directly referencing libraries out of // scope? Doing this is always going to be ambiguous and potentially // confusing. - _referenceChildren.addEntriesIfAbsent(sortedDocumentedPackages + _referenceChildren!.addEntriesIfAbsent(sortedDocumentedPackages .expand((p) => p.publicLibrariesSorted) .generateEntries()); // TODO(jcollins-g): Warn about directly referencing top level items // out of scope? Doing this will be even more ambiguous and // potentially confusing than doing so with libraries. - _referenceChildren.addEntriesIfAbsent(sortedDocumentedPackages + _referenceChildren!.addEntriesIfAbsent(sortedDocumentedPackages .expand((p) => p.publicLibrariesSorted) .expand((l) => [ ...l.publicConstants, @@ -1041,7 +1035,7 @@ class PackageGraph with CommentReferable, Nameable, ModelBuilder { ]) .generateEntries()); } - return _referenceChildren; + return _referenceChildren!; } @override diff --git a/lib/src/model/parameter.dart b/lib/src/model/parameter.dart index 5e62402d51..4af1d25f6a 100644 --- a/lib/src/model/parameter.dart +++ b/lib/src/model/parameter.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 - import 'package:analyzer/dart/element/element.dart'; // ignore: implementation_imports import 'package:analyzer/src/dart/element/member.dart' show ParameterMember; @@ -13,22 +11,21 @@ import 'package:dartdoc/src/model/model.dart'; class Parameter extends ModelElement implements EnclosedElement { Parameter( - ParameterElement element, Library library, PackageGraph packageGraph, - {ParameterMember originalMember}) + ParameterElement element, Library? library, PackageGraph packageGraph, + {ParameterMember? originalMember}) : super(element, library, packageGraph, originalMember); - String get defaultValue { + String? get defaultValue { if (!hasDefaultValue) return null; - return element.defaultValueCode; + return element!.defaultValueCode; } @override - ModelElement get enclosingElement => (element.enclosingElement != null) - ? modelBuilder.from(element.enclosingElement, library) - : null; + ModelElement get enclosingElement => + modelBuilder.from(element!.enclosingElement!, library!); bool get hasDefaultValue { - return element.defaultValueCode != null && - element.defaultValueCode.isNotEmpty; + return element!.defaultValueCode != null && + element!.defaultValueCode!.isNotEmpty; } @override @@ -37,19 +34,19 @@ class Parameter extends ModelElement implements EnclosedElement { } @override - String get href => null; + String? get href => null; @override String get htmlId { - if (element.enclosingElement != null) { - var enclosingName = element.enclosingElement.name; - if (element.enclosingElement is GenericFunctionTypeElement) { + if (element!.enclosingElement != null) { + var enclosingName = element!.enclosingElement!.name; + if (element!.enclosingElement is GenericFunctionTypeElement) { // TODO(jcollins-g): Drop when GenericFunctionTypeElement populates name. // Also, allowing null here is allowed as a workaround for // dart-lang/sdk#32005. - for (var e = element.enclosingElement; + for (var e = element!.enclosingElement!; e.enclosingElement != null; - e = e.enclosingElement) { + e = e.enclosingElement!) { enclosingName = e.name; if (enclosingName != null && enclosingName.isNotEmpty) break; } @@ -65,23 +62,23 @@ class Parameter extends ModelElement implements EnclosedElement { @override bool operator ==(Object other) => - other is Parameter && (element.type == other.element.type); + other is Parameter && (element!.type == other.element!.type); - bool get isCovariant => element.isCovariant; + bool get isCovariant => element!.isCovariant; - bool get isRequiredPositional => element.isRequiredPositional; + bool get isRequiredPositional => element!.isRequiredPositional; - bool get isNamed => element.isNamed; + bool get isNamed => element!.isNamed; - bool get isOptionalPositional => element.isOptionalPositional; + bool get isOptionalPositional => element!.isOptionalPositional; /// Only true if this is a required named parameter. - bool get isRequiredNamed => element.isRequiredNamed; + bool get isRequiredNamed => element!.isRequiredNamed; @override String get kind => 'parameter'; - Map _referenceChildren; + Map? _referenceChildren; @override Map get referenceChildren { @@ -89,28 +86,28 @@ class Parameter extends ModelElement implements EnclosedElement { _referenceChildren = {}; var _modelType = modelType; if (_modelType is Callable) { - _referenceChildren.addEntriesIfAbsent( + _referenceChildren!.addEntriesIfAbsent( _modelType.parameters.explicitOnCollisionWith(this)); } - _referenceChildren.addEntriesIfAbsent( + _referenceChildren!.addEntriesIfAbsent( modelType.typeArguments.explicitOnCollisionWith(this)); if (_modelType is Callable) { - _referenceChildren.addEntriesIfAbsent( + _referenceChildren!.addEntriesIfAbsent( _modelType.returnType.typeArguments.explicitOnCollisionWith(this)); } } - return _referenceChildren; + return _referenceChildren!; } @override Iterable get referenceParents => [enclosingElement]; @override - ParameterElement get element => super.element; + ParameterElement? get element => super.element as ParameterElement?; @override - ParameterMember get originalMember => super.originalMember; + ParameterMember? get originalMember => + super.originalMember as ParameterMember?; - ElementType _modelType; - ElementType get modelType => _modelType ??= - modelBuilder.typeFrom((originalMember ?? element).type, library); + late final ElementType modelType = + modelBuilder.typeFrom((originalMember ?? element)!.type, library!); } diff --git a/lib/src/model/prefix.dart b/lib/src/model/prefix.dart index 1b3a3f0bfd..be1a931ba1 100644 --- a/lib/src/model/prefix.dart +++ b/lib/src/model/prefix.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/scope.dart'; import 'package:dartdoc/src/model/comment_referable.dart'; @@ -17,38 +15,38 @@ import '../../dartdoc.dart'; class Prefix extends ModelElement implements EnclosedElement { /// [library] is the library the prefix is defined in, not the [Library] /// referred to by the [PrefixElement]. - Prefix(PrefixElement element, Library library, PackageGraph packageGraph) + Prefix(PrefixElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); @override bool get isCanonical => false; - Library _associatedLibrary; + Library? _associatedLibrary; // TODO(jcollins-g): consider connecting PrefixElement to the imported library // in analyzer? Library get associatedLibrary => - _associatedLibrary ??= modelBuilder.fromElement(library.element.imports + (_associatedLibrary ??= modelBuilder.fromElement(library!.element.imports .firstWhere((i) => i.prefix == element) - .importedLibrary); + .importedLibrary!) as Library?)!; @override - Library get canonicalModelElement => associatedLibrary.canonicalLibrary; + Library? get canonicalModelElement => associatedLibrary.canonicalLibrary; @override - Scope get scope => element.scope; + Scope get scope => element!.scope; @override - PrefixElement get element => super.element; + PrefixElement? get element => super.element as PrefixElement?; @override - ModelElement get enclosingElement => library; + ModelElement? get enclosingElement => library; @override String get filePath => throw UnimplementedError('prefixes have no generated files in dartdoc'); @override - String get href => canonicalModelElement?.href; + String? get href => canonicalModelElement?.href; @override String get kind => 'prefix'; diff --git a/lib/src/model/privacy.dart b/lib/src/model/privacy.dart index 0b00685aa7..9961eb0dda 100644 --- a/lib/src/model/privacy.dart +++ b/lib/src/model/privacy.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 - /// Classes implementing this have a public/private distinction. abstract class Privacy { bool get isPublic; diff --git a/lib/src/model/source_code_mixin.dart b/lib/src/model/source_code_mixin.dart index c36b5cb244..d5dfd98a0d 100644 --- a/lib/src/model/source_code_mixin.dart +++ b/lib/src/model/source_code_mixin.dart @@ -2,22 +2,20 @@ // 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:analyzer/dart/element/element.dart'; import 'package:analyzer/source/line_info.dart'; import 'package:dartdoc/src/model/model.dart'; abstract class SourceCodeMixin implements Documentable { - ModelNode get modelNode; + ModelNode? get modelNode; - CharacterLocation get characterLocation; + CharacterLocation? get characterLocation; - Element get element; + Element? get element; - bool get hasSourceCode => config.includeSource && sourceCode.isNotEmpty; + bool get hasSourceCode => config.includeSource && sourceCode!.isNotEmpty; - Library get library; + Library? get library; - String get sourceCode => modelNode == null ? '' : modelNode.sourceCode; + String? get sourceCode => modelNode == null ? '' : modelNode!.sourceCode; } diff --git a/lib/src/model/top_level_container.dart b/lib/src/model/top_level_container.dart index 62fdee0511..2148dcd8e6 100644 --- a/lib/src/model/top_level_container.dart +++ b/lib/src/model/top_level_container.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 - import 'package:dartdoc/src/model/model.dart'; import 'package:dartdoc/src/model_utils.dart' as model_utils; @@ -28,7 +26,7 @@ abstract class TopLevelContainer implements Nameable { Iterable get properties; - Iterable get functions; + Iterable? get functions; Iterable get typedefs; @@ -52,7 +50,7 @@ abstract class TopLevelContainer implements Nameable { Iterable get publicClasses => model_utils.filterNonPublic(classes); - List _publicClassesSorted; + List? _publicClassesSorted; // TODO(jcollins-g): Setting this type parameter to `Container` magically // fixes a number of type problems in the AOT compiler, but I am mystified as // to why that should be the case. @@ -62,7 +60,7 @@ abstract class TopLevelContainer implements Nameable { Iterable get publicExtensions => model_utils.filterNonPublic(extensions); - List _publicExtensionsSorted; + List? _publicExtensionsSorted; Iterable get publicExtensionsSorted => _publicExtensionsSorted ??= publicExtensions.toList()..sort(byName); @@ -74,40 +72,40 @@ abstract class TopLevelContainer implements Nameable { Iterable get publicEnums => model_utils.filterNonPublic(enums); - List _publicEnumsSorted; + List? _publicEnumsSorted; Iterable get publicEnumsSorted => _publicEnumsSorted ??= publicEnums.toList()..sort(byName); Iterable get publicExceptions => model_utils.filterNonPublic(exceptions); - List _publicExceptionsSorted; + List? _publicExceptionsSorted; Iterable get publicExceptionsSorted => _publicExceptionsSorted ??= publicExceptions.toList()..sort(byName); Iterable get publicFunctions => - model_utils.filterNonPublic(functions); + model_utils.filterNonPublic(functions!); - List _publicFunctionsSorted; + List? _publicFunctionsSorted; Iterable get publicFunctionsSorted => _publicFunctionsSorted ??= publicFunctions.toList()..sort(byName); Iterable get publicMixins => model_utils.filterNonPublic(mixins); - List _publicMixinsSorted; + List? _publicMixinsSorted; Iterable get publicMixinsSorted => _publicMixinsSorted ??= publicMixins.toList()..sort(byName); Iterable get publicProperties => model_utils.filterNonPublic(properties); - List _publicPropertiesSorted; + List? _publicPropertiesSorted; Iterable get publicPropertiesSorted => _publicPropertiesSorted ??= publicProperties.toList()..sort(byName); Iterable get publicTypedefs => model_utils.filterNonPublic(typedefs); - List _publicTypedefsSorted; + List? _publicTypedefsSorted; Iterable get publicTypedefsSorted => _publicTypedefsSorted ??= publicTypedefs.toList()..sort(byName); } diff --git a/lib/src/model/top_level_variable.dart b/lib/src/model/top_level_variable.dart index b250db3ee0..2fb9f905ff 100644 --- a/lib/src/model/top_level_variable.dart +++ b/lib/src/model/top_level_variable.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/model/comment_referable.dart'; import 'package:dartdoc/src/model/feature.dart'; @@ -14,18 +12,18 @@ class TopLevelVariable extends ModelElement with GetterSetterCombo, Categorization implements EnclosedElement { @override - final Accessor getter; + final Accessor? getter; @override - final Accessor setter; + final Accessor? setter; TopLevelVariable(TopLevelVariableElement element, Library library, PackageGraph packageGraph, this.getter, this.setter) : super(element, library, packageGraph) { if (getter != null) { - getter.enclosingCombo = this; + getter!.enclosingCombo = this; } if (setter != null) { - setter.enclosingCombo = this; + setter!.enclosingCombo = this; } } @@ -44,13 +42,13 @@ class TopLevelVariable extends ModelElement } @override - ModelElement get enclosingElement => library; + ModelElement? get enclosingElement => library; @override String get filePath => '${library.dirName}/$fileName'; @override - String get href { + String? get href { if (!identical(canonicalModelElement, this)) { return canonicalModelElement?.href; } @@ -60,18 +58,18 @@ class TopLevelVariable extends ModelElement } @override - bool get isConst => _variable.isConst; + bool get isConst => _variable!.isConst; @override bool get isFinal { /// isFinal returns true for the variable even if it has an explicit getter /// (which means we should not document it as "final"). if (hasExplicitGetter) return false; - return _variable.isFinal; + return _variable!.isFinal; } @override - bool get isLate => isFinal && _variable.isLate; + bool get isLate => isFinal && _variable!.isLate; @override String get kind => isConst ? 'top-level constant' : 'top-level property'; @@ -82,7 +80,14 @@ class TopLevelVariable extends ModelElement @override String get fileName => '${isConst ? '$name-constant' : name}.$fileType'; - TopLevelVariableElement get _variable => (element as TopLevelVariableElement); + TopLevelVariableElement? get _variable => + (element as TopLevelVariableElement?); + + @override + Package get package => super.package!; + + @override + Library get library => super.library!; @override Iterable get referenceParents => [definingLibrary]; diff --git a/lib/src/model/type_parameter.dart b/lib/src/model/type_parameter.dart index 3713955c75..33b18742ee 100644 --- a/lib/src/model/type_parameter.dart +++ b/lib/src/model/type_parameter.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:dartdoc/src/element_type.dart'; import 'package:dartdoc/src/model/comment_referable.dart'; @@ -12,33 +10,32 @@ import 'package:dartdoc/src/render/type_parameters_renderer.dart'; class TypeParameter extends ModelElement { TypeParameter( - TypeParameterElement element, Library library, PackageGraph packageGraph) + TypeParameterElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); @override - ModelElement get enclosingElement => (element.enclosingElement != null) - ? modelBuilder.from(element.enclosingElement, library) - : null; + ModelElement get enclosingElement => + modelBuilder.from(element!.enclosingElement!, library!); @override String get filePath => - '${enclosingElement.library.dirName}/${enclosingElement.name}/$name'; + '${enclosingElement.library!.dirName}/${enclosingElement.name}/$name'; @override /// [TypeParameter]s don't have documentation pages. - String get href => null; + String? get href => null; @override String get kind => 'type parameter'; - ElementType _boundType; + ElementType? _boundType; - ElementType get boundType { + ElementType? get boundType { if (_boundType == null) { - var bound = element.bound; + var bound = element!.bound; if (bound != null) { - _boundType = modelBuilder.typeFrom(bound, library); + _boundType = modelBuilder.typeFrom(bound, library!); } } return _boundType; @@ -47,46 +44,35 @@ class TypeParameter extends ModelElement { @override bool get hasParameters => false; - String _name; - @override - String get name { - _name ??= element.bound != null - ? '${element.name} extends ${boundType.nameWithGenerics}' - : element.name; - return _name; - } + late final String name = element!.bound != null + ? '${element!.name} extends ${boundType!.nameWithGenerics}' + : element!.name; - String _linkedName; + String? _linkedName; @override String get linkedName { - _linkedName ??= element.bound != null - ? '${element.name} extends ${boundType.linkedName}' - : element.name; - return _linkedName; + _linkedName ??= element!.bound != null + ? '${element!.name} extends ${boundType!.linkedName}' + : element!.name; + return _linkedName!; } - Map _referenceChildren; - @override - Map get referenceChildren { - if (_referenceChildren == null) { - _referenceChildren = {}; - if (boundType != null) { - _referenceChildren[boundType.name] = boundType; - } - } - return _referenceChildren; - } + late final Map referenceChildren = () { + var boundType = this.boundType; + if (boundType == null) return {}; + return {boundType.name: boundType}; + }(); @override Iterable get referenceParents => [enclosingElement]; @override - TypeParameterElement get element => super.element; + TypeParameterElement? get element => super.element as TypeParameterElement?; @override - String get referenceName => element.name; + String get referenceName => element!.name; } mixin TypeParameters implements ModelElement { diff --git a/lib/src/model/typedef.dart b/lib/src/model/typedef.dart index 6fbfd8c9bf..9964a839c1 100644 --- a/lib/src/model/typedef.dart +++ b/lib/src/model/typedef.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 - import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:dartdoc/src/element_type.dart'; @@ -14,20 +12,20 @@ import 'package:dartdoc/src/render/typedef_renderer.dart'; abstract class Typedef extends ModelElement with TypeParameters, Categorization implements EnclosedElement { - Typedef(TypeAliasElement element, Library library, PackageGraph packageGraph) + Typedef(TypeAliasElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph); - DartType get aliasedType => element.aliasedType; + DartType get aliasedType => element!.aliasedType; @override - TypeAliasElement get element => super.element; + TypeAliasElement? get element => super.element as TypeAliasElement?; - ElementType _modelType; + ElementType? _modelType; ElementType get modelType => - _modelType ??= modelBuilder.typeFrom(element.aliasedType, library); + _modelType ??= modelBuilder.typeFrom(element!.aliasedType, library); @override - Library get enclosingElement => library; + Library? get enclosingElement => library; @override String get nameWithGenerics => '$name${super.genericParameters}'; @@ -47,7 +45,7 @@ abstract class Typedef extends ModelElement FunctionTypedef get asCallable => this as FunctionTypedef; @override - String get href { + String? get href { if (!identical(canonicalModelElement, this)) { return canonicalModelElement?.href; } @@ -63,7 +61,13 @@ abstract class Typedef extends ModelElement String get kind => 'typedef'; @override - List get typeParameters => element.typeParameters.map((f) { + Library get library => super.library!; + + @override + Package get package => super.package!; + + @override + List get typeParameters => element!.typeParameters.map((f) { return modelBuilder.from(f, library) as TypeParameter; }).toList(); @@ -72,15 +76,15 @@ abstract class Typedef extends ModelElement @override Iterable get referenceParents => [definingLibrary]; - Map _referenceChildren; + Map? _referenceChildren; @override Map get referenceChildren { if (_referenceChildren == null) { _referenceChildren = {}; - _referenceChildren + _referenceChildren! .addEntriesIfAbsent(typeParameters.explicitOnCollisionWith(this)); } - return _referenceChildren; + return _referenceChildren!; } } @@ -89,7 +93,7 @@ abstract class Typedef extends ModelElement /// for `Function` itself. class GeneralizedTypedef extends Typedef { GeneralizedTypedef( - TypeAliasElement element, Library library, PackageGraph packageGraph) + TypeAliasElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph) { assert(!isCallable); } @@ -98,44 +102,44 @@ class GeneralizedTypedef extends Typedef { /// A typedef referring to a non-function, defined type. class ClassTypedef extends Typedef { ClassTypedef( - TypeAliasElement element, Library library, PackageGraph packageGraph) + TypeAliasElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph) { assert(!isCallable); assert(modelType.modelElement is Class); } @override - DefinedElementType get modelType => super.modelType; + DefinedElementType get modelType => super.modelType as DefinedElementType; @override Map get referenceChildren { if (_referenceChildren == null) { _referenceChildren = super.referenceChildren; - _referenceChildren + _referenceChildren! .addEntriesIfAbsent(modelType.modelElement.referenceChildren.entries); } - return _referenceChildren; + return _referenceChildren!; } } /// A typedef referring to a function type. class FunctionTypedef extends Typedef { FunctionTypedef( - TypeAliasElement element, Library library, PackageGraph packageGraph) + TypeAliasElement element, Library? library, PackageGraph packageGraph) : super(element, library, packageGraph) { assert(isCallable); } @override - Callable get modelType => super.modelType; + Callable get modelType => super.modelType as Callable; @override Map get referenceChildren { if (_referenceChildren == null) { _referenceChildren = super.referenceChildren; - _referenceChildren + _referenceChildren! .addEntriesIfAbsent(parameters.explicitOnCollisionWith(this)); } - return _referenceChildren; + return _referenceChildren!; } } diff --git a/lib/src/model_utils.dart b/lib/src/model_utils.dart index 6509d6cb58..71889910d0 100644 --- a/lib/src/model_utils.dart +++ b/lib/src/model_utils.dart @@ -95,9 +95,7 @@ Iterable findCanonicalFor( Iterable containers) { return containers.map((c) => c.packageGraph.findCanonicalModelElementFor(c.element) - as InheritingContainer ?? - // FIXME(nnbd) : remove ignore after package_graph is migrated - // ignore: dead_null_aware_expression + as InheritingContainer? ?? c); } diff --git a/lib/src/package_meta.dart b/lib/src/package_meta.dart index 99cd3db50c..9e267fe511 100644 --- a/lib/src/package_meta.dart +++ b/lib/src/package_meta.dart @@ -133,7 +133,7 @@ abstract class PackageMeta { bool get requiresFlutter; - void runPubGet(String flutterRoot); + void runPubGet(String? flutterRoot); String get name; @@ -355,10 +355,13 @@ class _FilePackageMeta extends PubPackageMeta { .exists); @override - void runPubGet(String flutterRoot) { + void runPubGet(String? flutterRoot) { String binPath; List parameters; if (requiresFlutter) { + if (flutterRoot == null) { + throw DartdocFailure('Package requires flutter but FLUTTER_ROOT unset'); + } binPath = p.join(flutterRoot, 'bin', 'flutter'); if (Platform.isWindows) binPath += '.bat'; parameters = ['pub', 'get']; @@ -385,16 +388,16 @@ class _FilePackageMeta extends PubPackageMeta { } @override - String get name => _pubspec['name']; + String get name => _pubspec['name'] ?? ''; @override - String get version => _pubspec['version']; + String get version => _pubspec['version'] ?? '0.0.0-unknown'; @override - String get description => _pubspec['description']; + String get description => _pubspec['description'] ?? ''; @override - String get homepage => _pubspec['homepage']; + String get homepage => _pubspec['homepage'] ?? ''; @override bool get requiresFlutter => @@ -459,7 +462,7 @@ class _SdkMeta extends PubPackageMeta { bool get isSdk => true; @override - void runPubGet(String flutterRoot) { + void runPubGet(String? flutterRoot) { throw 'unsupported operation'; } diff --git a/lib/src/render/parameter_renderer.dart b/lib/src/render/parameter_renderer.dart index d12d0d0c66..b3061d6b27 100644 --- a/lib/src/render/parameter_renderer.dart +++ b/lib/src/render/parameter_renderer.dart @@ -210,7 +210,7 @@ abstract class ParameterRenderer { buf.write(')'); buf.write(paramModelType.nullabilitySuffix); } - } else if (param.modelType != null) { + } else { var linkedTypeName = paramModelType.linkedName; if (linkedTypeName.isNotEmpty) { buf.write(typeName(linkedTypeName)); @@ -225,7 +225,7 @@ abstract class ParameterRenderer { if (param.hasDefaultValue) { buf.write(' = '); - buf.write(defaultValue(param.defaultValue)); + buf.write(defaultValue(param.defaultValue!)); } buf.write(suffix); diff --git a/lib/src/warnings.dart b/lib/src/warnings.dart index 36cbe48661..685c48617b 100644 --- a/lib/src/warnings.dart +++ b/lib/src/warnings.dart @@ -165,6 +165,24 @@ const Map packageWarningDefinitions = 'no-defining-library-found', 'The defining library for an element could not be found; the library may ' 'be imported or exported with a non-standard URI', + longHelp: [ + 'For non-canonicalized import or export paths, dartdoc can sometimes lose ', + 'track of the defining library for an element. If this happens, canonicalization', + 'will assume that reexported elements are defined somewhere it deems "reasonable", ', + 'defaulting first to the enclosing context\'s definingLibrary if available, ', + 'or the library is is visible in. This can lead to confusing documentation ', + 'structure that implies duplicate code where none exists.', + '', + 'To correct this, canonicalize all paths in the import or export chain', + 'making this symbol visible.', + '', + "For example: 'change `import 'package:dartdoc/src/model/../model/extension_target.dart';`", + "to `import 'package:dartdoc/src/model/extension_target.dart';`", + "or `import 'src/../src/foo.dart';`", + "to `import 'src/foo.dart';", + "or `import 'package:dartdoc//lib//foo.dart';", + "to `import 'package:dartdoc/lib/foo.dart';", + ], defaultWarningMode: PackageWarningMode.error), PackageWarning.notImplemented: PackageWarningDefinition( PackageWarning.notImplemented, @@ -286,7 +304,7 @@ mixin Warnable implements Canonicalization, CommentReferable { Warnable? get enclosingElement; - Package get package; + Package? get package; void warn( PackageWarning kind, { @@ -503,7 +521,7 @@ class PackageWarningCounter { _items.add(_JsonWarning(type, kind, fullMessage, entry)); } for (var item in _items) { - logWarning(item); + logWarning(item.toString()); } _items.clear(); } @@ -534,7 +552,7 @@ class PackageWarningCounter { PackageWarningOptionContext config = element?.config ?? packageGraph.defaultPackage.config; PackageWarningMode? warningMode; - var isLocal = element?.package.isLocal ?? true; + var isLocal = element?.package?.isLocal ?? true; if (!config.allowNonLocalWarnings && !isLocal) { warningMode = PackageWarningMode.ignore; } else { diff --git a/test/end2end/model_test.dart b/test/end2end/model_test.dart index da005cbb74..8a41f48592 100644 --- a/test/end2end/model_test.dart +++ b/test/end2end/model_test.dart @@ -9,6 +9,7 @@ library dartdoc.model_test; import 'dart:io'; +import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/source/line_info.dart'; import 'package:async/async.dart'; @@ -1048,10 +1049,19 @@ void main() { }); test('can import other libraries with unusual URIs', () { - expect( - fakeLibrary.importedExportedLibraries - .where((l) => l.name == 'import_unusual'), - isNotEmpty); + final Set fakeLibraryImportedExported = () { + var _importedExportedLibraries = {}; + for (var l in { + ...fakeLibrary.element.importedLibraries, + ...fakeLibrary.element.exportedLibraries + }) { + var lib = packageGraph.modelBuilder.fromElement(l) as Library; + _importedExportedLibraries.add(lib); + } + return _importedExportedLibraries; + }(); + expect(fakeLibraryImportedExported.any((l) => l.name == 'import_unusual'), + isTrue); }); test('@canonicalFor directive works', () {