diff --git a/lib/dartdoc.dart b/lib/dartdoc.dart index 521116bcc4..270bf61009 100644 --- a/lib/dartdoc.dart +++ b/lib/dartdoc.dart @@ -115,7 +115,7 @@ class DartdocFileWriter implements FileWriter { /// Generates Dart documentation for all public Dart libraries in the given /// directory. class Dartdoc { - final Generator generator; + Generator _generator; final PackageBuilder packageBuilder; final DartdocOptionContext config; final Set _writtenFiles = {}; @@ -125,12 +125,23 @@ class Dartdoc { final StreamController _onCheckProgress = StreamController(sync: true); - Dartdoc._(this.config, this.generator, this.packageBuilder) { + Dartdoc._(this.config, this._generator, this.packageBuilder) { _outputDir = config.resourceProvider .getFolder(config.resourceProvider.pathContext.absolute(config.output)) ..create(); } + // TODO(srawlins): Remove when https://github.com/dart-lang/linter/issues/2706 + // is fixed. + // ignore: unnecessary_getters_setters + Generator get generator => _generator; + + @visibleForTesting + // TODO(srawlins): Remove when https://github.com/dart-lang/linter/issues/2706 + // is fixed. + // ignore: unnecessary_getters_setters + set generator(Generator newGenerator) => _generator = newGenerator; + /// An asynchronous factory method that builds Dartdoc's file writers /// and returns a Dartdoc object with them. @Deprecated('Prefer fromContext() instead') @@ -195,18 +206,15 @@ class Dartdoc { 'in ${seconds.toStringAsFixed(1)} seconds'); stopwatch.reset(); - var generator = this.generator; - if (generator != null) { - // Create the out directory. - if (!_outputDir.exists) _outputDir.create(); + // Create the out directory. + if (!_outputDir.exists) _outputDir.create(); - var writer = DartdocFileWriter(_outputDir.path, config.resourceProvider); - await generator.generate(packageGraph, writer); + var writer = DartdocFileWriter(_outputDir.path, config.resourceProvider); + await generator.generate(packageGraph, writer); - _writtenFiles.addAll(writer.writtenFiles); - if (config.validateLinks && _writtenFiles.isNotEmpty) { - _validateLinks(packageGraph, _outputDir.path); - } + _writtenFiles.addAll(writer.writtenFiles); + if (config.validateLinks && _writtenFiles.isNotEmpty) { + _validateLinks(packageGraph, _outputDir.path); } var warnings = packageGraph.packageWarningCounter.warningCount; diff --git a/lib/options.dart b/lib/options.dart index e840fbf61a..537c83084f 100644 --- a/lib/options.dart +++ b/lib/options.dart @@ -44,6 +44,7 @@ class DartdocGeneratorOptionContext extends DartdocOptionContext { String get relCanonicalPrefix => optionSet['relCanonicalPrefix'].valueAt(context); + /// The 'templatesDir' Dartdoc option if one was specified; otherwise `null`. String get templatesDir => optionSet['templatesDir'].valueAt(context); // TODO(jdkoren): duplicated temporarily so that GeneratorContext is enough for configuration. diff --git a/lib/src/generator/dartdoc_generator_backend.dart b/lib/src/generator/dartdoc_generator_backend.dart index 5f7d8581fa..8b2d6aae8c 100644 --- a/lib/src/generator/dartdoc_generator_backend.dart +++ b/lib/src/generator/dartdoc_generator_backend.dart @@ -2,14 +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. +import 'package:analyzer/file_system/file_system.dart'; import 'package:dartdoc/dartdoc.dart'; import 'package:dartdoc/options.dart'; import 'package:dartdoc/src/generator/generator_frontend.dart'; import 'package:dartdoc/src/generator/generator_utils.dart' as generator_util; import 'package:dartdoc/src/generator/template_data.dart'; import 'package:dartdoc/src/generator/templates.dart'; -import 'package:dartdoc/src/generator/templates.runtime_renderers.dart'; -import 'package:dartdoc/src/mustachio/renderer_base.dart'; import 'package:dartdoc/src/warnings.dart'; import 'package:path/path.dart' as path show Context; @@ -60,16 +59,15 @@ class DartdocGeneratorBackendOptions implements TemplateOptions { } class SidebarGenerator { - final Template template; - final RenderFunction renderFunction; + final String Function(T context) renderFunction; final Map _renderCache = {}; - SidebarGenerator(this.template, this.renderFunction); + SidebarGenerator(this.renderFunction); // Retrieve the render for a specific key, or generate it using the given // template data if you need. String getRenderFor(Documentable key, T templateData) { - return _renderCache[key] ??= renderFunction(templateData, template); + return _renderCache[key] ??= renderFunction(templateData); } } @@ -81,15 +79,16 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { sidebarForLibrary; final SidebarGenerator> sidebarForContainer; + final ResourceProvider resourceProvider; final path.Context _pathContext; - DartdocGeneratorBackend( - DartdocGeneratorBackendOptions options, this.templates, this._pathContext) + DartdocGeneratorBackend(DartdocGeneratorBackendOptions options, + this.templates, this.resourceProvider) : options = options ?? DartdocGeneratorBackendOptions._defaults(), - sidebarForLibrary = SidebarGenerator( - templates.sidebarLibraryTemplate, renderSidebarForLibrary), - sidebarForContainer = SidebarGenerator( - templates.sidebarContainerTemplate, renderSidebarForContainer); + sidebarForLibrary = SidebarGenerator(templates.renderSidebarForLibrary), + sidebarForContainer = + SidebarGenerator(templates.renderSidebarForContainer), + _pathContext = resourceProvider.pathContext; /// Helper method to bind template data and emit the content to the writer. void write( @@ -129,7 +128,7 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { @override void generatePackage(FileWriter writer, PackageGraph graph, Package package) { TemplateData data = PackageTemplateData(options, graph, package); - var content = renderIndex(data, templates.indexTemplate); + var content = templates.renderIndex(data); write(writer, package.filePath, data, content); } @@ -137,7 +136,7 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { void generateCategory( FileWriter writer, PackageGraph packageGraph, Category category) { TemplateData data = CategoryTemplateData(options, packageGraph, category); - var content = renderCategory(data, templates.categoryTemplate); + var content = templates.renderCategory(data); write(writer, category.filePath, data, content); } @@ -146,7 +145,7 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { FileWriter writer, PackageGraph packageGraph, Library lib) { TemplateData data = LibraryTemplateData( options, packageGraph, lib, sidebarForLibrary.getRenderFor); - var content = renderLibrary(data, templates.libraryTemplate); + var content = templates.renderLibrary(data); write(writer, lib.filePath, data, content); } @@ -155,7 +154,7 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { FileWriter writer, PackageGraph packageGraph, Library lib, Class clazz) { TemplateData data = ClassTemplateData(options, packageGraph, lib, clazz, sidebarForLibrary.getRenderFor, sidebarForContainer.getRenderFor); - var content = renderClass(data, templates.classTemplate); + var content = templates.renderClass(data); write(writer, clazz.filePath, data, content); } @@ -169,7 +168,7 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { extension, sidebarForLibrary.getRenderFor, sidebarForContainer.getRenderFor); - var content = renderExtension(data, templates.extensionTemplate); + var content = templates.renderExtension(data); write(writer, extension.filePath, data, content); } @@ -178,7 +177,7 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { FileWriter writer, PackageGraph packageGraph, Library lib, Mixin mixin) { TemplateData data = MixinTemplateData(options, packageGraph, lib, mixin, sidebarForLibrary.getRenderFor, sidebarForContainer.getRenderFor); - var content = renderMixin(data, templates.mixinTemplate); + var content = templates.renderMixin(data); write(writer, mixin.filePath, data, content); } @@ -187,7 +186,7 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { Library lib, Class clazz, Constructor constructor) { TemplateData data = ConstructorTemplateData(options, packageGraph, lib, clazz, constructor, sidebarForContainer.getRenderFor); - var content = renderConstructor(data, templates.constructorTemplate); + var content = templates.renderConstructor(data); write(writer, constructor.filePath, data, content); } @@ -196,7 +195,7 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { FileWriter writer, PackageGraph packageGraph, Library lib, Enum eNum) { TemplateData data = EnumTemplateData(options, packageGraph, lib, eNum, sidebarForLibrary.getRenderFor, sidebarForContainer.getRenderFor); - var content = renderEnum(data, templates.enumTemplate); + var content = templates.renderEnum(data); write(writer, eNum.filePath, data, content); } @@ -205,7 +204,7 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { Library lib, ModelFunction function) { TemplateData data = FunctionTemplateData( options, packageGraph, lib, function, sidebarForLibrary.getRenderFor); - var content = renderFunction(data, templates.functionTemplate); + var content = templates.renderFunction(data); write(writer, function.filePath, data, content); } @@ -214,7 +213,7 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { Container clazz, Method method) { TemplateData data = MethodTemplateData(options, packageGraph, lib, clazz, method, sidebarForContainer.getRenderFor); - var content = renderMethod(data, templates.methodTemplate); + var content = templates.renderMethod(data); write(writer, method.filePath, data, content); } @@ -228,7 +227,7 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { Library lib, Container clazz, Field property) { TemplateData data = PropertyTemplateData(options, packageGraph, lib, clazz, property, sidebarForContainer.getRenderFor); - var content = renderProperty(data, templates.propertyTemplate); + var content = templates.renderProperty(data); write(writer, property.filePath, data, content); } @@ -237,8 +236,7 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { Library lib, TopLevelVariable property) { TemplateData data = TopLevelPropertyTemplateData( options, packageGraph, lib, property, sidebarForLibrary.getRenderFor); - var content = - renderTopLevelProperty(data, templates.topLevelPropertyTemplate); + var content = templates.renderTopLevelProperty(data); write(writer, property.filePath, data, content); } @@ -252,11 +250,10 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend { Library lib, Typedef typeDef) { TemplateData data = TypedefTemplateData( options, packageGraph, lib, typeDef, sidebarForLibrary.getRenderFor); - var content = renderTypedef(data, templates.typeDefTemplate); + var content = templates.renderTypedef(data); write(writer, typeDef.filePath, data, content); } @override - Future generateAdditionalFiles( - FileWriter writer, PackageGraph graph) async {} + Future generateAdditionalFiles(FileWriter writer) async {} } diff --git a/lib/src/generator/generator_frontend.dart b/lib/src/generator/generator_frontend.dart index 18ad546c15..08d9f3caff 100644 --- a/lib/src/generator/generator_frontend.dart +++ b/lib/src/generator/generator_frontend.dart @@ -19,7 +19,7 @@ class GeneratorFrontEnd implements Generator { Future generate(PackageGraph packageGraph, FileWriter writer) async { var indexElements = []; _generateDocs(packageGraph, writer, indexElements); - await _generatorBackend.generateAdditionalFiles(writer, packageGraph); + await _generatorBackend.generateAdditionalFiles(writer); var categories = indexElements .whereType() @@ -29,7 +29,8 @@ class GeneratorFrontEnd implements Generator { _generatorBackend.generateSearchIndex(writer, indexElements); } - // Traverses the package graph and collects elements for the search index. + /// Traverses the package graph and generates documentation for all contained + /// elements. void _generateDocs(PackageGraph packageGraph, FileWriter writer, List indexAccumulator) { if (packageGraph == null) return; @@ -338,5 +339,5 @@ abstract class GeneratorBackend { FileWriter writer, PackageGraph graph, Library library, Typedef typedef); /// Emit files not specific to a Dart language element. - Future generateAdditionalFiles(FileWriter writer, PackageGraph graph); + Future generateAdditionalFiles(FileWriter writer); } diff --git a/lib/src/generator/html_generator.dart b/lib/src/generator/html_generator.dart index 4afd0205e2..bf73bcc889 100644 --- a/lib/src/generator/html_generator.dart +++ b/lib/src/generator/html_generator.dart @@ -4,6 +4,7 @@ library dartdoc.html_generator; +import 'package:analyzer/file_system/file_system.dart'; import 'package:dartdoc/options.dart'; import 'package:dartdoc/src/generator/dartdoc_generator_backend.dart'; import 'package:dartdoc/src/generator/generator.dart'; @@ -12,45 +13,45 @@ import 'package:dartdoc/src/generator/html_resources.g.dart' as resources; import 'package:dartdoc/src/generator/resource_loader.dart'; import 'package:dartdoc/src/generator/template_data.dart'; import 'package:dartdoc/src/generator/templates.dart'; -import 'package:dartdoc/src/generator/templates.runtime_renderers.dart'; import 'package:dartdoc/src/model/package.dart'; import 'package:dartdoc/src/model/package_graph.dart'; -import 'package:path/path.dart' as path show Context; -Future initHtmlGenerator( - DartdocGeneratorOptionContext context) async { - var templates = await Templates.fromContext(context); +/// Creates a [Generator] with an [HtmlGeneratorBackend] backend. +/// +/// [forceRuntimeTemplates] should only be given [true] during tests. +Future initHtmlGenerator(DartdocGeneratorOptionContext context, + {bool forceRuntimeTemplates = false}) async { + var templates = await Templates.fromContext(context, + forceRuntimeTemplates: forceRuntimeTemplates); var options = DartdocGeneratorBackendOptions.fromContext(context); - var backend = HtmlGeneratorBackend( - options, templates, context.resourceProvider.pathContext); + var backend = + HtmlGeneratorBackend(options, templates, context.resourceProvider); return GeneratorFrontEnd(backend); } /// Generator backend for html output. class HtmlGeneratorBackend extends DartdocGeneratorBackend { HtmlGeneratorBackend(DartdocGeneratorBackendOptions options, - Templates templates, path.Context pathContext) - : super(options, templates, pathContext); + Templates templates, ResourceProvider resourceProvider) + : super(options, templates, resourceProvider); @override void generatePackage(FileWriter writer, PackageGraph graph, Package package) { super.generatePackage(writer, graph, package); // We have to construct the data again. This only happens once per package. TemplateData data = PackageTemplateData(options, graph, package); - var content = renderError(data, templates.errorTemplate); + var content = templates.renderError(data); write(writer, '__404error.html', data, content); } @override - Future generateAdditionalFiles( - FileWriter writer, PackageGraph graph) async { + Future generateAdditionalFiles(FileWriter writer) async { await _copyResources(writer); if (options.favicon != null) { // Allow overwrite of favicon. - var bytes = - writer.resourceProvider.getFile(options.favicon).readAsBytesSync(); + var bytes = resourceProvider.getFile(options.favicon).readAsBytesSync(); writer.writeBytes( - graph.resourceProvider.pathContext.join('static-assets', 'favicon.png'), + resourceProvider.pathContext.join('static-assets', 'favicon.png'), bytes, allowOverwrite: true, ); @@ -64,10 +65,10 @@ class HtmlGeneratorBackend extends DartdocGeneratorBackend { '$_dartdocResourcePrefix, encountered $resourcePath'); } var destFileName = resourcePath.substring(_dartdocResourcePrefix.length); - var destFilePath = writer.resourceProvider.pathContext - .join('static-assets', destFileName); + var destFilePath = + resourceProvider.pathContext.join('static-assets', destFileName); writer.writeBytes(destFilePath, - await writer.resourceProvider.loadResourceAsBytes(resourcePath)); + await resourceProvider.loadResourceAsBytes(resourcePath)); } } diff --git a/lib/src/generator/markdown_generator.dart b/lib/src/generator/markdown_generator.dart index 5b8c96e795..e51e7b477b 100644 --- a/lib/src/generator/markdown_generator.dart +++ b/lib/src/generator/markdown_generator.dart @@ -2,38 +2,40 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import 'package:analyzer/file_system/file_system.dart'; import 'package:dartdoc/options.dart'; import 'package:dartdoc/src/generator/dartdoc_generator_backend.dart'; import 'package:dartdoc/src/generator/generator.dart'; import 'package:dartdoc/src/generator/generator_frontend.dart'; import 'package:dartdoc/src/generator/template_data.dart'; import 'package:dartdoc/src/generator/templates.dart'; -import 'package:dartdoc/src/generator/templates.runtime_renderers.dart'; import 'package:dartdoc/src/model/package.dart'; import 'package:dartdoc/src/model/package_graph.dart'; -import 'package:path/path.dart' as path show Context; -Future initMarkdownGenerator( - DartdocGeneratorOptionContext context) async { +/// Creates a [Generator] with an [MarkdownGeneratorBackend] backend. +/// +/// [forceRuntimeTemplates] should only be given [true] during tests. +Future initMarkdownGenerator(DartdocGeneratorOptionContext context, + {bool forceRuntimeTemplates = false}) async { var templates = await Templates.fromContext(context); var options = DartdocGeneratorBackendOptions.fromContext(context); - var backend = MarkdownGeneratorBackend( - options, templates, context.resourceProvider.pathContext); + var backend = + MarkdownGeneratorBackend(options, templates, context.resourceProvider); return GeneratorFrontEnd(backend); } /// Generator backend for markdown output. class MarkdownGeneratorBackend extends DartdocGeneratorBackend { MarkdownGeneratorBackend(DartdocGeneratorBackendOptions options, - Templates templates, path.Context pathContext) - : super(options, templates, pathContext); + Templates templates, ResourceProvider resourceProvider) + : super(options, templates, resourceProvider); @override void generatePackage(FileWriter writer, PackageGraph graph, Package package) { super.generatePackage(writer, graph, package); // We have to construct the data again. This only happens once per package. TemplateData data = PackageTemplateData(options, graph, package); - var content = renderError(data, templates.errorTemplate); + var content = templates.renderError(data); write(writer, '__404error.md', data, content); } } diff --git a/lib/src/generator/resource_loader.dart b/lib/src/generator/resource_loader.dart index abb61a544f..b4f77842d3 100644 --- a/lib/src/generator/resource_loader.dart +++ b/lib/src/generator/resource_loader.dart @@ -32,6 +32,11 @@ extension ResourceLoader on ResourceProvider { return getFile(uri.toFilePath()); } + Future getResourceFolder(String path) async { + var uri = await resolveResourceUri(Uri.parse(path)); + return getFolder(uri.toFilePath()); + } + /// Helper function for resolving to a non-relative, non-package URI. @visibleForTesting Future resolveResourceUri(Uri uri) { diff --git a/lib/src/generator/templates.aot_renderers_for_html.dart b/lib/src/generator/templates.aot_renderers_for_html.dart index 355d22ed37..eed53ffcb2 100644 --- a/lib/src/generator/templates.aot_renderers_for_html.dart +++ b/lib/src/generator/templates.aot_renderers_for_html.dart @@ -31,11 +31,13 @@ import 'package:dartdoc/src/model/typedef.dart' as _i8; String renderCategory(_i1.CategoryTemplateData context0) { final buffer = StringBuffer(); buffer.write(_renderCategory_partial_head_0(context0)); + buffer.writeln(); buffer.write('''
'''); var context1 = context0.self; if (context1 != null) { + buffer.writeln(); buffer.write('''

'''); buffer.writeEscaped(context1.name.toString()); @@ -46,6 +48,7 @@ String renderCategory(_i1.CategoryTemplateData context0) { buffer.write(_renderCategory_partial_documentation_1(context1, context0)); buffer.writeln(); if (context1.hasPublicLibraries == true) { + buffer.writeln(); buffer.write('''

Libraries

@@ -59,12 +62,14 @@ String renderCategory(_i1.CategoryTemplateData context0) { _renderCategory_partial_library_2(context3, context1, context0)); } } + buffer.writeln(); buffer.write('''
'''); } buffer.writeln(); if (context1.hasPublicClasses == true) { + buffer.writeln(); buffer.write('''

Classes

@@ -78,12 +83,14 @@ String renderCategory(_i1.CategoryTemplateData context0) { _renderCategory_partial_class_3(context5, context1, context0)); } } + buffer.writeln(); buffer.write('''
'''); } buffer.writeln(); if (context1.hasPublicMixins == true) { + buffer.writeln(); buffer.write('''

Mixins

@@ -97,12 +104,14 @@ String renderCategory(_i1.CategoryTemplateData context0) { _renderCategory_partial_mixin_4(context7, context1, context0)); } } + buffer.writeln(); buffer.write('''
'''); } buffer.writeln(); if (context1.hasPublicConstants == true) { + buffer.writeln(); buffer.write('''

Constants

@@ -116,12 +125,14 @@ String renderCategory(_i1.CategoryTemplateData context0) { _renderCategory_partial_constant_5(context9, context1, context0)); } } + buffer.writeln(); buffer.write('''
'''); } buffer.writeln(); if (context1.hasPublicProperties == true) { + buffer.writeln(); buffer.write('''

Properties

@@ -135,12 +146,14 @@ String renderCategory(_i1.CategoryTemplateData context0) { context11, context1, context0)); } } + buffer.writeln(); buffer.write('''
'''); } buffer.writeln(); if (context1.hasPublicFunctions == true) { + buffer.writeln(); buffer.write('''

Functions

@@ -154,12 +167,14 @@ String renderCategory(_i1.CategoryTemplateData context0) { context13, context1, context0)); } } + buffer.writeln(); buffer.write('''
'''); } buffer.writeln(); if (context1.hasPublicEnums == true) { + buffer.writeln(); buffer.write('''

Enums

@@ -173,12 +188,14 @@ String renderCategory(_i1.CategoryTemplateData context0) { _renderCategory_partial_class_3(context15, context1, context0)); } } + buffer.writeln(); buffer.write('''
'''); } buffer.writeln(); if (context1.hasPublicTypedefs == true) { + buffer.writeln(); buffer.write('''

Typedefs

@@ -192,12 +209,14 @@ String renderCategory(_i1.CategoryTemplateData context0) { _renderCategory_partial_typedef_8(context17, context1, context0)); } } + buffer.writeln(); buffer.write('''
'''); } buffer.writeln(); if (context1.hasPublicExceptions == true) { + buffer.writeln(); buffer.write('''

Exceptions / Errors

@@ -211,11 +230,13 @@ String renderCategory(_i1.CategoryTemplateData context0) { _renderCategory_partial_class_3(context19, context1, context0)); } } + buffer.writeln(); buffer.write('''
'''); } } + buffer.writeln(); buffer.write('''

@@ -223,6 +244,7 @@ String renderCategory(_i1.CategoryTemplateData context0) { @@ -242,6 +265,7 @@ String renderCategory(_i1.CategoryTemplateData context0) { buffer.write(''' '''); buffer.write(_renderCategory_partial_sidebar_for_category_11(context0)); + buffer.writeln(); buffer.write(''' @@ -261,11 +285,13 @@ String _renderCategory_partial_head_0(_i1.CategoryTemplateData context0) { '''); if (context0.includeVersion == true) { + buffer.writeln(); buffer.write(''' '''); } + buffer.writeln(); buffer.write(''' '''); + buffer.writeln(); buffer.write(''' '''); buffer.write(context0.layoutTitle.toString()); buffer.write(''''''); } if (context0.hasHomepage == true) { + buffer.writeln(); buffer.write('''
  • '''); @@ -396,10 +433,12 @@ String _renderCategory_partial_documentation_1( _i2.Category context1, _i1.CategoryTemplateData context0) { final buffer = StringBuffer(); if (context1.hasDocumentation == true) { + buffer.writeln(); buffer.write('''
    '''); buffer.write(context1.documentationAsHtml.toString()); + buffer.writeln(); buffer.write('''
    '''); } @@ -419,6 +458,7 @@ String _renderCategory_partial_library_2(_i3.Library context2, buffer.write(''' '''); buffer.write(__renderCategory_partial_library_2_partial_categorization_0( context2, context1, context0)); + buffer.writeln(); buffer.write('''
    '''); @@ -427,6 +467,7 @@ String _renderCategory_partial_library_2(_i3.Library context2, buffer.write(' '); buffer.write(context2.extendedDocLink.toString()); } + buffer.writeln(); buffer.write('''
    '''); @@ -469,6 +510,7 @@ String _renderCategory_partial_class_3(_i4.Class context2, buffer.write(''' '''); buffer.write(__renderCategory_partial_class_3_partial_categorization_0( context2, context1, context0)); + buffer.writeln(); buffer.write('''
    @@ -476,6 +518,7 @@ String _renderCategory_partial_class_3(_i4.Class context2, buffer.write(context2.oneLineDoc.toString()); buffer.write(' '); buffer.write(context2.extendedDocLink.toString()); + buffer.writeln(); buffer.write('''
    '''); @@ -518,6 +561,7 @@ String _renderCategory_partial_mixin_4(_i5.Mixin context2, buffer.write(''' '''); buffer.write(__renderCategory_partial_mixin_4_partial_categorization_0( context2, context1, context0)); + buffer.writeln(); buffer.write('''
    @@ -525,6 +569,7 @@ String _renderCategory_partial_mixin_4(_i5.Mixin context2, buffer.write(context2.oneLineDoc.toString()); buffer.write(' '); buffer.write(context2.extendedDocLink.toString()); + buffer.writeln(); buffer.write('''
    '''); @@ -570,6 +615,7 @@ String _renderCategory_partial_constant_5(_i6.TopLevelVariable context2, '''); buffer.write(__renderCategory_partial_constant_5_partial_categorization_0( context2, context1, context0)); + buffer.writeln(); buffer.write('''
    @@ -580,6 +626,7 @@ String _renderCategory_partial_constant_5(_i6.TopLevelVariable context2, buffer.write('\n '); buffer.write(__renderCategory_partial_constant_5_partial_features_1( context2, context1, context0)); + buffer.writeln(); buffer.write('''
    '''); @@ -646,6 +693,7 @@ String _renderCategory_partial_property_6(_i6.TopLevelVariable context2, buffer.write(''' '''); buffer.write(__renderCategory_partial_property_6_partial_categorization_0( context2, context1, context0)); + buffer.writeln(); buffer.write(''' '''); @@ -729,6 +778,7 @@ String _renderCategory_partial_callable_7(_i7.ModelFunctionTyped context2, '''); buffer.write(__renderCategory_partial_callable_7_partial_categorization_0( context2, context1, context0)); + buffer.writeln(); buffer.write(''' '''); @@ -790,6 +841,7 @@ String _renderCategory_partial_typedef_8(_i8.Typedef context2, if (context2.isCallable == true) { var context3 = context2.asCallable; if (context3 != null) { + buffer.writeln(); buffer.write('''
    '''); buffer.write(context0.layoutTitle.toString()); buffer.write('''
  • '''); } if (context0.hasHomepage == true) { + buffer.writeln(); buffer.write('''
  • Topics
  • '''); var context3 = context2.documentedCategoriesSorted; if (context3 != null) { for (var context4 in context3) { + buffer.writeln(); buffer.write('''
  • '''); buffer.write(context4.linkedName.toString()); @@ -1041,10 +1106,12 @@ String _renderCategory_partial_packages_10(_i1.CategoryTemplateData context0) { } } } + buffer.writeln(); buffer.write('''
  • Libraries
  • '''); } if (context2.isFirstPackage != true) { + buffer.writeln(); buffer.write('''
  • '''); buffer.writeEscaped(context2.name.toString()); @@ -1055,6 +1122,7 @@ String _renderCategory_partial_packages_10(_i1.CategoryTemplateData context0) { var context6 = context5.publicLibrariesSorted; if (context6 != null) { for (var context7 in context6) { + buffer.writeln(); buffer.write('''
  • '''); buffer.write(context7.linkedName.toString()); @@ -1065,6 +1133,7 @@ String _renderCategory_partial_packages_10(_i1.CategoryTemplateData context0) { var context8 = context2.categoriesWithPublicLibraries; if (context8 != null) { for (var context9 in context8) { + buffer.writeln(); buffer.write('''
  • '''); buffer.writeEscaped(context9.name.toString()); @@ -1072,6 +1141,7 @@ String _renderCategory_partial_packages_10(_i1.CategoryTemplateData context0) { var context10 = context9.publicLibrariesSorted; if (context10 != null) { for (var context11 in context10) { + buffer.writeln(); buffer.write('''
  • '''); buffer.write(context11.linkedName.toString()); @@ -1082,6 +1152,7 @@ String _renderCategory_partial_packages_10(_i1.CategoryTemplateData context0) { } } } + buffer.writeln(); buffer.write(''' '''); @@ -1096,6 +1167,7 @@ String _renderCategory_partial_sidebar_for_category_11( var context1 = context0.self; if (context1 != null) { if (context1.hasPublicLibraries == true) { + buffer.writeln(); buffer.write('''
  • @@ -1346,11 +1440,13 @@ String _renderCategory_partial_footer_12(_i1.CategoryTemplateData context0) { String renderClass(_i1.ClassTemplateData context0) { final buffer = StringBuffer(); buffer.write(_renderClass_partial_head_0(context0)); + buffer.writeln(); buffer.write('''
    '''); var context1 = context0.self; if (context1 != null) { + buffer.writeln(); buffer.write('''
    '''); buffer.write(_renderClass_partial_source_link_1(context1, context0)); @@ -1371,10 +1467,12 @@ String renderClass(_i1.ClassTemplateData context0) { buffer.write(_renderClass_partial_documentation_4(context2, context0)); buffer.writeln(); if (context2.hasModifiers == true) { + buffer.writeln(); buffer.write('''
    '''); if (context2.hasPublicSuperChainReversed == true) { + buffer.writeln(); buffer.write('''
    Inheritance
      @@ -1384,12 +1482,14 @@ String renderClass(_i1.ClassTemplateData context0) { var context3 = context2.publicSuperChainReversed; if (context3 != null) { for (var context4 in context3) { + buffer.writeln(); buffer.write('''
    • '''); buffer.write(context4.linkedName.toString()); buffer.write('''
    • '''); } } + buffer.writeln(); buffer.write('''
    • '''); buffer.write(context2.name.toString()); @@ -1398,6 +1498,7 @@ String renderClass(_i1.ClassTemplateData context0) { } buffer.writeln(); if (context2.hasPublicInterfaces == true) { + buffer.writeln(); buffer.write('''
      Implemented types
      @@ -1405,90 +1506,106 @@ String renderClass(_i1.ClassTemplateData context0) { var context5 = context2.publicInterfaces; if (context5 != null) { for (var context6 in context5) { + buffer.writeln(); buffer.write('''
    • '''); buffer.write(context6.linkedName.toString()); buffer.write('''
    • '''); } } + buffer.writeln(); buffer.write('''
    '''); } buffer.writeln(); if (context2.hasPublicMixedInTypes == true) { + buffer.writeln(); buffer.write('''
    Mixed in types
      '''); var context7 = context2.publicMixedInTypes; if (context7 != null) { for (var context8 in context7) { + buffer.writeln(); buffer.write('''
    • '''); buffer.write(context8.linkedName.toString()); buffer.write('''
    • '''); } } + buffer.writeln(); buffer.write('''
    '''); } buffer.writeln(); if (context2.hasPublicImplementors == true) { + buffer.writeln(); buffer.write('''
    Implementers
      '''); var context9 = context2.publicImplementorsSorted; if (context9 != null) { for (var context10 in context9) { + buffer.writeln(); buffer.write('''
    • '''); buffer.write(context10.linkedName.toString()); buffer.write('''
    • '''); } } + buffer.writeln(); buffer.write('''
    '''); } buffer.writeln(); if (context2.hasPotentiallyApplicableExtensions == true) { + buffer.writeln(); buffer.write('''
    Available Extensions
      '''); var context11 = context2.potentiallyApplicableExtensionsSorted; if (context11 != null) { for (var context12 in context11) { + buffer.writeln(); buffer.write('''
    • '''); buffer.write(context12.linkedName.toString()); buffer.write('''
    • '''); } } + buffer.writeln(); buffer.write('''
    '''); } buffer.writeln(); if (context2.hasAnnotations == true) { + buffer.writeln(); buffer.write('''
    Annotations
      '''); var context13 = context2.annotations; if (context13 != null) { for (var context14 in context13) { + buffer.writeln(); buffer.write('''
    • '''); buffer.write(context14.linkedNameWithParameters.toString()); buffer.write('''
    • '''); } } + buffer.writeln(); buffer.write('''
    '''); } + buffer.writeln(); buffer.write('''
    '''); } buffer.writeln(); if (context2.hasPublicConstructors == true) { + buffer.writeln(); buffer.write('''

    Constructors

    @@ -1497,6 +1614,7 @@ String renderClass(_i1.ClassTemplateData context0) { var context15 = context2.publicConstructorsSorted; if (context15 != null) { for (var context16 in context15) { + buffer.writeln(); buffer.write('''
    const
    '''); } if (context16.isFactory == true) { + buffer.writeln(); buffer.write('''
    factory
    '''); } + buffer.writeln(); buffer.write(''' '''); } } + buffer.writeln(); buffer.write(''' '''); } buffer.writeln(); if (context2.hasPublicInstanceFields == true) { + buffer.writeln(); buffer.write('''
    (_i1.ClassTemplateData context0) { _renderClass_partial_callable_6(context20, context2, context0)); } } + buffer.writeln(); buffer.write('''
    '''); } buffer.writeln(); if (context2.hasPublicInstanceOperators == true) { + buffer.writeln(); buffer.write('''

    Static Properties

    @@ -1610,12 +1739,14 @@ String renderClass(_i1.ClassTemplateData context0) { _renderClass_partial_property_5(context24, context2, context0)); } } + buffer.writeln(); buffer.write('''
    '''); } buffer.writeln(); if (context2.hasPublicStaticMethods == true) { + buffer.writeln(); buffer.write('''

    Static Methods

    @@ -1628,12 +1759,14 @@ String renderClass(_i1.ClassTemplateData context0) { _renderClass_partial_callable_6(context26, context2, context0)); } } + buffer.writeln(); buffer.write('''
    '''); } buffer.writeln(); if (context2.hasPublicConstantFields == true) { + buffer.writeln(); buffer.write('''

    Constants

    @@ -1647,11 +1780,13 @@ String renderClass(_i1.ClassTemplateData context0) { _renderClass_partial_constant_7(context28, context2, context0)); } } + buffer.writeln(); buffer.write('''
    '''); } } + buffer.writeln(); buffer.write('''
    @@ -1659,6 +1794,7 @@ String renderClass(_i1.ClassTemplateData context0) { @@ -1693,11 +1831,13 @@ String _renderClass_partial_head_0( '''); if (context0.includeVersion == true) { + buffer.writeln(); buffer.write(''' '''); } + buffer.writeln(); buffer.write(''' ( } } buffer.write('\n\n '); + buffer.writeln(); buffer.write(''' '''); + buffer.writeln(); buffer.write(''' ( var context3 = context0.navLinks; if (context3 != null) { for (var context4 in context3) { + buffer.writeln(); buffer.write('''
  • ( } } if (context0.hasHomepage != true) { + buffer.writeln(); buffer.write('''
  • '''); buffer.write(context0.layoutTitle.toString()); buffer.write('''
  • '''); } if (context0.hasHomepage == true) { + buffer.writeln(); buffer.write('''
  • '''); @@ -1828,6 +1979,7 @@ String _renderClass_partial_source_link_1( _i4.Class context1, _i1.ClassTemplateData context0) { final buffer = StringBuffer(); if (context1.hasSourceHref == true) { + buffer.writeln(); buffer.write(''' @@ -2955,11 +3201,13 @@ String _renderEnum_partial_head_0(_i1.EnumTemplateData context0) { '''); if (context0.includeVersion == true) { + buffer.writeln(); buffer.write(''' '''); } + buffer.writeln(); buffer.write(''' '''); + buffer.writeln(); buffer.write(''' '''); buffer.write(context0.layoutTitle.toString()); buffer.write('''
  • '''); } if (context0.hasHomepage == true) { + buffer.writeln(); buffer.write('''
  • '''); @@ -3090,6 +3349,7 @@ String _renderEnum_partial_source_link_1( _i12.Enum context1, _i1.EnumTemplateData context0) { final buffer = StringBuffer(); if (context1.hasSourceHref == true) { + buffer.writeln(); buffer.write('''