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

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

Issue 78713004: Expose exported classes as well. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years 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
« no previous file with comments | « pkg/docgen/bin/dartdoc.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 /// **docgen** is a tool for creating machine readable representations of Dart 5 /// **docgen** is a tool for creating machine readable representations of Dart
6 /// code metadata, including: classes, members, comments and annotations. 6 /// code metadata, including: classes, members, comments and annotations.
7 /// 7 ///
8 /// docgen is run on a `.dart` file or a directory containing `.dart` files. 8 /// docgen is run on a `.dart` file or a directory containing `.dart` files.
9 /// 9 ///
10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR] 10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR]
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 filteredEntities.map((e) => e.typeName)); 369 filteredEntities.map((e) => e.typeName));
370 if (append) { 370 if (append) {
371 var previousIndex = 371 var previousIndex =
372 JSON.decode(new File('docs/index.json').readAsStringSync()); 372 JSON.decode(new File('docs/index.json').readAsStringSync());
373 index.addAll(previousIndex); 373 index.addAll(previousIndex);
374 } 374 }
375 _writeToFile(JSON.encode(index), 'index.json'); 375 _writeToFile(JSON.encode(index), 'index.json');
376 } 376 }
377 377
378 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { 378 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) {
379 var result = new Library(docName(library), 379 var result = new Library(library);
Alan Knight 2013/11/20 21:29:20 Awesome!
380 (actualLibrary) => _commentToHtml(library, actualLibrary),
381 _classes(library.classes),
382 _methods(library.functions),
383 _variables(library.variables),
384 _isHidden(library), library);
385 _findPackage(library, result); 380 _findPackage(library, result);
386 logger.fine('Generated library for ${result.name}'); 381 logger.fine('Generated library for ${result.name}');
387 return result; 382 return result;
388 } 383 }
389 384
390 void _writeIndexableToFile(Indexable result, bool outputToYaml) { 385 void _writeIndexableToFile(Indexable result, bool outputToYaml) {
391 var outputFile = result.fileName; 386 var outputFile = result.fileName;
392 var output; 387 var output;
393 if (outputToYaml) { 388 if (outputToYaml) {
394 output = getYamlString(result.toMap()); 389 output = getYamlString(result.toMap());
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner)); 421 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner));
427 } else { 422 } else {
428 return (mirror.isPrivate || _isHidden(mirror.owner)); 423 return (mirror.isPrivate || _isHidden(mirror.owner));
429 } 424 }
430 } 425 }
431 426
432 bool _isVisible(Indexable item) { 427 bool _isVisible(Indexable item) {
433 return _includePrivate || !item.isPrivate; 428 return _includePrivate || !item.isPrivate;
434 } 429 }
435 430
436 /// Returns a list of meta annotations assocated with a mirror.
437 List<Annotation> _annotations(DeclarationMirror mirror) {
438 var annotationMirrors = mirror.metadata.where((e) =>
439 e is dart2js.Dart2JsConstructedConstantMirror);
440 var annotations = [];
441 annotationMirrors.forEach((annotation) {
442 var parameterList = annotation.type.variables.values
443 .where((e) => e.isFinal)
444 .map((e) => annotation.getField(e.simpleName).reflectee)
445 .where((e) => e != null)
446 .toList();
447 if (!skippedAnnotations.contains(docName(annotation.type))) {
448 annotations.add(new Annotation(docName(annotation.type),
449 parameterList));
450 }
451 });
452 return annotations;
453 }
454
455 /// Returns any documentation comments associated with a mirror with 431 /// Returns any documentation comments associated with a mirror with
456 /// simple markdown converted to html. 432 /// simple markdown converted to html.
457 /// 433 ///
458 /// It's possible to have a comment that comes from one mirror applied to 434 /// It's possible to have a comment that comes from one mirror applied to
459 /// another, in the case of an inherited comment. 435 /// another, in the case of an inherited comment.
460 String _commentToHtml(DeclarationMirror mirror, [DeclarationMirror appliedTo]) { 436 String _commentToHtml(DeclarationMirror mirror, [DeclarationMirror appliedTo]) {
461 if (appliedTo == null) appliedTo = mirror; 437 if (appliedTo == null) appliedTo = mirror;
462 String commentText; 438 String commentText;
463 mirror.metadata.forEach((metadata) { 439 mirror.metadata.forEach((metadata) {
464 if (metadata is CommentInstanceMirror) { 440 if (metadata is CommentInstanceMirror) {
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 var owner = scope.owner; 643 var owner = scope.owner;
668 if (owner is ClassMirror) { 644 if (owner is ClassMirror) {
669 return fixReference(name, owner.library, owner, scope); 645 return fixReference(name, owner.library, owner, scope);
670 } else { 646 } else {
671 return fixReference(name, owner, null, scope); 647 return fixReference(name, owner, null, scope);
672 } 648 }
673 } 649 }
674 return null; 650 return null;
675 } 651 }
676 652
677 /// Returns a map of [Variable] objects constructed from [mirrorMap].
678 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) {
679 var data = {};
680 // TODO(janicejl): When map to map feature is created, replace the below with
681 // a filter. Issue(#9590).
682 mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
683 if (_includePrivate || !_isHidden(mirror)) {
684 entityMap[docName(mirror)] = new Variable(mirrorName, mirror.isFinal,
685 mirror.isStatic, mirror.isConst, _type(mirror.type),
686 (actualVariable) => _commentToHtml(mirror, actualVariable),
687 _annotations(mirror), docName(mirror),
688 _isHidden(mirror), docName(mirror.owner), mirror);
689 data[mirrorName] = entityMap[docName(mirror)];
690 }
691 });
692 return data;
693 }
694
695 /// Returns a map of [Method] objects constructed from [mirrorMap].
696 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) {
697 var group = new MethodGroup();
698 mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
699 if (_includePrivate || !mirror.isPrivate) {
700 group.addMethod(mirror);
701 }
702 });
703 return group;
704 }
705
706 /// Returns the [Class] for the given [mirror] has already been created, and if
707 /// it does not exist, creates it.
708 Class _class(ClassMirror mirror) {
709 var clazz = entityMap[docName(mirror)];
710 if (clazz == null) {
711 var superclass = mirror.superclass != null ?
712 _class(mirror.superclass) : null;
713 var interfaces =
714 mirror.superinterfaces.map((interface) => _class(interface));
715 clazz = new Class(mirror.simpleName, superclass,
716 (actualClass) => _commentToHtml(mirror, actualClass),
717 interfaces.toList(), _variables(mirror.variables),
718 _methods(mirror.methods), _annotations(mirror), _generics(mirror),
719 docName(mirror), _isHidden(mirror), docName(mirror.owner),
720 mirror.isAbstract, mirror);
721 if (superclass != null) clazz.addInherited(superclass);
722 interfaces.forEach((interface) => clazz.addInherited(interface));
723 entityMap[docName(mirror)] = clazz;
724 }
725 return clazz;
726 }
727
728 /// Returns a map of [Class] objects constructed from [mirrorMap].
729 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) {
730 var group = new ClassGroup();
731 mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
732 group.addClass(mirror);
733 });
734 return group;
735 }
736
737 /// Returns a map of [Parameter] objects constructed from [mirrorList].
738 Map<String, Parameter> _parameters(List<ParameterMirror> mirrorList) {
739 var data = {};
740 mirrorList.forEach((ParameterMirror mirror) {
741 data[mirror.simpleName] = new Parameter(mirror.simpleName,
742 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue,
743 _type(mirror.type), mirror.defaultValue,
744 _annotations(mirror));
745 });
746 return data;
747 }
748
749 /// Returns a map of [Generic] objects constructed from the class mirror.
750 Map<String, Generic> _generics(ClassMirror mirror) {
751 return new Map.fromIterable(mirror.typeVariables,
752 key: (e) => e.toString(),
753 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName));
754 }
755
756 /// Returns a single [Type] object constructed from the Method.returnType
757 /// Type mirror.
758 Type _type(TypeMirror mirror) {
759 return new Type(docName(mirror), _typeGenerics(mirror));
760 }
761
762 /// Returns a list of [Type] objects constructed from TypeMirrors.
763 List<Type> _typeGenerics(TypeMirror mirror) {
764 if (mirror is ClassMirror && !mirror.isTypedef) {
765 var innerList = [];
766 mirror.typeArguments.forEach((e) {
767 innerList.add(new Type(docName(e), _typeGenerics(e)));
768 });
769 return innerList;
770 }
771 return [];
772 }
773
774 /// Writes text to a file in the 'docs' directory. 653 /// Writes text to a file in the 'docs' directory.
775 void _writeToFile(String text, String filename, {bool append: false}) { 654 void _writeToFile(String text, String filename, {bool append: false}) {
776 Directory dir = new Directory('docs'); 655 Directory dir = new Directory('docs');
777 if (!dir.existsSync()) { 656 if (!dir.existsSync()) {
778 dir.createSync(); 657 dir.createSync();
779 } 658 }
780 // We assume there's a single extra level of directory structure for packages. 659 // We assume there's a single extra level of directory structure for packages.
781 if (path.split(filename).length > 1) { 660 if (path.split(filename).length > 1) {
782 var subdir = new Directory(path.join('docs', path.dirname(filename))); 661 var subdir = new Directory(path.join('docs', path.dirname(filename)));
783 if (!subdir.existsSync()) { 662 if (!subdir.existsSync()) {
(...skipping 19 matching lines...) Expand all
803 } 682 }
804 }); 683 });
805 return outputMap; 684 return outputMap;
806 } 685 }
807 686
808 /// A type for the function that generates a comment from a mirror. 687 /// A type for the function that generates a comment from a mirror.
809 typedef String CommentGenerator(Mirror m); 688 typedef String CommentGenerator(Mirror m);
810 689
811 /// A class representing all programming constructs, like library or class. 690 /// A class representing all programming constructs, like library or class.
812 class Indexable { 691 class Indexable {
813 String name;
814 String get qualifiedName => fileName; 692 String get qualifiedName => fileName;
815 bool isPrivate; 693 bool isPrivate;
816 Mirror mirror; 694 DeclarationMirror mirror;
695
696 Indexable(this.mirror) {
697 this.isPrivate = _isHidden(mirror);
698 }
817 699
818 // The qualified name (for URL purposes) and the file name are the same, 700 // The qualified name (for URL purposes) and the file name are the same,
819 // of the form packageName/ClassName or packageName/ClassName.methodName. 701 // of the form packageName/ClassName or packageName/ClassName.methodName.
820 // This defines both the URL and the directory structure. 702 // This defines both the URL and the directory structure.
821 String get fileName => packagePrefix + ownerPrefix + name; 703 String get fileName => packagePrefix + ownerPrefix + name;
822 704
823 Indexable get owningEntity => entityMap[owner]; 705 Indexable get owningEntity => entityMap[owner];
824 706
825 String get ownerPrefix => owningEntity == null 707 String get ownerPrefix => owningEntity == null ?
826 ? (owner == null || owner.isEmpty ? '' : owner + '.') 708 (owner == null || owner.isEmpty ? '' : owner + '.') :
827 : owningEntity.qualifiedName + '.'; 709 owningEntity.qualifiedName + '.';
828 710
829 String get packagePrefix => ''; 711 String get packagePrefix => '';
830 712
831 /// Documentation comment with converted markdown. 713 /// Documentation comment with converted markdown.
832 String _comment; 714 String _comment;
833 715
834 String get comment { 716 String get comment {
835 if (_comment != null) return _comment; 717 if (_comment != null) return _comment;
836 _comment = _commentFunction(mirror); 718 _comment = _commentFunction(mirror);
837 if (_comment.isEmpty) { 719 if (_comment.isEmpty) {
838 _mdnComment(this); 720 _mdnComment(this);
839 } 721 }
840 return _comment; 722 return _comment;
841 } 723 }
842 724
843 set comment(x) => _comment = x; 725 set comment(x) => _comment = x;
844 726
845 /// We defer evaluating the comment until we have all the context available 727 String get name => mirror.simpleName;
846 CommentGenerator _commentFunction;
847 728
848 /// Qualified Name of the owner of this Indexable Item. 729 /// Qualified Name of the owner of this Indexable Item.
849 /// For Library, owner will be ""; 730 String get owner => docName(mirror.owner);
850 String owner;
851 731
852 Indexable(this.name, this._commentFunction, this.isPrivate, this.owner, 732 /// We defer evaluating the comment until we have all the context available
853 this.mirror); 733 CommentGenerator get _commentFunction =>
Alan Knight 2013/11/20 21:29:20 If this is always there, could we just call make i
Emily Fortuna 2013/11/21 19:29:59 Good point. I ended up doing this refactor in incr
734 (itemToDocument) => _commentToHtml(mirror, itemToDocument);
854 735
855 /// The type of this member to be used in index.txt. 736 /// The type of this member to be used in index.txt.
856 String get typeName => ''; 737 String get typeName => '';
857 738
858 /// Creates a [Map] with this [Indexable]'s name and a preview comment. 739 /// Creates a [Map] with this [Indexable]'s name and a preview comment.
859 Map get previewMap { 740 Map get previewMap {
860 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; 741 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName };
861 if (comment != '') { 742 if (comment != '') {
862 var index = comment.indexOf('</p>'); 743 var index = comment.indexOf('</p>');
863 finalMap['preview'] = '${comment.substring(0, index)}</p>'; 744 finalMap['preview'] = '${comment.substring(0, index)}</p>';
864 } 745 }
865 return finalMap; 746 return finalMap;
866 } 747 }
867 748
749 /// Returns a map of [Variable] objects constructed from [mirrorMap].
750 Map<String, Variable> _processVariables(Map<String,
751 VariableMirror> mirrorMap) {
752 var data = {};
753 // TODO(janicejl): When map to map feature is created, replace the below
754 // with a filter. Issue(#9590).
755 mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
756 if (_includePrivate || !_isHidden(mirror)) {
757 entityMap[docName(mirror)] = new Variable(mirrorName, mirror);
758 data[mirrorName] = entityMap[docName(mirror)];
759 }
760 });
761 return data;
762 }
763
764 /// Returns a map of [Method] objects constructed from [mirrorMap].
765 MethodGroup _processMethods(Map<String, MethodMirror> mirrorMap) {
Alan Knight 2013/11/20 21:29:20 A bit of inconsistency with naming that we're proc
Emily Fortuna 2013/11/21 19:29:59 renamed to create
766 var group = new MethodGroup();
767 mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
768 if (_includePrivate || !mirror.isPrivate) {
769 group.addMethod(mirror);
770 }
771 });
772 return group;
773 }
774
775 /// Returns a map of [Parameter] objects constructed from [mirrorList].
776 Map<String, Parameter> _processParameters(List<ParameterMirror> mirrorList) {
777 var data = {};
778 mirrorList.forEach((ParameterMirror mirror) {
779 data[mirror.simpleName] = new Parameter(mirror.simpleName,
780 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue,
781 _processType(mirror.type), mirror.defaultValue,
782 _processAnnotations(mirror));
783 });
784 return data;
785 }
786
787 /// Returns a map of [Generic] objects constructed from the class mirror.
788 Map<String, Generic> _processGenerics(ClassMirror mirror) {
789 return new Map.fromIterable(mirror.typeVariables,
790 key: (e) => e.toString(),
791 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName));
792 }
793
794 /// Returns a single [Type] object constructed from the Method.returnType
795 /// Type mirror.
796 Type _processType(TypeMirror mirror) {
797 return new Type(docName(mirror), _processTypeGenerics(mirror));
798 }
799
800 /// Returns a list of [Type] objects constructed from TypeMirrors.
801 List<Type> _processTypeGenerics(TypeMirror mirror) {
802 if (mirror is ClassMirror && !mirror.isTypedef) {
803 var innerList = [];
804 mirror.typeArguments.forEach((e) {
805 innerList.add(new Type(docName(e), _processTypeGenerics(e)));
806 });
807 return innerList;
808 }
809 return [];
810 }
811
812 /// Returns a list of meta annotations assocated with a mirror.
813 List<Annotation> _processAnnotations(DeclarationMirror mirror) {
814 var annotationMirrors = mirror.metadata.where((e) =>
815 e is dart2js.Dart2JsConstructedConstantMirror);
816 var annotations = [];
817 annotationMirrors.forEach((annotation) {
818 var parameterList = annotation.type.variables.values
819 .where((e) => e.isFinal)
820 .map((e) => annotation.getField(e.simpleName).reflectee)
821 .where((e) => e != null)
822 .toList();
823 if (!skippedAnnotations.contains(docName(annotation.type))) {
824 annotations.add(new Annotation(docName(annotation.type),
825 parameterList));
826 }
827 });
828 return annotations;
829 }
830
868 /// Return an informative [Object.toString] for debugging. 831 /// Return an informative [Object.toString] for debugging.
869 String toString() => "${super.toString()}(${name.toString()})"; 832 String toString() => "${super.toString()}(${name.toString()})";
870 833
871 /// Return a map representation of this type. 834 /// Return a map representation of this type.
872 Map toMap() {} 835 Map toMap() {}
873 } 836 }
874 837
875 /// A class containing contents of a Dart library. 838 /// A class containing contents of a Dart library.
876 class Library extends Indexable { 839 class Library extends Indexable {
877 840
878 /// Top-level variables in the library. 841 /// Top-level variables in the library.
879 Map<String, Variable> variables; 842 Map<String, Variable> variables;
880 843
881 /// Top-level functions in the library. 844 /// Top-level functions in the library.
882 MethodGroup functions; 845 MethodGroup functions;
883 846
884 /// Classes defined within the library 847 /// Classes defined within the library
885 ClassGroup classes; 848 ClassGroup classes;
886 849
887 String packageName = ''; 850 String packageName = '';
888 bool hasBeenCheckedForPackage = false; 851 bool hasBeenCheckedForPackage = false;
852 String packageIntro;
889 853
890 String get packagePrefix => packageName == null || packageName.isEmpty 854 Library(LibraryMirror libraryMirror) : super(libraryMirror) {
891 ? '' 855 var exported = _calcExportedItems(libraryMirror);
892 : '$packageName/'; 856 this.classes = _processClasses(
857 exported['classes']..addAll(libraryMirror.classes));
858 this.functions = _processMethods(
859 exported['methods']..addAll(libraryMirror.functions));
860 this.variables = _processVariables(
861 exported['variables']..addAll(libraryMirror.variables));
862 print(classes.toMap().toString());
Alan Knight 2013/11/20 21:29:20 Leftover debugging?
Emily Fortuna 2013/11/21 19:29:59 yep. removed.
863 }
893 864
894 String packageIntro; 865 String get packagePrefix => packageName == null || packageName.isEmpty ?
866 '' : '$packageName/';
895 867
896 Map get previewMap { 868 Map get previewMap {
897 var basic = super.previewMap; 869 var basic = super.previewMap;
898 basic['packageName'] = packageName; 870 basic['packageName'] = packageName;
899 if (packageIntro != null) { 871 if (packageIntro != null) {
900 basic['packageIntro'] = packageIntro; 872 basic['packageIntro'] = packageIntro;
901 } 873 }
902 return basic; 874 return basic;
903 } 875 }
904 876
905 Library(String name, Function commentFunction, this.classes, this.functions, 877 String get owner => '';
906 this.variables, bool isPrivate, Mirror mirror) 878
907 : super(name, commentFunction, isPrivate, "", mirror); 879 String get name => docName(mirror);
880
881 /// Returns a map of [Class] objects constructed from [mirrorMap].
Alan Knight 2013/11/20 21:29:20 "Returns a [ClassGroup] with a map of" ?
Emily Fortuna 2013/11/21 19:29:59 Done.
882 ClassGroup _processClasses(Map<String, ClassMirror> mirrorMap) {
883 var group = new ClassGroup();
884 mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
885 group.addClass(mirror);
886 });
887 return group;
888 }
889
890 /// For the given library determine what items (if any) are exported.
891 ///
892 /// Returns a Map with three keys: "classes", "methods", and "variables" the
893 /// values of which point to a map of exported name identifiers with values
894 /// corresponding to the actual DeclarationMirror.
895 Map<String, Map<String, DeclarationMirror>> _calcExportedItems(
896 LibraryMirror library) {
897 var exports = {};
898 exports['classes'] = {};
899 exports['methods'] = {};
900 exports['variables'] = {};
901
902 // Determine the classes, variables and methods that are exported for a
903 // specific dependency.
904 _populateExports(LibraryDependencyMirror export, bool showExport) {
905 if (!showExport) {
906 // Add all items, and then remove the hidden ones.
907 // Ex: "export foo hide bar"
908 exports['classes'].addAll(export.targetLibrary.classes);
909 exports['methods'].addAll(export.targetLibrary.functions);
910 exports['variables'].addAll(export.targetLibrary.variables);
911 }
912 for (CombinatorMirror combinator in export.combinators) {
913 for (String identifier in combinator.identifiers) {
914 DeclarationMirror declaration =
915 export.targetLibrary.lookupInScope(identifier);
916 if (declaration == null) {
917 // Technically this should be a bug, but some of our packages
918 // (such as the polymer package) are curently broken in this
919 // way, so we just produce a warning.
920 print('Warning identifier $identifier not found in library '
921 '${export.targetLibrary.qualifiedName}');
922 } else {
923 var subMap = exports['classes'];
924 if (declaration is MethodMirror) {
925 subMap = exports['methods'];
926 } else if (declaration is VariableMirror) {
927 subMap = exports['variables'];
928 }
929 if (showExport) {
930 subMap[identifier] = declaration;
931 } else {
932 subMap.remove(identifier);
933 }
934 }
935 }
936 }
937 }
938
939 Iterable<LibraryDependencyMirror> exportList =
940 library.libraryDependencies.where((lib) => lib.isExport);
941 for (LibraryDependencyMirror export in exportList) {
942 // If there is a show in the export, add only the show items to the
943 // library. Ex: "export foo show bar"
944 // Otherwise, add all items, and then remove the hidden ones.
945 // Ex: "export foo hide bar"
946 _populateExports(export,
947 export.combinators.any((combinator) => combinator.isShow));
948 }
949 return exports;
950 }
908 951
909 /// Generates a map describing the [Library] object. 952 /// Generates a map describing the [Library] object.
910 Map toMap() => { 953 Map toMap() => {
911 'name': name, 954 'name': name,
912 'qualifiedName': qualifiedName, 955 'qualifiedName': qualifiedName,
913 'comment': comment, 956 'comment': comment,
914 'variables': recurseMap(variables), 957 'variables': recurseMap(variables),
915 'functions': functions.toMap(), 958 'functions': functions.toMap(),
916 'classes': classes.toMap(), 959 'classes': classes.toMap(),
917 'packageName': packageName, 960 'packageName': packageName,
(...skipping 29 matching lines...) Expand all
947 990
948 Class superclass; 991 Class superclass;
949 bool isAbstract; 992 bool isAbstract;
950 993
951 /// List of the meta annotations on the class. 994 /// List of the meta annotations on the class.
952 List<Annotation> annotations; 995 List<Annotation> annotations;
953 996
954 /// Make sure that we don't check for inherited comments more than once. 997 /// Make sure that we don't check for inherited comments more than once.
955 bool _commentsEnsured = false; 998 bool _commentsEnsured = false;
956 999
957 Class(String name, this.superclass, Function commentFunction, this.interfaces, 1000 Class(ClassMirror classMirror) : super(classMirror) {
958 this.variables, this.methods, this.annotations, this.generics, 1001 var superclass = classMirror.superclass != null ?
959 String qualifiedName, bool isPrivate, String owner, this.isAbstract, 1002 _getClassFromClassMirror(classMirror.superclass) : null;
960 Mirror mirror) 1003 var interfaces = classMirror.superinterfaces.map(
961 : super(name, commentFunction, isPrivate, owner, mirror); 1004 (interface) => _getClassFromClassMirror(interface));
1005
1006 this.superclass = superclass;
1007 this.interfaces = interfaces.toList();
1008 this.variables = _processVariables(classMirror.variables);
1009 this.methods = _processMethods(classMirror.methods);
1010 this.annotations = _processAnnotations(classMirror);
1011 this.generics = _processGenerics(classMirror);
1012 this.isAbstract = classMirror.isAbstract;
1013
1014 // Tell all superclasses that you are a subclass.
1015 if (!classMirror.isNameSynthetic && _isVisible(this)) {
1016 parentChain().forEach((parentClass) {
1017 parentClass.addSubclass(this);
1018 });
1019 }
1020
1021 if (this.superclass != null) addInherited(superclass);
1022 interfaces.forEach((interface) => addInherited(interface));
1023 }
962 1024
963 String get typeName => 'class'; 1025 String get typeName => 'class';
964 1026
965 /// Returns a list of all the parent classes. 1027 /// Returns a list of all the parent classes.
966 List<Class> parent() { 1028 List<Class> parentChain() {
967 var parent = superclass == null ? [] : [superclass]; 1029 var parent = superclass == null ? [] : [superclass];
968 parent.addAll(interfaces); 1030 parent.addAll(interfaces);
969 return parent; 1031 return parent;
970 } 1032 }
971 1033
972 /// Add all inherited variables and methods from the provided superclass. 1034 /// Add all inherited variables and methods from the provided superclass.
973 /// If [_includePrivate] is true, it also adds the variables and methods from 1035 /// If [_includePrivate] is true, it also adds the variables and methods from
974 /// the superclass. 1036 /// the superclass.
975 void addInherited(Class superclass) { 1037 void addInherited(Class superclass) {
976 inheritedVariables.addAll(superclass.inheritedVariables); 1038 inheritedVariables.addAll(superclass.inheritedVariables);
977 inheritedVariables.addAll(_filterStatics(superclass.variables)); 1039 inheritedVariables.addAll(_filterStatics(superclass.variables));
978 inheritedMethods.addInherited(superclass); 1040 inheritedMethods.addInherited(superclass);
979 } 1041 }
980 1042
981 /// Add the subclass to the class. 1043 /// Add the subclass to the class.
982 /// 1044 ///
983 /// If [this] is private, it will add the subclass to the list of subclasses i n 1045 /// If [this] is private, it will add the subclass to the list of subclasses
984 /// the superclasses. 1046 /// in the superclasses.
985 void addSubclass(Class subclass) { 1047 void addSubclass(Class subclass) {
986 if (!_includePrivate && isPrivate) { 1048 if (!_includePrivate && isPrivate) {
987 if (superclass != null) superclass.addSubclass(subclass); 1049 if (superclass != null) superclass.addSubclass(subclass);
988 interfaces.forEach((interface) { 1050 interfaces.forEach((interface) {
989 interface.addSubclass(subclass); 1051 interface.addSubclass(subclass);
990 }); 1052 });
991 } else { 1053 } else {
992 subclasses.add(subclass); 1054 subclasses.add(subclass);
993 } 1055 }
994 } 1056 }
995 1057
1058 /// Returns the [Class] for the given [mirror] has already been created, and
Alan Knight 2013/11/20 21:29:20 Missing an "if it"?
Emily Fortuna 2013/11/21 19:29:59 Done.
1059 /// if it does not exist, creates it.
1060 static Class _getClassFromClassMirror(ClassMirror mirror) {
Alan Knight 2013/11/20 21:29:20 Naming nit. The "get" doesn't add much, and if it'
Emily Fortuna 2013/11/21 19:29:59 Good call. Fixed.
1061 var clazz = entityMap[docName(mirror)];
1062 if (clazz == null) {
1063 clazz = new Class(mirror);
1064 entityMap[docName(mirror)] = clazz;
1065 }
1066 return clazz;
1067 }
1068
996 /// Check if this [Class] is an error or exception. 1069 /// Check if this [Class] is an error or exception.
997 bool isError() { 1070 bool isError() {
998 if (qualifiedName == 'dart-core.Error' || 1071 if (qualifiedName == 'dart-core.Error' ||
999 qualifiedName == 'dart-core.Exception') 1072 qualifiedName == 'dart-core.Exception')
1000 return true; 1073 return true;
1001 for (var interface in interfaces) { 1074 for (var interface in interfaces) {
1002 if (interface.isError()) return true; 1075 if (interface.isError()) return true;
1003 } 1076 }
1004 if (superclass == null) return false; 1077 if (superclass == null) return false;
1005 return superclass.isError(); 1078 return superclass.isError();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 Map<String, Class> classes = {}; 1141 Map<String, Class> classes = {};
1069 Map<String, Typedef> typedefs = {}; 1142 Map<String, Typedef> typedefs = {};
1070 Map<String, Class> errors = {}; 1143 Map<String, Class> errors = {};
1071 1144
1072 void addClass(ClassMirror classMirror) { 1145 void addClass(ClassMirror classMirror) {
1073 if (classMirror.isTypedef) { 1146 if (classMirror.isTypedef) {
1074 // This is actually a Dart2jsTypedefMirror, and it does define value, 1147 // This is actually a Dart2jsTypedefMirror, and it does define value,
1075 // but we don't have visibility to that type. 1148 // but we don't have visibility to that type.
1076 var mirror = classMirror; 1149 var mirror = classMirror;
1077 if (_includePrivate || !mirror.isPrivate) { 1150 if (_includePrivate || !mirror.isPrivate) {
1078 entityMap[docName(mirror)] = new Typedef(mirror.simpleName, 1151 entityMap[docName(mirror)] = new Typedef(mirror);
1079 docName(mirror.value.returnType),
1080 (actualTypedef) => _commentToHtml(mirror, actualTypedef),
1081 _generics(mirror), _parameters(mirror.value.parameters),
1082 _annotations(mirror), docName(mirror), _isHidden(mirror),
1083 docName(mirror.owner), mirror);
1084 typedefs[mirror.simpleName] = entityMap[docName(mirror)]; 1152 typedefs[mirror.simpleName] = entityMap[docName(mirror)];
1085 } 1153 }
1086 } else { 1154 } else {
1087 var clazz = _class(classMirror); 1155 var clazz = Class._getClassFromClassMirror(classMirror);
1088
1089 // Adding inherited parent variables and methods.
1090 clazz.parent().forEach((parent) {
1091 if (_isVisible(clazz)) {
1092 parent.addSubclass(clazz);
1093 }
1094 });
1095 1156
1096 if (clazz.isError()) { 1157 if (clazz.isError()) {
1097 errors[classMirror.simpleName] = clazz; 1158 errors[classMirror.simpleName] = clazz;
1098 } else if (classMirror.isClass) { 1159 } else if (classMirror.isClass) {
1099 classes[classMirror.simpleName] = clazz; 1160 classes[classMirror.simpleName] = clazz;
1100 } else { 1161 } else {
1101 throw new ArgumentError( 1162 throw new ArgumentError(
1102 '${classMirror.simpleName} - no class type match. '); 1163 '${classMirror.simpleName} - no class type match. ');
1103 } 1164 }
1104 } 1165 }
(...skipping 17 matching lines...) Expand all
1122 String returnType; 1183 String returnType;
1123 1184
1124 Map<String, Parameter> parameters; 1185 Map<String, Parameter> parameters;
1125 1186
1126 /// Generic information about the typedef. 1187 /// Generic information about the typedef.
1127 Map<String, Generic> generics; 1188 Map<String, Generic> generics;
1128 1189
1129 /// List of the meta annotations on the typedef. 1190 /// List of the meta annotations on the typedef.
1130 List<Annotation> annotations; 1191 List<Annotation> annotations;
1131 1192
1132 Typedef(String name, this.returnType, Function commentFunction, this.generics, 1193 Typedef(mirror) : super(mirror) {
1133 this.parameters, this.annotations, 1194 this.returnType = docName(mirror.value.returnType);
1134 String qualifiedName, bool isPrivate, String owner, Mirror mirror) 1195 this.generics = _processGenerics(mirror);
1135 : super(name, commentFunction, isPrivate, owner, mirror); 1196 this.parameters = _processParameters(mirror.value.parameters);
1197 this.annotations = _processAnnotations(mirror);
1198 }
1136 1199
1137 Map toMap() => { 1200 Map toMap() => {
1138 'name': name, 1201 'name': name,
1139 'qualifiedName': qualifiedName, 1202 'qualifiedName': qualifiedName,
1140 'comment': comment, 1203 'comment': comment,
1141 'return': returnType, 1204 'return': returnType,
1142 'parameters': recurseMap(parameters), 1205 'parameters': recurseMap(parameters),
1143 'annotations': annotations.map((a) => a.toMap()).toList(), 1206 'annotations': annotations.map((a) => a.toMap()).toList(),
1144 'generics': recurseMap(generics) 1207 'generics': recurseMap(generics)
1145 }; 1208 };
1146 1209
1147 String get typeName => 'typedef'; 1210 String get typeName => 'typedef';
1148 } 1211 }
1149 1212
1150 /// A class containing properties of a Dart variable. 1213 /// A class containing properties of a Dart variable.
1151 class Variable extends Indexable { 1214 class Variable extends Indexable {
1152 1215
1153 bool isFinal; 1216 bool isFinal;
1154 bool isStatic; 1217 bool isStatic;
1155 bool isConst; 1218 bool isConst;
1156 Type type; 1219 Type type;
1220 String _variableName;
1157 1221
1158 /// List of the meta annotations on the variable. 1222 /// List of the meta annotations on the variable.
1159 List<Annotation> annotations; 1223 List<Annotation> annotations;
1160 1224
1161 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type, 1225 Variable(this._variableName, VariableMirror mirror) : super(mirror) {
1162 Function commentFunction, this.annotations, String qualifiedName, 1226 this.isFinal = mirror.isFinal;
1163 bool isPrivate, String owner, Mirror mirror) 1227 this.isStatic = mirror.isStatic;
1164 : super(name, commentFunction, isPrivate, owner, mirror) { 1228 this.isConst = mirror.isConst;
1229 this.type = _processType(mirror.type);
1230 this.annotations = _processAnnotations(mirror);
1165 } 1231 }
1166 1232
1233 String get name => this._variableName;
Alan Knight 2013/11/20 21:29:20 Why the explicit "this."?
Emily Fortuna 2013/11/21 19:29:59 oops. Refactoring cruft from when it was part of t
1234
1167 /// Generates a map describing the [Variable] object. 1235 /// Generates a map describing the [Variable] object.
1168 Map toMap() => { 1236 Map toMap() => {
1169 'name': name, 1237 'name': name,
1170 'qualifiedName': qualifiedName, 1238 'qualifiedName': qualifiedName,
1171 'comment': comment, 1239 'comment': comment,
1172 'final': isFinal.toString(), 1240 'final': isFinal.toString(),
1173 'static': isStatic.toString(), 1241 'static': isStatic.toString(),
1174 'constant': isConst.toString(), 1242 'constant': isConst.toString(),
1175 'type': new List.filled(1, type.toMap()), 1243 'type': new List.filled(1, type.toMap()),
1176 'annotations': annotations.map((a) => a.toMap()).toList() 1244 'annotations': annotations.map((a) => a.toMap()).toList()
(...skipping 25 matching lines...) Expand all
1202 bool isSetter; 1270 bool isSetter;
1203 bool isOperator; 1271 bool isOperator;
1204 Type returnType; 1272 Type returnType;
1205 1273
1206 /// Qualified name to state where the comment is inherited from. 1274 /// Qualified name to state where the comment is inherited from.
1207 String commentInheritedFrom = ""; 1275 String commentInheritedFrom = "";
1208 1276
1209 /// List of the meta annotations on the method. 1277 /// List of the meta annotations on the method.
1210 List<Annotation> annotations; 1278 List<Annotation> annotations;
1211 1279
1212 Method(String name, this.isStatic, this.isAbstract, this.isConst, 1280 Method(MethodMirror mirror) : super(mirror) {
1213 this.returnType, Function commentFunction, this.parameters, 1281 this.isStatic = mirror.isStatic;
1214 this.annotations, 1282 this.isAbstract = mirror.isAbstract;
1215 String qualifiedName, bool isPrivate, String owner, this.isConstructor, 1283 this.isConst = mirror.isConstConstructor;
1216 this.isGetter, this.isSetter, this.isOperator, Mirror mirror) 1284 this.returnType = _processType(mirror.returnType);
1217 : super(name, commentFunction, isPrivate, owner, mirror) { 1285 this.parameters = _processParameters(mirror.parameters);
1286 this.annotations = _processAnnotations(mirror);
1287 this.isConstructor = mirror.isConstructor;
1288 this.isGetter = mirror.isGetter;
1289 this.isSetter = mirror.isSetter;
1290 this.isOperator = mirror.isOperator;
1218 } 1291 }
1219 1292
1220 /// Makes sure that the method with an inherited equivalent have comments. 1293 /// Makes sure that the method with an inherited equivalent have comments.
1221 void ensureCommentFor(Method inheritedMethod) { 1294 void ensureCommentFor(Method inheritedMethod) {
1222 if (comment.isNotEmpty) return; 1295 if (comment.isNotEmpty) return;
1223 comment = inheritedMethod._commentFunction(mirror); 1296 comment = inheritedMethod._commentFunction(mirror);
1224 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? 1297 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ?
1225 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; 1298 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom;
1226 } 1299 }
1227 1300
(...skipping 28 matching lines...) Expand all
1256 /// A container to categorize methods into the following groups: setters, 1329 /// A container to categorize methods into the following groups: setters,
1257 /// getters, constructors, operators, regular methods. 1330 /// getters, constructors, operators, regular methods.
1258 class MethodGroup { 1331 class MethodGroup {
1259 Map<String, Method> setters = {}; 1332 Map<String, Method> setters = {};
1260 Map<String, Method> getters = {}; 1333 Map<String, Method> getters = {};
1261 Map<String, Method> constructors = {}; 1334 Map<String, Method> constructors = {};
1262 Map<String, Method> operators = {}; 1335 Map<String, Method> operators = {};
1263 Map<String, Method> regularMethods = {}; 1336 Map<String, Method> regularMethods = {};
1264 1337
1265 void addMethod(MethodMirror mirror) { 1338 void addMethod(MethodMirror mirror) {
1266 var method = new Method(mirror.simpleName, mirror.isStatic, 1339 var method = new Method(mirror);
1267 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType),
1268 (actualMethod) => _commentToHtml(mirror, actualMethod),
1269 _parameters(mirror.parameters),
1270 _annotations(mirror), docName(mirror), _isHidden(mirror),
1271 docName(mirror.owner), mirror.isConstructor, mirror.isGetter,
1272 mirror.isSetter, mirror.isOperator, mirror);
1273 entityMap[docName(mirror)] = method; 1340 entityMap[docName(mirror)] = method;
1274 if (mirror.isSetter) { 1341 if (mirror.isSetter) {
1275 setters[mirror.simpleName] = method; 1342 setters[mirror.simpleName] = method;
1276 } else if (mirror.isGetter) { 1343 } else if (mirror.isGetter) {
1277 getters[mirror.simpleName] = method; 1344 getters[mirror.simpleName] = method;
1278 } else if (mirror.isConstructor) { 1345 } else if (mirror.isConstructor) {
1279 constructors[mirror.simpleName] = method; 1346 constructors[mirror.simpleName] = method;
1280 } else if (mirror.isOperator) { 1347 } else if (mirror.isOperator) {
1281 operators[mirror.simpleName] = method; 1348 operators[mirror.simpleName] = method;
1282 } else if (mirror.isRegularMethod) { 1349 } else if (mirror.isRegularMethod) {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 'name': qualifiedName, 1482 'name': qualifiedName,
1416 'parameters': parameters 1483 'parameters': parameters
1417 }; 1484 };
1418 } 1485 }
1419 1486
1420 /// Given a mirror, returns its qualified name, but following the conventions 1487 /// Given a mirror, returns its qualified name, but following the conventions
1421 /// we're using in Dartdoc, which is that library names with dots in them 1488 /// we're using in Dartdoc, which is that library names with dots in them
1422 /// have them replaced with hyphens. 1489 /// have them replaced with hyphens.
1423 String docName(DeclarationMirror m) { 1490 String docName(DeclarationMirror m) {
1424 if (m is LibraryMirror) { 1491 if (m is LibraryMirror) {
1425 return (m as LibraryMirror).qualifiedName.replaceAll('.','-'); 1492 return m.qualifiedName.replaceAll('.','-');
1426 } 1493 }
1427 var owner = m.owner; 1494 var owner = m.owner;
1428 if (owner == null) return m.qualifiedName; 1495 if (owner == null) return m.qualifiedName;
1429 // For the unnamed constructor we just return the class name. 1496 // For the unnamed constructor we just return the class name.
1430 if (m.simpleName == '') return docName(owner); 1497 if (m.simpleName == '') return docName(owner);
1431 return docName(owner) + '.' + m.simpleName; 1498 return docName(owner) + '.' + m.simpleName;
1432 } 1499 }
1433 1500
1434 /// Remove statics from the map of inherited items before adding them. 1501 /// Remove statics from the map of inherited items before adding them.
1435 Map _filterStatics(Map items) { 1502 Map _filterStatics(Map items) {
1436 var result = {}; 1503 var result = {};
1437 items.forEach((name, item) { 1504 items.forEach((name, item) {
1438 if (!item.isStatic) { 1505 if (!item.isStatic) {
1439 result[name] = item; 1506 result[name] = item;
1440 } 1507 }
1441 }); 1508 });
1442 return result; 1509 return result;
1443 } 1510 }
OLDNEW
« no previous file with comments | « pkg/docgen/bin/dartdoc.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698