Skip to content

Commit 104176e

Browse files
committed
Merge branch 'master' of github.com:dart-lang/dartdoc into 0.15.0-release
2 parents b2e3e28 + ece0eea commit 104176e

File tree

301 files changed

+5154
-306
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

301 files changed

+5154
-306
lines changed

analysis_options.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ analyzer:
22
strong-mode: true
33
language:
44
enableGenericMethods: true
5+
enableSuperMixins: true
56
exclude:
67
- 'doc/**'
78
- 'lib/templates/*.html'

lib/src/html/html_generator.dart

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ library dartdoc.html_generator;
77
import 'dart:async' show Future, StreamController, Stream;
88
import 'dart:io' show File;
99

10+
import 'package:path/path.dart' as p;
11+
1012
import '../generator.dart';
1113
import '../model.dart';
1214
import 'html_generator_instance.dart';
15+
import 'template_data.dart';
1316
import 'templates.dart';
1417

1518
typedef String Renderer(String input);
@@ -44,7 +47,7 @@ class HtmlGenerator extends Generator {
4447
Stream<File> get onFileCreated => _onFileCreated.stream;
4548

4649
@override
47-
Set<String> get writtenFiles => _instance.writtenFiles;
50+
final Set<String> writtenFiles = new Set<String>();
4851

4952
static Future<HtmlGenerator> create(
5053
{HtmlGeneratorOptions options,
@@ -66,22 +69,61 @@ class HtmlGenerator extends Generator {
6669

6770
/// Actually write out the documentation for [package].
6871
/// Stores the HtmlGeneratorInstance so we can access it in [writtenFiles].
69-
Future generate(Package package, String outputDirectoryPath) {
72+
Future generate(Package package, String outputDirectoryPath) async {
7073
assert(_instance == null);
71-
_instance = new HtmlGeneratorInstance(
72-
_options, _templates, package, outputDirectoryPath, _onFileCreated);
73-
return _instance.generate();
74+
75+
var enabled = true;
76+
void write(String filePath, Object content, {bool allowOverwrite}) {
77+
allowOverwrite ??= false;
78+
if (!enabled) {
79+
throw new StateError('`write` was called after `generate` completed.');
80+
}
81+
// If you see this assert, we're probably being called to build non-canonical
82+
// docs somehow. Check data.self.isCanonical and callers for bugs.
83+
assert(allowOverwrite || !writtenFiles.contains(filePath));
84+
85+
var file = new File(p.join(outputDirectoryPath, filePath));
86+
var parent = file.parent;
87+
if (!parent.existsSync()) {
88+
parent.createSync(recursive: true);
89+
}
90+
91+
if (content is String) {
92+
file.writeAsStringSync(content);
93+
} else if (content is List<int>) {
94+
file.writeAsBytesSync(content);
95+
} else {
96+
throw new ArgumentError.value(
97+
content, 'content', '`content` must be `String` or `List<int>`.');
98+
}
99+
_onFileCreated.add(file);
100+
writtenFiles.add(filePath);
101+
}
102+
103+
try {
104+
_instance =
105+
new HtmlGeneratorInstance(_options, _templates, package, write);
106+
await _instance.generate();
107+
} finally {
108+
enabled = false;
109+
}
74110
}
75111
}
76112

77-
class HtmlGeneratorOptions {
113+
class HtmlGeneratorOptions implements HtmlOptions {
78114
final String url;
79-
final String relCanonicalPrefix;
80115
final String faviconPath;
81-
final String toolVersion;
82-
final bool useCategories;
83116
final bool prettyIndexJson;
84117

118+
@override
119+
final bool useCategories;
120+
121+
@override
122+
final String relCanonicalPrefix;
123+
124+
@override
125+
final String toolVersion;
126+
85127
HtmlGeneratorOptions(
86128
{this.url,
87129
this.relCanonicalPrefix,

lib/src/html/html_generator_instance.dart

Lines changed: 30 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
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;
66
import 'dart:convert' show JsonEncoder;
7-
import 'dart:io' show Directory, File;
7+
import 'dart:io' show File;
88

99
import 'package:collection/collection.dart' show compareNatural;
1010
import 'package:dartdoc/src/model_utils.dart';
@@ -19,29 +19,17 @@ import 'resources.g.dart' as resources;
1919
import 'template_data.dart';
2020
import 'templates.dart';
2121

22-
class HtmlGeneratorInstance implements HtmlOptions {
22+
typedef void FileWriter(String path, Object content, {bool allowOverwrite});
23+
24+
class HtmlGeneratorInstance {
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-
30-
@override
31-
String get relCanonicalPrefix => _options.relCanonicalPrefix;
32-
33-
@override
34-
String get toolVersion => _options.toolVersion;
35-
36-
String get _faviconPath => _options.faviconPath;
37-
bool get _useCategories => _options.useCategories;
29+
final FileWriter _writer;
3830

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);
31+
HtmlGeneratorInstance(
32+
this._options, this._templates, this._package, this._writer);
4533

4634
Future generate() async {
4735
if (_package != null) {
@@ -50,13 +38,11 @@ class HtmlGeneratorInstance implements HtmlOptions {
5038
}
5139

5240
await _copyResources();
53-
if (_faviconPath != null) {
54-
var bytes = new File(_faviconPath).readAsBytesSync();
41+
if (_options.faviconPath != null) {
42+
var bytes = new File(_options.faviconPath).readAsBytesSync();
5543
// Allow overwrite of favicon.
56-
String filename =
57-
path.join(_outputDirectoryPath, 'static-assets', 'favicon.png');
58-
writtenFiles.remove(filename);
59-
_writeFile(filename, bytes);
44+
_writer(path.join('static-assets', 'favicon.png'), bytes,
45+
allowOverwrite: true);
6046
}
6147
}
6248

@@ -95,7 +81,7 @@ class HtmlGeneratorInstance implements HtmlOptions {
9581
});
9682

9783
String json = encoder.convert(indexItems);
98-
_writeFile(path.join(_outputDirectoryPath, 'index.json'), '${json}\n');
84+
_writer(path.join('index.json'), '${json}\n');
9985
}
10086

10187
void _generateDocs() {
@@ -178,7 +164,7 @@ class HtmlGeneratorInstance implements HtmlOptions {
178164
}
179165

180166
void generatePackage() {
181-
TemplateData data = new PackageTemplateData(this, _package, _useCategories);
167+
TemplateData data = new PackageTemplateData(_options, _package);
182168
logInfo('documenting ${_package.name}');
183169

184170
_build('index.html', _templates.indexTemplate, data);
@@ -190,35 +176,35 @@ class HtmlGeneratorInstance implements HtmlOptions {
190176
if (!lib.isAnonymous && !lib.hasDocumentation) {
191177
package.warnOnElement(lib, PackageWarning.noLibraryLevelDocs);
192178
}
193-
TemplateData data =
194-
new LibraryTemplateData(this, package, lib, _useCategories);
179+
TemplateData data = new LibraryTemplateData(_options, package, lib);
195180

196181
_build(path.join(lib.dirName, '${lib.fileName}'),
197182
_templates.libraryTemplate, data);
198183
}
199184

200185
void generateClass(Package package, Library lib, Class clazz) {
201-
TemplateData data = new ClassTemplateData(this, package, lib, clazz);
186+
TemplateData data = new ClassTemplateData(_options, package, lib, clazz);
202187
_build(path.joinAll(clazz.href.split('/')), _templates.classTemplate, data);
203188
}
204189

205190
void generateConstructor(
206191
Package package, Library lib, Class clazz, Constructor constructor) {
207192
TemplateData data =
208-
new ConstructorTemplateData(this, package, lib, clazz, constructor);
193+
new ConstructorTemplateData(_options, package, lib, clazz, constructor);
209194

210195
_build(path.joinAll(constructor.href.split('/')),
211196
_templates.constructorTemplate, data);
212197
}
213198

214199
void generateEnum(Package package, Library lib, Enum eNum) {
215-
TemplateData data = new EnumTemplateData(this, package, lib, eNum);
200+
TemplateData data = new EnumTemplateData(_options, package, lib, eNum);
216201

217202
_build(path.joinAll(eNum.href.split('/')), _templates.enumTemplate, data);
218203
}
219204

220205
void generateFunction(Package package, Library lib, ModelFunction function) {
221-
TemplateData data = new FunctionTemplateData(this, package, lib, function);
206+
TemplateData data =
207+
new FunctionTemplateData(_options, package, lib, function);
222208

223209
_build(path.joinAll(function.href.split('/')), _templates.functionTemplate,
224210
data);
@@ -227,7 +213,7 @@ class HtmlGeneratorInstance implements HtmlOptions {
227213
void generateMethod(
228214
Package package, Library lib, Class clazz, Method method) {
229215
TemplateData data =
230-
new MethodTemplateData(this, package, lib, clazz, method);
216+
new MethodTemplateData(_options, package, lib, clazz, method);
231217

232218
_build(
233219
path.joinAll(method.href.split('/')), _templates.methodTemplate, data);
@@ -236,7 +222,7 @@ class HtmlGeneratorInstance implements HtmlOptions {
236222
void generateConstant(
237223
Package package, Library lib, Class clazz, Field property) {
238224
TemplateData data =
239-
new ConstantTemplateData(this, package, lib, clazz, property);
225+
new ConstantTemplateData(_options, package, lib, clazz, property);
240226

241227
_build(path.joinAll(property.href.split('/')), _templates.constantTemplate,
242228
data);
@@ -245,7 +231,7 @@ class HtmlGeneratorInstance implements HtmlOptions {
245231
void generateProperty(
246232
Package package, Library lib, Class clazz, Field property) {
247233
TemplateData data =
248-
new PropertyTemplateData(this, package, lib, clazz, property);
234+
new PropertyTemplateData(_options, package, lib, clazz, property);
249235

250236
_build(path.joinAll(property.href.split('/')), _templates.propertyTemplate,
251237
data);
@@ -254,7 +240,7 @@ class HtmlGeneratorInstance implements HtmlOptions {
254240
void generateTopLevelProperty(
255241
Package package, Library lib, TopLevelVariable property) {
256242
TemplateData data =
257-
new TopLevelPropertyTemplateData(this, package, lib, property);
243+
new TopLevelPropertyTemplateData(_options, package, lib, property);
258244

259245
_build(path.joinAll(property.href.split('/')),
260246
_templates.topLevelPropertyTemplate, data);
@@ -263,14 +249,15 @@ class HtmlGeneratorInstance implements HtmlOptions {
263249
void generateTopLevelConstant(
264250
Package package, Library lib, TopLevelVariable property) {
265251
TemplateData data =
266-
new TopLevelConstTemplateData(this, package, lib, property);
252+
new TopLevelConstTemplateData(_options, package, lib, property);
267253

268254
_build(path.joinAll(property.href.split('/')),
269255
_templates.topLevelConstantTemplate, data);
270256
}
271257

272258
void generateTypeDef(Package package, Library lib, Typedef typeDef) {
273-
TemplateData data = new TypedefTemplateData(this, package, lib, typeDef);
259+
TemplateData data =
260+
new TypedefTemplateData(_options, package, lib, typeDef);
274261

275262
_build(path.joinAll(typeDef.href.split('/')), _templates.typeDefTemplate,
276263
data);
@@ -285,44 +272,16 @@ class HtmlGeneratorInstance implements HtmlOptions {
285272
'encountered $resourcePath');
286273
}
287274
String destFileName = resourcePath.substring(prefix.length);
288-
_writeFile(path.join(_outputDirectoryPath, 'static-assets', destFileName),
275+
_writer(path.join('static-assets', destFileName),
289276
await loader.loadAsBytes(resourcePath));
290277
}
291278
}
292279

293280
void _build(String filename, TemplateRenderer template, TemplateData data) {
294-
String fullName = path.join(_outputDirectoryPath, filename);
295-
296281
String content = template(data,
297282
assumeNullNonExistingProperty: false, errorOnMissingProperty: true);
298283

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);
284+
_writer(filename, content);
285+
if (data.self is ModelElement) _documentedElements.add(data.self);
327286
}
328287
}

0 commit comments

Comments
 (0)