Chromium Code Reviews| 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 * |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 | 46 |
| 47 /// Current member being documented to be used for comment links. | 47 /// Current member being documented to be used for comment links. |
| 48 MemberMirror _currentMember; | 48 MemberMirror _currentMember; |
| 49 | 49 |
| 50 /// Resolves reference links in doc comments. | 50 /// Resolves reference links in doc comments. |
| 51 markdown.Resolver linkResolver; | 51 markdown.Resolver linkResolver; |
| 52 | 52 |
| 53 /// Index of all the qualified names documented. | 53 /// Index of all the qualified names documented. |
| 54 Set<String> qualifiedNameIndex = new Set<String>(); | 54 Set<String> qualifiedNameIndex = new Set<String>(); |
| 55 | 55 |
| 56 /// Index of all the classes created. This is to ensure that no class is | |
| 57 /// created more than once. | |
| 58 Map<String, Class> classMap = new Map<String, Class>(); | |
| 59 | |
| 60 /// Index of all the libraries that needs to be outputted after all objects are | |
|
Alan Knight
2013/07/29 20:29:01
Nit. While contemporary dictionaries seem to consi
janicejl
2013/07/30 00:41:31
Done.
| |
| 61 /// created and updated. | |
| 62 Set<Library> libraries = new Set<Library>(); | |
| 63 | |
| 56 /** | 64 /** |
| 57 * Docgen constructor initializes the link resolver for markdown parsing. | 65 * Docgen constructor initializes the link resolver for markdown parsing. |
| 58 * Also initializes the command line arguments. | 66 * Also initializes the command line arguments. |
| 59 * | 67 * |
| 60 * [packageRoot] is the packages directory of the directory being analyzed. | 68 * [packageRoot] is the packages directory of the directory being analyzed. |
| 61 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will | 69 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will |
| 62 * also be documented. | 70 * also be documented. |
| 63 * If [parseSdk] is `true`, then all Dart SDK libraries will be documented. | 71 * If [parseSdk] is `true`, then all Dart SDK libraries will be documented. |
| 64 * This option is useful when only the SDK libraries are needed. | 72 * This option is useful when only the SDK libraries are needed. |
| 65 * | 73 * |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 // Currently, a string is thrown when it fails to create a mirror | 196 // Currently, a string is thrown when it fails to create a mirror |
| 189 // system, and it is not possible to use the stack trace. BUG(#11622) | 197 // system, and it is not possible to use the stack trace. BUG(#11622) |
| 190 // To avoid printing the stack trace. | 198 // To avoid printing the stack trace. |
| 191 exit(1); | 199 exit(1); |
| 192 }); | 200 }); |
| 193 } | 201 } |
| 194 | 202 |
| 195 /** | 203 /** |
| 196 * Creates documentation for filtered libraries. | 204 * Creates documentation for filtered libraries. |
| 197 */ | 205 */ |
| 198 void _documentLibraries(List<LibraryMirror> libraries, | 206 void _documentLibraries(List<LibraryMirror> libs, |
| 199 {bool includeSdk:false, bool includePrivate:false, bool | 207 {bool includeSdk:false, bool includePrivate:false, bool |
| 200 outputToYaml:true}) { | 208 outputToYaml:true}) { |
| 201 libraries.forEach((lib) { | 209 libs.forEach((lib) { |
| 202 // Files belonging to the SDK have a uri that begins with 'dart:'. | 210 // Files belonging to the SDK have a uri that begins with 'dart:'. |
| 203 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { | 211 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { |
| 204 var library = generateLibrary(lib, includePrivate: includePrivate); | 212 var library = generateLibrary(lib, includePrivate: includePrivate); |
| 205 _writeLibraryToFile(library, outputToYaml); | 213 libraries.add(library); |
| 206 } | 214 } |
| 207 }); | 215 }); |
| 216 // Output libraries to file after all information is generated. | |
| 217 libraries.forEach((lib) => _writeLibraryToFile(lib, outputToYaml)); | |
| 208 // Outputs a text file with a list of files available after creating all | 218 // Outputs a text file with a list of files available after creating all |
| 209 // the libraries. This will help the viewer know what files are available | 219 // the libraries. This will help the viewer know what files are available |
| 210 // to read in. | 220 // to read in. |
| 211 _writeToFile(listDir('docs').join('\n').replaceAll('docs/', ''), | 221 _writeToFile(listDir('docs').join('\n').replaceAll('docs/', ''), |
| 212 'library_list.txt'); | 222 'library_list.txt'); |
| 213 // Outputs all the qualified names documented. This will help generate search | 223 // Outputs all the qualified names documented. This will help generate search |
| 214 // results. | 224 // results. |
| 215 _writeToFile(qualifiedNameIndex.join('\n'), 'index.txt'); | 225 _writeToFile(qualifiedNameIndex.join('\n'), 'index.txt'); |
| 216 } | 226 } |
| 217 | 227 |
| 218 Library generateLibrary(dart2js.Dart2JsLibraryMirror library, | 228 Library generateLibrary(dart2js.Dart2JsLibraryMirror library, |
| 219 {bool includePrivate:false}) { | 229 {bool includePrivate:false}) { |
| 220 _currentLibrary = library; | 230 _currentLibrary = library; |
| 221 var result = new Library(library.qualifiedName, _getComment(library), | 231 var result = new Library(library.qualifiedName, _getComment(library), |
| 222 _getVariables(library.variables, includePrivate), | 232 _getVariables(library.variables, includePrivate), |
| 223 _getMethods(library.functions, includePrivate), | 233 _getMethods(library.functions, includePrivate), |
| 224 _getClasses(library.classes, includePrivate)); | 234 _getClasses(library.classes, includePrivate)); |
| 225 logger.fine('Generated library for ${result.name}'); | 235 logger.fine('Generated library for ${result.name}'); |
| 226 return result; | 236 return result; |
| 227 } | 237 } |
| 228 | 238 |
| 229 void _writeLibraryToFile(Library result, bool outputToYaml) { | 239 void _writeLibraryToFile(Library result, bool outputToYaml) { |
| 230 if (outputToYaml) { | 240 if (outputToYaml) { |
| 231 _writeToFile(getYamlString(result.toMap()), '${result.name}.yaml'); | 241 _writeToFile(getYamlString(result.toMap()), '${result.name}.yaml'); |
| 232 } else { | 242 } else { |
| 233 _writeToFile(stringify(result.toMap()), '${result.name}.json'); | 243 _writeToFile(stringify(result.toMap()), '${result.name}.json'); |
| 234 } | 244 } |
| 235 | |
| 236 } | 245 } |
| 237 | 246 |
| 238 /** | 247 /** |
| 239 * Returns a list of meta annotations assocated with a mirror. | 248 * Returns a list of meta annotations assocated with a mirror. |
| 240 */ | 249 */ |
| 241 List<String> _getAnnotations(DeclarationMirror mirror) { | 250 List<String> _getAnnotations(DeclarationMirror mirror) { |
| 242 var annotations = mirror.metadata.where((e) => | 251 var annotations = mirror.metadata.where((e) => |
| 243 e is dart2js.Dart2JsConstructedConstantMirror); | 252 e is dart2js.Dart2JsConstructedConstantMirror); |
| 244 return annotations.map((e) => e.type.qualifiedName).toList(); | 253 return annotations.map((e) => e.type.qualifiedName).toList(); |
| 245 } | 254 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 353 Map<String, Class> _getClasses(Map<String, ClassMirror> mirrorMap, | 362 Map<String, Class> _getClasses(Map<String, ClassMirror> mirrorMap, |
| 354 bool includePrivate) { | 363 bool includePrivate) { |
| 355 | 364 |
| 356 var abstractClasses = {}; | 365 var abstractClasses = {}; |
| 357 var classes = {}; | 366 var classes = {}; |
| 358 var typedefs = {}; | 367 var typedefs = {}; |
| 359 var errors = {}; | 368 var errors = {}; |
| 360 | 369 |
| 361 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { | 370 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { |
| 362 if (includePrivate || !mirror.isPrivate) { | 371 if (includePrivate || !mirror.isPrivate) { |
| 372 _currentClass = mirror; | |
| 363 var superclass = (mirror.superclass != null) ? | 373 var superclass = (mirror.superclass != null) ? |
| 364 mirror.superclass.qualifiedName : ''; | 374 mirror.superclass.qualifiedName : ''; |
| 365 var interfaces = | 375 var interfaces = |
| 366 mirror.superinterfaces.map((interface) => interface.qualifiedName); | 376 mirror.superinterfaces.map((interface) => interface.qualifiedName); |
| 367 var clazz = new Class(mirrorName, superclass, _getComment(mirror), | 377 var clazz = classMap[mirror.qualifiedName]; |
| 368 interfaces.toList(), _getVariables(mirror.variables, includePrivate), | 378 if (clazz == null) { |
|
Alan Knight
2013/07/29 20:29:01
This method is getting very long, and it looks lik
janicejl
2013/07/30 00:41:31
Done.
| |
| 369 _getMethods(mirror.methods, includePrivate), | 379 clazz = new Class(mirrorName, superclass, _getComment(mirror), |
| 370 _getAnnotations(mirror), _getGenerics(mirror), mirror.qualifiedName); | 380 interfaces.toList(), |
| 371 _currentClass = mirror; | 381 _getVariables(mirror.variables, includePrivate), |
| 382 _getMethods(mirror.methods, includePrivate), | |
| 383 _getAnnotations(mirror), | |
| 384 _getGenerics(mirror), mirror.qualifiedName); | |
| 385 classMap[mirror.qualifiedName] = clazz; | |
| 386 } | |
| 387 | |
| 388 // Adding inherited superclass variables and methods. | |
| 389 if (superclass != '') { | |
| 390 var superclazz = classMap[superclass]; | |
| 391 if (superclazz == null) { | |
| 392 var supersuperclass = (mirror.superclass.superclass != null) ? | |
| 393 mirror.superclass.superclass.qualifiedName : ''; | |
| 394 var superclassInterfaces = mirror.superclass.superinterfaces | |
| 395 .map((interface) => interface.qualifiedName); | |
| 396 superclazz = new Class(mirror.superclass.simpleName, supersuperclass, | |
| 397 _getComment(mirror.superclass), superclassInterfaces.toList(), | |
| 398 _getVariables(mirror.superclass.variables, includePrivate), | |
| 399 _getMethods(mirror.superclass.methods, includePrivate), | |
| 400 _getAnnotations(mirror.superclass), | |
| 401 _getGenerics(mirror.superclass), mirror.superclass.qualifiedName); | |
| 402 classMap[mirror.superclass.qualifiedName] = superclazz; | |
| 403 } | |
| 404 superclazz.subclasses.add(clazz.qualifiedName); | |
| 405 superclazz.methods.keys.forEach((key) { | |
| 406 if (key != 'constructors') { | |
|
Alan Knight
2013/07/29 20:29:01
This seems like it's crying out for an accessor li
janicejl
2013/07/30 00:41:31
Done.
| |
| 407 clazz.inheritedMethods[key].addAll(superclazz.methods[key]); | |
| 408 } | |
| 409 }); | |
| 410 } | |
| 411 | |
| 412 // Adding inherited interface variables and methods. | |
| 413 mirror.superinterfaces.forEach((interface) { | |
| 414 var interfaceClass = classMap[interface.qualifiedName]; | |
| 415 if (interfaceClass == null) { | |
| 416 var interfaceSuperClass = (interface.superclass != null) ? | |
| 417 interface.superclass.qualifiedName : ''; | |
| 418 var interfaceInterfaces = interface.superinterfaces | |
| 419 .map((i) => i.qualifiedName); | |
| 420 interfaceClass = new Class(interface.simpleName, | |
| 421 interfaceSuperClass, _getComment(interface), | |
| 422 interfaceInterfaces.toList(), | |
| 423 _getVariables(interface.variables, includePrivate), | |
| 424 _getMethods(interface.methods, includePrivate), | |
| 425 _getAnnotations(interface), _getGenerics(interface), | |
| 426 interface.qualifiedName); | |
| 427 classMap[interface.qualifiedName] = interfaceClass; | |
| 428 } | |
| 429 interfaceClass.subclasses.add(clazz.qualifiedName); | |
| 430 clazz.inheritedVariables.addAll(interfaceClass.variables); | |
| 431 interfaceClass.methods.keys.forEach((key) { | |
| 432 if (key != 'constructors') { | |
| 433 clazz.inheritedMethods[key].addAll(interfaceClass.methods[key]); | |
| 434 } | |
| 435 }); | |
| 436 }); | |
| 372 | 437 |
| 373 if (isError(mirror.qualifiedName)) { | 438 if (isError(mirror.qualifiedName)) { |
| 374 errors[mirrorName] = clazz; | 439 errors[mirrorName] = clazz; |
| 375 } else if (mirror.isTypedef) { | 440 } else if (mirror.isTypedef) { |
| 376 typedefs[mirrorName] = new Typedef(mirrorName, | 441 typedefs[mirrorName] = new Typedef(mirrorName, |
| 377 mirror.value.returnType.qualifiedName, _getComment(mirror), | 442 mirror.value.returnType.qualifiedName, _getComment(mirror), |
| 378 _getGenerics(mirror), _getParameters(mirror.value.parameters), | 443 _getGenerics(mirror), _getParameters(mirror.value.parameters), |
| 379 _getAnnotations(mirror), mirror.qualifiedName); | 444 _getAnnotations(mirror), mirror.qualifiedName); |
| 380 } else if (mirror.isAbstract) { | 445 } else if (mirror.isAbstract) { |
| 381 abstractClasses[mirrorName] = clazz; | 446 abstractClasses[mirrorName] = clazz; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 520 }; | 585 }; |
| 521 } | 586 } |
| 522 | 587 |
| 523 /** | 588 /** |
| 524 * A class containing contents of a Dart class. | 589 * A class containing contents of a Dart class. |
| 525 */ | 590 */ |
| 526 class Class extends Indexable { | 591 class Class extends Indexable { |
| 527 | 592 |
| 528 /// List of the names of interfaces that this class implements. | 593 /// List of the names of interfaces that this class implements. |
| 529 List<String> interfaces; | 594 List<String> interfaces; |
| 595 | |
| 596 /// Names of classes that extends or implements this class. | |
| 597 List<String> subclasses = []; | |
| 530 | 598 |
| 531 /// Top-level variables in the class. | 599 /// Top-level variables in the class. |
| 532 Map<String, Variable> variables; | 600 Map<String, Variable> variables; |
| 601 | |
| 602 /// Inherited variables in the class. | |
| 603 Map<String, Variable> inheritedVariables = {}; | |
| 533 | 604 |
| 534 /// Methods in the class. | 605 /// Methods in the class. |
| 535 Map<String, Map<String, Method>> methods; | 606 Map<String, Map<String, Method>> methods; |
| 536 | 607 |
| 608 /// Inherited methods in the class. | |
|
Alan Knight
2013/07/29 20:29:01
I'm not clear why methods in the class itself seem
| |
| 609 Map<String, Map<String, Method>> inheritedMethods = { | |
| 610 'setters': {}, | |
|
Alan Knight
2013/07/29 20:29:01
It seems like it might be nicer if this an object,
janicejl
2013/07/30 00:41:31
Done.
| |
| 611 'getters': {}, | |
| 612 'constructors': {}, | |
| 613 'operators': {}, | |
| 614 'methods': {} | |
| 615 }; | |
| 616 | |
| 537 /// Generic infomation about the class. | 617 /// Generic infomation about the class. |
| 538 Map<String, Generic> generics; | 618 Map<String, Generic> generics; |
| 539 | 619 |
| 540 String superclass; | 620 String superclass; |
| 541 | 621 |
| 542 /// List of the meta annotations on the class. | 622 /// List of the meta annotations on the class. |
| 543 List<String> annotations; | 623 List<String> annotations; |
| 544 | 624 |
| 545 Class(String name, this.superclass, String comment, this.interfaces, | 625 Class(String name, this.superclass, String comment, this.interfaces, |
| 546 this.variables, this.methods, this.annotations, this.generics, | 626 this.variables, this.methods, this.annotations, this.generics, |
| 547 String qualifiedName) : super(name, comment, qualifiedName) {} | 627 String qualifiedName) : super(name, comment, qualifiedName) {} |
| 548 | 628 |
| 549 /// Generates a map describing the [Class] object. | 629 /// Generates a map describing the [Class] object. |
| 550 Map toMap() => { | 630 Map toMap() => { |
| 551 'name': name, | 631 'name': name, |
|
Alan Knight
2013/07/29 20:29:01
I think literal maps can be indented just two.
janicejl
2013/07/30 00:41:31
Done.
| |
| 552 'qualifiedname': qualifiedName, | 632 'qualifiedname': qualifiedName, |
| 553 'comment': comment, | 633 'comment': comment, |
| 554 'superclass': superclass, | 634 'superclass': superclass, |
| 555 'implements': new List.from(interfaces), | 635 'implements': new List.from(interfaces), |
| 636 'subclass': new List.from(subclasses), | |
| 556 'variables': recurseMap(variables), | 637 'variables': recurseMap(variables), |
| 638 'inheritedvariables': recurseMap(inheritedVariables), | |
| 557 'methods': recurseMap(methods), | 639 'methods': recurseMap(methods), |
| 640 'inheritedmethods': recurseMap(inheritedMethods), | |
| 558 'annotations': new List.from(annotations), | 641 'annotations': new List.from(annotations), |
| 559 'generics': recurseMap(generics) | 642 'generics': recurseMap(generics) |
| 560 }; | 643 }; |
| 561 } | 644 } |
| 562 | 645 |
| 563 class Typedef extends Indexable { | 646 class Typedef extends Indexable { |
| 564 String returnType; | 647 String returnType; |
| 565 | 648 |
| 566 Map<String, Parameter> parameters; | 649 Map<String, Parameter> parameters; |
| 567 | 650 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 730 String outer; | 813 String outer; |
| 731 List<Type> inner; | 814 List<Type> inner; |
| 732 | 815 |
| 733 Type(this.outer, this.inner); | 816 Type(this.outer, this.inner); |
| 734 | 817 |
| 735 Map toMap() => { | 818 Map toMap() => { |
| 736 'outer': outer, | 819 'outer': outer, |
| 737 'inner': new List.from(inner.map((e) => e.toMap())) | 820 'inner': new List.from(inner.map((e) => e.toMap())) |
| 738 }; | 821 }; |
| 739 } | 822 } |
| OLD | NEW |