Skip to content

Create generator subpackage for generator files #2150

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 4 commits into from
Feb 26, 2020
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
2 changes: 1 addition & 1 deletion build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ builders:
resource_builder:
import: "tool/builder.dart"
builder_factories: ["resourceBuilder"]
build_extensions: {'$lib$': ['src/html/resources.g.dart']}
build_extensions: {'$lib$': ['src/generator/html_resources.g.dart']}
build_to: "source"
auto_apply: none

Expand Down
8 changes: 4 additions & 4 deletions lib/dartdoc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import 'dart:convert';
import 'dart:io';

import 'package:dartdoc/src/dartdoc_options.dart';
import 'package:dartdoc/src/empty_generator.dart';
import 'package:dartdoc/src/generator.dart';
import 'package:dartdoc/src/html/html_generator.dart';
import 'package:dartdoc/src/generator/empty_generator.dart';
import 'package:dartdoc/src/generator/generator.dart';
import 'package:dartdoc/src/generator/html_generator.dart';
import 'package:dartdoc/src/logging.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/package_meta.dart';
Expand All @@ -29,7 +29,7 @@ import 'package:path/path.dart' as path;

export 'package:dartdoc/src/dartdoc_options.dart';
export 'package:dartdoc/src/element_type.dart';
export 'package:dartdoc/src/generator.dart';
export 'package:dartdoc/src/generator/generator.dart';
export 'package:dartdoc/src/model/model.dart';
export 'package:dartdoc/src/package_meta.dart';

Expand Down
204 changes: 204 additions & 0 deletions lib/src/generator/dartdoc_generator_backend.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// 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:dartdoc/dartdoc.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/model/model.dart';
import 'package:dartdoc/src/model/package.dart';
import 'package:dartdoc/src/model/package_graph.dart';
import 'package:dartdoc/src/warnings.dart';
import 'package:mustache/mustache.dart';
import 'package:path/path.dart' as path;

/// Configuration options for the Dartdoc's default backend.
class DartdocGeneratorBackendOptions implements TemplateOptions {
@override
final String relCanonicalPrefix;
@override
final String toolVersion;

final String favicon;

final bool prettyIndexJson;

@override
final bool useBaseHref;

DartdocGeneratorBackendOptions.fromContext(
DartdocGeneratorOptionContext context)
: relCanonicalPrefix = context.relCanonicalPrefix,
toolVersion = dartdocVersion,
favicon = context.favicon,
prettyIndexJson = context.prettyIndexJson,
useBaseHref = context.useBaseHref;

DartdocGeneratorBackendOptions(
{this.relCanonicalPrefix,
this.toolVersion,
this.favicon,
this.prettyIndexJson = false,
this.useBaseHref = false});
}

/// Base GeneratorBackend for Dartdoc's supported formats.
abstract class DartdocGeneratorBackend implements GeneratorBackend {
final DartdocGeneratorBackendOptions options;
final Templates templates;

DartdocGeneratorBackend(
DartdocGeneratorBackendOptions options, this.templates)
: this.options = (options ?? DartdocGeneratorBackendOptions());

/// Helper method to bind template data and emit the content to the writer.
void render(FileWriter writer, String filename, Template template,
TemplateData data) {
String content = template.renderString(data);
if (!options.useBaseHref) {
content = content.replaceAll(HTMLBASE_PLACEHOLDER, data.htmlBase);
}
writer.write(filename, content,
element: data.self is Warnable ? data.self : null);
}

@override
void generateCategoryJson(
FileWriter writer, List<Categorization> categories) {
String json = generator_util.generateCategoryJson(
categories, options.prettyIndexJson);
if (!options.useBaseHref) {
json = json.replaceAll(HTMLBASE_PLACEHOLDER, '');
}
writer.write(path.join('categories.json'), '${json}\n');
}

@override
void generateSearchIndex(FileWriter writer, List<Indexable> indexedElements) {
String json = generator_util.generateSearchIndexJson(
indexedElements, options.prettyIndexJson);
if (!options.useBaseHref) {
json = json.replaceAll(HTMLBASE_PLACEHOLDER, '');
}
writer.write(path.join('index.json'), '${json}\n');
}

@override
void generatePackage(FileWriter writer, PackageGraph graph, Package package) {
TemplateData data = PackageTemplateData(options, graph, package);
render(writer, package.filePath, templates.indexTemplate, data);
}

@override
void generateCategory(
FileWriter writer, PackageGraph packageGraph, Category category) {
TemplateData data = CategoryTemplateData(options, packageGraph, category);
render(writer, category.filePath, templates.categoryTemplate, data);
}

@override
void generateLibrary(
FileWriter writer, PackageGraph packageGraph, Library lib) {
TemplateData data = LibraryTemplateData(options, packageGraph, lib);
render(writer, lib.filePath, templates.libraryTemplate, data);
}

@override
void generateClass(
FileWriter writer, PackageGraph packageGraph, Library lib, Class clazz) {
TemplateData data = ClassTemplateData(options, packageGraph, lib, clazz);
render(writer, clazz.filePath, templates.classTemplate, data);
}

@override
void generateExtension(FileWriter writer, PackageGraph packageGraph,
Library lib, Extension extension) {
TemplateData data =
ExtensionTemplateData(options, packageGraph, lib, extension);
render(writer, extension.filePath, templates.extensionTemplate, data);
}

@override
void generateMixin(
FileWriter writer, PackageGraph packageGraph, Library lib, Mixin mixin) {
TemplateData data = MixinTemplateData(options, packageGraph, lib, mixin);
render(writer, mixin.filePath, templates.mixinTemplate, data);
}

@override
void generateConstructor(FileWriter writer, PackageGraph packageGraph,
Library lib, Class clazz, Constructor constructor) {
TemplateData data =
ConstructorTemplateData(options, packageGraph, lib, clazz, constructor);

render(writer, constructor.filePath, templates.constructorTemplate, data);
}

@override
void generateEnum(
FileWriter writer, PackageGraph packageGraph, Library lib, Enum eNum) {
TemplateData data = EnumTemplateData(options, packageGraph, lib, eNum);

render(writer, eNum.filePath, templates.enumTemplate, data);
}

@override
void generateFunction(FileWriter writer, PackageGraph packageGraph,
Library lib, ModelFunction function) {
TemplateData data =
FunctionTemplateData(options, packageGraph, lib, function);

render(writer, function.filePath, templates.functionTemplate, data);
}

@override
void generateMethod(FileWriter writer, PackageGraph packageGraph, Library lib,
Container clazz, Method method) {
TemplateData data =
MethodTemplateData(options, packageGraph, lib, clazz, method);

render(writer, method.filePath, templates.methodTemplate, data);
}

@override
void generateConstant(FileWriter writer, PackageGraph packageGraph,
Library lib, Container clazz, Field property) =>
generateProperty(writer, packageGraph, lib, clazz, property);

@override
void generateProperty(FileWriter writer, PackageGraph packageGraph,
Library lib, Container clazz, Field property) {
TemplateData data =
PropertyTemplateData(options, packageGraph, lib, clazz, property);

render(writer, property.filePath, templates.propertyTemplate, data);
}

@override
void generateTopLevelProperty(FileWriter writer, PackageGraph packageGraph,
Library lib, TopLevelVariable property) {
TemplateData data =
TopLevelPropertyTemplateData(options, packageGraph, lib, property);

render(writer, property.filePath, templates.topLevelPropertyTemplate, data);
}

@override
void generateTopLevelConstant(FileWriter writer, PackageGraph packageGraph,
Library lib, TopLevelVariable property) =>
generateTopLevelProperty(writer, packageGraph, lib, property);

@override
void generateTypeDef(FileWriter writer, PackageGraph packageGraph,
Library lib, Typedef typeDef) {
TemplateData data =
TypedefTemplateData(options, packageGraph, lib, typeDef);

render(writer, typeDef.filePath, templates.typeDefTemplate, data);
}

@override
void generateAdditionalFiles(FileWriter writer, PackageGraph graph) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ library dartdoc.empty_generator;
import 'dart:async';

import 'package:dartdoc/src/dartdoc_options.dart';
import 'package:dartdoc/src/generator.dart';
import 'package:dartdoc/src/generator/generator.dart';
import 'package:dartdoc/src/logging.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/model_utils.dart';
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import 'dart:async';

import 'package:dartdoc/src/generator.dart';
import 'package:dartdoc/src/generator/generator.dart';
import 'package:dartdoc/src/logging.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/model_utils.dart';
Expand Down
File renamed without changes.
65 changes: 65 additions & 0 deletions lib/src/generator/html_generator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// 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.

library dartdoc.html_generator;

import 'dart:async' show Future;
import 'dart:io' show File;

import 'package:dartdoc/dartdoc.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/html_resources.g.dart' as resources;
import 'package:dartdoc/src/generator/resource_loader.dart' as resource_loader;
import 'package:dartdoc/src/generator/template_data.dart';
import 'package:dartdoc/src/generator/templates.dart';
import 'package:path/path.dart' as path;

Future<Generator> initHtmlGenerator(
DartdocGeneratorOptionContext context) async {
var templates = await Templates.fromContext(context);
var options = DartdocGeneratorBackendOptions.fromContext(context);
var backend = HtmlGeneratorBackend(options, templates);
return GeneratorFrontEnd(backend);
}

/// Generator backend for html output.
class HtmlGeneratorBackend extends DartdocGeneratorBackend {
HtmlGeneratorBackend(
DartdocGeneratorBackendOptions options, Templates templates)
: super(options, templates);

@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);
render(writer, '__404error.html', templates.errorTemplate, data);
}

@override
void generateAdditionalFiles(FileWriter writer, PackageGraph graph) async {
await _copyResources(writer);
if (options.favicon != null) {
// Allow overwrite of favicon.
var bytes = File(options.favicon).readAsBytesSync();
writer.write(path.join('static-assets', 'favicon.png'), bytes,
allowOverwrite: true);
}
}

Future _copyResources(FileWriter writer) async {
final prefix = 'package:dartdoc/resources/';
for (String resourcePath in resources.resource_names) {
if (!resourcePath.startsWith(prefix)) {
throw StateError('Resource paths must start with $prefix, '
'encountered $resourcePath');
}
String destFileName = resourcePath.substring(prefix.length);
writer.write(path.join('static-assets', destFileName),
await resource_loader.loadAsBytes(resourcePath));
}
}
}
File renamed without changes.
Loading