22// for details. All rights reserved. Use of this source code is governed by a
33// BSD-style license that can be found in the LICENSE file.
44
5- import 'dart:async' show Future, StreamController ;
5+ import 'dart:async' show Future;
66import 'dart:convert' show JsonEncoder;
7- import 'dart:io' show Directory, File;
7+ import 'dart:io' show File;
88
99import 'package:collection/collection.dart' show compareNatural;
1010import 'package:dartdoc/src/model_utils.dart' ;
@@ -19,13 +19,14 @@ import 'resources.g.dart' as resources;
1919import 'template_data.dart' ;
2020import 'templates.dart' ;
2121
22+ typedef void FileWriter (String path, Object content, {bool allowOverwrite});
23+
2224class HtmlGeneratorInstance implements HtmlOptions {
2325 final HtmlGeneratorOptions _options;
2426 final Templates _templates;
2527 final Package _package;
26- final String _outputDirectoryPath;
2728 final List <ModelElement > _documentedElements = < ModelElement > [];
28- final StreamController < File > _onFileCreated ;
29+ final FileWriter _writer ;
2930
3031 @override
3132 String get relCanonicalPrefix => _options.relCanonicalPrefix;
@@ -36,12 +37,8 @@ class HtmlGeneratorInstance implements HtmlOptions {
3637 String get _faviconPath => _options.faviconPath;
3738 bool get _useCategories => _options.useCategories;
3839
39- // Protect against bugs in canonicalization by tracking what files we
40- // write.
41- final Set <String > writtenFiles = new Set <String >();
42-
43- HtmlGeneratorInstance (this ._options, this ._templates, this ._package,
44- this ._outputDirectoryPath, this ._onFileCreated);
40+ HtmlGeneratorInstance (
41+ this ._options, this ._templates, this ._package, this ._writer);
4542
4643 Future generate () async {
4744 if (_package != null ) {
@@ -53,10 +50,8 @@ class HtmlGeneratorInstance implements HtmlOptions {
5350 if (_faviconPath != null ) {
5451 var bytes = new File (_faviconPath).readAsBytesSync ();
5552 // Allow overwrite of favicon.
56- String filename =
57- path.join (_outputDirectoryPath, 'static-assets' , 'favicon.png' );
58- writtenFiles.remove (filename);
59- _writeFile (filename, bytes);
53+ _writer (path.join ('static-assets' , 'favicon.png' ), bytes,
54+ allowOverwrite: true );
6055 }
6156 }
6257
@@ -95,7 +90,7 @@ class HtmlGeneratorInstance implements HtmlOptions {
9590 });
9691
9792 String json = encoder.convert (indexItems);
98- _writeFile (path.join (_outputDirectoryPath, 'index.json' ), '${json }\n ' );
93+ _writer (path.join ('index.json' ), '${json }\n ' );
9994 }
10095
10196 void _generateDocs () {
@@ -285,44 +280,16 @@ class HtmlGeneratorInstance implements HtmlOptions {
285280 'encountered $resourcePath ' );
286281 }
287282 String destFileName = resourcePath.substring (prefix.length);
288- _writeFile (path.join (_outputDirectoryPath, 'static-assets' , destFileName),
283+ _writer (path.join ('static-assets' , destFileName),
289284 await loader.loadAsBytes (resourcePath));
290285 }
291286 }
292287
293288 void _build (String filename, TemplateRenderer template, TemplateData data) {
294- String fullName = path.join (_outputDirectoryPath, filename);
295-
296289 String content = template (data,
297290 assumeNullNonExistingProperty: false , errorOnMissingProperty: true );
298291
299- _writeFile (fullName, content);
300- if (data.self is ModelElement ) {
301- _documentedElements.add (data.self);
302- }
303- }
304-
305- /// [content] must be either [String] or [List<int>] .
306- void _writeFile (String filename, Object content) {
307- // If you see this assert, we're probably being called to build non-canonical
308- // docs somehow. Check data.self.isCanonical and callers for bugs.
309- assert (! writtenFiles.contains (filename));
310-
311- File file = new File (filename);
312- Directory parent = file.parent;
313- if (! parent.existsSync ()) {
314- parent.createSync (recursive: true );
315- }
316-
317- if (content is String ) {
318- file.writeAsStringSync (content);
319- } else if (content is List <int >) {
320- file.writeAsBytesSync (content);
321- } else {
322- throw new ArgumentError .value (
323- content, 'content' , '`content` must be `String` or `List<int>`.' );
324- }
325- _onFileCreated.add (file);
326- writtenFiles.add (filename);
292+ _writer (filename, content);
293+ if (data.self is ModelElement ) _documentedElements.add (data.self);
327294 }
328295}
0 commit comments