Skip to content

Use Mustachio AOT compiler for default templates #2677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions lib/dartdoc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> _writtenFiles = {};
Expand All @@ -125,12 +125,23 @@ class Dartdoc {
final StreamController<String> _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')
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions lib/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
53 changes: 25 additions & 28 deletions lib/src/generator/dartdoc_generator_backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -60,16 +59,15 @@ class DartdocGeneratorBackendOptions implements TemplateOptions {
}

class SidebarGenerator<T extends TemplateData> {
final Template template;
final RenderFunction<T> renderFunction;
final String Function(T context) renderFunction;
final Map<Documentable, String> _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);
}
}

Expand All @@ -81,15 +79,16 @@ abstract class DartdocGeneratorBackend implements GeneratorBackend {
sidebarForLibrary;
final SidebarGenerator<TemplateDataWithContainer<Documentable>>
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(
Expand Down Expand Up @@ -129,15 +128,15 @@ 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);
}

@override
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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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);
}

Expand All @@ -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<void> generateAdditionalFiles(
FileWriter writer, PackageGraph graph) async {}
Future<void> generateAdditionalFiles(FileWriter writer) async {}
}
7 changes: 4 additions & 3 deletions lib/src/generator/generator_frontend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class GeneratorFrontEnd implements Generator {
Future<void> generate(PackageGraph packageGraph, FileWriter writer) async {
var indexElements = <Indexable>[];
_generateDocs(packageGraph, writer, indexElements);
await _generatorBackend.generateAdditionalFiles(writer, packageGraph);
await _generatorBackend.generateAdditionalFiles(writer);

var categories = indexElements
.whereType<Categorization>()
Expand All @@ -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<Indexable> indexAccumulator) {
if (packageGraph == null) return;
Expand Down Expand Up @@ -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<void> generateAdditionalFiles(FileWriter writer, PackageGraph graph);
Future<void> generateAdditionalFiles(FileWriter writer);
}
37 changes: 19 additions & 18 deletions lib/src/generator/html_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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<Generator> 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<Generator> 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<void> generateAdditionalFiles(
FileWriter writer, PackageGraph graph) async {
Future<void> 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,
);
Expand All @@ -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));
}
}

Expand Down
Loading