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

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

Issue 180243024: pkg/docgen: refactoring and cleanup (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: just refactoring Created 6 years, 9 months 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 | « no previous file | pkg/docgen/lib/src/mdn.dart » ('j') | pkg/docgen/lib/src/models.dart » ('J')
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]
11 /// 11 ///
12 /// This creates files called `docs/<library_name>.yaml` in your current 12 /// This creates files called `docs/<library_name>.yaml` in your current
13 /// working directory. 13 /// working directory.
14 library docgen; 14 library docgen;
15 15
16 import 'dart:convert'; 16 import 'dart:convert';
17 import 'dart:io'; 17 import 'dart:io';
18 import 'dart:async'; 18 import 'dart:async';
19 19
20 import 'package:logging/logging.dart'; 20 import 'package:logging/logging.dart';
21 import 'package:markdown/markdown.dart' as markdown; 21 import 'package:markdown/markdown.dart' as markdown;
22 import 'package:path/path.dart' as path; 22 import 'package:path/path.dart' as path;
23 import 'package:yaml/yaml.dart'; 23 import 'package:yaml/yaml.dart';
24 24
25 import 'dart2yaml.dart'; 25 import 'dart2yaml.dart';
26 import 'src/io.dart'; 26 import 'src/io.dart';
27 import 'src/mdn.dart';
28 import 'src/models.dart';
29 import 'src/utils.dart';
30
27 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; 31 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api;
28 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart'; 32 import '../../../sdk/lib/_internal/compiler/implementation/filenames.dart';
29 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro rs.dart' 33 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirro rs.dart'
30 as dart2js_mirrors; 34 as dart2js_mirrors;
31 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart' 35 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart'
32 as dart2js; 36 as dart2js;
33 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/source_mirror s.dart'; 37 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/source_mirror s.dart';
34 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util. dart' 38 import '../../../sdk/lib/_internal/compiler/implementation/mirrors/mirrors_util. dart'
35 as dart2js_util; 39 as dart2js_util;
36 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart'; 40 import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider. dart';
37 import '../../../sdk/lib/_internal/libraries.dart'; 41 import '../../../sdk/lib/_internal/libraries.dart';
38 42
39 const _DEFAULT_OUTPUT_DIRECTORY = 'docs'; 43 const _DEFAULT_OUTPUT_DIRECTORY = 'docs';
40 44
41 /// Annotations that we do not display in the viewer. 45 /// Annotations that we do not display in the viewer.
42 const List<String> _SKIPPED_ANNOTATIONS = const [ 46 const List<String> _SKIPPED_ANNOTATIONS = const [
43 'metadata.DocsEditable', '_js_helper.JSName', '_js_helper.Creates', 47 'metadata.DocsEditable', '_js_helper.JSName', '_js_helper.Creates',
44 '_js_helper.Returns']; 48 '_js_helper.Returns'];
45 49
46 /// Support for [:foo:]-style code comments to the markdown parser. 50 /// Support for [:foo:]-style code comments to the markdown parser.
47 List<markdown.InlineSyntax> _MARKDOWN_SYNTAXES = 51 final List<markdown.InlineSyntax> _MARKDOWN_SYNTAXES =
48 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')]; 52 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')];
49 53
50 /// If we can't find the SDK introduction text, which will happen if running 54 /// If we can't find the SDK introduction text, which will happen if running
51 /// from a snapshot and using --parse-sdk or --include-sdk, then use this 55 /// from a snapshot and using --parse-sdk or --include-sdk, then use this
52 /// hard-coded version. This should be updated to be consistent with the text 56 /// hard-coded version. This should be updated to be consistent with the text
53 /// in docgen/doc/sdk-introduction.md 57 /// in docgen/doc/sdk-introduction.md
54 const _DEFAULT_SDK_INTRODUCTION = """ 58 const _DEFAULT_SDK_INTRODUCTION = """
55 Welcome to the Dart API reference documentation, 59 Welcome to the Dart API reference documentation,
56 covering the official Dart API libraries. 60 covering the official Dart API libraries.
57 Some of the most fundamental Dart libraries include: 61 Some of the most fundamental Dart libraries include:
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 String get packagePrefix => packageName == null || packageName.isEmpty ? 215 String get packagePrefix => packageName == null || packageName.isEmpty ?
212 '' : '$packageName/'; 216 '' : '$packageName/';
213 217
214 LibraryMirror _getOwningLibraryFromMirror(DeclarationMirror mirror) { 218 LibraryMirror _getOwningLibraryFromMirror(DeclarationMirror mirror) {
215 if (mirror is LibraryMirror) return mirror; 219 if (mirror is LibraryMirror) return mirror;
216 if (mirror == null) return null; 220 if (mirror == null) return null;
217 return _getOwningLibraryFromMirror(mirror.owner); 221 return _getOwningLibraryFromMirror(mirror.owner);
218 } 222 }
219 } 223 }
220 224
221 /// Docgen representation of an item to be documented, that wraps around a
222 /// dart2js mirror.
223 abstract class MirrorBased {
224 /// The original dart2js mirror around which this object wraps.
225 DeclarationMirror get mirror;
226
227 /// Returns a list of meta annotations assocated with a mirror.
228 static List<Annotation> _createAnnotations(DeclarationMirror mirror,
229 Library owningLibrary) {
230 var annotationMirrors = mirror.metadata.where((e) =>
231 e is dart2js_mirrors.Dart2JsConstructedConstantMirror);
232 var annotations = [];
233 annotationMirrors.forEach((annotation) {
234 var docgenAnnotation = new Annotation(annotation, owningLibrary);
235 if (!_SKIPPED_ANNOTATIONS.contains(
236 dart2js_util.qualifiedNameOf(docgenAnnotation.mirror))) {
237 annotations.add(docgenAnnotation);
238 }
239 });
240 return annotations;
241 }
242 }
243
244 /// Top level documentation traversal and generation object. 225 /// Top level documentation traversal and generation object.
245 /// 226 ///
246 /// Yes, everything in this class is used statically so this technically doesn't 227 /// Yes, everything in this class is used statically so this technically doesn't
247 /// need to be its own class, but it's grouped together for semantic separation 228 /// need to be its own class, but it's grouped together for semantic separation
248 /// from the other classes and functionality in this library. 229 /// from the other classes and functionality in this library.
249 class _Generator { 230 class _Generator {
250 /// The directory where the output docs are generated. 231 /// The directory where the output docs are generated.
251 static String _outputDirectory; 232 static String _outputDirectory;
252 233
253 /// This is set from the command line arguments flag --include-private 234 /// This is set from the command line arguments flag --include-private
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 }); 817 });
837 } 818 }
838 }, 819 },
839 onError: (e) { 820 onError: (e) {
840 print('HttpServer: an error occured $e'); 821 print('HttpServer: an error occured $e');
841 }); 822 });
842 }); 823 });
843 } 824 }
844 } 825 }
845 826
827 /** Walk up the owner chain to find the owning library. */
Emily Fortuna 2014/03/06 22:05:38 Consistency! Triple slashes are everywhere through
kevmoo 2014/03/06 22:20:17 Sticking with copy-paste the old style for this CL
828 Library _getOwningLibrary(Indexable indexable) {
Emily Fortuna 2014/03/06 22:05:38 make static function instead of global?
kevmoo 2014/03/06 22:20:17 If the static uses privates on the class or make u
Alan Knight 2014/03/12 18:17:56 Why static or global at all? Why not just have thi
kevmoo 2014/03/17 02:01:29 Done.
829 if (indexable is Library) return indexable;
830 return _getOwningLibrary(indexable.owner);
831 }
832
846 /// An item that is categorized in our mirrorToDocgen map, as a distinct, 833 /// An item that is categorized in our mirrorToDocgen map, as a distinct,
847 /// searchable element. 834 /// searchable element.
848 /// 835 ///
849 /// These are items that refer to concrete entities (a Class, for example, 836 /// These are items that refer to concrete entities (a Class, for example,
850 /// but not a Type, which is a "pointer" to a class) that we wish to be 837 /// but not a Type, which is a "pointer" to a class) that we wish to be
851 /// globally resolvable. This includes things such as class methods and 838 /// globally resolvable. This includes things such as class methods and
852 /// variables, but parameters for methods are not "Indexable" as we do not want 839 /// variables, but parameters for methods are not "Indexable" as we do not want
853 /// the user to be able to search for a method based on its parameter names! 840 /// the user to be able to search for a method based on its parameter names!
854 /// The set of indexable items also includes Typedefs, since the user can refer 841 /// The set of indexable items also includes Typedefs, since the user can refer
855 /// to them as concrete entities in a particular scope. 842 /// to them as concrete entities in a particular scope.
856 abstract class Indexable extends MirrorBased { 843 abstract class Indexable extends MirrorBased {
857 /// The dart:core library, which contains all types that are always available 844 /// The dart:core library, which contains all types that are always available
858 /// without import. 845 /// without import.
859 static Library _coreLibrary; 846 static Library _coreLibrary;
860 847
861 /// Set of libraries declared in the SDK, so libraries that can be accessed 848 /// Set of libraries declared in the SDK, so libraries that can be accessed
862 /// when running dart by default. 849 /// when running dart by default.
863 static Iterable<LibraryMirror> _sdkLibraries; 850 static Iterable<LibraryMirror> _sdkLibraries;
864 851
852 final DeclarationMirror mirror;
Alan Knight 2014/03/12 18:17:56 If we're re-formatting these to have their own lin
kevmoo 2014/03/17 02:01:29 Not sure what the docs should be. Reverting whites
853
854 final bool isPrivate;
855
865 String get qualifiedName => fileName; 856 String get qualifiedName => fileName;
866 bool isPrivate; 857
867 DeclarationMirror mirror;
868 /// The comment text pre-resolution. We keep this around because inherited 858 /// The comment text pre-resolution. We keep this around because inherited
869 /// methods need to resolve links differently from the superclass. 859 /// methods need to resolve links differently from the superclass.
870 String _unresolvedComment = ''; 860 String _unresolvedComment = '';
871 861
872 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move
873 // MDN-specific code to its own library that is imported into the default
874 // impl?
875 /// Map of all the comments for dom elements from MDN.
876 static Map _mdn;
877 862
878 /// Index of all the dart2js mirrors examined to corresponding MirrorBased 863 /// Index of all the dart2js mirrors examined to corresponding MirrorBased
879 /// docgen objects. 864 /// docgen objects.
880 /// 865 ///
881 /// Used for lookup because of the dart2js mirrors exports 866 /// Used for lookup because of the dart2js mirrors exports
882 /// issue. The second level map is indexed by owner docName for faster lookup. 867 /// issue. The second level map is indexed by owner docName for faster lookup.
883 /// Why two levels of lookup? Speed, man. Speed. 868 /// Why two levels of lookup? Speed, man. Speed.
884 static Map<String, Map<String, Set<Indexable>>> _mirrorToDocgen = 869 static Map<String, Map<String, Set<Indexable>>> _mirrorToDocgen =
885 new Map<String, Map<String, Set<Indexable>>>(); 870 new Map<String, Map<String, Set<Indexable>>>();
886 871
887 Indexable(this.mirror) { 872 Indexable(DeclarationMirror mirror)
888 this.isPrivate = _isHidden(mirror); 873 : this.mirror = mirror,
874 this.isPrivate = isHidden(mirror) {
889 875
890 var map = _mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)]; 876 var map = _mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)];
891 if (map == null) map = new Map<String, Set<Indexable>>(); 877 if (map == null) map = new Map<String, Set<Indexable>>();
892 878
893 var set = map[owner.docName]; 879 var set = map[owner.docName];
894 if (set == null) set = new Set<Indexable>(); 880 if (set == null) set = new Set<Indexable>();
895 set.add(this); 881 set.add(this);
896 map[owner.docName] = set; 882 map[owner.docName] = set;
897 _mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)] = map; 883 _mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)] = map;
898 } 884 }
899 885
900 /** Walk up the owner chain to find the owning library. */
901 Library _getOwningLibrary(Indexable indexable) {
902 if (indexable is Library) return indexable;
903 return _getOwningLibrary(indexable.owner);
904 }
905
906 static _initializeTopLevelLibraries(MirrorSystem mirrorSystem) { 886 static _initializeTopLevelLibraries(MirrorSystem mirrorSystem) {
907 _sdkLibraries = mirrorSystem.libraries.values.where( 887 _sdkLibraries = mirrorSystem.libraries.values.where(
908 (each) => each.uri.scheme == 'dart'); 888 (each) => each.uri.scheme == 'dart');
909 _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) => 889 _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) =>
910 lib.uri.toString().startsWith('dart:core'))); 890 lib.uri.toString().startsWith('dart:core')));
911 } 891 }
912 892
913 /// Returns this object's qualified name, but following the conventions 893 /// Returns this object's qualified name, but following the conventions
914 /// we're using in Dartdoc, which is that library names with dots in them 894 /// we're using in Dartdoc, which is that library names with dots in them
915 /// have them replaced with hyphens. 895 /// have them replaced with hyphens.
916 String get docName; 896 String get docName;
917 897
918 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. 898 /// Converts all [foo] references in comments to <a>libraryName.foo</a>.
919 markdown.Node fixReference(String name) { 899 markdown.Node fixReference(String name) {
920 // Attempt the look up the whole name up in the scope. 900 // Attempt the look up the whole name up in the scope.
921 String elementName = findElementInScope(name); 901 String elementName = findElementInScope(name);
922 if (elementName != null) { 902 if (elementName != null) {
923 return new markdown.Element.text('a', elementName); 903 return new markdown.Element.text('a', elementName);
924 } 904 }
925 return _fixComplexReference(name); 905 return _fixComplexReference(name);
926 } 906 }
927 907
928 /// Look for the specified name starting with the current member, and 908 /// Look for the specified name starting with the current member, and
929 /// progressively working outward to the current library scope. 909 /// progressively working outward to the current library scope.
930 String findElementInScope(String name) => 910 String findElementInScope(String name) =>
931 _findElementInScope(name, packagePrefix); 911 _findElementInScope(name, packagePrefix);
932 912
933 /// For a given name, determine if we need to resolve it as a qualified name
934 /// or a simple name in the source mirors.
935 static determineLookupFunc(name) => name.contains('.') ?
936 dart2js_util.lookupQualifiedInScope :
937 (mirror, name) => mirror.lookupInScope(name);
938
939 /// The reference to this element based on where it is printed as a 913 /// The reference to this element based on where it is printed as a
940 /// documentation file and also the unique URL to refer to this item. 914 /// documentation file and also the unique URL to refer to this item.
941 /// 915 ///
942 /// The qualified name (for URL purposes) and the file name are the same, 916 /// The qualified name (for URL purposes) and the file name are the same,
943 /// of the form packageName/ClassName or packageName/ClassName.methodName. 917 /// of the form packageName/ClassName or packageName/ClassName.methodName.
944 /// This defines both the URL and the directory structure. 918 /// This defines both the URL and the directory structure.
945 String get fileName => packagePrefix + ownerPrefix + name; 919 String get fileName => packagePrefix + ownerPrefix + name;
946 920
947 /// The full docName of the owner element, appended with a '.' for this 921 /// The full docName of the owner element, appended with a '.' for this
948 /// object's name to be appended. 922 /// object's name to be appended.
(...skipping 30 matching lines...) Expand all
979 /// 953 ///
980 /// "Owning" is defined as the object one scope-level above which this item 954 /// "Owning" is defined as the object one scope-level above which this item
981 /// is defined. Ex: The owner for a top level class, would be its enclosing 955 /// is defined. Ex: The owner for a top level class, would be its enclosing
982 /// library. The owner of a local variable in a method would be the enclosing 956 /// library. The owner of a local variable in a method would be the enclosing
983 /// method. 957 /// method.
984 Indexable get owner => new DummyMirror(mirror.owner); 958 Indexable get owner => new DummyMirror(mirror.owner);
985 959
986 /// Generates MDN comments from database.json. 960 /// Generates MDN comments from database.json.
987 String _mdnComment(); 961 String _mdnComment();
988 962
989 /// Generates the MDN Comment for variables and method DOM elements.
990 String _mdnMemberComment(String type, String member) {
991 var mdnType = _mdn[type];
992 if (mdnType == null) return '';
993 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member,
994 orElse: () => null);
995 if (mdnMember == null) return '';
996 if (mdnMember['help'] == null || mdnMember['help'] == '') return '';
997 if (mdnMember['url'] == null) return '';
998 return _htmlifyMdn(mdnMember['help'], mdnMember['url']);
999 }
1000
1001 /// Generates the MDN Comment for class DOM elements.
1002 String _mdnTypeComment(String type) {
1003 var mdnType = _mdn[type];
1004 if (mdnType == null) return '';
1005 if (mdnType['summary'] == null || mdnType['summary'] == "") return '';
1006 if (mdnType['srcUrl'] == null) return '';
1007 return _htmlifyMdn(mdnType['summary'], mdnType['srcUrl']);
1008 }
1009
1010 /// Encloses the given content in an MDN div and the original source link.
1011 String _htmlifyMdn(String content, String url) {
1012 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">'
1013 '<a href="' + url.trim() + '">from Mdn</a></p></div>';
1014 }
1015
1016 /// The type of this member to be used in index.txt. 963 /// The type of this member to be used in index.txt.
1017 String get typeName => ''; 964 String get typeName => '';
1018 965
1019 /// Creates a [Map] with this [Indexable]'s name and a preview comment. 966 /// Creates a [Map] with this [Indexable]'s name and a preview comment.
1020 Map get previewMap { 967 Map get previewMap {
1021 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; 968 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName };
1022 var preview = _preview; 969 var preview = _preview;
1023 if(preview != null) finalMap['preview'] = preview; 970 if(preview != null) finalMap['preview'] = preview;
1024 return finalMap; 971 return finalMap;
1025 } 972 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 /// Returns a map of [Variable] objects constructed from [mirrorMap]. 1021 /// Returns a map of [Variable] objects constructed from [mirrorMap].
1075 /// The optional parameter [containingLibrary] is contains data for variables 1022 /// The optional parameter [containingLibrary] is contains data for variables
1076 /// defined at the top level of a library (potentially for exporting 1023 /// defined at the top level of a library (potentially for exporting
1077 /// purposes). 1024 /// purposes).
1078 Map<String, Variable> _createVariables(Iterable<VariableMirror> mirrors, 1025 Map<String, Variable> _createVariables(Iterable<VariableMirror> mirrors,
1079 Indexable owner) { 1026 Indexable owner) {
1080 var data = {}; 1027 var data = {};
1081 // TODO(janicejl): When map to map feature is created, replace the below 1028 // TODO(janicejl): When map to map feature is created, replace the below
1082 // with a filter. Issue(#9590). 1029 // with a filter. Issue(#9590).
1083 mirrors.forEach((VariableMirror mirror) { 1030 mirrors.forEach((VariableMirror mirror) {
1084 if (_Generator._includePrivate || !_isHidden(mirror)) { 1031 if (_Generator._includePrivate || !isHidden(mirror)) {
1085 var mirrorName = dart2js_util.nameOf(mirror); 1032 var mirrorName = dart2js_util.nameOf(mirror);
1086 data[mirrorName] = new Variable(mirrorName, mirror, owner); 1033 data[mirrorName] = new Variable(mirrorName, mirror, owner);
1087 } 1034 }
1088 }); 1035 });
1089 return data; 1036 return data;
1090 } 1037 }
1091 1038
1092 /// Returns a map of [Method] objects constructed from [mirrorMap]. 1039 /// Returns a map of [Method] objects constructed from [mirrorMap].
1093 /// The optional parameter [containingLibrary] is contains data for variables 1040 /// The optional parameter [containingLibrary] is contains data for variables
1094 /// defined at the top level of a library (potentially for exporting 1041 /// defined at the top level of a library (potentially for exporting
(...skipping 26 matching lines...) Expand all
1121 key: (e) => dart2js_util.nameOf(e), 1068 key: (e) => dart2js_util.nameOf(e),
1122 value: (e) => new Generic(e)); 1069 value: (e) => new Generic(e));
1123 } 1070 }
1124 1071
1125 /// Return an informative [Object.toString] for debugging. 1072 /// Return an informative [Object.toString] for debugging.
1126 String toString() => "${super.toString()}(${name.toString()})"; 1073 String toString() => "${super.toString()}(${name.toString()})";
1127 1074
1128 /// Return a map representation of this type. 1075 /// Return a map representation of this type.
1129 Map toMap(); 1076 Map toMap();
1130 1077
1131 /// A declaration is private if itself is private, or the owner is private.
1132 // Issue(12202) - A declaration is public even if it's owner is private.
1133 bool _isHidden(DeclarationMirror mirror) {
1134 if (mirror is LibraryMirror) {
1135 return _isLibraryPrivate(mirror);
1136 } else if (mirror.owner is LibraryMirror) {
1137 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner)
1138 || mirror.isNameSynthetic);
1139 } else {
1140 return (mirror.isPrivate || _isHidden(mirror.owner)
1141 || owner.mirror.isNameSynthetic);
1142 }
1143 }
1144 1078
1145 /// Returns true if a library name starts with an underscore, and false
1146 /// otherwise.
1147 ///
1148 /// An example that starts with _ is _js_helper.
1149 /// An example that contains ._ is dart._collection.dev
1150 bool _isLibraryPrivate(LibraryMirror mirror) {
1151 // This method is needed because LibraryMirror.isPrivate returns `false` all
1152 // the time.
1153 var sdkLibrary = LIBRARIES[dart2js_util.nameOf(mirror)];
1154 if (sdkLibrary != null) {
1155 return !sdkLibrary.documented;
1156 } else if (dart2js_util.nameOf(mirror).startsWith('_') ||
1157 dart2js_util.nameOf(mirror).contains('._')) {
1158 return true;
1159 }
1160 return false;
1161 }
1162 1079
1163 ////// Top level resolution functions 1080 ////// Top level resolution functions
1164 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. 1081 /// Converts all [foo] references in comments to <a>libraryName.foo</a>.
1165 static markdown.Node globalFixReference(String name) { 1082 static markdown.Node globalFixReference(String name) {
1166 // Attempt the look up the whole name up in the scope. 1083 // Attempt the look up the whole name up in the scope.
1167 String elementName = _findElementInScope(name, ''); 1084 String elementName = _findElementInScope(name, '');
1168 if (elementName != null) { 1085 if (elementName != null) {
1169 return new markdown.Element.text('a', elementName); 1086 return new markdown.Element.text('a', elementName);
1170 } 1087 }
1171 return _fixComplexReference(name); 1088 return _fixComplexReference(name);
1172 } 1089 }
1173 1090
1174 /// This is a more complex reference. Try to break up if its of the form A<B> 1091 /// This is a more complex reference. Try to break up if its of the form A<B>
1175 /// where A is an alphanumeric string and B is an A, a list of B ("B, B, B"), 1092 /// where A is an alphanumeric string and B is an A, a list of B ("B, B, B"),
1176 /// or of the form A<B>. Note: unlike other the other markdown-style links, 1093 /// or of the form A<B>. Note: unlike other the other markdown-style links,
1177 /// all text inside the square brackets is treated as part of the link (aka 1094 /// all text inside the square brackets is treated as part of the link (aka
1178 /// the * is interpreted literally as a *, not as a indicator for bold <em>. 1095 /// the * is interpreted literally as a *, not as a indicator for bold <em>.
1179 /// 1096 ///
1180 /// Example: [foo&lt;_bar_>] will produce 1097 /// Example: [foo&lt;_bar_>] will produce
1181 /// <a>resolvedFoo</a>&lt;<a>resolved_bar_</a>> rather than an italicized 1098 /// <a>resolvedFoo</a>&lt;<a>resolved_bar_</a>> rather than an italicized
1182 /// version of resolvedBar. 1099 /// version of resolvedBar.
1183 static markdown.Node _fixComplexReference(String name) { 1100 static markdown.Node _fixComplexReference(String name) {
1184 // Parse into multiple elements we can try to resolve. 1101 // Parse into multiple elements we can try to resolve.
1185 var tokens = _tokenizeComplexReference(name); 1102 var tokens = tokenizeComplexReference(name);
1186 1103
1187 // Produce an html representation of our elements. Group unresolved and 1104 // Produce an html representation of our elements. Group unresolved and
1188 // plain text are grouped into "link" elements so they display as code. 1105 // plain text are grouped into "link" elements so they display as code.
1189 final textElements = [' ', ',', '>', _LESS_THAN]; 1106 final textElements = [' ', ',', '>', LESS_THAN];
1190 var accumulatedHtml = ''; 1107 var accumulatedHtml = '';
1191 1108
1192 for (var token in tokens) { 1109 for (var token in tokens) {
1193 bool added = false; 1110 bool added = false;
1194 if (!textElements.contains(token)) { 1111 if (!textElements.contains(token)) {
1195 String elementName = _findElementInScope(token, ''); 1112 String elementName = _findElementInScope(token, '');
1196 if (elementName != null) { 1113 if (elementName != null) {
1197 accumulatedHtml += markdown.renderToHtml([new markdown.Element.text( 1114 accumulatedHtml += markdown.renderToHtml([new markdown.Element.text(
1198 'a', elementName)]); 1115 'a', elementName)]);
1199 added = true; 1116 added = true;
1200 } 1117 }
1201 } 1118 }
1202 if (!added) { 1119 if (!added) {
1203 accumulatedHtml += token; 1120 accumulatedHtml += token;
1204 } 1121 }
1205 } 1122 }
1206 return new markdown.Text(accumulatedHtml); 1123 return new markdown.Text(accumulatedHtml);
1207 } 1124 }
1208 1125
1209
1210 // HTML escaped version of '<' character.
1211 static final _LESS_THAN = '&lt;';
1212
1213 /// Chunk the provided name into individual parts to be resolved. We take a
1214 /// simplistic approach to chunking, though, we break at " ", ",", "&lt;"
1215 /// and ">". All other characters are grouped into the name to be resolved.
1216 /// As a result, these characters will all be treated as part of the item to
1217 /// be resolved (aka the * is interpreted literally as a *, not as an
1218 /// indicator for bold <em>.
1219 static List<String> _tokenizeComplexReference(String name) {
1220 var tokens = [];
1221 var append = false;
1222 var index = 0;
1223 while(index < name.length) {
1224 if (name.indexOf(_LESS_THAN, index) == index) {
1225 tokens.add(_LESS_THAN);
1226 append = false;
1227 index += _LESS_THAN.length;
1228 } else if (name[index] == ' ' || name[index] == ',' ||
1229 name[index] == '>') {
1230 tokens.add(name[index]);
1231 append = false;
1232 index++;
1233 } else {
1234 if (append) {
1235 tokens[tokens.length - 1] = tokens.last + name[index];
1236 } else {
1237 tokens.add(name[index]);
1238 append = true;
1239 }
1240 index++;
1241 }
1242 }
1243 return tokens;
1244 }
1245
1246 static String _findElementInScope(String name, String packagePrefix) { 1126 static String _findElementInScope(String name, String packagePrefix) {
1247 var lookupFunc = determineLookupFunc(name); 1127 var lookupFunc = determineLookupFunc(name);
1248 // Look in the dart core library scope. 1128 // Look in the dart core library scope.
1249 var coreScope = _coreLibrary == null? null : 1129 var coreScope = _coreLibrary == null? null :
1250 lookupFunc(_coreLibrary.mirror, name); 1130 lookupFunc(_coreLibrary.mirror, name);
1251 if (coreScope != null) return packagePrefix + _coreLibrary.docName; 1131 if (coreScope != null) return packagePrefix + _coreLibrary.docName;
1252 1132
1253 // If it's a reference that starts with a another library name, then it 1133 // If it's a reference that starts with a another library name, then it
1254 // looks for a match of that library name in the other sdk libraries. 1134 // looks for a match of that library name in the other sdk libraries.
1255 if(name.contains('.')) { 1135 if(name.contains('.')) {
(...skipping 15 matching lines...) Expand all
1271 } 1151 }
1272 } 1152 }
1273 } 1153 }
1274 } 1154 }
1275 return null; 1155 return null;
1276 } 1156 }
1277 1157
1278 /// Expand the method map [mapToExpand] into a more detailed map that 1158 /// Expand the method map [mapToExpand] into a more detailed map that
1279 /// separates out setters, getters, constructors, operators, and methods. 1159 /// separates out setters, getters, constructors, operators, and methods.
1280 Map _expandMethodMap(Map<String, Method> mapToExpand) => { 1160 Map _expandMethodMap(Map<String, Method> mapToExpand) => {
1281 'setters': recurseMap(_filterMap(mapToExpand, 1161 'setters': recurseMap(filterMap(mapToExpand,
1282 (key, val) => val.mirror.isSetter)), 1162 (key, val) => val.mirror.isSetter)),
1283 'getters': recurseMap(_filterMap(mapToExpand, 1163 'getters': recurseMap(filterMap(mapToExpand,
1284 (key, val) => val.mirror.isGetter)), 1164 (key, val) => val.mirror.isGetter)),
1285 'constructors': recurseMap(_filterMap(mapToExpand, 1165 'constructors': recurseMap(filterMap(mapToExpand,
1286 (key, val) => val.mirror.isConstructor)), 1166 (key, val) => val.mirror.isConstructor)),
1287 'operators': recurseMap(_filterMap(mapToExpand, 1167 'operators': recurseMap(filterMap(mapToExpand,
1288 (key, val) => val.mirror.isOperator)), 1168 (key, val) => val.mirror.isOperator)),
1289 'methods': recurseMap(_filterMap(mapToExpand, 1169 'methods': recurseMap(filterMap(mapToExpand,
1290 (key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator)) 1170 (key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator))
1291 }; 1171 };
1292 1172
1293 /// Transforms the map by calling toMap on each value in it.
1294 Map recurseMap(Map inputMap) {
1295 var outputMap = {};
1296 inputMap.forEach((key, value) {
1297 if (value is Map) {
1298 outputMap[key] = recurseMap(value);
1299 } else {
1300 outputMap[key] = value.toMap();
1301 }
1302 });
1303 return outputMap;
1304 }
1305
1306 Map _filterMap(Map map, Function test) {
1307 var exported = new Map();
1308 map.forEach((key, value) {
1309 if (test(key, value)) exported[key] = value;
1310 });
1311 return exported;
1312 }
1313
1314 /// Accessor to determine if this item and all of its owners are visible. 1173 /// Accessor to determine if this item and all of its owners are visible.
1315 bool get _isVisible => _Generator._isFullChainVisible(this); 1174 bool get _isVisible => _Generator._isFullChainVisible(this);
1316 1175
1317 /// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object. 1176 /// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object.
1318 /// 1177 ///
1319 /// We have this global lookup function to avoid re-implementing looking up 1178 /// We have this global lookup function to avoid re-implementing looking up
1320 /// the scoping rules for comment resolution here (it is currently done in 1179 /// the scoping rules for comment resolution here (it is currently done in
1321 /// mirrors). If no corresponding MirrorBased object is found, we return a 1180 /// mirrors). If no corresponding MirrorBased object is found, we return a
1322 /// [DummyMirror] that simply returns the original mirror's qualifiedName 1181 /// [DummyMirror] that simply returns the original mirror's qualifiedName
1323 /// while behaving like a MirrorBased object. 1182 /// while behaving like a MirrorBased object.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1421 this.functions = _createMethods(_addAll(exported['methods'], 1280 this.functions = _createMethods(_addAll(exported['methods'],
1422 libraryMirror.declarations.values.where( 1281 libraryMirror.declarations.values.where(
1423 (mirror) => mirror is MethodMirror)).values, this); 1282 (mirror) => mirror is MethodMirror)).values, this);
1424 this.variables = _createVariables(_addAll(exported['variables'], 1283 this.variables = _createVariables(_addAll(exported['variables'],
1425 dart2js_util.variablesOf(libraryMirror.declarations)).values, this); 1284 dart2js_util.variablesOf(libraryMirror.declarations)).values, this);
1426 } 1285 }
1427 1286
1428 /// Look for the specified name starting with the current member, and 1287 /// Look for the specified name starting with the current member, and
1429 /// progressively working outward to the current library scope. 1288 /// progressively working outward to the current library scope.
1430 String findElementInScope(String name) { 1289 String findElementInScope(String name) {
1431 var lookupFunc = Indexable.determineLookupFunc(name); 1290 var lookupFunc = determineLookupFunc(name);
1432 var libraryScope = lookupFunc(mirror, name); 1291 var libraryScope = lookupFunc(mirror, name);
1433 if (libraryScope != null) { 1292 if (libraryScope != null) {
1434 var result = Indexable.getDocgenObject(libraryScope, this); 1293 var result = Indexable.getDocgenObject(libraryScope, this);
1435 if (result is DummyMirror) return packagePrefix + result.docName; 1294 if (result is DummyMirror) return packagePrefix + result.docName;
1436 return result.packagePrefix + result.docName; 1295 return result.packagePrefix + result.docName;
1437 } 1296 }
1438 return super.findElementInScope(name); 1297 return super.findElementInScope(name);
1439 } 1298 }
1440 1299
1441 String _mdnComment() => ''; 1300 String _mdnComment() => '';
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1562 /// corresponding to the actual DeclarationMirror. 1421 /// corresponding to the actual DeclarationMirror.
1563 Map<String, Map<String, DeclarationMirror>> _calcExportedItems( 1422 Map<String, Map<String, DeclarationMirror>> _calcExportedItems(
1564 LibrarySourceMirror library) { 1423 LibrarySourceMirror library) {
1565 var exports = {}; 1424 var exports = {};
1566 exports['classes'] = {}; 1425 exports['classes'] = {};
1567 exports['methods'] = {}; 1426 exports['methods'] = {};
1568 exports['variables'] = {}; 1427 exports['variables'] = {};
1569 1428
1570 // Determine the classes, variables and methods that are exported for a 1429 // Determine the classes, variables and methods that are exported for a
1571 // specific dependency. 1430 // specific dependency.
1572 _populateExports(LibraryDependencyMirror export, bool showExport) { 1431 void _populateExports(LibraryDependencyMirror export, bool showExport) {
1573 if (!showExport) { 1432 if (!showExport) {
1574 // Add all items, and then remove the hidden ones. 1433 // Add all items, and then remove the hidden ones.
1575 // Ex: "export foo hide bar" 1434 // Ex: "export foo hide bar"
1576 _addAll(exports['classes'], 1435 _addAll(exports['classes'],
1577 dart2js_util.typesOf(export.targetLibrary.declarations)); 1436 dart2js_util.typesOf(export.targetLibrary.declarations));
1578 _addAll(exports['methods'], 1437 _addAll(exports['methods'],
1579 export.targetLibrary.declarations.values.where( 1438 export.targetLibrary.declarations.values.where(
1580 (mirror) => mirror is MethodMirror)); 1439 (mirror) => mirror is MethodMirror));
1581 _addAll(exports['variables'], 1440 _addAll(exports['variables'],
1582 dart2js_util.variablesOf(export.targetLibrary.declarations)); 1441 dart2js_util.variablesOf(export.targetLibrary.declarations));
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1660 1519
1661 /// Returns this object's qualified name, but following the conventions 1520 /// Returns this object's qualified name, but following the conventions
1662 /// we're using in Dartdoc, which is that library names with dots in them 1521 /// we're using in Dartdoc, which is that library names with dots in them
1663 /// have them replaced with hyphens. 1522 /// have them replaced with hyphens.
1664 String get docName => owner.docName + '.' + dart2js_util.nameOf(mirror); 1523 String get docName => owner.docName + '.' + dart2js_util.nameOf(mirror);
1665 1524
1666 OwnedIndexable(DeclarationMirror mirror, this.owner) : super(mirror); 1525 OwnedIndexable(DeclarationMirror mirror, this.owner) : super(mirror);
1667 1526
1668 /// Generates MDN comments from database.json. 1527 /// Generates MDN comments from database.json.
1669 String _mdnComment() { 1528 String _mdnComment() {
1670 //Check if MDN is loaded.
1671 if (Indexable._mdn == null) {
1672 // Reading in MDN related json file.
1673 var root = _Generator._rootDirectory;
1674 var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json');
1675 var mdnFile = new File(mdnPath);
1676 if (mdnFile.existsSync()) {
1677 Indexable._mdn = JSON.decode(mdnFile.readAsStringSync());
1678 } else {
1679 _Generator.logger.warning("Cannot find MDN docs expected at $mdnPath");
1680 Indexable._mdn = {};
1681 }
1682 }
1683 var domAnnotation = this.annotations.firstWhere( 1529 var domAnnotation = this.annotations.firstWhere(
1684 (e) => e.mirror.qualifiedName == #metadata.DomName, 1530 (e) => e.mirror.qualifiedName == #metadata.DomName,
1685 orElse: () => null); 1531 orElse: () => null);
1686 if (domAnnotation == null) return ''; 1532 if (domAnnotation == null) return '';
1687 var domName = domAnnotation.parameters.single; 1533 var domName = domAnnotation.parameters.single;
1688 var parts = domName.split('.');
1689 if (parts.length == 2) return _mdnMemberComment(parts[0], parts[1]);
1690 if (parts.length == 1) return _mdnTypeComment(parts[0]);
1691 1534
1692 throw new StateError('More than two items is not supported: $parts'); 1535 return mdnComment(_Generator._rootDirectory, _Generator.logger, domName);
1693 } 1536 }
1694 1537
1695 String get packagePrefix => owner.packagePrefix; 1538 String get packagePrefix => owner.packagePrefix;
1696 } 1539 }
1697 1540
1698 /// A class containing contents of a Dart class. 1541 /// A class containing contents of a Dart class.
1699 class Class extends OwnedIndexable implements Comparable { 1542 class Class extends OwnedIndexable implements Comparable {
1700 1543
1701 /// List of the names of interfaces that this class implements. 1544 /// List of the names of interfaces that this class implements.
1702 List<Class> interfaces = []; 1545 List<Class> interfaces = [];
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1761 var superinterfaces = classMirror.superinterfaces.map( 1604 var superinterfaces = classMirror.superinterfaces.map(
1762 (interface) => new Class._possiblyDifferentOwner(interface, owner)); 1605 (interface) => new Class._possiblyDifferentOwner(interface, owner));
1763 this.superclass = classMirror.superclass == null? null : 1606 this.superclass = classMirror.superclass == null? null :
1764 new Class._possiblyDifferentOwner(classMirror.superclass, owner); 1607 new Class._possiblyDifferentOwner(classMirror.superclass, owner);
1765 1608
1766 interfaces = superinterfaces.toList(); 1609 interfaces = superinterfaces.toList();
1767 variables = _createVariables( 1610 variables = _createVariables(
1768 dart2js_util.variablesOf(classMirror.declarations), this); 1611 dart2js_util.variablesOf(classMirror.declarations), this);
1769 methods = _createMethods(classMirror.declarations.values.where( 1612 methods = _createMethods(classMirror.declarations.values.where(
1770 (mirror) => mirror is MethodMirror), this); 1613 (mirror) => mirror is MethodMirror), this);
1771 annotations = MirrorBased._createAnnotations(classMirror, _getOwningLibrary( owner)); 1614 annotations = _createAnnotations(classMirror, _getOwningLibrary(owner));
1772 generics = _createGenerics(classMirror); 1615 generics = _createGenerics(classMirror);
1773 isAbstract = classMirror.isAbstract; 1616 isAbstract = classMirror.isAbstract;
1774 inheritedMethods = new Map<String, Method>(); 1617 inheritedMethods = new Map<String, Method>();
1775 1618
1776 // Tell superclass that you are a subclass, unless you are not 1619 // Tell superclass that you are a subclass, unless you are not
1777 // visible or an intermediary mixin class. 1620 // visible or an intermediary mixin class.
1778 if (!classMirror.isNameSynthetic && _isVisible && superclass != null) { 1621 if (!classMirror.isNameSynthetic && _isVisible && superclass != null) {
1779 superclass.addSubclass(this); 1622 superclass.addSubclass(this);
1780 } 1623 }
1781 1624
1782 if (this.superclass != null) addInherited(superclass); 1625 if (this.superclass != null) addInherited(superclass);
1783 interfaces.forEach((interface) => addInherited(interface)); 1626 interfaces.forEach((interface) => addInherited(interface));
1784 } 1627 }
1785 1628
1786 String _lookupInClassAndSuperclasses(String name) { 1629 String _lookupInClassAndSuperclasses(String name) {
1787 var lookupFunc = Indexable.determineLookupFunc(name); 1630 var lookupFunc = determineLookupFunc(name);
1788 var classScope = this; 1631 var classScope = this;
1789 while (classScope != null) { 1632 while (classScope != null) {
1790 var classFunc = lookupFunc(classScope.mirror, name); 1633 var classFunc = lookupFunc(classScope.mirror, name);
1791 if (classFunc != null) { 1634 if (classFunc != null) {
1792 return packagePrefix + Indexable.getDocgenObject(classFunc, owner).docNa me; 1635 return packagePrefix + Indexable.getDocgenObject(classFunc, owner).docNa me;
1793 } 1636 }
1794 classScope = classScope.superclass; 1637 classScope = classScope.superclass;
1795 } 1638 }
1796 return null; 1639 return null;
1797 } 1640 }
1798 1641
1799 /// Look for the specified name starting with the current member, and 1642 /// Look for the specified name starting with the current member, and
1800 /// progressively working outward to the current library scope. 1643 /// progressively working outward to the current library scope.
1801 String findElementInScope(String name) { 1644 String findElementInScope(String name) {
1802 var lookupFunc = Indexable.determineLookupFunc(name); 1645 var lookupFunc = determineLookupFunc(name);
1803 var result = _lookupInClassAndSuperclasses(name); 1646 var result = _lookupInClassAndSuperclasses(name);
1804 if (result != null) { 1647 if (result != null) {
1805 return result; 1648 return result;
1806 } 1649 }
1807 result = owner.findElementInScope(name); 1650 result = owner.findElementInScope(name);
1808 return result == null ? super.findElementInScope(name) : result; 1651 return result == null ? super.findElementInScope(name) : result;
1809 } 1652 }
1810 1653
1811 String get typeName => 'class'; 1654 String get typeName => 'class';
1812 1655
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1944 aTypedef = new Typedef._(mirror, owningLibrary); 1787 aTypedef = new Typedef._(mirror, owningLibrary);
1945 } 1788 }
1946 return aTypedef; 1789 return aTypedef;
1947 } 1790 }
1948 1791
1949 Typedef._(TypedefMirror mirror, Library owningLibrary) : 1792 Typedef._(TypedefMirror mirror, Library owningLibrary) :
1950 super(mirror, owningLibrary) { 1793 super(mirror, owningLibrary) {
1951 returnType = Indexable.getDocgenObject(mirror.referent.returnType).docName; 1794 returnType = Indexable.getDocgenObject(mirror.referent.returnType).docName;
1952 generics = _createGenerics(mirror); 1795 generics = _createGenerics(mirror);
1953 parameters = _createParameters(mirror.referent.parameters, owningLibrary); 1796 parameters = _createParameters(mirror.referent.parameters, owningLibrary);
1954 annotations = MirrorBased._createAnnotations(mirror, owningLibrary); 1797 annotations = _createAnnotations(mirror, owningLibrary);
Emily Fortuna 2014/03/06 22:05:38 is having a bunch of random global functions reall
kevmoo 2014/03/06 22:20:17 Random top-level methods make dependencies clear.
Alan Knight 2014/03/12 18:17:56 I don't think it's about strict dependency require
kevmoo 2014/03/17 02:01:29 Since MirrorBased is in another library and we wan
1955 } 1798 }
1956 1799
1957 Map toMap() { 1800 Map toMap() {
1958 var map = { 1801 var map = {
1959 'name': name, 1802 'name': name,
1960 'qualifiedName': qualifiedName, 1803 'qualifiedName': qualifiedName,
1961 'comment': comment, 1804 'comment': comment,
1962 'return': returnType, 1805 'return': returnType,
1963 'parameters': recurseMap(parameters), 1806 'parameters': recurseMap(parameters),
1964 'annotations': annotations.map((a) => a.toMap()).toList(), 1807 'annotations': annotations.map((a) => a.toMap()).toList(),
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1997 } 1840 }
1998 return variable; 1841 return variable;
1999 } 1842 }
2000 1843
2001 Variable._(this._variableName, VariableMirror mirror, Indexable owner) : 1844 Variable._(this._variableName, VariableMirror mirror, Indexable owner) :
2002 super(mirror, owner) { 1845 super(mirror, owner) {
2003 isFinal = mirror.isFinal; 1846 isFinal = mirror.isFinal;
2004 isStatic = mirror.isStatic; 1847 isStatic = mirror.isStatic;
2005 isConst = mirror.isConst; 1848 isConst = mirror.isConst;
2006 type = new Type(mirror.type, _getOwningLibrary(owner)); 1849 type = new Type(mirror.type, _getOwningLibrary(owner));
2007 annotations = MirrorBased._createAnnotations(mirror, _getOwningLibrary(owner )); 1850 annotations = _createAnnotations(mirror, _getOwningLibrary(owner));
2008 } 1851 }
2009 1852
2010 String get name => _variableName; 1853 String get name => _variableName;
2011 1854
2012 /// Generates a map describing the [Variable] object. 1855 /// Generates a map describing the [Variable] object.
2013 Map toMap() => { 1856 Map toMap() => {
2014 'name': name, 1857 'name': name,
2015 'qualifiedName': qualifiedName, 1858 'qualifiedName': qualifiedName,
2016 'comment': comment, 1859 'comment': comment,
2017 'final': isFinal, 1860 'final': isFinal,
2018 'static': isStatic, 1861 'static': isStatic,
2019 'constant': isConst, 1862 'constant': isConst,
2020 'type': new List.filled(1, type.toMap()), 1863 'type': new List.filled(1, type.toMap()),
2021 'annotations': annotations.map((a) => a.toMap()).toList() 1864 'annotations': annotations.map((a) => a.toMap()).toList()
2022 }; 1865 };
2023 1866
2024 String get typeName => 'property'; 1867 String get typeName => 'property';
2025 1868
2026 get comment { 1869 get comment {
2027 if (_comment != null) return _comment; 1870 if (_comment != null) return _comment;
2028 if (owner is Class) { 1871 if (owner is Class) {
2029 (owner as Class).ensureComments(); 1872 (owner as Class).ensureComments();
2030 } 1873 }
2031 return super.comment; 1874 return super.comment;
2032 } 1875 }
2033 1876
2034 String findElementInScope(String name) { 1877 String findElementInScope(String name) {
2035 var lookupFunc = Indexable.determineLookupFunc(name); 1878 var lookupFunc = determineLookupFunc(name);
2036 var result = lookupFunc(mirror, name); 1879 var result = lookupFunc(mirror, name);
2037 if (result != null) { 1880 if (result != null) {
2038 result = Indexable.getDocgenObject(result); 1881 result = Indexable.getDocgenObject(result);
2039 if (result is DummyMirror) return packagePrefix + result.docName; 1882 if (result is DummyMirror) return packagePrefix + result.docName;
2040 return result.packagePrefix + result.docName; 1883 return result.packagePrefix + result.docName;
2041 } 1884 }
2042 1885
2043 if (owner != null) { 1886 if (owner != null) {
2044 var result = owner.findElementInScope(name); 1887 var result = owner.findElementInScope(name);
2045 if (result != null) { 1888 if (result != null) {
(...skipping 30 matching lines...) Expand all
2076 return method; 1919 return method;
2077 } 1920 }
2078 1921
2079 Method._(MethodMirror mirror, Indexable owner, this.methodInheritedFrom) 1922 Method._(MethodMirror mirror, Indexable owner, this.methodInheritedFrom)
2080 : super(mirror, owner) { 1923 : super(mirror, owner) {
2081 isStatic = mirror.isStatic; 1924 isStatic = mirror.isStatic;
2082 isAbstract = mirror.isAbstract; 1925 isAbstract = mirror.isAbstract;
2083 isConst = mirror.isConstConstructor; 1926 isConst = mirror.isConstConstructor;
2084 returnType = new Type(mirror.returnType, _getOwningLibrary(owner)); 1927 returnType = new Type(mirror.returnType, _getOwningLibrary(owner));
2085 parameters = _createParameters(mirror.parameters, owner); 1928 parameters = _createParameters(mirror.parameters, owner);
2086 annotations = MirrorBased._createAnnotations(mirror, _getOwningLibrary(owner )); 1929 annotations = _createAnnotations(mirror, _getOwningLibrary(owner));
2087 } 1930 }
2088 1931
2089 Method get originallyInheritedFrom => methodInheritedFrom == null ? 1932 Method get originallyInheritedFrom => methodInheritedFrom == null ?
2090 this : methodInheritedFrom.originallyInheritedFrom; 1933 this : methodInheritedFrom.originallyInheritedFrom;
2091 1934
2092 /// Look for the specified name starting with the current member, and 1935 /// Look for the specified name starting with the current member, and
2093 /// progressively working outward to the current library scope. 1936 /// progressively working outward to the current library scope.
2094 String findElementInScope(String name) { 1937 String findElementInScope(String name) {
2095 var lookupFunc = Indexable.determineLookupFunc(name); 1938 var lookupFunc = determineLookupFunc(name);
2096 1939
2097 var memberScope = lookupFunc(this.mirror, name); 1940 var memberScope = lookupFunc(this.mirror, name);
2098 if (memberScope != null) { 1941 if (memberScope != null) {
2099 // do we check for a dummy mirror returned here and look up with an owner 1942 // do we check for a dummy mirror returned here and look up with an owner
2100 // higher ooooor in getDocgenObject do we include more things in our 1943 // higher ooooor in getDocgenObject do we include more things in our
2101 // lookup 1944 // lookup
2102 var result = Indexable.getDocgenObject(memberScope, owner); 1945 var result = Indexable.getDocgenObject(memberScope, owner);
2103 if (result is DummyMirror && owner.owner != null 1946 if (result is DummyMirror && owner.owner != null
2104 && owner.owner is! DummyMirror) { 1947 && owner.owner is! DummyMirror) {
2105 var aresult = Indexable.getDocgenObject(memberScope, owner.owner); 1948 var aresult = Indexable.getDocgenObject(memberScope, owner.owner);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2205 final List<Annotation> annotations; 2048 final List<Annotation> annotations;
2206 2049
2207 Parameter(ParameterMirror mirror, Library owningLibrary) 2050 Parameter(ParameterMirror mirror, Library owningLibrary)
2208 : this.mirror = mirror, 2051 : this.mirror = mirror,
2209 name = dart2js_util.nameOf(mirror), 2052 name = dart2js_util.nameOf(mirror),
2210 isOptional = mirror.isOptional, 2053 isOptional = mirror.isOptional,
2211 isNamed = mirror.isNamed, 2054 isNamed = mirror.isNamed,
2212 hasDefaultValue = mirror.hasDefaultValue, 2055 hasDefaultValue = mirror.hasDefaultValue,
2213 defaultValue = '${mirror.defaultValue}', 2056 defaultValue = '${mirror.defaultValue}',
2214 type = new Type(mirror.type, owningLibrary), 2057 type = new Type(mirror.type, owningLibrary),
2215 annotations = MirrorBased._createAnnotations(mirror, owningLibrary); 2058 annotations = _createAnnotations(mirror, owningLibrary);
2216 2059
2217 /// Generates a map describing the [Parameter] object. 2060 /// Generates a map describing the [Parameter] object.
2218 Map toMap() => { 2061 Map toMap() => {
2219 'name': name, 2062 'name': name,
2220 'optional': isOptional, 2063 'optional': isOptional,
2221 'named': isNamed, 2064 'named': isNamed,
2222 'default': hasDefaultValue, 2065 'default': hasDefaultValue,
2223 'type': new List.filled(1, type.toMap()), 2066 'type': new List.filled(1, type.toMap()),
2224 'value': defaultValue, 2067 'value': defaultValue,
2225 'annotations': annotations.map((a) => a.toMap()).toList() 2068 'annotations': annotations.map((a) => a.toMap()).toList()
2226 }; 2069 };
2227 } 2070 }
2228 2071
2229 /// A Docgen wrapper around the dart2js mirror for a generic type.
2230 class Generic extends MirrorBased {
2231 final TypeVariableMirror mirror;
2232 Generic(this.mirror);
2233 Map toMap() => {
2234 'name': dart2js_util.nameOf(mirror),
2235 'type': dart2js_util.qualifiedNameOf(mirror.upperBound)
2236 };
2237 }
2238
2239 /// Docgen wrapper around the mirror for a return type, and/or its generic 2072 /// Docgen wrapper around the mirror for a return type, and/or its generic
2240 /// type parameters. 2073 /// type parameters.
2241 /// 2074 ///
2242 /// Return types are of a form [outer]<[inner]>. 2075 /// Return types are of a form [outer]<[inner]>.
2243 /// If there is no [inner] part, [inner] will be an empty list. 2076 /// If there is no [inner] part, [inner] will be an empty list.
2244 /// 2077 ///
2245 /// For example: 2078 /// For example:
2246 /// int size() 2079 /// int size()
2247 /// "return" : 2080 /// "return" :
2248 /// - "outer" : "dart-core.int" 2081 /// - "outer" : "dart-core.int"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 .map((e) => originalMirror.getField(e.simpleName).reflectee) 2141 .map((e) => originalMirror.getField(e.simpleName).reflectee)
2309 .where((e) => e != null) 2142 .where((e) => e != null)
2310 .toList(); 2143 .toList();
2311 } 2144 }
2312 2145
2313 Map toMap() => { 2146 Map toMap() => {
2314 'name': Indexable.getDocgenObject(mirror, owningLibrary).docName, 2147 'name': Indexable.getDocgenObject(mirror, owningLibrary).docName,
2315 'parameters': parameters 2148 'parameters': parameters
2316 }; 2149 };
2317 } 2150 }
2151
2152 /// Returns a list of meta annotations assocated with a mirror.
2153 List<Annotation> _createAnnotations(DeclarationMirror mirror,
2154 Library owningLibrary) {
2155 var annotationMirrors = mirror.metadata.where((e) =>
2156 e is dart2js_mirrors.Dart2JsConstructedConstantMirror);
2157 var annotations = [];
2158 annotationMirrors.forEach((annotation) {
2159 var docgenAnnotation = new Annotation(annotation, owningLibrary);
2160 if (!_SKIPPED_ANNOTATIONS.contains(
2161 dart2js_util.qualifiedNameOf(docgenAnnotation.mirror))) {
2162 annotations.add(docgenAnnotation);
2163 }
2164 });
2165 return annotations;
2166 }
OLDNEW
« no previous file with comments | « no previous file | pkg/docgen/lib/src/mdn.dart » ('j') | pkg/docgen/lib/src/models.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698