| 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 |
| 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 libraries.forEach((lib) => _writeLibraryToFile(lib, outputToYaml)); |
| 208 // Outputs a text file with a list of files available after creating all | 217 // 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 | 218 // the libraries. This will help the viewer know what files are available |
| 210 // to read in. | 219 // to read in. |
| 211 _writeToFile(listDir('docs').join('\n').replaceAll('docs/', ''), | 220 _writeToFile(listDir('docs').join('\n').replaceAll('docs/', ''), |
| 212 'library_list.txt'); | 221 'library_list.txt'); |
| 213 // Outputs all the qualified names documented. This will help generate search | 222 // Outputs all the qualified names documented. This will help generate search |
| 214 // results. | 223 // results. |
| 215 _writeToFile(qualifiedNameIndex.join('\n'), 'index.txt'); | 224 _writeToFile(qualifiedNameIndex.join('\n'), 'index.txt'); |
| 216 } | 225 } |
| 217 | 226 |
| 218 Library generateLibrary(dart2js.Dart2JsLibraryMirror library, | 227 Library generateLibrary(dart2js.Dart2JsLibraryMirror library, |
| 219 {bool includePrivate:false}) { | 228 {bool includePrivate:false}) { |
| 220 _currentLibrary = library; | 229 _currentLibrary = library; |
| 221 var result = new Library(library.qualifiedName, _getComment(library), | 230 var result = new Library(library.qualifiedName, _getComment(library), |
| 222 _getVariables(library.variables, includePrivate), | 231 _getVariables(library.variables, includePrivate), |
| 223 _getMethods(library.functions, includePrivate), | 232 _getMethods(library.functions, includePrivate), |
| 224 _getClasses(library.classes, includePrivate)); | 233 _getClasses(library.classes, includePrivate)); |
| 225 logger.fine('Generated library for ${result.name}'); | 234 logger.fine('Generated library for ${result.name}'); |
| 226 return result; | 235 return result; |
| 227 } | 236 } |
| 228 | 237 |
| 229 void _writeLibraryToFile(Library result, bool outputToYaml) { | 238 void _writeLibraryToFile(Library result, bool outputToYaml) { |
| 230 if (outputToYaml) { | 239 if (outputToYaml) { |
| 231 _writeToFile(getYamlString(result.toMap()), '${result.name}.yaml'); | 240 _writeToFile(getYamlString(result.toMap()), '${result.name}.yaml'); |
| 232 } else { | 241 } else { |
| 233 _writeToFile(stringify(result.toMap()), '${result.name}.json'); | 242 _writeToFile(stringify(result.toMap()), '${result.name}.json'); |
| 234 } | 243 } |
| 235 | |
| 236 } | 244 } |
| 237 | 245 |
| 238 /** | 246 /** |
| 239 * Returns a list of meta annotations assocated with a mirror. | 247 * Returns a list of meta annotations assocated with a mirror. |
| 240 */ | 248 */ |
| 241 List<String> _getAnnotations(DeclarationMirror mirror) { | 249 List<String> _getAnnotations(DeclarationMirror mirror) { |
| 242 var annotations = mirror.metadata.where((e) => | 250 var annotations = mirror.metadata.where((e) => |
| 243 e is dart2js.Dart2JsConstructedConstantMirror); | 251 e is dart2js.Dart2JsConstructedConstantMirror); |
| 244 return annotations.map((e) => e.type.qualifiedName).toList(); | 252 return annotations.map((e) => e.type.qualifiedName).toList(); |
| 245 } | 253 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 Map<String, Class> _getClasses(Map<String, ClassMirror> mirrorMap, | 361 Map<String, Class> _getClasses(Map<String, ClassMirror> mirrorMap, |
| 354 bool includePrivate) { | 362 bool includePrivate) { |
| 355 | 363 |
| 356 var abstractClasses = {}; | 364 var abstractClasses = {}; |
| 357 var classes = {}; | 365 var classes = {}; |
| 358 var typedefs = {}; | 366 var typedefs = {}; |
| 359 var errors = {}; | 367 var errors = {}; |
| 360 | 368 |
| 361 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { | 369 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { |
| 362 if (includePrivate || !mirror.isPrivate) { | 370 if (includePrivate || !mirror.isPrivate) { |
| 371 _currentClass = mirror; |
| 363 var superclass = (mirror.superclass != null) ? | 372 var superclass = (mirror.superclass != null) ? |
| 364 mirror.superclass.qualifiedName : ''; | 373 mirror.superclass.qualifiedName : ''; |
| 365 var interfaces = | 374 var interfaces = |
| 366 mirror.superinterfaces.map((interface) => interface.qualifiedName); | 375 mirror.superinterfaces.map((interface) => interface.qualifiedName); |
| 367 var clazz = new Class(mirrorName, superclass, _getComment(mirror), | 376 var clazz = classMap[mirror.qualifiedName]; |
| 368 interfaces.toList(), _getVariables(mirror.variables, includePrivate), | 377 if (clazz == null) { |
| 369 _getMethods(mirror.methods, includePrivate), | 378 clazz = new Class(mirrorName, superclass, _getComment(mirror), |
| 370 _getAnnotations(mirror), _getGenerics(mirror), mirror.qualifiedName); | 379 interfaces.toList(), |
| 371 _currentClass = mirror; | 380 _getVariables(mirror.variables, includePrivate), |
| 381 _getMethods(mirror.methods, includePrivate), |
| 382 _getAnnotations(mirror), |
| 383 _getGenerics(mirror), mirror.qualifiedName); |
| 384 classMap[mirror.qualifiedName] = clazz; |
| 385 } |
| 386 |
| 387 // Adding inherited superclass variables and methods. |
| 388 if (superclass != '') { |
| 389 var superclazz = classMap[superclass]; |
| 390 if (superclazz == null) { |
| 391 var supersuperclass = (mirror.superclass.superclass != null) ? |
| 392 mirror.superclass.superclass.qualifiedName : ''; |
| 393 var superclassInterfaces = mirror.superclass.superinterfaces |
| 394 .map((interface) => interface.qualifiedName); |
| 395 superclazz = new Class(mirror.superclass.simpleName, supersuperclass, |
| 396 _getComment(mirror.superclass), superclassInterfaces.toList(), |
| 397 _getVariables(mirror.superclass.variables, includePrivate), |
| 398 _getMethods(mirror.superclass.methods, includePrivate), |
| 399 _getAnnotations(mirror.superclass), |
| 400 _getGenerics(mirror.superclass), mirror.superclass.qualifiedName); |
| 401 classMap[mirror.superclass.qualifiedName] = superclazz; |
| 402 } |
| 403 superclazz.subclasses.add(clazz.qualifiedName); |
| 404 superclazz.methods.keys.forEach((key) { |
| 405 if (key != 'constructors') { |
| 406 clazz.inheritedMethods[key].addAll(superclazz.methods[key]); |
| 407 } |
| 408 }); |
| 409 } |
| 410 |
| 411 // Adding inherited interface variables and methods. |
| 412 mirror.superinterfaces.forEach((interface) { |
| 413 var interfaceClass = classMap[interface.qualifiedName]; |
| 414 if (interfaceClass == null) { |
| 415 var interfaceSuperClass = (interface.superclass != null) ? |
| 416 interface.superclass.qualifiedName : ''; |
| 417 var interfaceInterfaces = interface.superinterfaces |
| 418 .map((i) => i.qualifiedName); |
| 419 interfaceClass = new Class(interface.simpleName, |
| 420 interfaceSuperClass, _getComment(interface), |
| 421 interfaceInterfaces.toList(), |
| 422 _getVariables(interface.variables, includePrivate), |
| 423 _getMethods(interface.methods, includePrivate), |
| 424 _getAnnotations(interface), _getGenerics(interface), |
| 425 interface.qualifiedName); |
| 426 classMap[interface.qualifiedName] = interfaceClass; |
| 427 } |
| 428 interfaceClass.subclasses.add(clazz.qualifiedName); |
| 429 clazz.inheritedVariables.addAll(interfaceClass.variables); |
| 430 interfaceClass.methods.keys.forEach((key) { |
| 431 if (key != 'constructors') { |
| 432 clazz.inheritedMethods[key].addAll(interfaceClass.methods[key]); |
| 433 } |
| 434 }); |
| 435 }); |
| 372 | 436 |
| 373 if (isError(mirror.qualifiedName)) { | 437 if (isError(mirror.qualifiedName)) { |
| 374 errors[mirrorName] = clazz; | 438 errors[mirrorName] = clazz; |
| 375 } else if (mirror.isTypedef) { | 439 } else if (mirror.isTypedef) { |
| 376 typedefs[mirrorName] = new Typedef(mirrorName, | 440 typedefs[mirrorName] = new Typedef(mirrorName, |
| 377 mirror.value.returnType.qualifiedName, _getComment(mirror), | 441 mirror.value.returnType.qualifiedName, _getComment(mirror), |
| 378 _getGenerics(mirror), _getParameters(mirror.value.parameters), | 442 _getGenerics(mirror), _getParameters(mirror.value.parameters), |
| 379 _getAnnotations(mirror), mirror.qualifiedName); | 443 _getAnnotations(mirror), mirror.qualifiedName); |
| 380 } else if (mirror.isAbstract) { | 444 } else if (mirror.isAbstract) { |
| 381 abstractClasses[mirrorName] = clazz; | 445 abstractClasses[mirrorName] = clazz; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 }; | 584 }; |
| 521 } | 585 } |
| 522 | 586 |
| 523 /** | 587 /** |
| 524 * A class containing contents of a Dart class. | 588 * A class containing contents of a Dart class. |
| 525 */ | 589 */ |
| 526 class Class extends Indexable { | 590 class Class extends Indexable { |
| 527 | 591 |
| 528 /// List of the names of interfaces that this class implements. | 592 /// List of the names of interfaces that this class implements. |
| 529 List<String> interfaces; | 593 List<String> interfaces; |
| 594 |
| 595 List<String> subclasses = []; |
| 530 | 596 |
| 531 /// Top-level variables in the class. | 597 /// Top-level variables in the class. |
| 532 Map<String, Variable> variables; | 598 Map<String, Variable> variables; |
| 599 |
| 600 /// Inherited variables in the class. |
| 601 Map<String, Variable> inheritedVariables = {}; |
| 533 | 602 |
| 534 /// Methods in the class. | 603 /// Methods in the class. |
| 535 Map<String, Map<String, Method>> methods; | 604 Map<String, Map<String, Method>> methods; |
| 536 | 605 |
| 606 /// Inherited methods in the class. |
| 607 Map<String, Map<String, Method>> inheritedMethods = { |
| 608 'setters': {}, |
| 609 'getters': {}, |
| 610 'constructors': {}, |
| 611 'operators': {}, |
| 612 'methods': {} |
| 613 }; |
| 614 |
| 537 /// Generic infomation about the class. | 615 /// Generic infomation about the class. |
| 538 Map<String, Generic> generics; | 616 Map<String, Generic> generics; |
| 539 | 617 |
| 540 String superclass; | 618 String superclass; |
| 541 | 619 |
| 542 /// List of the meta annotations on the class. | 620 /// List of the meta annotations on the class. |
| 543 List<String> annotations; | 621 List<String> annotations; |
| 544 | 622 |
| 545 Class(String name, this.superclass, String comment, this.interfaces, | 623 Class(String name, this.superclass, String comment, this.interfaces, |
| 546 this.variables, this.methods, this.annotations, this.generics, | 624 this.variables, this.methods, this.annotations, this.generics, |
| 547 String qualifiedName) : super(name, comment, qualifiedName) {} | 625 String qualifiedName) : super(name, comment, qualifiedName) {} |
| 548 | 626 |
| 549 /// Generates a map describing the [Class] object. | 627 /// Generates a map describing the [Class] object. |
| 550 Map toMap() => { | 628 Map toMap() => { |
| 551 'name': name, | 629 'name': name, |
| 552 'qualifiedname': qualifiedName, | 630 'qualifiedname': qualifiedName, |
| 553 'comment': comment, | 631 'comment': comment, |
| 554 'superclass': superclass, | 632 'superclass': superclass, |
| 555 'implements': new List.from(interfaces), | 633 'implements': new List.from(interfaces), |
| 634 'subclass': new List.from(subclasses), |
| 556 'variables': recurseMap(variables), | 635 'variables': recurseMap(variables), |
| 636 'inheritedvariables': recurseMap(inheritedVariables), |
| 557 'methods': recurseMap(methods), | 637 'methods': recurseMap(methods), |
| 638 'inheritedmethods': recurseMap(inheritedMethods), |
| 558 'annotations': new List.from(annotations), | 639 'annotations': new List.from(annotations), |
| 559 'generics': recurseMap(generics) | 640 'generics': recurseMap(generics) |
| 560 }; | 641 }; |
| 561 } | 642 } |
| 562 | 643 |
| 563 class Typedef extends Indexable { | 644 class Typedef extends Indexable { |
| 564 String returnType; | 645 String returnType; |
| 565 | 646 |
| 566 Map<String, Parameter> parameters; | 647 Map<String, Parameter> parameters; |
| 567 | 648 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 String outer; | 811 String outer; |
| 731 List<Type> inner; | 812 List<Type> inner; |
| 732 | 813 |
| 733 Type(this.outer, this.inner); | 814 Type(this.outer, this.inner); |
| 734 | 815 |
| 735 Map toMap() => { | 816 Map toMap() => { |
| 736 'outer': outer, | 817 'outer': outer, |
| 737 'inner': new List.from(inner.map((e) => e.toMap())) | 818 'inner': new List.from(inner.map((e) => e.toMap())) |
| 738 }; | 819 }; |
| 739 } | 820 } |
| OLD | NEW |