blob: 9dcd8da13609324dd39a7413d1d56506b1e3be00 [file] [log] [blame]
// 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/src/generator/generator.dart';
import 'package:dartdoc/src/generator/generator_backend.dart';
import 'package:dartdoc/src/generator/templates.dart';
import 'package:dartdoc/src/logging.dart';
import 'package:dartdoc/src/model/model.dart';
import 'package:dartdoc/src/model_utils.dart';
import 'package:dartdoc/src/runtime_stats.dart';
import 'package:dartdoc/src/warnings.dart';
/// A [Generator] that delegates rendering to a [GeneratorBackend] and delegates
/// file creation to a [FileWriter].
class GeneratorFrontEnd implements Generator {
final GeneratorBackend _generatorBackend;
GeneratorFrontEnd(this._generatorBackend);
@override
Future<void> generate(PackageGraph? packageGraph) async {
if (_generatorBackend.templates is RuntimeTemplates) {
packageGraph?.defaultPackage.warn(
PackageWarning.deprecated,
message: "The '--templates-dir' option is deprecated, and will soon no "
'longer be supported.',
);
}
await _generatorBackend.generateAdditionalFiles();
if (packageGraph == null) {
return;
}
var indexElements = _generateDocs(packageGraph);
var categories = indexElements
.whereType<Categorization>()
.where((e) => e.hasCategorization)
.toList(growable: false);
_generatorBackend.generateCategoryJson(categories);
_generatorBackend.generateSearchIndex(indexElements);
}
@override
Set<String> get writtenFiles => _generatorBackend.writer.writtenFiles;
/// Traverses the [packageGraph] and generates documentation for all contained
/// elements.
List<Documentable> _generateDocs(PackageGraph packageGraph) {
runtimeStats.resetAccumulators({
'writtenCategoryFileCount',
'writtenClassFileCount',
'writtenConstructorFileCount',
'writtenEnumFileCount',
'writtenExtensionFileCount',
'writtenExtensionTypeFileCount',
'writtenFunctionFileCount',
'writtenLibraryFileCount',
'writtenMethodFileCount',
'writtenMixinFileCount',
'writtenPackageFileCount',
'writtenPropertyFileCount',
'writtenSidebarFileCount',
'writtenTopLevelPropertyFileCount',
'writtenTypedefFileCount'
});
_generatorBackend.generatePackage(
packageGraph, packageGraph.defaultPackage);
var indexAccumulator = <Documentable>[];
var multiplePackages = packageGraph.localPackages.length > 1;
void generateConstants(Container container, Library library) {
for (var constant in container.constantFields.whereDocumented) {
if (!constant.isCanonical) continue;
indexAccumulator.add(constant);
_generatorBackend.generateProperty(
packageGraph, library, container, constant);
}
}
void generateConstructors(Constructable constructable, Library library) {
for (var constructor in constructable.constructors.whereDocumented) {
if (!constructor.isCanonical) continue;
indexAccumulator.add(constructor);
_generatorBackend.generateConstructor(
packageGraph, library, constructable, constructor);
}
}
void generateInstanceMethods(Container container, Library library) {
for (var method in container.instanceMethods.whereDocumented) {
if (!method.isCanonical) continue;
indexAccumulator.add(method);
_generatorBackend.generateMethod(
packageGraph, library, container, method);
}
}
void generateInstanceOperators(Container container, Library library) {
for (var operator in container.instanceOperators.whereDocumented) {
if (!operator.isCanonical) continue;
indexAccumulator.add(operator);
_generatorBackend.generateMethod(
packageGraph, library, container, operator);
}
}
void generateInstanceProperties(Container container, Library library) {
for (var property in container.instanceFields.whereDocumented) {
if (!property.isCanonical) continue;
indexAccumulator.add(property);
_generatorBackend.generateProperty(
packageGraph, library, container, property);
}
}
void generateStaticMethods(Container container, Library library) {
for (var method in container.staticMethods.whereDocumented) {
if (!method.isCanonical) continue;
indexAccumulator.add(method);
_generatorBackend.generateMethod(
packageGraph, library, container, method);
}
}
void generateStaticProperties(Container container, Library library) {
for (var property in container.variableStaticFields.whereDocumented) {
if (!property.isCanonical) continue;
indexAccumulator.add(property);
_generatorBackend.generateProperty(
packageGraph, library, container, property);
}
}
for (var package in packageGraph.localPackages) {
if (multiplePackages) {
logInfo('Generating docs for package ${package.name}...');
}
for (var category in package.categories.whereDocumented) {
logInfo('Generating docs for category ${category.name} from '
'${category.package.fullyQualifiedName}...');
indexAccumulator.add(category);
_generatorBackend.generateCategory(packageGraph, category);
}
for (var lib in package.libraries.whereDocumented) {
if (!multiplePackages) {
logInfo('Generating docs for library ${lib.breadcrumbName} from '
'${lib.element2.firstFragment.source.uri}...');
}
if (!lib.isAnonymous && !lib.hasDocumentation) {
packageGraph.warnOnElement(lib, PackageWarning.noLibraryLevelDocs);
}
indexAccumulator.add(lib);
_generatorBackend.generateLibrary(packageGraph, lib);
for (var class_ in lib.classesAndExceptions.whereDocumentedIn(lib)) {
indexAccumulator.add(class_);
_generatorBackend.generateClass(packageGraph, lib, class_);
var canonicalLibrary = class_.canonicalLibraryOrThrow;
generateConstants(class_, canonicalLibrary);
generateConstructors(class_, canonicalLibrary);
generateInstanceMethods(class_, canonicalLibrary);
generateInstanceOperators(class_, canonicalLibrary);
generateInstanceProperties(class_, canonicalLibrary);
generateStaticMethods(class_, canonicalLibrary);
generateStaticProperties(class_, canonicalLibrary);
}
for (var extension in lib.extensions.whereDocumentedIn(lib)) {
indexAccumulator.add(extension);
_generatorBackend.generateExtension(packageGraph, lib, extension);
var canonicalLibrary = extension.canonicalLibraryOrThrow;
generateConstants(extension, canonicalLibrary);
generateInstanceMethods(extension, canonicalLibrary);
generateInstanceOperators(extension, canonicalLibrary);
generateInstanceProperties(extension, canonicalLibrary);
generateStaticMethods(extension, canonicalLibrary);
generateStaticProperties(extension, canonicalLibrary);
}
for (var extensionType in lib.extensionTypes.whereDocumentedIn(lib)) {
indexAccumulator.add(extensionType);
_generatorBackend.generateExtensionType(
packageGraph, lib, extensionType);
var canonicalLibrary = extensionType.canonicalLibraryOrThrow;
generateConstants(extensionType, canonicalLibrary);
generateConstructors(extensionType, canonicalLibrary);
generateInstanceMethods(extensionType, canonicalLibrary);
generateInstanceOperators(extensionType, canonicalLibrary);
generateInstanceProperties(extensionType, canonicalLibrary);
generateStaticMethods(extensionType, canonicalLibrary);
generateStaticProperties(extensionType, canonicalLibrary);
}
for (var mixin in lib.mixins.whereDocumentedIn(lib)) {
indexAccumulator.add(mixin);
_generatorBackend.generateMixin(packageGraph, lib, mixin);
var canonicalLibrary = mixin.canonicalLibraryOrThrow;
generateConstants(mixin, canonicalLibrary);
generateInstanceMethods(mixin, canonicalLibrary);
generateInstanceOperators(mixin, canonicalLibrary);
generateInstanceProperties(mixin, canonicalLibrary);
generateStaticMethods(mixin, canonicalLibrary);
generateStaticProperties(mixin, canonicalLibrary);
}
for (var enum_ in lib.enums.whereDocumentedIn(lib)) {
indexAccumulator.add(enum_);
_generatorBackend.generateEnum(packageGraph, lib, enum_);
var canonicalLibrary = enum_.canonicalLibraryOrThrow;
generateConstants(enum_, canonicalLibrary);
generateConstructors(enum_, canonicalLibrary);
generateInstanceMethods(enum_, canonicalLibrary);
generateInstanceOperators(enum_, canonicalLibrary);
generateInstanceProperties(enum_, canonicalLibrary);
generateStaticMethods(enum_, canonicalLibrary);
generateStaticProperties(enum_, canonicalLibrary);
}
for (var constant in lib.constants.whereDocumentedIn(lib)) {
indexAccumulator.add(constant);
_generatorBackend.generateTopLevelProperty(
packageGraph, lib, constant);
}
for (var property in lib.properties.whereDocumentedIn(lib)) {
indexAccumulator.add(property);
_generatorBackend.generateTopLevelProperty(
packageGraph, lib, property);
}
for (var function in lib.functions.whereDocumentedIn(lib)) {
indexAccumulator.add(function);
_generatorBackend.generateFunction(packageGraph, lib, function);
}
for (var typeDef in lib.typedefs.whereDocumentedIn(lib)) {
indexAccumulator.add(typeDef);
_generatorBackend.generateTypeDef(packageGraph, lib, typeDef);
}
}
}
return indexAccumulator;
}
}