OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 /** | 5 /** |
6 * **docgen** is a tool for creating machine readable representations of Dart | 6 * **docgen** is a tool for creating machine readable representations of Dart |
7 * code metadata, including: classes, members, comments and annotations. | 7 * code metadata, including: classes, members, comments and annotations. |
8 * | 8 * |
9 * docgen is run on a `.dart` file or a directory containing `.dart` files. | 9 * docgen is run on a `.dart` file or a directory containing `.dart` files. |
10 * | 10 * |
11 * $ dart docgen.dart [OPTIONS] [FILE/DIR] | 11 * $ dart docgen.dart [OPTIONS] [FILE/DIR] |
12 * | 12 * |
13 * This creates files called `docs/<library_name>.yaml` in your current | 13 * This creates files called `docs/<library_name>.yaml` in your current |
14 * working directory. | 14 * working directory. |
15 */ | 15 */ |
16 library docgen; | 16 library docgen; |
17 | 17 |
| 18 import 'dart:convert'; |
18 import 'dart:io'; | 19 import 'dart:io'; |
19 import 'dart:json'; | |
20 import 'dart:async'; | 20 import 'dart:async'; |
21 | 21 |
22 import 'package:logging/logging.dart'; | 22 import 'package:logging/logging.dart'; |
23 import 'package:markdown/markdown.dart' as markdown; | 23 import 'package:markdown/markdown.dart' as markdown; |
24 import 'package:path/path.dart' as path; | 24 import 'package:path/path.dart' as path; |
25 | 25 |
26 import 'dart2yaml.dart'; | 26 import 'dart2yaml.dart'; |
27 import 'src/io.dart'; | 27 import 'src/io.dart'; |
28 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; | 28 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; |
29 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; | 29 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 var filteredEntities = entityMap.values.where(_isVisible); | 246 var filteredEntities = entityMap.values.where(_isVisible); |
247 | 247 |
248 // Outputs a JSON file with all libraries and their preview comments. | 248 // Outputs a JSON file with all libraries and their preview comments. |
249 // This will help the viewer know what libraries are available to read in. | 249 // This will help the viewer know what libraries are available to read in. |
250 var libraryMap; | 250 var libraryMap; |
251 if (append) { | 251 if (append) { |
252 var docsDir = listDir('docs'); | 252 var docsDir = listDir('docs'); |
253 if (!docsDir.contains('docs/library_list.json')) { | 253 if (!docsDir.contains('docs/library_list.json')) { |
254 throw new StateError('No library_list.json'); | 254 throw new StateError('No library_list.json'); |
255 } | 255 } |
256 libraryMap = parse(new File('docs/library_list.json').readAsStringSync()); | 256 libraryMap = |
| 257 JSON.decode(new File('docs/library_list.json').readAsStringSync()); |
257 libraryMap['libraries'].addAll(filteredEntities | 258 libraryMap['libraries'].addAll(filteredEntities |
258 .where((e) => e is Library) | 259 .where((e) => e is Library) |
259 .map((e) => e.previewMap)); | 260 .map((e) => e.previewMap)); |
260 if (introduction.isNotEmpty) { | 261 if (introduction.isNotEmpty) { |
261 var intro = libraryMap['introduction']; | 262 var intro = libraryMap['introduction']; |
262 if (intro.isNotEmpty) intro += '<br/><br/>'; | 263 if (intro.isNotEmpty) intro += '<br/><br/>'; |
263 intro += markdown.markdownToHtml( | 264 intro += markdown.markdownToHtml( |
264 new File(introduction).readAsStringSync(), | 265 new File(introduction).readAsStringSync(), |
265 linkResolver: linkResolver, inlineSyntaxes: markdownSyntaxes); | 266 linkResolver: linkResolver, inlineSyntaxes: markdownSyntaxes); |
266 libraryMap['introduction'] = intro; | 267 libraryMap['introduction'] = intro; |
267 } | 268 } |
268 outputToYaml = libraryMap['filetype'] == 'yaml'; | 269 outputToYaml = libraryMap['filetype'] == 'yaml'; |
269 } else { | 270 } else { |
270 libraryMap = { | 271 libraryMap = { |
271 'libraries' : filteredEntities.where((e) => | 272 'libraries' : filteredEntities.where((e) => |
272 e is Library).map((e) => e.previewMap).toList(), | 273 e is Library).map((e) => e.previewMap).toList(), |
273 'introduction' : introduction == '' ? | 274 'introduction' : introduction == '' ? |
274 '' : markdown.markdownToHtml(new File(introduction) | 275 '' : markdown.markdownToHtml(new File(introduction) |
275 .readAsStringSync(), linkResolver: linkResolver, | 276 .readAsStringSync(), linkResolver: linkResolver, |
276 inlineSyntaxes: markdownSyntaxes), | 277 inlineSyntaxes: markdownSyntaxes), |
277 'filetype' : outputToYaml ? 'yaml' : 'json' | 278 'filetype' : outputToYaml ? 'yaml' : 'json' |
278 }; | 279 }; |
279 } | 280 } |
280 _writeToFile(stringify(libraryMap), 'library_list.json'); | 281 _writeToFile(JSON.encode(libraryMap), 'library_list.json'); |
281 // Output libraries and classes to file after all information is generated. | 282 // Output libraries and classes to file after all information is generated. |
282 filteredEntities.where((e) => e is Class || e is Library).forEach((output) { | 283 filteredEntities.where((e) => e is Class || e is Library).forEach((output) { |
283 _writeIndexableToFile(output, outputToYaml); | 284 _writeIndexableToFile(output, outputToYaml); |
284 }); | 285 }); |
285 // Outputs all the qualified names documented with their type. | 286 // Outputs all the qualified names documented with their type. |
286 // This will help generate search results. | 287 // This will help generate search results. |
287 _writeToFile(filteredEntities.map((e) => | 288 _writeToFile(filteredEntities.map((e) => |
288 '${e.qualifiedName} ${e.typeName}').join('\n'), | 289 '${e.qualifiedName} ${e.typeName}').join('\n'), |
289 'index.txt', append: append); | 290 'index.txt', append: append); |
290 } | 291 } |
291 | 292 |
292 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { | 293 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { |
293 _currentLibrary = library; | 294 _currentLibrary = library; |
294 var result = new Library(library.qualifiedName, _commentToHtml(library), | 295 var result = new Library(library.qualifiedName, _commentToHtml(library), |
295 _variables(library.variables), | 296 _variables(library.variables), |
296 _methods(library.functions), | 297 _methods(library.functions), |
297 _classes(library.classes), _isHidden(library)); | 298 _classes(library.classes), _isHidden(library)); |
298 logger.fine('Generated library for ${result.name}'); | 299 logger.fine('Generated library for ${result.name}'); |
299 return result; | 300 return result; |
300 } | 301 } |
301 | 302 |
302 void _writeIndexableToFile(Indexable result, bool outputToYaml) { | 303 void _writeIndexableToFile(Indexable result, bool outputToYaml) { |
303 if (outputToYaml) { | 304 if (outputToYaml) { |
304 _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml'); | 305 _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml'); |
305 } else { | 306 } else { |
306 _writeToFile(stringify(result.toMap()), '${result.qualifiedName}.json'); | 307 _writeToFile(JSON.encode(result.toMap()), '${result.qualifiedName}.json'); |
307 } | 308 } |
308 } | 309 } |
309 | 310 |
310 /** | 311 /** |
311 * Returns true if a library name starts with an underscore, and false | 312 * Returns true if a library name starts with an underscore, and false |
312 * otherwise. | 313 * otherwise. |
313 * | 314 * |
314 * An example that starts with _ is _js_helper. | 315 * An example that starts with _ is _js_helper. |
315 * An example that contains ._ is dart._collection.dev | 316 * An example that contains ._ is dart._collection.dev |
316 */ | 317 */ |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 | 393 |
393 /** | 394 /** |
394 * Generates MDN comments from database.json. | 395 * Generates MDN comments from database.json. |
395 */ | 396 */ |
396 void _mdnComment(Indexable item) { | 397 void _mdnComment(Indexable item) { |
397 //Check if MDN is loaded. | 398 //Check if MDN is loaded. |
398 if (_mdn == null) { | 399 if (_mdn == null) { |
399 // Reading in MDN related json file. | 400 // Reading in MDN related json file. |
400 var mdnDir = path.join(path.dirname(path.dirname(path.dirname(path.dirname( | 401 var mdnDir = path.join(path.dirname(path.dirname(path.dirname(path.dirname( |
401 path.absolute(new Options().script))))), 'utils', 'apidoc', 'mdn'); | 402 path.absolute(new Options().script))))), 'utils', 'apidoc', 'mdn'); |
402 _mdn = parse(new File(path.join(mdnDir, 'database.json')) | 403 _mdn = JSON.decode(new File(path.join(mdnDir, 'database.json')) |
403 .readAsStringSync()); | 404 .readAsStringSync()); |
404 } | 405 } |
405 if (item.comment.isNotEmpty) return; | 406 if (item.comment.isNotEmpty) return; |
406 var domAnnotation = item.annotations.firstWhere( | 407 var domAnnotation = item.annotations.firstWhere( |
407 (e) => e.qualifiedName == 'metadata.DomName', orElse: () => null); | 408 (e) => e.qualifiedName == 'metadata.DomName', orElse: () => null); |
408 if (domAnnotation == null) return; | 409 if (domAnnotation == null) return; |
409 var domName = domAnnotation.parameters.single; | 410 var domName = domAnnotation.parameters.single; |
410 var parts = domName.split('.'); | 411 var parts = domName.split('.'); |
411 if (parts.length == 2) item.comment = _mdnMemberComment(parts[0], parts[1]); | 412 if (parts.length == 2) item.comment = _mdnMemberComment(parts[0], parts[1]); |
412 if (parts.length == 1) item.comment = _mdnTypeComment(parts[0]); | 413 if (parts.length == 1) item.comment = _mdnTypeComment(parts[0]); |
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1172 String qualifiedName; | 1173 String qualifiedName; |
1173 List<String> parameters; | 1174 List<String> parameters; |
1174 | 1175 |
1175 Annotation(this.qualifiedName, this.parameters); | 1176 Annotation(this.qualifiedName, this.parameters); |
1176 | 1177 |
1177 Map toMap() => { | 1178 Map toMap() => { |
1178 'name': qualifiedName, | 1179 'name': qualifiedName, |
1179 'parameters': parameters | 1180 'parameters': parameters |
1180 }; | 1181 }; |
1181 } | 1182 } |
OLD | NEW |