Refactor handling of generateDocs:false (#4095)

Not sure if anyone is using this option really. But I think the handling
can be simplified.

But it seems that having multiple Generator classes just for deciding
whether to write files or not is excessive, and likely to get out of
sync (does the EmptyGenerator really still do whatever GeneratorFrontend
does, just without writing files?)
diff --git a/bin/dartdoc.dart b/bin/dartdoc.dart
index a79652d..6dafdeb 100644
--- a/bin/dartdoc.dart
+++ b/bin/dartdoc.dart
@@ -20,8 +20,5 @@
   final packageConfigProvider = PhysicalPackageConfigProvider();
   final packageBuilder =
       PubPackageBuilder(config, pubPackageMetaProvider, packageConfigProvider);
-  final dartdoc = config.generateDocs
-      ? Dartdoc.fromContext(config, packageBuilder)
-      : Dartdoc.withEmptyGenerator(config, packageBuilder);
-  dartdoc.executeGuarded();
+  Dartdoc.fromContext(config, packageBuilder).executeGuarded();
 }
diff --git a/lib/src/dartdoc.dart b/lib/src/dartdoc.dart
index 2628109..8c847ab 100644
--- a/lib/src/dartdoc.dart
+++ b/lib/src/dartdoc.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:dartdoc/src/dartdoc_options.dart';
 import 'package:dartdoc/src/failure.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';
@@ -27,10 +26,28 @@
 // Update when pubspec version changes by running `pub run build_runner build`
 const String dartdocVersion = packageVersion;
 
+/// Used for the generateDocs:false option.
+///
+/// Writes nothing.
+class NoFileWriter implements FileWriter {
+  @override
+  void write(String filePath, String content, {Warnable? element}) {
+    // Do nothing
+  }
+
+  @override
+  void writeBytes(String filePath, List<int> content,
+      {bool allowOverwrite = false}) {
+    // Do nothing
+  }
+
+  @override
+  Set<String> get writtenFiles => {};
+}
+
 class DartdocFileWriter implements FileWriter {
   final String _outputDir;
-  @override
-  final ResourceProvider resourceProvider;
+  final ResourceProvider _resourceProvider;
   final Map<String, Warnable?> _fileElementMap = {};
   @override
   final Set<String> writtenFiles = {};
@@ -43,7 +60,7 @@
 
   DartdocFileWriter(
     this._outputDir,
-    this.resourceProvider, {
+    this._resourceProvider, {
     int maxFileCount = 0,
     int maxTotalSize = 0,
   })  : _maxFileCount = maxFileCount,
@@ -115,8 +132,8 @@
   /// Returns the file at [outFile] relative to [_outputDir], creating the
   /// parent directory if necessary.
   File _getFile(String outFile) {
-    var file = resourceProvider
-        .getFile(resourceProvider.pathContext.join(_outputDir, outFile));
+    var file = _resourceProvider
+        .getFile(_resourceProvider.pathContext.join(_outputDir, outFile));
     var parent = file.parent;
     if (!parent.exists) {
       parent.create();
@@ -144,19 +161,6 @@
   @visibleForTesting
   set generator(Generator newGenerator) => _generator = newGenerator;
 
-  /// Factory method that builds Dartdoc with an empty generator.
-  factory Dartdoc.withEmptyGenerator(
-    DartdocOptionContext config,
-    PackageBuilder packageBuilder,
-  ) {
-    return Dartdoc._(
-      config,
-      config.resourceProvider.getFolder('UNUSED'),
-      initEmptyGenerator(),
-      packageBuilder,
-    );
-  }
-
   /// Builds Dartdoc with a generator determined by [context].
   factory Dartdoc.fromContext(
     DartdocGeneratorOptionContext context,
@@ -165,12 +169,14 @@
     var resourceProvider = context.resourceProvider;
     var outputPath = resourceProvider.pathContext.absolute(context.output);
     var outputDir = resourceProvider.getFolder(outputPath)..create();
-    var writer = DartdocFileWriter(
-      outputPath,
-      resourceProvider,
-      maxFileCount: context.maxFileCount,
-      maxTotalSize: context.maxTotalSize,
-    );
+    var writer = context.generateDocs
+        ? DartdocFileWriter(
+            outputPath,
+            resourceProvider,
+            maxFileCount: context.maxFileCount,
+            maxTotalSize: context.maxTotalSize,
+          )
+        : NoFileWriter();
     return Dartdoc._(
       context,
       outputDir,
diff --git a/lib/src/dartdoc_options.dart b/lib/src/dartdoc_options.dart
index ad112bc..8ba75d9 100644
--- a/lib/src/dartdoc_options.dart
+++ b/lib/src/dartdoc_options.dart
@@ -1278,6 +1278,9 @@
   bool get useBaseHref => optionSet['useBaseHref'].valueAt(context);
 
   String? get resourcesDir => optionSet['resourcesDir'].valueAt(context);
+
+  /// Whether to generate docs or perform a dry run.
+  bool get generateDocs => optionSet['generateDocs'].valueAt(context);
 }
 
 class DartdocProgramOptionContext extends DartdocGeneratorOptionContext
@@ -1288,9 +1291,6 @@
   DartdocProgramOptionContext.fromDefaultContextLocation(
       super.optionSet, super.resourceProvider)
       : super.fromDefaultContextLocation();
-
-  /// Whether to generate docs or perform a dry run.
-  bool get generateDocs => optionSet['generateDocs'].valueAt(context);
 }
 
 List<DartdocOption<bool>> createDartdocProgramOptions(
diff --git a/lib/src/generator/empty_generator.dart b/lib/src/generator/empty_generator.dart
deleted file mode 100644
index 3feeea9..0000000
--- a/lib/src/generator/empty_generator.dart
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2022, 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/logging.dart';
-import 'package:dartdoc/src/model/model.dart';
-import 'package:dartdoc/src/model_utils.dart';
-
-/// A generator that does not generate files, but does traverse the
-/// [PackageGraph] and access [ModelElement.documentationAsHtml] for every
-/// element as though it were.
-class EmptyGenerator implements Generator {
-  @override
-  Future<void> generate(PackageGraph packageGraph) {
-    logProgress(packageGraph.defaultPackage.documentationAsHtml);
-    for (var package in {
-      packageGraph.defaultPackage,
-      ...packageGraph.localPackages
-    }) {
-      for (var category in package.categories.whereDocumented) {
-        logProgress(category.documentationAsHtml);
-      }
-
-      for (var lib in package.libraries.whereDocumented) {
-        for (var e in lib.allModelElements.whereDocumented) {
-          logProgress(e.documentationAsHtml);
-        }
-      }
-    }
-    return Future.value();
-  }
-
-  @override
-  Set<String> get writtenFiles => const {};
-}
-
-Generator initEmptyGenerator() {
-  return EmptyGenerator();
-}
diff --git a/lib/src/generator/generator.dart b/lib/src/generator/generator.dart
index 13511dc..896e077 100644
--- a/lib/src/generator/generator.dart
+++ b/lib/src/generator/generator.dart
@@ -5,15 +5,16 @@
 /// A library containing an abstract documentation generator.
 library;
 
-import 'package:analyzer/file_system/file_system.dart';
 import 'package:dartdoc/src/dartdoc_options.dart';
-import 'package:dartdoc/src/model/package_graph.dart';
+import 'package:dartdoc/src/generator/generator_backend.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/package_meta.dart';
+import 'package:dartdoc/src/runtime_stats.dart';
 import 'package:dartdoc/src/warnings.dart';
 
 abstract class FileWriter {
-  ResourceProvider get resourceProvider;
-
   /// All filenames written by this generator.
   Set<String> get writtenFiles;
 
@@ -36,13 +37,234 @@
 /// A generator generates documentation for a given package.
 ///
 /// Generators can generate documentation in different formats: HTML, JSON, etc.
-abstract class Generator {
-  /// Generates the documentation for the given package using the specified
-  /// writer. Completes the returned future when done.
-  Future<void> generate(PackageGraph packageGraph);
+class Generator {
+  final GeneratorBackend _generatorBackend;
 
-  /// The set of of files written by the generator backend.
-  Set<String> get writtenFiles;
+  Generator(this._generatorBackend);
+
+  Future<void> generate(PackageGraph? packageGraph) async {
+    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);
+  }
+
+  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.element.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;
+  }
 }
 
 List<DartdocOption> createGeneratorOptions(
diff --git a/lib/src/generator/generator_frontend.dart b/lib/src/generator/generator_frontend.dart
deleted file mode 100644
index 33f23f8..0000000
--- a/lib/src/generator/generator_frontend.dart
+++ /dev/null
@@ -1,245 +0,0 @@
-// 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/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 {
-    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.element.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;
-  }
-}
diff --git a/lib/src/generator/html_generator.dart b/lib/src/generator/html_generator.dart
index c179e3e..9b5c136 100644
--- a/lib/src/generator/html_generator.dart
+++ b/lib/src/generator/html_generator.dart
@@ -5,7 +5,6 @@
 import 'package:dartdoc/src/dartdoc_options.dart';
 import 'package:dartdoc/src/generator/generator.dart';
 import 'package:dartdoc/src/generator/generator_backend.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';
 import 'package:dartdoc/src/generator/template_data.dart';
@@ -20,9 +19,9 @@
 }) {
   var templates = HtmlAotTemplates();
   var options = DartdocGeneratorBackendOptions.fromContext(context);
-  var backend = HtmlGeneratorBackend(
+  var generatorBackend = HtmlGeneratorBackend(
       options, templates, writer, context.resourceProvider);
-  return GeneratorFrontEnd(backend);
+  return Generator(generatorBackend);
 }
 
 /// Generator backend for HTML output.
diff --git a/test/html_generator_test.dart b/test/html_generator_test.dart
index 8983c99..8344af4 100644
--- a/test/html_generator_test.dart
+++ b/test/html_generator_test.dart
@@ -9,7 +9,6 @@
 import 'package:dartdoc/src/dartdoc_options.dart';
 import 'package:dartdoc/src/generator/generator.dart';
 import 'package:dartdoc/src/generator/generator_backend.dart';
-import 'package:dartdoc/src/generator/generator_frontend.dart';
 import 'package:dartdoc/src/generator/html_generator.dart';
 import 'package:dartdoc/src/generator/html_resources.g.dart';
 import 'package:dartdoc/src/generator/templates.dart';
@@ -33,7 +32,7 @@
     late FakePackageConfigProvider packageConfigProvider;
 
     final Templates templates = HtmlAotTemplates();
-    late GeneratorFrontEnd generator;
+    late Generator generator;
 
     late Folder projectRoot;
     late String projectPath;
@@ -66,7 +65,7 @@
       var outputPath = projectRoot.getChildAssumingFolder('doc').path;
       var writer = DartdocFileWriter(outputPath, resourceProvider);
 
-      generator = GeneratorFrontEnd(
+      generator = Generator(
           HtmlGeneratorBackend(options, templates, writer, resourceProvider));
     });