@@ -44,40 +44,79 @@ class DartdocGeneratorOptionContext extends DartdocOptionContext
44
44
: super (optionSet, dir);
45
45
}
46
46
47
+ class DartdocFileWriter implements FileWriter {
48
+ final String outputDir;
49
+ final Map <String , Warnable > _fileElementMap = {};
50
+ @override
51
+ final Set <String > writtenFiles = Set ();
52
+
53
+ DartdocFileWriter (this .outputDir);
54
+
55
+ @override
56
+ void write (String filePath, Object content,
57
+ {bool allowOverwrite, Warnable element}) {
58
+ // Replace '/' separators with proper separators for the platform.
59
+ String outFile = path.joinAll (filePath.split ('/' ));
60
+
61
+ allowOverwrite ?? = false ;
62
+ if (! allowOverwrite) {
63
+ if (_fileElementMap.containsKey (outFile)) {
64
+ assert (element != null ,
65
+ 'Attempted overwrite of ${outFile } without corresponding element' );
66
+ Warnable originalElement = _fileElementMap[outFile];
67
+ Iterable <Warnable > referredFrom =
68
+ originalElement != null ? [originalElement] : null ;
69
+ element? .warn (PackageWarning .duplicateFile,
70
+ message: outFile, referredFrom: referredFrom);
71
+ }
72
+ }
73
+ _fileElementMap[outFile] = element;
74
+
75
+ var file = File (path.join (outputDir, outFile));
76
+ var parent = file.parent;
77
+ if (! parent.existsSync ()) {
78
+ parent.createSync (recursive: true );
79
+ }
80
+
81
+ if (content is String ) {
82
+ file.writeAsStringSync (content);
83
+ } else if (content is List <int >) {
84
+ file.writeAsBytesSync (content);
85
+ } else {
86
+ throw ArgumentError .value (
87
+ content, 'content' , '`content` must be `String` or `List<int>`.' );
88
+ }
89
+
90
+ writtenFiles.add (outFile);
91
+ logProgress (outFile);
92
+ }
93
+ }
94
+
47
95
/// Generates Dart documentation for all public Dart libraries in the given
48
96
/// directory.
49
97
class Dartdoc extends PackageBuilder {
50
- final List < Generator > generators ;
98
+ final Generator generator ;
51
99
final Set <String > writtenFiles = Set ();
52
100
Directory outputDir;
53
101
54
102
// Fires when the self checks make progress.
55
103
final StreamController <String > _onCheckProgress =
56
104
StreamController (sync : true );
57
105
58
- Dartdoc ._(DartdocOptionContext config, this .generators ) : super (config) {
106
+ Dartdoc ._(DartdocOptionContext config, this .generator ) : super (config) {
59
107
outputDir = Directory (config.output)..createSync (recursive: true );
60
- generators.forEach ((g) => g.onFileCreated.listen (logProgress));
61
108
}
62
109
63
110
/// An asynchronous factory method that builds Dartdoc's file writers
64
111
/// and returns a Dartdoc object with them.
65
112
static Future <Dartdoc > withDefaultGenerators (
66
113
DartdocGeneratorOptionContext config) async {
67
- List <Generator > generators = await initHtmlGenerators (config);
68
- return Dartdoc ._(config, generators);
114
+ return Dartdoc ._(config, await initHtmlGenerator (config));
69
115
}
70
116
71
117
/// An asynchronous factory method that builds
72
118
static Future <Dartdoc > withEmptyGenerator (DartdocOptionContext config) async {
73
- List <Generator > generators = await initEmptyGenerators (config);
74
- return Dartdoc ._(config, generators);
75
- }
76
-
77
- /// Basic synchronous factory that gives a stripped down Dartdoc that won't
78
- /// use generators. Useful for testing.
79
- factory Dartdoc .withoutGenerators (DartdocOptionContext config) {
80
- return Dartdoc ._(config, []);
119
+ return Dartdoc ._(config, await initEmptyGenerator (config));
81
120
}
82
121
83
122
Stream <String > get onCheckProgress => _onCheckProgress.stream;
@@ -94,19 +133,20 @@ class Dartdoc extends PackageBuilder {
94
133
double seconds;
95
134
packageGraph = await buildPackageGraph ();
96
135
seconds = _stopwatch.elapsedMilliseconds / 1000.0 ;
97
- logInfo (
98
- "Initialized dartdoc with ${packageGraph . libraries . length } librar${packageGraph . libraries . length == 1 ? 'y' : 'ies' } "
136
+ int libs = packageGraph.libraries.length;
137
+ logInfo ( "Initialized dartdoc with ${libs } librar${libs == 1 ? 'y' : 'ies' } "
99
138
"in ${seconds .toStringAsFixed (1 )} seconds" );
100
139
_stopwatch.reset ();
101
140
102
- if (generators.isNotEmpty) {
141
+ final generator = this .generator;
142
+ if (generator != null ) {
103
143
// Create the out directory.
104
144
if (! outputDir.existsSync ()) outputDir.createSync (recursive: true );
105
145
106
- for ( var generator in generators) {
107
- await generator.generate (packageGraph, outputDir.path );
108
- writtenFiles. addAll (generator.writtenFiles.keys. map (path.normalize));
109
- }
146
+ DartdocFileWriter writer = DartdocFileWriter (outputDir.path);
147
+ await generator.generate (packageGraph, writer );
148
+
149
+ writtenFiles. addAll (writer.writtenFiles);
110
150
if (config.validateLinks && writtenFiles.isNotEmpty) {
111
151
validateLinks (packageGraph, outputDir.path);
112
152
}
@@ -122,8 +162,8 @@ class Dartdoc extends PackageBuilder {
122
162
}
123
163
124
164
seconds = _stopwatch.elapsedMilliseconds / 1000.0 ;
125
- logInfo (
126
- "Documented ${packageGraph . localPublicLibraries . length } public librar${packageGraph . localPublicLibraries . length == 1 ? 'y' : 'ies' } "
165
+ libs = packageGraph.localPublicLibraries.length;
166
+ logInfo ( "Documented ${libs } public librar${libs == 1 ? 'y' : 'ies' } "
127
167
"in ${seconds .toStringAsFixed (1 )} seconds" );
128
168
return DartdocResults (config.topLevelPackageMeta, packageGraph, outputDir);
129
169
}
0 commit comments