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

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

Issue 237863002: pkg/docgen: add --indent-json option (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';
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 /// Docgen constructor initializes the link resolver for markdown parsing. 52 /// Docgen constructor initializes the link resolver for markdown parsing.
53 /// Also initializes the command line arguments. 53 /// Also initializes the command line arguments.
54 /// 54 ///
55 /// [packageRoot] is the packages directory of the directory being analyzed. 55 /// [packageRoot] is the packages directory of the directory being analyzed.
56 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will 56 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will
57 /// also be documented. 57 /// also be documented.
58 /// 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.
59 /// This option is useful when only the SDK libraries are needed. 59 /// This option is useful when only the SDK libraries are needed.
60 /// 60 ///
61 /// Returned Future completes with true if document generation is successful. 61 /// Returned Future completes with true if document generation is successful.
62 Future<bool> generateDocumentation(List<String> files, {String packageRoot, bool 62 Future<bool> generateDocumentation(List<String> files, {String packageRoot,
63 outputToYaml: true, bool includePrivate: false, bool includeSdk: false, bool 63 bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false,
64 parseSdk: false, String introFileName: '', out: 64 bool parseSdk: false, String introFileName: '',
65 DEFAULT_OUTPUT_DIRECTORY, List<String> excludeLibraries: const [], bool 65 out: DEFAULT_OUTPUT_DIRECTORY, List<String> excludeLibraries: const [], bool
66 includeDependentPackages: false, String startPage, String dartBinary, String 66 includeDependentPackages: false, String startPage, String dartBinary,
67 pubScript}) { 67 String pubScript, bool indentJSON: false}) {
68 _excluded = excludeLibraries; 68 _excluded = excludeLibraries;
69 _pubScript = pubScript; 69 _pubScript = pubScript;
70 _dartBinary = dartBinary; 70 _dartBinary = dartBinary;
71 71
72 logger.onRecord.listen((record) => print(record.message)); 72 logger.onRecord.listen((record) => print(record.message));
73 73
74 _ensureOutputDirectory(out); 74 _ensureOutputDirectory(out);
75 var updatedPackageRoot = _obtainPackageRoot(packageRoot, parseSdk, files); 75 var updatedPackageRoot = _obtainPackageRoot(packageRoot, parseSdk, files);
76 76
77 var requestedLibraries = _findLibrariesToDocument(files, 77 var requestedLibraries = _findLibrariesToDocument(files,
(...skipping 18 matching lines...) Expand all
96 new Map.fromIterables(availableLibraries.map((each) => each.uri), 96 new Map.fromIterables(availableLibraries.map((each) => each.uri),
97 availableLibraries); 97 availableLibraries);
98 var librariesToDocument = requestedLibraries 98 var librariesToDocument = requestedLibraries
99 .map((each) { 99 .map((each) {
100 return availableLibrariesByPath 100 return availableLibrariesByPath
101 .putIfAbsent(each, () => throw "Missing library $each"); 101 .putIfAbsent(each, () => throw "Missing library $each");
102 }).toList(); 102 }).toList();
103 librariesToDocument.addAll((includeSdk || parseSdk) ? sdkLibraries : []); 103 librariesToDocument.addAll((includeSdk || parseSdk) ? sdkLibraries : []);
104 librariesToDocument.removeWhere((x) => _excluded.contains( 104 librariesToDocument.removeWhere((x) => _excluded.contains(
105 dart2js_util.nameOf(x))); 105 dart2js_util.nameOf(x)));
106 _documentLibraries(librariesToDocument, includeSdk: includeSdk, 106 _documentLibraries(librariesToDocument, includeSdk, parseSdk, introFileName,
107 parseSdk: parseSdk, introFileName: introFileName, startPage: startPage); 107 startPage, indentJSON);
108 return true; 108 return true;
109 }); 109 });
110 } 110 }
111 111
112 112
113 /// 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
114 /// documentation of the libraries. 114 /// documentation of the libraries.
115 Future<MirrorSystem> getMirrorSystem(List<Uri> libraries, 115 Future<MirrorSystem> getMirrorSystem(List<Uri> libraries,
116 bool includePrivate, {String packageRoot, bool parseSdk: false}) { 116 bool includePrivate, {String packageRoot, bool parseSdk: false}) {
117 if (libraries.isEmpty) throw new StateError('No Libraries.'); 117 if (libraries.isEmpty) throw new StateError('No Libraries.');
118 118
119 includePrivateMembers = includePrivate; 119 includePrivateMembers = includePrivate;
120 120
121 // 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.
122 // 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
123 // 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
124 var root = rootDirectory; 124 var root = rootDirectory;
125 var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk'))); 125 var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk')));
126 if (!new Directory(sdkRoot).existsSync()) { 126 if (!new Directory(sdkRoot).existsSync()) {
127 sdkRoot = path.normalize(path.absolute(path.join(root, 'dart-sdk'))); 127 sdkRoot = path.normalize(path.absolute(path.join(root, 'dart-sdk')));
128 } 128 }
129 logger.info('SDK Root: ${sdkRoot}'); 129 logger.info('SDK Root: ${sdkRoot}');
130 return analyzeLibraries(libraries, sdkRoot, 130 return analyzeLibraries(libraries, sdkRoot,
131 packageRoot: packageRoot); 131 packageRoot: packageRoot);
132 } 132 }
133 133
134 /// Writes [text] to a file in the output directory. 134 /// Writes [text] to a file in the output directory.
135 void _writeToFile(String text, String filename) { 135 void _writeToFile(String text, String filename) {
136 if (text == null) return; 136 if (text == null) return;
137 Directory dir = new Directory(_outputDirectory); 137
kevmoo 2014/04/14 21:37:49 This was a whole mountain of silly.
Emily Fortuna 2014/04/14 23:40:33 oy vey. thank you.
138 if (!dir.existsSync()) { 138 var filePath = path.join(_outputDirectory, filename);
139 dir.createSync(); 139
140 } 140 var parentDir = new Directory(path.dirname(filePath));
141 if (path.split(filename).length > 1) { 141 if (!parentDir.existsSync()) parentDir.createSync(recursive: true);
142 var splitList = path.split(filename); 142
143 for (int i = 0; i < splitList.length; i++) { 143 new File(filePath)
144 var level = splitList[i]; 144 .writeAsStringSync(text, mode: FileMode.WRITE);
145 }
146 for (var level in path.split(filename)) {
147 var subdir = new Directory(path.join(_outputDirectory, path.dirname(
148 filename)));
149 if (!subdir.existsSync()) {
150 subdir.createSync();
151 }
152 }
153 }
154 File file = new File(path.join(_outputDirectory, filename));
155 file.writeAsStringSync(text, mode: FileMode.WRITE);
156 } 145 }
157 146
158 /// Resolve all the links in the introductory comments for a given library or 147 /// Resolve all the links in the introductory comments for a given library or
159 /// package as specified by [filename]. 148 /// package as specified by [filename].
160 String _readIntroductionFile(String fileName, bool includeSdk) { 149 String _readIntroductionFile(String fileName, bool includeSdk) {
161 var linkResolver = (name) => globalFixReference(name); 150 var linkResolver = (name) => globalFixReference(name);
162 var defaultText = includeSdk ? _DEFAULT_SDK_INTRODUCTION : ''; 151 var defaultText = includeSdk ? _DEFAULT_SDK_INTRODUCTION : '';
163 var introText = defaultText; 152 var introText = defaultText;
164 if (fileName.isNotEmpty) { 153 if (fileName.isNotEmpty) {
165 var introFile = new File(fileName); 154 var introFile = new File(fileName);
(...skipping 13 matching lines...) Expand all
179 return compare; 168 return compare;
180 } 169 }
181 170
182 if (a is Library) return -1; 171 if (a is Library) return -1;
183 if (b is Library) return 1; 172 if (b is Library) return 1;
184 173
185 return a.qualifiedName.compareTo(b.qualifiedName); 174 return a.qualifiedName.compareTo(b.qualifiedName);
186 } 175 }
187 176
188 /// Creates documentation for filtered libraries. 177 /// Creates documentation for filtered libraries.
189 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false, 178 void _documentLibraries(List<LibraryMirror> libs, bool includeSdk,
190 bool parseSdk: false, String introFileName: '', String startPage}) { 179 bool parseSdk, String introFileName, String startPage, bool indentJson) {
191 libs.forEach((lib) { 180 libs.forEach((lib) {
192 // Files belonging to the SDK have a uri that begins with 'dart:'. 181 // Files belonging to the SDK have a uri that begins with 'dart:'.
193 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { 182 if (includeSdk || !lib.uri.toString().startsWith('dart:')) {
194 generateLibrary(lib); 183 generateLibrary(lib);
195 } 184 }
196 }); 185 });
197 186
198 var filteredEntities = new SplayTreeSet<Indexable>(_indexableComparer); 187 var filteredEntities = new SplayTreeSet<Indexable>(_indexableComparer);
199 for (Map<String, Set<Indexable>> firstLevel in mirrorToDocgen.values) { 188 for (Map<String, Set<Indexable>> firstLevel in mirrorToDocgen.values) {
200 for (Set<Indexable> items in firstLevel.values) { 189 for (Set<Indexable> items in firstLevel.values) {
201 for (Indexable item in items) { 190 for (Indexable item in items) {
202 if (isFullChainVisible(item)) { 191 if (isFullChainVisible(item)) {
203 if (item is! Method || 192 if (item is! Method ||
204 (item is Method && item.methodInheritedFrom == null)) { 193 (item is Method && item.methodInheritedFrom == null)) {
205 filteredEntities.add(item); 194 filteredEntities.add(item);
206 } 195 }
207 } 196 }
208 } 197 }
209 } 198 }
210 } 199 }
211 200
212 // Outputs a JSON file with all libraries and their preview comments. 201 // Outputs a JSON file with all libraries and their preview comments.
213 // This will help the viewer know what libraries are available to read in. 202 // This will help the viewer know what libraries are available to read in.
214 Map<String, dynamic> libraryMap = { 203 Map<String, dynamic> libraryMap = {
215 'libraries': filteredEntities.where((e) => e is Library).map((e) => 204 'libraries': filteredEntities.where((e) => e is Library).map((e) =>
216 e.previewMap).toList(), 205 e.previewMap).toList(),
217 'introduction': _readIntroductionFile(introFileName, includeSdk), 206 'introduction': _readIntroductionFile(introFileName, includeSdk),
218 'filetype': 'json' 207 'filetype': 'json'
219 }; 208 };
220 _writeOutputFiles(libraryMap, filteredEntities, startPage); 209
210 var encoder = new JsonEncoder.withIndent(indentJson ? ' ' : null);
211
212 _writeOutputFiles(libraryMap, filteredEntities, startPage, encoder);
221 } 213 }
222 214
223 /// Output all of the libraries and classes into json files for consumption by a 215 /// Output all of the libraries and classes into json files for consumption by a
224 /// viewer. 216 /// viewer.
225 void _writeOutputFiles(Map<String, dynamic> libraryMap, Iterable<Indexable> 217 void _writeOutputFiles(Map<String, dynamic> libraryMap, Iterable<Indexable>
226 filteredEntities, String startPage) { 218 filteredEntities, String startPage, JsonEncoder encoder) {
227 if (startPage != null) libraryMap['start-page'] = startPage; 219 if (startPage != null) libraryMap['start-page'] = startPage;
228 220
229 _writeToFile(JSON.encode(libraryMap), 'library_list.json'); 221 _writeToFile(encoder.convert(libraryMap), 'library_list.json');
230 222
231 // Output libraries and classes to file after all information is generated. 223 // Output libraries and classes to file after all information is generated.
232 filteredEntities.where((e) => e is Class || e is Library).forEach((output) { 224 filteredEntities.where((e) => e is Class || e is Library).forEach((output) {
233 _writeIndexableToFile(output); 225 _writeIndexableToFile(output, encoder);
234 }); 226 });
235 227
236 // Outputs all the qualified names documented with their type. 228 // Outputs all the qualified names documented with their type.
237 // This will help generate search results. 229 // This will help generate search results.
238 var sortedEntities = filteredEntities.map((e) => 230 var sortedEntities = filteredEntities
239 '${e.qualifiedName} ${e.typeName}').toList()..sort(); 231 .map((e) => '${e.qualifiedName} ${e.typeName}')
232 .toList();
240 233
241 _writeToFile(sortedEntities.join('\n') + '\n', 'index.txt'); 234 sortedEntities.sort();
235
236 var buffer = new StringBuffer()
kevmoo 2014/04/14 21:37:49 Avoid creating a huge string, then another one jus
Emily Fortuna 2014/04/14 23:40:33 sgtm
237 ..writeAll(sortedEntities, '\n')
238 ..write('\n');
239
240 _writeToFile(buffer.toString(), 'index.txt');
241
242 var index = new SplayTreeMap.fromIterable(filteredEntities, 242 var index = new SplayTreeMap.fromIterable(filteredEntities,
243 key: (e) => e.qualifiedName, value: (e) => e.typeName); 243 key: (e) => e.qualifiedName, value: (e) => e.typeName);
244 244
245 _writeToFile(JSON.encode(index), 'index.json'); 245 _writeToFile(encoder.convert(index), 'index.json');
246 } 246 }
247 247
248 /// Helper method to serialize the given Indexable out to a file. 248 /// Helper method to serialize the given Indexable out to a file.
249 void _writeIndexableToFile(Indexable result) { 249 void _writeIndexableToFile(Indexable result, JsonEncoder encoder) {
250 var outputFile = result.fileName + '.json'; 250 var outputFile = result.fileName + '.json';
251 var output = JSON.encode(result.toMap()); 251 var output = encoder.convert(result.toMap());
252 _writeToFile(output, outputFile); 252 _writeToFile(output, outputFile);
253 } 253 }
254 254
255 /// 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
256 /// available on the file system. 256 /// available on the file system.
257 void _ensureOutputDirectory(String outputDirectory) { 257 void _ensureOutputDirectory(String outputDirectory) {
258 _outputDirectory = outputDirectory; 258 _outputDirectory = outputDirectory;
259 var dir = new Directory(_outputDirectory); 259 var dir = new Directory(_outputDirectory);
260 if (dir.existsSync()) dir.deleteSync(recursive: true); 260 if (dir.existsSync()) dir.deleteSync(recursive: true);
261 } 261 }
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 * [Samples](http://www.dartlang.org/samples/) 463 * [Samples](http://www.dartlang.org/samples/)
464 * [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)
465 465
466 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
467 [Dart project](https://code.google.com/p/dart/). 467 [Dart project](https://code.google.com/p/dart/).
468 If you'd like to contribute to this documentation, see 468 If you'd like to contribute to this documentation, see
469 [Contributing](https://code.google.com/p/dart/wiki/Contributing) 469 [Contributing](https://code.google.com/p/dart/wiki/Contributing)
470 and 470 and
471 [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).
472 """; 472 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698