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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 58 /// Resolves reference links in doc comments. | 58 /// Resolves reference links in doc comments. |
| 59 markdown.Resolver linkResolver; | 59 markdown.Resolver linkResolver; |
| 60 | 60 |
| 61 /// Index of all indexable items. This also ensures that no class is | 61 /// Index of all indexable items. This also ensures that no class is |
| 62 /// created more than once. | 62 /// created more than once. |
| 63 Map<String, Indexable> entityMap = new Map<String, Indexable>(); | 63 Map<String, Indexable> entityMap = new Map<String, Indexable>(); |
| 64 | 64 |
| 65 /// This is set from the command line arguments flag --include-private | 65 /// This is set from the command line arguments flag --include-private |
| 66 bool _includePrivate = false; | 66 bool _includePrivate = false; |
| 67 | 67 |
| 68 /// Map of all the comments for dom elements from MDN. | |
| 69 Map _mdn; | |
| 70 | |
| 68 /** | 71 /** |
| 69 * Docgen constructor initializes the link resolver for markdown parsing. | 72 * Docgen constructor initializes the link resolver for markdown parsing. |
| 70 * Also initializes the command line arguments. | 73 * Also initializes the command line arguments. |
| 71 * | 74 * |
| 72 * [packageRoot] is the packages directory of the directory being analyzed. | 75 * [packageRoot] is the packages directory of the directory being analyzed. |
| 73 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will | 76 * If [includeSdk] is `true`, then any SDK libraries explicitly imported will |
| 74 * also be documented. | 77 * also be documented. |
| 75 * If [parseSdk] is `true`, then all Dart SDK libraries will be documented. | 78 * If [parseSdk] is `true`, then all Dart SDK libraries will be documented. |
| 76 * This option is useful when only the SDK libraries are needed. | 79 * This option is useful when only the SDK libraries are needed. |
| 77 * | 80 * |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 89 if (packageRoot == null && !parseSdk) { | 92 if (packageRoot == null && !parseSdk) { |
| 90 var type = FileSystemEntity.typeSync(files.first); | 93 var type = FileSystemEntity.typeSync(files.first); |
| 91 if (type == FileSystemEntityType.DIRECTORY) { | 94 if (type == FileSystemEntityType.DIRECTORY) { |
| 92 packageRoot = _findPackageRoot(files.first); | 95 packageRoot = _findPackageRoot(files.first); |
| 93 } else if (type == FileSystemEntityType.FILE) { | 96 } else if (type == FileSystemEntityType.FILE) { |
| 94 logger.warning('WARNING: No package root defined. If Docgen fails, try ' | 97 logger.warning('WARNING: No package root defined. If Docgen fails, try ' |
| 95 'again by setting the --package-root option.'); | 98 'again by setting the --package-root option.'); |
| 96 } | 99 } |
| 97 } | 100 } |
| 98 logger.info('Package Root: ${packageRoot}'); | 101 logger.info('Package Root: ${packageRoot}'); |
| 99 | |
| 100 linkResolver = (name) => | 102 linkResolver = (name) => |
| 101 fixReference(name, _currentLibrary, _currentClass, _currentMember); | 103 fixReference(name, _currentLibrary, _currentClass, _currentMember); |
| 102 | 104 |
| 103 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk) | 105 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk) |
| 104 .then((MirrorSystem mirrorSystem) { | 106 .then((MirrorSystem mirrorSystem) { |
| 105 if (mirrorSystem.libraries.isEmpty) { | 107 if (mirrorSystem.libraries.isEmpty) { |
| 106 throw new StateError('No library mirrors were created.'); | 108 throw new StateError('No library mirrors were created.'); |
| 107 } | 109 } |
| 108 _documentLibraries(mirrorSystem.libraries.values,includeSdk: includeSdk, | 110 _documentLibraries(mirrorSystem.libraries.values,includeSdk: includeSdk, |
| 109 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk); | 111 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk); |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 306 } | 308 } |
| 307 } | 309 } |
| 308 | 310 |
| 309 bool _isVisible(Indexable item) { | 311 bool _isVisible(Indexable item) { |
| 310 return _includePrivate || !item.isPrivate; | 312 return _includePrivate || !item.isPrivate; |
| 311 } | 313 } |
| 312 | 314 |
| 313 /** | 315 /** |
| 314 * Returns a list of meta annotations assocated with a mirror. | 316 * Returns a list of meta annotations assocated with a mirror. |
| 315 */ | 317 */ |
| 316 List<String> _annotations(DeclarationMirror mirror) { | 318 List<Annotation> _annotations(DeclarationMirror mirror) { |
| 317 var annotationMirrors = mirror.metadata.where((e) => | 319 var annotationMirrors = mirror.metadata.where((e) => |
| 318 e is dart2js.Dart2JsConstructedConstantMirror); | 320 e is dart2js.Dart2JsConstructedConstantMirror); |
| 319 var annotations = []; | 321 var annotations = []; |
| 320 annotationMirrors.forEach((annotation) { | 322 annotationMirrors.forEach((annotation) { |
| 321 var parameterList = annotation.type.variables.values | 323 var parameterList = annotation.type.variables.values |
| 322 .where((e) => e.isFinal) | 324 .where((e) => e.isFinal) |
| 323 .map((e) => annotation.getField(e.simpleName).reflectee) | 325 .map((e) => annotation.getField(e.simpleName).reflectee) |
| 324 .where((e) => e != null) | 326 .where((e) => e != null) |
| 325 .toList(); | 327 .toList(); |
| 326 if (validAnnotations.contains(annotation.type.qualifiedName)) { | 328 if (validAnnotations.contains(annotation.type.qualifiedName)) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 350 } | 352 } |
| 351 }); | 353 }); |
| 352 | 354 |
| 353 commentText = commentText == null ? '' : | 355 commentText = commentText == null ? '' : |
| 354 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver, | 356 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver, |
| 355 inlineSyntaxes: markdownSyntaxes); | 357 inlineSyntaxes: markdownSyntaxes); |
| 356 return commentText; | 358 return commentText; |
| 357 } | 359 } |
| 358 | 360 |
| 359 /** | 361 /** |
| 362 * Generates MDN comments from database.json. | |
| 363 */ | |
| 364 void _mdnComment(Indexable item) { | |
| 365 //Check if MDN is loaded. | |
| 366 if (_mdn == null) { | |
| 367 // Reading in MDN related json file. | |
| 368 var mdnDir = path.join(path.dirname(path.dirname(path.dirname(path.dirname( | |
| 369 path.absolute(new Options().script))))), 'utils', 'apidoc', 'mdn'); | |
| 370 _mdn = parse(new File(path.join(mdnDir, 'database.json')) | |
| 371 .readAsStringSync()); | |
| 372 } | |
| 373 if (item.comment != null && item.comment != '') return; | |
|
Emily Fortuna
2013/08/15 18:13:05
can you use isNotEmpty here, too, instead?
janicejl
2013/08/15 18:38:11
Done.
| |
| 374 var domAnnotation = item.annotations.where( | |
| 375 (e) => e.qualifiedName == 'metadata.DomName'); | |
| 376 if (domAnnotation.length != 1) return; | |
| 377 var domName = domAnnotation.single.parameters.single; | |
| 378 var parts = domName.split('.'); | |
| 379 if (parts.length == 2) item.comment = _mdnMemberComment(parts[0], parts[1]); | |
| 380 if (parts.length == 1) item.comment = _mdnTypeComment(parts[0]); | |
| 381 } | |
| 382 | |
| 383 /** | |
| 384 * Generates the MDN Comment for variables and method DOM elements. | |
| 385 */ | |
| 386 String _mdnMemberComment(String type, String member) { | |
| 387 var mdnType = _mdn[type]; | |
| 388 if (mdnType == null) return ''; | |
| 389 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member, | |
| 390 orElse: () => null); | |
| 391 if (mdnMember == null) return ''; | |
| 392 if (mdnMember['help'] == null || mdnMember['help'] == '') return ''; | |
| 393 if (mdnMember['url'] == null) return ''; | |
| 394 return _htmlMdn(mdnMember['help'], mdnMember['url']); | |
| 395 } | |
| 396 | |
| 397 /** | |
| 398 * Generates the MDN Comment for class DOM elements. | |
| 399 */ | |
| 400 String _mdnTypeComment(String type) { | |
| 401 var mdnType = _mdn[type]; | |
| 402 if (mdnType == null) return ''; | |
| 403 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; | |
| 404 if (mdnType['srcUrl'] == null) return ''; | |
| 405 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']); | |
| 406 } | |
| 407 | |
| 408 String _htmlMdn(String content, String url) { | |
| 409 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">' | |
| 410 '<a href="' + url.trim() + '">from Mdn</a></p></div>'; | |
| 411 } | |
| 412 | |
| 413 /** | |
| 360 * Converts all [foo] references in comments to <a>libraryName.foo</a>. | 414 * Converts all [foo] references in comments to <a>libraryName.foo</a>. |
| 361 */ | 415 */ |
| 362 markdown.Node fixReference(String name, LibraryMirror currentLibrary, | 416 markdown.Node fixReference(String name, LibraryMirror currentLibrary, |
| 363 ClassMirror currentClass, MemberMirror currentMember) { | 417 ClassMirror currentClass, MemberMirror currentMember) { |
| 364 var reference; | 418 var reference; |
| 365 var memberScope = currentMember == null ? | 419 var memberScope = currentMember == null ? |
| 366 null : currentMember.lookupInScope(name); | 420 null : currentMember.lookupInScope(name); |
| 367 if (memberScope != null) { | 421 if (memberScope != null) { |
| 368 reference = memberScope.qualifiedName; | 422 reference = memberScope.qualifiedName; |
| 369 } else { | 423 } else { |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 614 /// Inherited methods in the class. | 668 /// Inherited methods in the class. |
| 615 MethodGroup inheritedMethods = new MethodGroup(); | 669 MethodGroup inheritedMethods = new MethodGroup(); |
| 616 | 670 |
| 617 /// Generic infomation about the class. | 671 /// Generic infomation about the class. |
| 618 Map<String, Generic> generics; | 672 Map<String, Generic> generics; |
| 619 | 673 |
| 620 Class superclass; | 674 Class superclass; |
| 621 bool isAbstract; | 675 bool isAbstract; |
| 622 | 676 |
| 623 /// List of the meta annotations on the class. | 677 /// List of the meta annotations on the class. |
| 624 List<String> annotations; | 678 List<Annotation> annotations; |
| 625 | 679 |
| 626 Class(String name, this.superclass, String comment, this.interfaces, | 680 Class(String name, this.superclass, String comment, this.interfaces, |
| 627 this.variables, this.methods, this.annotations, this.generics, | 681 this.variables, this.methods, this.annotations, this.generics, |
| 628 String qualifiedName, bool isPrivate, String owner, this.isAbstract) | 682 String qualifiedName, bool isPrivate, String owner, this.isAbstract) |
| 629 : super(name, comment, qualifiedName, isPrivate, owner); | 683 : super(name, comment, qualifiedName, isPrivate, owner) { |
| 684 _mdnComment(this); | |
| 685 } | |
| 630 | 686 |
| 631 String get typeName => 'class'; | 687 String get typeName => 'class'; |
| 632 | 688 |
| 633 /** | 689 /** |
| 634 * Returns a list of all the parent classes. | 690 * Returns a list of all the parent classes. |
| 635 */ | 691 */ |
| 636 List<Class> parent() { | 692 List<Class> parent() { |
| 637 var parent = superclass == null ? [] : [superclass]; | 693 var parent = superclass == null ? [] : [superclass]; |
| 638 parent.addAll(interfaces); | 694 parent.addAll(interfaces); |
| 639 return parent; | 695 return parent; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 801 | 857 |
| 802 class Typedef extends Indexable { | 858 class Typedef extends Indexable { |
| 803 String returnType; | 859 String returnType; |
| 804 | 860 |
| 805 Map<String, Parameter> parameters; | 861 Map<String, Parameter> parameters; |
| 806 | 862 |
| 807 /// Generic information about the typedef. | 863 /// Generic information about the typedef. |
| 808 Map<String, Generic> generics; | 864 Map<String, Generic> generics; |
| 809 | 865 |
| 810 /// List of the meta annotations on the typedef. | 866 /// List of the meta annotations on the typedef. |
| 811 List<String> annotations; | 867 List<Annotation> annotations; |
| 812 | 868 |
| 813 Typedef(String name, this.returnType, String comment, this.generics, | 869 Typedef(String name, this.returnType, String comment, this.generics, |
| 814 this.parameters, this.annotations, | 870 this.parameters, this.annotations, |
| 815 String qualifiedName, bool isPrivate, String owner) | 871 String qualifiedName, bool isPrivate, String owner) |
| 816 : super(name, comment, qualifiedName, isPrivate, owner); | 872 : super(name, comment, qualifiedName, isPrivate, owner); |
| 817 | 873 |
| 818 Map toMap() => { | 874 Map toMap() => { |
| 819 'name': name, | 875 'name': name, |
| 820 'qualifiedName': qualifiedName, | 876 'qualifiedName': qualifiedName, |
| 821 'comment': comment, | 877 'comment': comment, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 832 * A class containing properties of a Dart variable. | 888 * A class containing properties of a Dart variable. |
| 833 */ | 889 */ |
| 834 class Variable extends Indexable { | 890 class Variable extends Indexable { |
| 835 | 891 |
| 836 bool isFinal; | 892 bool isFinal; |
| 837 bool isStatic; | 893 bool isStatic; |
| 838 bool isConst; | 894 bool isConst; |
| 839 Type type; | 895 Type type; |
| 840 | 896 |
| 841 /// List of the meta annotations on the variable. | 897 /// List of the meta annotations on the variable. |
| 842 List<String> annotations; | 898 List<Annotation> annotations; |
| 843 | 899 |
| 844 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type, | 900 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type, |
| 845 String comment, this.annotations, String qualifiedName, bool isPrivate, | 901 String comment, this.annotations, String qualifiedName, bool isPrivate, |
| 846 String owner) : super(name, comment, qualifiedName, isPrivate, owner); | 902 String owner) : super(name, comment, qualifiedName, isPrivate, owner) { |
| 903 _mdnComment(this); | |
| 904 } | |
| 847 | 905 |
| 848 /// Generates a map describing the [Variable] object. | 906 /// Generates a map describing the [Variable] object. |
| 849 Map toMap() => { | 907 Map toMap() => { |
| 850 'name': name, | 908 'name': name, |
| 851 'qualifiedName': qualifiedName, | 909 'qualifiedName': qualifiedName, |
| 852 'comment': comment, | 910 'comment': comment, |
| 853 'final': isFinal.toString(), | 911 'final': isFinal.toString(), |
| 854 'static': isStatic.toString(), | 912 'static': isStatic.toString(), |
| 855 'constant': isConst.toString(), | 913 'constant': isConst.toString(), |
| 856 'type': new List.filled(1, type.toMap()), | 914 'type': new List.filled(1, type.toMap()), |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 874 bool isConstructor; | 932 bool isConstructor; |
| 875 bool isGetter; | 933 bool isGetter; |
| 876 bool isSetter; | 934 bool isSetter; |
| 877 bool isOperator; | 935 bool isOperator; |
| 878 Type returnType; | 936 Type returnType; |
| 879 | 937 |
| 880 /// Qualified name to state where the comment is inherited from. | 938 /// Qualified name to state where the comment is inherited from. |
| 881 String commentInheritedFrom = ""; | 939 String commentInheritedFrom = ""; |
| 882 | 940 |
| 883 /// List of the meta annotations on the method. | 941 /// List of the meta annotations on the method. |
| 884 List<String> annotations; | 942 List<Annotation> annotations; |
| 885 | 943 |
| 886 Method(String name, this.isStatic, this.isAbstract, this.isConst, | 944 Method(String name, this.isStatic, this.isAbstract, this.isConst, |
| 887 this.returnType, String comment, this.parameters, this.annotations, | 945 this.returnType, String comment, this.parameters, this.annotations, |
| 888 String qualifiedName, bool isPrivate, String owner, this.isConstructor, | 946 String qualifiedName, bool isPrivate, String owner, this.isConstructor, |
| 889 this.isGetter, this.isSetter, this.isOperator) | 947 this.isGetter, this.isSetter, this.isOperator) |
| 890 : super(name, comment, qualifiedName, isPrivate, owner); | 948 : super(name, comment, qualifiedName, isPrivate, owner) { |
| 949 _mdnComment(this); | |
| 950 } | |
| 891 | 951 |
| 892 /** | 952 /** |
| 893 * Makes sure that the method with an inherited equivalent have comments. | 953 * Makes sure that the method with an inherited equivalent have comments. |
| 894 */ | 954 */ |
| 895 void ensureCommentFor(Method inheritedMethod) { | 955 void ensureCommentFor(Method inheritedMethod) { |
| 896 if (comment.isNotEmpty) return; | 956 if (comment.isNotEmpty) return; |
| 897 entityMap[inheritedMethod.owner].ensureComments(); | 957 entityMap[inheritedMethod.owner].ensureComments(); |
| 898 comment = inheritedMethod.comment; | 958 comment = inheritedMethod.comment; |
| 899 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? | 959 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? |
| 900 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; | 960 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 999 class Parameter { | 1059 class Parameter { |
| 1000 | 1060 |
| 1001 String name; | 1061 String name; |
| 1002 bool isOptional; | 1062 bool isOptional; |
| 1003 bool isNamed; | 1063 bool isNamed; |
| 1004 bool hasDefaultValue; | 1064 bool hasDefaultValue; |
| 1005 Type type; | 1065 Type type; |
| 1006 String defaultValue; | 1066 String defaultValue; |
| 1007 | 1067 |
| 1008 /// List of the meta annotations on the parameter. | 1068 /// List of the meta annotations on the parameter. |
| 1009 List<String> annotations; | 1069 List<Annotation> annotations; |
| 1010 | 1070 |
| 1011 Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue, | 1071 Parameter(this.name, this.isOptional, this.isNamed, this.hasDefaultValue, |
| 1012 this.type, this.defaultValue, this.annotations); | 1072 this.type, this.defaultValue, this.annotations); |
| 1013 | 1073 |
| 1014 /// Generates a map describing the [Parameter] object. | 1074 /// Generates a map describing the [Parameter] object. |
| 1015 Map toMap() => { | 1075 Map toMap() => { |
| 1016 'name': name, | 1076 'name': name, |
| 1017 'optional': isOptional.toString(), | 1077 'optional': isOptional.toString(), |
| 1018 'named': isNamed.toString(), | 1078 'named': isNamed.toString(), |
| 1019 'default': hasDefaultValue.toString(), | 1079 'default': hasDefaultValue.toString(), |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1087 String qualifiedName; | 1147 String qualifiedName; |
| 1088 List<String> parameters; | 1148 List<String> parameters; |
| 1089 | 1149 |
| 1090 Annotation(this.qualifiedName, this.parameters); | 1150 Annotation(this.qualifiedName, this.parameters); |
| 1091 | 1151 |
| 1092 Map toMap() => { | 1152 Map toMap() => { |
| 1093 'name': qualifiedName, | 1153 'name': qualifiedName, |
| 1094 'parameters': parameters | 1154 'parameters': parameters |
| 1095 }; | 1155 }; |
| 1096 } | 1156 } |
| OLD | NEW |