Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: pkg/docgen/lib/src/generator.dart

Issue 237443004: pkg/docgen: removed yaml and append output support (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library docgen.generator; 5 library docgen.generator;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:convert'; 9 import 'dart:convert';
10 import 'dart:io'; 10 import 'dart:io';
11 11
12 import 'package:markdown/markdown.dart' as markdown; 12 import 'package:markdown/markdown.dart' as markdown;
13 import 'package:path/path.dart' as path; 13 import 'package:path/path.dart' as path;
14 14
15 import '../../../../sdk/lib/_internal/compiler/compiler.dart' as api; 15 import '../../../../sdk/lib/_internal/compiler/compiler.dart' as api;
16 import '../../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; 16 import '../../../../sdk/lib/_internal/compiler/implementation/filenames.dart';
17 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/analyze.da rt' 17 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/analyze.da rt'
18 as dart2js; 18 as dart2js;
19 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mi rrors.dart' 19 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mi rrors.dart'
20 as dart2js_mirrors; 20 as dart2js_mirrors;
21 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_ut il.dart' 21 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_ut il.dart'
22 as dart2js_util; 22 as dart2js_util;
23 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/source_mir rors.dart'; 23 import '../../../../sdk/lib/_internal/compiler/implementation/mirrors/source_mir rors.dart';
24 import '../../../../sdk/lib/_internal/compiler/implementation/source_file_provid er.dart'; 24 import '../../../../sdk/lib/_internal/compiler/implementation/source_file_provid er.dart';
25 import '../../../../sdk/lib/_internal/libraries.dart'; 25 import '../../../../sdk/lib/_internal/libraries.dart';
26 26
27 import 'dart2yaml.dart';
28 import 'io.dart'; 27 import 'io.dart';
29 import 'library_helpers.dart'; 28 import 'library_helpers.dart';
30 import 'models.dart'; 29 import 'models.dart';
31 import 'package_helpers.dart' show packageNameFor, rootDirectory; 30 import 'package_helpers.dart' show packageNameFor, rootDirectory;
32 31
33 const String DEFAULT_OUTPUT_DIRECTORY = 'docs'; 32 const String DEFAULT_OUTPUT_DIRECTORY = 'docs';
34 33
35 /// The directory where the output docs are generated. 34 /// The directory where the output docs are generated.
36 String get outputDirectory => _outputDirectory; 35 String get outputDirectory => _outputDirectory;
37 String _outputDirectory; 36 String _outputDirectory;
(...skipping 17 matching lines...) Expand all
55 /// 54 ///
56 /// [packageRoot] is the packages directory of the directory being analyzed. 55 /// [packageRoot] is the packages directory of the directory being analyzed.
57 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will 56 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will
58 /// also be documented. 57 /// also be documented.
59 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented. 58 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented.
60 /// This option is useful when only the SDK libraries are needed. 59 /// This option is useful when only the SDK libraries are needed.
61 /// 60 ///
62 /// Returned Future completes with true if document generation is successful. 61 /// Returned Future completes with true if document generation is successful.
63 Future<bool> generateDocumentation(List<String> files, {String packageRoot, bool 62 Future<bool> generateDocumentation(List<String> files, {String packageRoot, bool
64 outputToYaml: true, bool includePrivate: false, bool includeSdk: false, bool 63 outputToYaml: true, bool includePrivate: false, bool includeSdk: false, bool
65 parseSdk: false, bool append: false, String introFileName: '', out: 64 parseSdk: false, String introFileName: '', out:
66 DEFAULT_OUTPUT_DIRECTORY, List<String> excludeLibraries: const [], bool 65 DEFAULT_OUTPUT_DIRECTORY, List<String> excludeLibraries: const [], bool
67 includeDependentPackages: false, String startPage, String dartBinary, String 66 includeDependentPackages: false, String startPage, String dartBinary, String
68 pubScript}) { 67 pubScript}) {
69 _excluded = excludeLibraries; 68 _excluded = excludeLibraries;
70 _pubScript = pubScript; 69 _pubScript = pubScript;
71 _dartBinary = dartBinary; 70 _dartBinary = dartBinary;
72 71
73 logger.onRecord.listen((record) => print(record.message)); 72 logger.onRecord.listen((record) => print(record.message));
74 73
75 _ensureOutputDirectory(out, append); 74 _ensureOutputDirectory(out);
76 var updatedPackageRoot = _obtainPackageRoot(packageRoot, parseSdk, files); 75 var updatedPackageRoot = _obtainPackageRoot(packageRoot, parseSdk, files);
77 76
78 var requestedLibraries = _findLibrariesToDocument(files, 77 var requestedLibraries = _findLibrariesToDocument(files,
79 includeDependentPackages); 78 includeDependentPackages);
80 79
81 var allLibraries = []..addAll(requestedLibraries); 80 var allLibraries = []..addAll(requestedLibraries);
82 if (includeSdk) { 81 if (includeSdk) {
83 allLibraries.addAll(_listSdk()); 82 allLibraries.addAll(_listSdk());
84 } 83 }
85 84
(...skipping 12 matching lines...) Expand all
98 availableLibraries); 97 availableLibraries);
99 var librariesToDocument = requestedLibraries 98 var librariesToDocument = requestedLibraries
100 .map((each) { 99 .map((each) {
101 return availableLibrariesByPath 100 return availableLibrariesByPath
102 .putIfAbsent(each, () => throw "Missing library $each"); 101 .putIfAbsent(each, () => throw "Missing library $each");
103 }).toList(); 102 }).toList();
104 librariesToDocument.addAll((includeSdk || parseSdk) ? sdkLibraries : []); 103 librariesToDocument.addAll((includeSdk || parseSdk) ? sdkLibraries : []);
105 librariesToDocument.removeWhere((x) => _excluded.contains( 104 librariesToDocument.removeWhere((x) => _excluded.contains(
106 dart2js_util.nameOf(x))); 105 dart2js_util.nameOf(x)));
107 _documentLibraries(librariesToDocument, includeSdk: includeSdk, 106 _documentLibraries(librariesToDocument, includeSdk: includeSdk,
108 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk, 107 parseSdk: parseSdk, introFileName: introFileName, startPage: startPage);
109 introFileName: introFileName, startPage: startPage);
110 return true; 108 return true;
111 }); 109 });
112 } 110 }
113 111
114 112
115 /// Analyzes set of libraries by getting a mirror system and triggers the 113 /// Analyzes set of libraries by getting a mirror system and triggers the
116 /// documentation of the libraries. 114 /// documentation of the libraries.
117 Future<MirrorSystem> getMirrorSystem(List<Uri> libraries, 115 Future<MirrorSystem> getMirrorSystem(List<Uri> libraries,
118 bool includePrivate, {String packageRoot, bool parseSdk: false}) { 116 bool includePrivate, {String packageRoot, bool parseSdk: false}) {
119 if (libraries.isEmpty) throw new StateError('No Libraries.'); 117 if (libraries.isEmpty) throw new StateError('No Libraries.');
120 118
121 includePrivateMembers = includePrivate; 119 includePrivateMembers = includePrivate;
122 120
123 // Finds the root of SDK library based off the location of docgen. 121 // Finds the root of SDK library based off the location of docgen.
124 // We have two different places to look, depending if we're in a development 122 // We have two different places to look, depending if we're in a development
125 // repo or in a built SDK, either sdk or dart-sdk respectively 123 // repo or in a built SDK, either sdk or dart-sdk respectively
126 var root = rootDirectory; 124 var root = rootDirectory;
127 var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk'))); 125 var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk')));
128 if (!new Directory(sdkRoot).existsSync()) { 126 if (!new Directory(sdkRoot).existsSync()) {
129 sdkRoot = path.normalize(path.absolute(path.join(root, 'dart-sdk'))); 127 sdkRoot = path.normalize(path.absolute(path.join(root, 'dart-sdk')));
130 } 128 }
131 logger.info('SDK Root: ${sdkRoot}'); 129 logger.info('SDK Root: ${sdkRoot}');
132 return analyzeLibraries(libraries, sdkRoot, 130 return analyzeLibraries(libraries, sdkRoot,
133 packageRoot: packageRoot); 131 packageRoot: packageRoot);
134 } 132 }
135 133
136 /// Writes [text] to a file in the output directory. 134 /// Writes [text] to a file in the output directory.
137 void _writeToFile(String text, String filename, {bool append: false}) { 135 void _writeToFile(String text, String filename) {
138 if (text == null) return; 136 if (text == null) return;
139 Directory dir = new Directory(_outputDirectory); 137 Directory dir = new Directory(_outputDirectory);
140 if (!dir.existsSync()) { 138 if (!dir.existsSync()) {
141 dir.createSync(); 139 dir.createSync();
142 } 140 }
143 if (path.split(filename).length > 1) { 141 if (path.split(filename).length > 1) {
144 var splitList = path.split(filename); 142 var splitList = path.split(filename);
145 for (int i = 0; i < splitList.length; i++) { 143 for (int i = 0; i < splitList.length; i++) {
146 var level = splitList[i]; 144 var level = splitList[i];
147 } 145 }
148 for (var level in path.split(filename)) { 146 for (var level in path.split(filename)) {
149 var subdir = new Directory(path.join(_outputDirectory, path.dirname( 147 var subdir = new Directory(path.join(_outputDirectory, path.dirname(
150 filename))); 148 filename)));
151 if (!subdir.existsSync()) { 149 if (!subdir.existsSync()) {
152 subdir.createSync(); 150 subdir.createSync();
153 } 151 }
154 } 152 }
155 } 153 }
156 File file = new File(path.join(_outputDirectory, filename)); 154 File file = new File(path.join(_outputDirectory, filename));
157 file.writeAsStringSync(text, mode: append ? FileMode.APPEND : FileMode.WRITE); 155 file.writeAsStringSync(text, mode: FileMode.WRITE);
158 } 156 }
159 157
160 /// Resolve all the links in the introductory comments for a given library or 158 /// Resolve all the links in the introductory comments for a given library or
161 /// package as specified by [filename]. 159 /// package as specified by [filename].
162 String _readIntroductionFile(String fileName, bool includeSdk) { 160 String _readIntroductionFile(String fileName, bool includeSdk) {
163 var linkResolver = (name) => globalFixReference(name); 161 var linkResolver = (name) => globalFixReference(name);
164 var defaultText = includeSdk ? _DEFAULT_SDK_INTRODUCTION : ''; 162 var defaultText = includeSdk ? _DEFAULT_SDK_INTRODUCTION : '';
165 var introText = defaultText; 163 var introText = defaultText;
166 if (fileName.isNotEmpty) { 164 if (fileName.isNotEmpty) {
167 var introFile = new File(fileName); 165 var introFile = new File(fileName);
(...skipping 13 matching lines...) Expand all
181 return compare; 179 return compare;
182 } 180 }
183 181
184 if (a is Library) return -1; 182 if (a is Library) return -1;
185 if (b is Library) return 1; 183 if (b is Library) return 1;
186 184
187 return a.qualifiedName.compareTo(b.qualifiedName); 185 return a.qualifiedName.compareTo(b.qualifiedName);
188 } 186 }
189 187
190 /// Creates documentation for filtered libraries. 188 /// Creates documentation for filtered libraries.
191 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false, bool 189 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false,
192 outputToYaml: true, bool append: false, bool parseSdk: false, String 190 bool parseSdk: false, String introFileName: '', String startPage}) {
193 introFileName: '', String startPage}) {
194 libs.forEach((lib) { 191 libs.forEach((lib) {
195 // Files belonging to the SDK have a uri that begins with 'dart:'. 192 // Files belonging to the SDK have a uri that begins with 'dart:'.
196 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { 193 if (includeSdk || !lib.uri.toString().startsWith('dart:')) {
197 generateLibrary(lib); 194 generateLibrary(lib);
198 } 195 }
199 }); 196 });
200 197
201 var filteredEntities = new SplayTreeSet<Indexable>(_indexableComparer); 198 var filteredEntities = new SplayTreeSet<Indexable>(_indexableComparer);
202 for (Map<String, Set<Indexable>> firstLevel in mirrorToDocgen.values) { 199 for (Map<String, Set<Indexable>> firstLevel in mirrorToDocgen.values) {
203 for (Set<Indexable> items in firstLevel.values) { 200 for (Set<Indexable> items in firstLevel.values) {
204 for (Indexable item in items) { 201 for (Indexable item in items) {
205 if (isFullChainVisible(item)) { 202 if (isFullChainVisible(item)) {
206 if (item is! Method || 203 if (item is! Method ||
207 (item is Method && item.methodInheritedFrom == null)) { 204 (item is Method && item.methodInheritedFrom == null)) {
208 filteredEntities.add(item); 205 filteredEntities.add(item);
209 } 206 }
210 } 207 }
211 } 208 }
212 } 209 }
213 } 210 }
214 211
215 // Outputs a JSON file with all libraries and their preview comments. 212 // Outputs a JSON file with all libraries and their preview comments.
216 // This will help the viewer know what libraries are available to read in. 213 // This will help the viewer know what libraries are available to read in.
217 Map<String, dynamic> libraryMap; 214 Map<String, dynamic> libraryMap = {
218
219 if (append) {
220 var docsDir = listDir(_outputDirectory);
221 if (!docsDir.contains('$_outputDirectory/library_list.json')) {
222 throw new StateError('No library_list.json');
223 }
224 libraryMap = JSON.decode(new File('$_outputDirectory/library_list.json'
225 ).readAsStringSync());
226 libraryMap['libraries'].addAll(filteredEntities.where((e) => e is Library
227 ).map((e) => e.previewMap));
228 var intro = libraryMap['introduction'];
229 var spacing = intro.isEmpty ? '' : '<br/><br/>';
230 libraryMap['introduction'] =
231 "$intro$spacing${_readIntroductionFile(introFileName, includeSdk)}";
232 outputToYaml = libraryMap['filetype'] == 'yaml';
233 } else {
234 libraryMap = {
235 'libraries': filteredEntities.where((e) => e is Library).map((e) => 215 'libraries': filteredEntities.where((e) => e is Library).map((e) =>
236 e.previewMap).toList(), 216 e.previewMap).toList(),
237 'introduction': _readIntroductionFile(introFileName, includeSdk), 217 'introduction': _readIntroductionFile(introFileName, includeSdk),
238 'filetype': outputToYaml ? 'yaml' : 'json' 218 'filetype': 'json'
239 }; 219 };
240 } 220 _writeOutputFiles(libraryMap, filteredEntities, startPage);
241 _writeOutputFiles(libraryMap, filteredEntities, outputToYaml, append,
242 startPage);
243 } 221 }
244 222
245 /// Output all of the libraries and classes into json or yaml files for 223 /// Output all of the libraries and classes into json files for consumption by a
246 /// consumption by a viewer. 224 /// viewer.
247 void _writeOutputFiles(Map<String, dynamic> libraryMap, Iterable<Indexable> 225 void _writeOutputFiles(Map<String, dynamic> libraryMap, Iterable<Indexable>
248 filteredEntities, bool outputToYaml, bool append, String startPage) { 226 filteredEntities, String startPage) {
249 if (startPage != null) libraryMap['start-page'] = startPage; 227 if (startPage != null) libraryMap['start-page'] = startPage;
250 228
251 _writeToFile(JSON.encode(libraryMap), 'library_list.json'); 229 _writeToFile(JSON.encode(libraryMap), 'library_list.json');
252 230
253 // Output libraries and classes to file after all information is generated. 231 // Output libraries and classes to file after all information is generated.
254 filteredEntities.where((e) => e is Class || e is Library).forEach((output) { 232 filteredEntities.where((e) => e is Class || e is Library).forEach((output) {
255 _writeIndexableToFile(output, outputToYaml); 233 _writeIndexableToFile(output);
256 }); 234 });
257 235
258 // Outputs all the qualified names documented with their type. 236 // Outputs all the qualified names documented with their type.
259 // This will help generate search results. 237 // This will help generate search results.
260 var sortedEntities = filteredEntities.map((e) => 238 var sortedEntities = filteredEntities.map((e) =>
261 '${e.qualifiedName} ${e.typeName}').toList()..sort(); 239 '${e.qualifiedName} ${e.typeName}').toList()..sort();
262 240
263 _writeToFile(sortedEntities.join('\n') + '\n', 'index.txt', append: append); 241 _writeToFile(sortedEntities.join('\n') + '\n', 'index.txt');
264 var index = new SplayTreeMap.fromIterable(filteredEntities, 242 var index = new SplayTreeMap.fromIterable(filteredEntities,
265 key: (e) => e.qualifiedName, value: (e) => e.typeName); 243 key: (e) => e.qualifiedName, value: (e) => e.typeName);
266 244
267 if (append) {
268 var previousIndex = JSON.decode(new File('$_outputDirectory/index.json'
269 ).readAsStringSync());
270 index.addAll(previousIndex);
271 }
272 _writeToFile(JSON.encode(index), 'index.json'); 245 _writeToFile(JSON.encode(index), 'index.json');
273 } 246 }
274 247
275 /// Helper method to serialize the given Indexable out to a file. 248 /// Helper method to serialize the given Indexable out to a file.
276 void _writeIndexableToFile(Indexable result, bool outputToYaml) { 249 void _writeIndexableToFile(Indexable result) {
277 var outputFile = result.fileName; 250 var outputFile = result.fileName + '.json';
278 var output; 251 var output = JSON.encode(result.toMap());
279 if (outputToYaml) {
280 output = getYamlString(result.toMap());
281 outputFile = outputFile + '.yaml';
282 } else {
283 output = JSON.encode(result.toMap());
284 outputFile = outputFile + '.json';
285 }
286 _writeToFile(output, outputFile); 252 _writeToFile(output, outputFile);
287 } 253 }
288 254
289 /// Set the location of the ouput directory, and ensure that the location is 255 /// Set the location of the ouput directory, and ensure that the location is
290 /// available on the file system. 256 /// available on the file system.
291 void _ensureOutputDirectory(String outputDirectory, bool append) { 257 void _ensureOutputDirectory(String outputDirectory) {
292 _outputDirectory = outputDirectory; 258 _outputDirectory = outputDirectory;
293 if (!append) { 259 var dir = new Directory(_outputDirectory);
294 var dir = new Directory(_outputDirectory); 260 if (dir.existsSync()) dir.deleteSync(recursive: true);
295 if (dir.existsSync()) dir.deleteSync(recursive: true);
296 }
297 } 261 }
298 262
299 /// Analyzes set of libraries and provides a mirror system which can be used 263 /// Analyzes set of libraries and provides a mirror system which can be used
300 /// for static inspection of the source code. 264 /// for static inspection of the source code.
301 Future<MirrorSystem> analyzeLibraries(List<Uri> libraries, String 265 Future<MirrorSystem> analyzeLibraries(List<Uri> libraries, String
302 libraryRoot, {String packageRoot}) { 266 libraryRoot, {String packageRoot}) {
303 SourceFileProvider provider = new CompilerSourceFileProvider(); 267 SourceFileProvider provider = new CompilerSourceFileProvider();
304 api.DiagnosticHandler diagnosticHandler = (new FormattingDiagnosticHandler( 268 api.DiagnosticHandler diagnosticHandler = (new FormattingDiagnosticHandler(
305 provider) 269 provider)
306 ..showHints = false 270 ..showHints = false
(...skipping 12 matching lines...) Expand all
319 // system, and it is not possible to use the stack trace. BUG(#11622) 283 // system, and it is not possible to use the stack trace. BUG(#11622)
320 // To avoid printing the stack trace. 284 // To avoid printing the stack trace.
321 exit(1); 285 exit(1);
322 }); 286 });
323 } 287 }
324 288
325 /// For this run of docgen, determine the packageRoot value. 289 /// For this run of docgen, determine the packageRoot value.
326 /// 290 ///
327 /// If packageRoot is not explicitly passed, we examine the files we're 291 /// If packageRoot is not explicitly passed, we examine the files we're
328 /// documenting to attempt to find a package root. 292 /// documenting to attempt to find a package root.
329 String _obtainPackageRoot(String packageRoot, bool parseSdk, List<String> files) 293 String _obtainPackageRoot(String packageRoot, bool parseSdk,
330 { 294 List<String> files) {
331 if (packageRoot == null && !parseSdk) { 295 if (packageRoot == null && !parseSdk) {
332 var type = FileSystemEntity.typeSync(files.first); 296 var type = FileSystemEntity.typeSync(files.first);
333 if (type == FileSystemEntityType.DIRECTORY) { 297 if (type == FileSystemEntityType.DIRECTORY) {
334 var files2 = listDir(files.first, recursive: true); 298 var files2 = listDir(files.first, recursive: true);
335 // Return '' means that there was no pubspec.yaml and therefor no p 299 // Return '' means that there was no pubspec.yaml and therefor no p
336 // ackageRoot. 300 // ackageRoot.
337 packageRoot = files2.firstWhere((f) => f.endsWith( 301 packageRoot = files2.firstWhere((f) => f.endsWith(
338 '${path.separator}pubspec.yaml'), orElse: () => ''); 302 '${path.separator}pubspec.yaml'), orElse: () => '');
339 if (packageRoot != '') { 303 if (packageRoot != '') {
340 packageRoot = path.join(path.dirname(packageRoot), 'packages'); 304 packageRoot = path.join(path.dirname(packageRoot), 'packages');
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 * [Samples](http://www.dartlang.org/samples/) 463 * [Samples](http://www.dartlang.org/samples/)
500 * [A Tour of the Dart Libraries](http://www.dartlang.org/docs/dart-up-and-runn ing/contents/ch03.html) 464 * [A Tour of the Dart Libraries](http://www.dartlang.org/docs/dart-up-and-runn ing/contents/ch03.html)
501 465
502 This API reference is automatically generated from the source code in the 466 This API reference is automatically generated from the source code in the
503 [Dart project](https://code.google.com/p/dart/). 467 [Dart project](https://code.google.com/p/dart/).
504 If you'd like to contribute to this documentation, see 468 If you'd like to contribute to this documentation, see
505 [Contributing](https://code.google.com/p/dart/wiki/Contributing) 469 [Contributing](https://code.google.com/p/dart/wiki/Contributing)
506 and 470 and
507 [Writing API Documentation](https://code.google.com/p/dart/wiki/WritingApiDocume ntation). 471 [Writing API Documentation](https://code.google.com/p/dart/wiki/WritingApiDocume ntation).
508 """; 472 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698