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

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

Issue 135653009: Fix package docnames for select return types, and some more docgen refactoring. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 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/test/multi_library_test.dart » ('j') | 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 [pub.dartlang.org](http://pub.dartlang.org). 79 [pub.dartlang.org](http://pub.dartlang.org).
80 80
81 The main site for learning and using Dart is 81 The main site for learning and using Dart is
82 [www.dartlang.org](http://www.dartlang.org). 82 [www.dartlang.org](http://www.dartlang.org).
83 Check out these pages: 83 Check out these pages:
84 84
85 * [Dart homepage](http://www.dartlang.org) 85 * [Dart homepage](http://www.dartlang.org)
86 * [Tutorials](http://www.dartlang.org/docs/tutorials/) 86 * [Tutorials](http://www.dartlang.org/docs/tutorials/)
87 * [Programmer's Guide](http://www.dartlang.org/docs/) 87 * [Programmer's Guide](http://www.dartlang.org/docs/)
88 * [Samples](http://www.dartlang.org/samples/) 88 * [Samples](http://www.dartlang.org/samples/)
89 * [A Tour of the Dart Libraries](http://www.dartlang.org/docs/dart-up-and-runn 89 * [A Tour of the Dart Libraries](http://www.dartlang.org/docs/dart-up-and-runn ing/contents/ch03.html)
90 ing/contents/ch03.html)
91 90
92 This API reference is automatically generated from the source code in the 91 This API reference is automatically generated from the source code in the
93 [Dart project](https://code.google.com/p/dart/). 92 [Dart project](https://code.google.com/p/dart/).
94 If you'd like to contribute to this documentation, see 93 If you'd like to contribute to this documentation, see
95 [Contributing](https://code.google.com/p/dart/wiki/Contributing) 94 [Contributing](https://code.google.com/p/dart/wiki/Contributing)
96 and 95 and
97 [Writing API Documentation](https://code.google.com/p/dart/wiki/WritingApiDocume 96 [Writing API Documentation](https://code.google.com/p/dart/wiki/WritingApiDocume ntation).
98 ntation).
99 """; 97 """;
100 98
101 // TODO(efortuna): The use of this field is odd (this is based on how it was 99 // TODO(efortuna): The use of this field is odd (this is based on how it was
102 // originally used. Try to cleanup. 100 // originally used. Try to cleanup.
103 /// Index of all indexable items. This also ensures that no class is 101 /// Index of all indexable items. This also ensures that no class is
104 /// created more than once. 102 /// created more than once.
105 Map<String, Indexable> entityMap = new Map<String, Indexable>(); 103 Map<String, Indexable> entityMap = new Map<String, Indexable>();
106 104
107 /// Index of all the dart2js mirrors examined to corresponding MirrorBased 105 /// Docgen constructor initializes the link resolver for markdown parsing.
108 /// docgen objects. 106 /// Also initializes the command line arguments.
109 /// 107 ///
110 /// Used for lookup because of the dart2js mirrors exports 108 /// [packageRoot] is the packages directory of the directory being analyzed.
111 /// issue. The second level map is indexed by owner docName for faster lookup. 109 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will
112 /// Why two levels of lookup? Speed, man. Speed. 110 /// also be documented.
113 Map<String, Map<String, Set<MirrorBased>>> mirrorToDocgen = 111 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented.
114 new Map<String, Map<String, Set<MirrorBased>>>(); 112 /// This option is useful when only the SDK libraries are needed.
113 ///
114 /// Returned Future completes with true if document generation is successful.
115 Future<bool> docgen(List<String> files, {String packageRoot,
116 bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false,
117 bool parseSdk: false, bool append: false, String introFileName: '',
118 out: _DEFAULT_OUTPUT_DIRECTORY, List<String> excludeLibraries : const [],
119 bool includeDependentPackages: false}) {
120 return _Generator.generateDocumentation(files, packageRoot: packageRoot,
121 outputToYaml: outputToYaml, includePrivate: includePrivate,
122 includeSdk: includeSdk, parseSdk: parseSdk, append: append,
123 introFileName: introFileName, out: out,
124 excludeLibraries: excludeLibraries,
125 includeDependentPackages: includeDependentPackages);
126 }
115 127
116 /// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object. 128 /// Analyzes set of libraries by getting a mirror system and triggers the
117 /// 129 /// documentation of the libraries.
118 /// We have this global lookup function to avoid re-implementing looking up the 130 Future<MirrorSystem> getMirrorSystem(List<Uri> libraries,
119 /// scoping rules for comment resolution here (it is currently done in mirrors). 131 {String packageRoot, bool parseSdk: false}) {
120 /// If no corresponding MirrorBased object is found, we return a [DummyMirror] 132 if (libraries.isEmpty) throw new StateError('No Libraries.');
121 /// that simply returns the original mirror's qualifiedName while behaving like
122 /// a MirrorBased object.
123 MirrorBased getDocgenObject(DeclarationMirror mirror, [Indexable owner]) {
124 Map<String, Set<MirrorBased>> docgenObj =
125 mirrorToDocgen[mirror.qualifiedName];
126 if (docgenObj == null) {
127 return new DummyMirror(mirror, owner);
128 }
129 133
130 Set<MirrorBased> results = new Set<MirrorBased>(); 134 // Finds the root of SDK library based off the location of docgen.
131 var setToExamine = new Set(); 135 var root = _Generator._rootDirectory;
132 if (owner != null) { 136 var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk')));
133 var firstSet = docgenObj[owner.docName]; 137 _Generator.logger.info('SDK Root: ${sdkRoot}');
134 if (firstSet != null) setToExamine.addAll(firstSet); 138 return _Generator._analyzeLibraries(libraries, sdkRoot,
135 if (Indexable._coreLibrary != null && 139 packageRoot: packageRoot);
136 docgenObj[Indexable._coreLibrary.docName] != null) {
137 setToExamine.addAll(docgenObj[Indexable._coreLibrary.docName]);
138 }
139 } else {
140 for (var value in docgenObj.values) {
141 setToExamine.addAll(value);
142 }
143 }
144
145 for(MirrorBased mirrorBased in setToExamine) {
146 // This check makes me sad, but Dart doesn't seem to be dynamic enough to
147 // write this another way. Dart2js and the editor didn't like the Type
148 // lookup in a map.
149 if (mirrorBased.mirror.qualifiedName == mirror.qualifiedName &&
150 ((mirror is ClassMirror && mirrorBased is Class)
151 || (mirror is LibraryMirror && mirrorBased is Library)
152 || (mirror is MethodMirror && mirrorBased is Method)
153 || (mirror is VariableMirror && mirrorBased is Variable)
154 || (mirror is TypedefMirror && mirrorBased is Typedef)
155 || (mirror is TypeMirror && mirrorBased is Type)
156 || (mirror is InstanceMirror && mirrorBased is Annotation))) {
157 results.add(mirrorBased);
158 }
159 }
160
161 if (results.length > 0) {
162 return results.first; // This might occur if we didn't specify an "owner."
163 }
164 return new DummyMirror(mirror, owner);
165 } 140 }
166 141
167 /// For types that we do not explicitly create or have not yet created in our 142 /// For types that we do not explicitly create or have not yet created in our
168 /// entity map (like core types). 143 /// entity map (like core types).
169 class DummyMirror implements MirrorBased { 144 class DummyMirror implements Indexable {
170 DeclarationMirror mirror; 145 DeclarationMirror mirror;
171 /// The library that contains this element, if any. Used as a hint to help 146 /// The library that contains this element, if any. Used as a hint to help
172 /// determine which object we're referring to when looking up this mirror in 147 /// determine which object we're referring to when looking up this mirror in
173 /// our map. 148 /// our map.
174 Indexable owner; 149 Indexable owner;
175 DummyMirror(this.mirror, [this.owner]); 150 DummyMirror(this.mirror, [this.owner]);
176 151
177 String get docName { 152 String get docName {
178 if (mirror == null) return ''; 153 if (mirror == null) return '';
179 if (mirror is LibraryMirror) { 154 if (mirror is LibraryMirror) {
180 return mirror.qualifiedName.replaceAll('.','-'); 155 return mirror.qualifiedName.replaceAll('.','-');
181 } 156 }
182 var mirrorOwner = mirror.owner; 157 var mirrorOwner = mirror.owner;
183 if (mirrorOwner == null) return mirror.qualifiedName; 158 if (mirrorOwner == null) return mirror.qualifiedName;
184 var simpleName = mirror.simpleName; 159 var simpleName = mirror.simpleName;
185 if (mirror is MethodMirror && (mirror as MethodMirror).isConstructor) { 160 if (mirror is MethodMirror && (mirror as MethodMirror).isConstructor) {
186 // We name constructors specially -- including the class name again and a 161 // We name constructors specially -- repeating the class name and a
187 // "-" to separate the constructor from its name (if any). 162 // "-" to separate the constructor from its name (if any).
188 simpleName = '${mirrorOwner.simpleName}-$simpleName'; 163 simpleName = '${mirrorOwner.simpleName}-$simpleName';
189 } 164 }
190 return getDocgenObject(mirrorOwner, owner).docName + '.' + simpleName; 165 return Indexable.getDocgenObject(mirrorOwner, owner).docName + '.' +
166 simpleName;
191 } 167 }
192 List<Annotation> _createAnnotations(DeclarationMirror mirror,
193 Library owningLibrary) => null;
194 168
195 bool get isPrivate => mirror == null? false : mirror.isPrivate; 169 bool get isPrivate => mirror == null? false : mirror.isPrivate;
170
171 String get packageName {
172 var libMirror = _getOwningLibraryFromMirror(mirror);
173 if (libMirror != null) {
174 return Library._packageName(libMirror);
175 }
176 return '';
177 }
178
179 String get packagePrefix => packageName == null || packageName.isEmpty ?
180 '' : '$packageName/';
181
182 LibraryMirror _getOwningLibraryFromMirror(DeclarationMirror mirror) {
183 if (mirror is LibraryMirror) return mirror;
184 if (mirror == null) return null;
185 return _getOwningLibraryFromMirror(mirror.owner);
186 }
196 } 187 }
197 188
189 /// Docgen representation of an item to be documented, that wraps around a
190 /// dart2js mirror.
198 abstract class MirrorBased { 191 abstract class MirrorBased {
199 DeclarationMirror get mirror; 192 DeclarationMirror get mirror;
200 MirrorBased owner;
201
202 /// Returns this object's qualified name, but following the conventions
203 /// we're using in Dartdoc, which is that library names with dots in them
204 /// have them replaced with hyphens.
205 String get docName => owner.docName + '.' + mirror.simpleName;
206 193
207 /// Returns a list of meta annotations assocated with a mirror. 194 /// Returns a list of meta annotations assocated with a mirror.
208 List<Annotation> _createAnnotations(DeclarationMirror mirror, 195 List<Annotation> _createAnnotations(DeclarationMirror mirror,
209 Library owningLibrary) { 196 Library owningLibrary) {
210 var annotationMirrors = mirror.metadata.where((e) => 197 var annotationMirrors = mirror.metadata.where((e) =>
211 e is dart2js.Dart2JsConstructedConstantMirror); 198 e is dart2js.Dart2JsConstructedConstantMirror);
212 var annotations = []; 199 var annotations = [];
213 annotationMirrors.forEach((annotation) { 200 annotationMirrors.forEach((annotation) {
214 var docgenAnnotation = new Annotation(annotation, owningLibrary); 201 var docgenAnnotation = new Annotation(annotation, owningLibrary);
215 if (!_SKIPPED_ANNOTATIONS.contains( 202 if (!_SKIPPED_ANNOTATIONS.contains(
216 docgenAnnotation.mirror.qualifiedName)) { 203 docgenAnnotation.mirror.qualifiedName)) {
217 annotations.add(docgenAnnotation); 204 annotations.add(docgenAnnotation);
218 } 205 }
219 }); 206 });
220 return annotations; 207 return annotations;
221 } 208 }
222
223 bool get isPrivate => false;
224 }
225
226 /// Docgen constructor initializes the link resolver for markdown parsing.
227 /// Also initializes the command line arguments.
228 ///
229 /// [packageRoot] is the packages directory of the directory being analyzed.
230 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will
231 /// also be documented.
232 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented.
233 /// This option is useful when only the SDK libraries are needed.
234 ///
235 /// Returned Future completes with true if document generation is successful.
236 Future<bool> docgen(List<String> files, {String packageRoot,
237 bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false,
238 bool parseSdk: false, bool append: false, String introFileName: '',
239 out: _DEFAULT_OUTPUT_DIRECTORY, List<String> excludeLibraries : const [],
240 bool includeDependentPackages: false}) {
241 return _Generator.generateDocumentation(files, packageRoot: packageRoot,
242 outputToYaml: outputToYaml, includePrivate: includePrivate,
243 includeSdk: includeSdk, parseSdk: parseSdk, append: append,
244 introFileName: introFileName, out: out,
245 excludeLibraries: excludeLibraries,
246 includeDependentPackages: includeDependentPackages);
247 }
248
249 /// Analyzes set of libraries by getting a mirror system and triggers the
250 /// documentation of the libraries.
251 Future<MirrorSystem> getMirrorSystem(List<Uri> libraries,
252 {String packageRoot, bool parseSdk: false}) {
253 if (libraries.isEmpty) throw new StateError('No Libraries.');
254 // Finds the root of SDK library based off the location of docgen.
255
256 var root = _Generator._rootDirectory;
257 var sdkRoot = path.normalize(path.absolute(path.join(root, 'sdk')));
258 _Generator.logger.info('SDK Root: ${sdkRoot}');
259 return _Generator._analyzeLibraries(libraries, sdkRoot,
260 packageRoot: packageRoot);
261 } 209 }
262 210
263 class _Generator { 211 class _Generator {
264 static var _outputDirectory; 212 static var _outputDirectory;
265 213
266 /// This is set from the command line arguments flag --include-private 214 /// This is set from the command line arguments flag --include-private
267 static bool _includePrivate = false; 215 static bool _includePrivate = false;
268 216
269 /// Library names to explicitly exclude. 217 /// Library names to explicitly exclude.
270 /// 218 ///
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 (includeSdk || parseSdk) ? Indexable._sdkLibraries : []); 273 (includeSdk || parseSdk) ? Indexable._sdkLibraries : []);
326 librariesToDocument.removeWhere( 274 librariesToDocument.removeWhere(
327 (x) => _excluded.contains(x.simpleName)); 275 (x) => _excluded.contains(x.simpleName));
328 _documentLibraries(librariesToDocument, includeSdk: includeSdk, 276 _documentLibraries(librariesToDocument, includeSdk: includeSdk,
329 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk, 277 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk,
330 introFileName: introFileName); 278 introFileName: introFileName);
331 return true; 279 return true;
332 }); 280 });
333 } 281 }
334 282
335 /// Writes text to a file in the output directory. 283 /// Writes [text] to a file in the output directory.
336 static void _writeToFile(String text, String filename, {bool append: false}) { 284 static void _writeToFile(String text, String filename, {bool append: false}) {
337 if (text == null) return; 285 if (text == null) return;
338 Directory dir = new Directory(_outputDirectory); 286 Directory dir = new Directory(_outputDirectory);
339 if (!dir.existsSync()) { 287 if (!dir.existsSync()) {
340 dir.createSync(); 288 dir.createSync();
341 } 289 }
342 if (path.split(filename).length > 1) { 290 if (path.split(filename).length > 1) {
343 var splitList = path.split(filename); 291 var splitList = path.split(filename);
344 for (int i = 0; i < splitList.length; i++) { 292 for (int i = 0; i < splitList.length; i++) {
345 var level = splitList[i]; 293 var level = splitList[i];
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 var sdk = new List<Uri>(); 563 var sdk = new List<Uri>();
616 LIBRARIES.forEach((String name, LibraryInfo info) { 564 LIBRARIES.forEach((String name, LibraryInfo info) {
617 if (info.documented) { 565 if (info.documented) {
618 sdk.add(Uri.parse('dart:$name')); 566 sdk.add(Uri.parse('dart:$name'));
619 logger.info('Add to SDK: ${sdk.last}'); 567 logger.info('Add to SDK: ${sdk.last}');
620 } 568 }
621 }); 569 });
622 return sdk; 570 return sdk;
623 } 571 }
624 572
625 static bool _isFullChainVisible(MirrorBased item) { 573 static bool _isFullChainVisible(Indexable item) {
626 // TODO: reconcile with isVisible 574 // TODO: reconcile with isVisible.
575 // TODO: Also should be able to take MirrorBased items in general probably.
627 var result = _includePrivate || (!item.isPrivate && (item.owner != null ? 576 var result = _includePrivate || (!item.isPrivate && (item.owner != null ?
628 _isFullChainVisible(item.owner) : true)); 577 _isFullChainVisible(item.owner) : true));
629 return result; 578 return result;
630 } 579 }
631 580
632 /// Currently left public for testing purposes. :-/ 581 /// Currently left public for testing purposes. :-/
633 static Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { 582 static Library generateLibrary(dart2js.Dart2JsLibraryMirror library) {
634 var result = new Library(library); 583 var result = new Library(library);
635 result._findPackage(library); 584 result._findPackage(library);
636 logger.fine('Generated library for ${result.name}'); 585 logger.fine('Generated library for ${result.name}');
637 return result; 586 return result;
638 } 587 }
639 } 588 }
640 589
641 /// An item that is categorized in our mirrorToDocgen map, as a distinct, 590 /// An item that is categorized in our mirrorToDocgen map, as a distinct,
642 /// searchable element. 591 /// searchable element.
643 /// 592 ///
644 /// These are items that refer to concrete entities (a Class, for example, 593 /// These are items that refer to concrete entities (a Class, for example,
645 /// but not a Type, which is a "pointer" to a class) that we wish to be 594 /// but not a Type, which is a "pointer" to a class) that we wish to be
646 /// globally resolvable. This includes things such as class methods and 595 /// globally resolvable. This includes things such as class methods and
647 /// variables, but parameters for methods are not "Indexable" as we do not want 596 /// variables, but parameters for methods are not "Indexable" as we do not want
648 /// the user to be able to search for a method based on its parameter names! 597 /// the user to be able to search for a method based on its parameter names!
649 /// The set of indexable items also includes Typedefs, since the user can refer 598 /// The set of indexable items also includes Typedefs, since the user can refer
650 /// to them as concrete entities in a particular scope. 599 /// to them as concrete entities in a particular scope.
651 class Indexable extends MirrorBased { 600 abstract class Indexable extends MirrorBased {
652 /// The dart:core library, which contains all types that are always available 601 /// The dart:core library, which contains all types that are always available
653 /// without import. 602 /// without import.
654 static Library _coreLibrary; 603 static Library _coreLibrary;
655 604
656 /// Set of libraries declared in the SDK, so libraries that can be accessed 605 /// Set of libraries declared in the SDK, so libraries that can be accessed
657 /// when running dart by default. 606 /// when running dart by default.
658 static Iterable<LibraryMirror> _sdkLibraries; 607 static Iterable<LibraryMirror> _sdkLibraries;
659 608
660 String get qualifiedName => fileName; 609 String get qualifiedName => fileName;
661 bool isPrivate; 610 bool isPrivate;
662 DeclarationMirror mirror; 611 DeclarationMirror mirror;
663 /// The comment text pre-resolution. We keep this around because inherited 612 /// The comment text pre-resolution. We keep this around because inherited
664 /// methods need to resolve links differently from the superclass. 613 /// methods need to resolve links differently from the superclass.
665 String _unresolvedComment = ''; 614 String _unresolvedComment = '';
666 615
667 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move 616 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move
668 // MDN-specific code to its own library that is imported into the default 617 // MDN-specific code to its own library that is imported into the default
669 // impl? 618 // impl?
670 /// Map of all the comments for dom elements from MDN. 619 /// Map of all the comments for dom elements from MDN.
671 static Map _mdn; 620 static Map _mdn;
672 621
622 /// Index of all the dart2js mirrors examined to corresponding MirrorBased
623 /// docgen objects.
624 ///
625 /// Used for lookup because of the dart2js mirrors exports
626 /// issue. The second level map is indexed by owner docName for faster lookup.
627 /// Why two levels of lookup? Speed, man. Speed.
628 static Map<String, Map<String, Set<Indexable>>> _mirrorToDocgen =
629 new Map<String, Map<String, Set<Indexable>>>();
630
673 Indexable(this.mirror) { 631 Indexable(this.mirror) {
674 this.isPrivate = _isHidden(mirror); 632 this.isPrivate = _isHidden(mirror);
675 633
676 var map = mirrorToDocgen[this.mirror.qualifiedName]; 634 var map = _mirrorToDocgen[this.mirror.qualifiedName];
677 if (map == null) map = new Map<String, Set<MirrorBased>>(); 635 if (map == null) map = new Map<String, Set<Indexable>>();
678 636
679 var set = map[owner.docName]; 637 var set = map[owner.docName];
680 if (set == null) set = new Set<MirrorBased>(); 638 if (set == null) set = new Set<Indexable>();
681 set.add(this); 639 set.add(this);
682 map[owner.docName] = set; 640 map[owner.docName] = set;
683 mirrorToDocgen[this.mirror.qualifiedName] = map; 641 _mirrorToDocgen[this.mirror.qualifiedName] = map;
684 } 642 }
685 643
686 /** Walk up the owner chain to find the owning library. */ 644 /** Walk up the owner chain to find the owning library. */
687 Library _getOwningLibrary(Indexable indexable) { 645 Library _getOwningLibrary(Indexable indexable) {
688 if (indexable is Library) return indexable; 646 if (indexable is Library) return indexable;
689 // TODO: is this needed?
690 if (indexable is DummyMirror) return getDocgenObject(indexable.mirror.librar y);
691 return _getOwningLibrary(indexable.owner); 647 return _getOwningLibrary(indexable.owner);
692 } 648 }
693 649
694 static initializeTopLevelLibraries(MirrorSystem mirrorSystem) { 650 static initializeTopLevelLibraries(MirrorSystem mirrorSystem) {
695 _sdkLibraries = mirrorSystem.libraries.values.where( 651 _sdkLibraries = mirrorSystem.libraries.values.where(
696 (each) => each.uri.scheme == 'dart'); 652 (each) => each.uri.scheme == 'dart');
697 _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) => 653 _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) =>
698 lib.uri.toString().startsWith('dart:core'))); 654 lib.uri.toString().startsWith('dart:core')));
699 } 655 }
700 656
657 /// Returns this object's qualified name, but following the conventions
658 /// we're using in Dartdoc, which is that library names with dots in them
659 /// have them replaced with hyphens.
660 String get docName;
661
701 markdown.Node fixReferenceWithScope(String name) => null; 662 markdown.Node fixReferenceWithScope(String name) => null;
702 663
703 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. 664 /// Converts all [foo] references in comments to <a>libraryName.foo</a>.
704 markdown.Node fixReference(String name) { 665 markdown.Node fixReference(String name) {
705 // Attempt the look up the whole name up in the scope. 666 // Attempt the look up the whole name up in the scope.
706 String elementName = findElementInScope(name); 667 String elementName = findElementInScope(name);
707 if (elementName != null) { 668 if (elementName != null) {
708 return new markdown.Element.text('a', elementName); 669 return new markdown.Element.text('a', elementName);
709 } 670 }
710 return _fixComplexReference(name); 671 return _fixComplexReference(name);
(...skipping 29 matching lines...) Expand all
740 if (_comment.isEmpty) { 701 if (_comment.isEmpty) {
741 _comment = _mdnComment(); 702 _comment = _mdnComment();
742 } 703 }
743 return _comment; 704 return _comment;
744 } 705 }
745 706
746 set comment(x) => _comment = x; 707 set comment(x) => _comment = x;
747 708
748 String get name => mirror.simpleName; 709 String get name => mirror.simpleName;
749 710
750 MirrorBased get owner => new DummyMirror(mirror.owner); 711 Indexable get owner => new DummyMirror(mirror.owner);
751 712
752 /// Generates MDN comments from database.json. 713 /// Generates MDN comments from database.json.
753 String _mdnComment() { 714 String _mdnComment() {
754 //Check if MDN is loaded. 715 //Check if MDN is loaded.
755 if (_mdn == null) { 716 if (_mdn == null) {
756 // Reading in MDN related json file. 717 // Reading in MDN related json file.
757 var root = _Generator._rootDirectory; 718 var root = _Generator._rootDirectory;
758 var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json'); 719 var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json');
759 _mdn = JSON.decode(new File(mdnPath).readAsStringSync()); 720 _mdn = JSON.decode(new File(mdnPath).readAsStringSync());
760 } 721 }
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 } 1038 }
1078 1039
1079 Map _filterMap(exported, map, test) { 1040 Map _filterMap(exported, map, test) {
1080 map.forEach((key, value) { 1041 map.forEach((key, value) {
1081 if (test(key, value)) exported[key] = value; 1042 if (test(key, value)) exported[key] = value;
1082 }); 1043 });
1083 return exported; 1044 return exported;
1084 } 1045 }
1085 1046
1086 bool get _isVisible => _Generator._includePrivate || !isPrivate; 1047 bool get _isVisible => _Generator._includePrivate || !isPrivate;
1048
1049 /// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object.
1050 ///
1051 /// We have this global lookup function to avoid re-implementing looking up
1052 /// the scoping rules for comment resolution here (it is currently done in
1053 /// mirrors). If no corresponding MirrorBased object is found, we return a
1054 /// [DummyMirror] that simply returns the original mirror's qualifiedName
1055 /// while behaving like a MirrorBased object.
1056 static Indexable getDocgenObject(DeclarationMirror mirror,
1057 [Indexable owner]) {
1058 Map<String, Set<Indexable>> docgenObj =
1059 _mirrorToDocgen[mirror.qualifiedName];
1060 if (docgenObj == null) {
1061 return new DummyMirror(mirror, owner);
1062 }
1063
1064 var setToExamine = new Set();
1065 if (owner != null) {
1066 var firstSet = docgenObj[owner.docName];
1067 if (firstSet != null) setToExamine.addAll(firstSet);
1068 if (_coreLibrary != null &&
1069 docgenObj[_coreLibrary.docName] != null) {
1070 setToExamine.addAll(docgenObj[_coreLibrary.docName]);
1071 }
1072 } else {
1073 for (var value in docgenObj.values) {
1074 setToExamine.addAll(value);
1075 }
1076 }
1077
1078 Set<Indexable> results = new Set<Indexable>();
1079 for(Indexable indexable in setToExamine) {
1080 if (indexable.mirror.qualifiedName == mirror.qualifiedName &&
1081 indexable._isValidMirror(mirror)) {
1082 results.add(indexable);
1083 }
1084 }
1085
1086 if (results.length > 0) {
1087 // This might occur if we didn't specify an "owner."
1088 return results.first;
1089 }
1090 return new DummyMirror(mirror, owner);
1091 }
1092
1093 bool _isValidMirror(DeclarationMirror mirror);
1087 } 1094 }
1088 1095
1089 /// A class containing contents of a Dart library. 1096 /// A class containing contents of a Dart library.
1090 class Library extends Indexable { 1097 class Library extends Indexable {
1091 1098
1092 /// Top-level variables in the library. 1099 /// Top-level variables in the library.
1093 Map<String, Variable> variables; 1100 Map<String, Variable> variables;
1094 1101
1095 /// Top-level functions in the library. 1102 /// Top-level functions in the library.
1096 Map<String, Method> functions; 1103 Map<String, Method> functions;
1097 1104
1098 Map<String, Class> classes = {}; 1105 Map<String, Class> classes = {};
1099 Map<String, Typedef> typedefs = {}; 1106 Map<String, Typedef> typedefs = {};
1100 Map<String, Class> errors = {}; 1107 Map<String, Class> errors = {};
1101 1108
1102 String packageName = ''; 1109 String packageName = '';
1103 bool hasBeenCheckedForPackage = false; 1110 bool hasBeenCheckedForPackage = false;
1104 String packageIntro; 1111 String packageIntro;
1105 1112
1106 /// Returns the [Library] for the given [mirror] if it has already been 1113 /// Returns the [Library] for the given [mirror] if it has already been
1107 /// created, else creates it. 1114 /// created, else creates it.
1108 factory Library(LibraryMirror mirror) { 1115 factory Library(LibraryMirror mirror) {
1109 var library = getDocgenObject(mirror); 1116 var library = Indexable.getDocgenObject(mirror);
1110 if (library is DummyMirror) { 1117 if (library is DummyMirror) {
1111 library = new Library._(mirror); 1118 library = new Library._(mirror);
1112 } 1119 }
1113 return library; 1120 return library;
1114 } 1121 }
1115 1122
1116 Library._(LibraryMirror libraryMirror) : super(libraryMirror) { 1123 Library._(LibraryMirror libraryMirror) : super(libraryMirror) {
1117 var exported = _calcExportedItems(libraryMirror); 1124 var exported = _calcExportedItems(libraryMirror);
1118 var exportedClasses = exported['classes']..addAll(libraryMirror.classes); 1125 var exportedClasses = exported['classes']..addAll(libraryMirror.classes);
1119 _findPackage(mirror); 1126 _findPackage(mirror);
1120 classes = {}; 1127 classes = {};
1121 typedefs = {}; 1128 typedefs = {};
1122 errors = {}; 1129 errors = {};
1123 exportedClasses.forEach((String mirrorName, ClassMirror classMirror) { 1130 exportedClasses.forEach((String mirrorName, ClassMirror classMirror) {
1124 if (classMirror.isTypedef) { 1131 if (classMirror.isTypedef) {
1125 // This is actually a Dart2jsTypedefMirror, and it does define value, 1132 // This is actually a Dart2jsTypedefMirror, and it does define value,
1126 // but we don't have visibility to that type. 1133 // but we don't have visibility to that type.
1127 var mirror = classMirror; 1134 var mirror = classMirror;
1128 if (_Generator._includePrivate || !mirror.isPrivate) { 1135 if (_Generator._includePrivate || !mirror.isPrivate) {
1129 entityMap[getDocgenObject(mirror).docName] = 1136 var aTypedef = new Typedef(mirror, this);
1130 new Typedef(mirror, this); 1137 entityMap[Indexable.getDocgenObject(mirror).docName] = aTypedef;
1131 typedefs[mirror.simpleName] = 1138 typedefs[mirror.simpleName] = aTypedef;
1132 entityMap[getDocgenObject(mirror).docName];
1133 } 1139 }
1134 } else { 1140 } else {
1135 var clazz = new Class(classMirror, this); 1141 var clazz = new Class(classMirror, this);
1136 1142
1137 if (clazz.isError()) { 1143 if (clazz.isError()) {
1138 errors[classMirror.simpleName] = clazz; 1144 errors[classMirror.simpleName] = clazz;
1139 } else if (classMirror.isClass) { 1145 } else if (classMirror.isClass) {
1140 classes[classMirror.simpleName] = clazz; 1146 classes[classMirror.simpleName] = clazz;
1141 } else { 1147 } else {
1142 throw new ArgumentError( 1148 throw new ArgumentError(
1143 '${classMirror.simpleName} - no class type match. '); 1149 '${classMirror.simpleName} - no class type match. ');
1144 } 1150 }
1145 } 1151 }
1146 }); 1152 });
1147 this.functions = _createMethods(exported['methods'] 1153 this.functions = _createMethods(exported['methods']
1148 ..addAll(libraryMirror.functions), this); 1154 ..addAll(libraryMirror.functions), this);
1149 this.variables = _createVariables(exported['variables'] 1155 this.variables = _createVariables(exported['variables']
1150 ..addAll(libraryMirror.variables), this); 1156 ..addAll(libraryMirror.variables), this);
1151 } 1157 }
1152 1158
1153 /// Look for the specified name starting with the current member, and 1159 /// Look for the specified name starting with the current member, and
1154 /// progressively working outward to the current library scope. 1160 /// progressively working outward to the current library scope.
1155 String findElementInScope(String name) { 1161 String findElementInScope(String name) {
1156 var lookupFunc = Indexable.determineLookupFunc(name); 1162 var lookupFunc = Indexable.determineLookupFunc(name);
1157 var libraryScope = lookupFunc(mirror, name); 1163 var libraryScope = lookupFunc(mirror, name);
1158 if (libraryScope != null) { 1164 if (libraryScope != null) {
1159 var result = getDocgenObject(libraryScope, this); 1165 var result = Indexable.getDocgenObject(libraryScope, this);
1160 if (result is DummyMirror) return packagePrefix + result.docName; 1166 if (result is DummyMirror) return packagePrefix + result.docName;
1161 return result.packagePrefix + result.docName; 1167 return result.packagePrefix + result.docName;
1162 } 1168 }
1163 return super.findElementInScope(name); 1169 return super.findElementInScope(name);
1164 } 1170 }
1165 1171
1166 /// For a library's [mirror], determine the name of the package (if any) we 1172 /// For a library's [mirror], determine the name of the package (if any) we
1167 /// believe it came from (because of its file URI). 1173 /// believe it came from (because of its file URI).
1168 /// 1174 ///
1169 /// If no package could be determined, we return an empty string. 1175 /// If no package could be determined, we return an empty string.
1170 String _findPackage(LibraryMirror mirror) { 1176 String _findPackage(LibraryMirror mirror) {
1171 if (mirror == null) return ''; 1177 if (mirror == null) return '';
1172 if (hasBeenCheckedForPackage) return packageName; 1178 if (hasBeenCheckedForPackage) return packageName;
1173 hasBeenCheckedForPackage = true; 1179 hasBeenCheckedForPackage = true;
1174 if (mirror.uri.scheme != 'file') return ''; 1180 if (mirror.uri.scheme != 'file') return '';
1175 var filePath = mirror.uri.toFilePath();
1176 // We assume that we are documenting only libraries under package/lib 1181 // We assume that we are documenting only libraries under package/lib
1177 var rootdir = path.dirname((path.dirname(filePath))); 1182 packageName = _packageName(mirror);
1178 var pubspec = path.join(rootdir, 'pubspec.yaml');
1179 packageName = _packageName(pubspec);
1180 // Associate the package readme with all the libraries. This is a bit 1183 // Associate the package readme with all the libraries. This is a bit
1181 // wasteful, but easier than trying to figure out which partial match 1184 // wasteful, but easier than trying to figure out which partial match
1182 // is best. 1185 // is best.
1183 packageIntro = _packageIntro(rootdir); 1186 packageIntro = _packageIntro(_getRootdir(mirror));
1184 return packageName; 1187 return packageName;
1185 } 1188 }
1186 1189
1187 String _packageIntro(packageDir) { 1190 String _packageIntro(packageDir) {
1188 var dir = new Directory(packageDir); 1191 var dir = new Directory(packageDir);
1189 var files = dir.listSync(); 1192 var files = dir.listSync();
1190 var readmes = files.where((FileSystemEntity each) => (each is File && 1193 var readmes = files.where((FileSystemEntity each) => (each is File &&
1191 each.path.substring(packageDir.length + 1, each.path.length) 1194 each.path.substring(packageDir.length + 1, each.path.length)
1192 .startsWith('README'))).toList(); 1195 .startsWith('README'))).toList();
1193 if (readmes.isEmpty) return ''; 1196 if (readmes.isEmpty) return '';
1194 // If there are multiples, pick the shortest name. 1197 // If there are multiples, pick the shortest name.
1195 readmes.sort((a, b) => a.path.length.compareTo(b.path.length)); 1198 readmes.sort((a, b) => a.path.length.compareTo(b.path.length));
1196 var readme = readmes.first; 1199 var readme = readmes.first;
1197 var linkResolver = (name) => Indexable.globalFixReference(name); 1200 var linkResolver = (name) => Indexable.globalFixReference(name);
1198 var contents = markdown.markdownToHtml(readme 1201 var contents = markdown.markdownToHtml(readme
1199 .readAsStringSync(), linkResolver: linkResolver, 1202 .readAsStringSync(), linkResolver: linkResolver,
1200 inlineSyntaxes: _MARKDOWN_SYNTAXES); 1203 inlineSyntaxes: _MARKDOWN_SYNTAXES);
1201 return contents; 1204 return contents;
1202 } 1205 }
1203 1206
1207 /// Given a LibraryMirror that is a library, return the name of the directory
1208 /// holding that library.
1209 static String _getRootdir(LibraryMirror mirror) =>
1210 path.dirname(path.dirname(mirror.uri.toFilePath()));
1211
1204 /// Read a pubspec and return the library name. 1212 /// Read a pubspec and return the library name.
1205 String _packageName(String pubspecName) { 1213 static String _packageName(LibraryMirror mirror) {
1214 if (mirror.uri.scheme != 'file') return '';
1215 var rootdir = _getRootdir(mirror);
1216 var pubspecName = path.join(rootdir, 'pubspec.yaml');
1206 File pubspec = new File(pubspecName); 1217 File pubspec = new File(pubspecName);
1207 if (!pubspec.existsSync()) return ''; 1218 if (!pubspec.existsSync()) return '';
1208 var contents = pubspec.readAsStringSync(); 1219 var contents = pubspec.readAsStringSync();
1209 var spec = loadYaml(contents); 1220 var spec = loadYaml(contents);
1210 return spec["name"]; 1221 return spec["name"];
1211 } 1222 }
1212 1223
1213 markdown.Node fixReferenceWithScope(String name) => fixReference(name); 1224 markdown.Node fixReferenceWithScope(String name) => fixReference(name);
1214 1225
1215 String get packagePrefix => packageName == null || packageName.isEmpty ? 1226 String get packagePrefix => packageName == null || packageName.isEmpty ?
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 .map((e) => e.previewMap).toList(), 1318 .map((e) => e.previewMap).toList(),
1308 'typedef': recurseMap(typedefs), 1319 'typedef': recurseMap(typedefs),
1309 'error': errors.values.where((e) => e._isVisible) 1320 'error': errors.values.where((e) => e._isVisible)
1310 .map((e) => e.previewMap).toList() 1321 .map((e) => e.previewMap).toList()
1311 }, 1322 },
1312 'packageName': packageName, 1323 'packageName': packageName,
1313 'packageIntro' : packageIntro 1324 'packageIntro' : packageIntro
1314 }; 1325 };
1315 1326
1316 String get typeName => 'library'; 1327 String get typeName => 'library';
1328
1329 bool _isValidMirror(DeclarationMirror mirror) => mirror is LibraryMirror;
1330 }
1331
1332 abstract class OwnedIndexable extends Indexable {
1333 Indexable owner;
1334
1335 /// Returns this object's qualified name, but following the conventions
1336 /// we're using in Dartdoc, which is that library names with dots in them
1337 /// have them replaced with hyphens.
1338 String get docName => owner.docName + '.' + mirror.simpleName;
1339
1340 OwnedIndexable(DeclarationMirror mirror, this.owner) : super(mirror);
1317 } 1341 }
1318 1342
1319 /// A class containing contents of a Dart class. 1343 /// A class containing contents of a Dart class.
1320 class Class extends Indexable implements Comparable { 1344 class Class extends OwnedIndexable implements Comparable {
1321 1345
1322 /// List of the names of interfaces that this class implements. 1346 /// List of the names of interfaces that this class implements.
1323 List<Class> interfaces = []; 1347 List<Class> interfaces = [];
1324 1348
1325 /// Names of classes that extends or implements this class. 1349 /// Names of classes that extends or implements this class.
1326 Set<Class> subclasses = new Set<Class>(); 1350 Set<Class> subclasses = new Set<Class>();
1327 1351
1328 /// Top-level variables in the class. 1352 /// Top-level variables in the class.
1329 Map<String, Variable> variables; 1353 Map<String, Variable> variables;
1330 1354
(...skipping 10 matching lines...) Expand all
1341 1365
1342 Class superclass; 1366 Class superclass;
1343 bool isAbstract; 1367 bool isAbstract;
1344 1368
1345 /// List of the meta annotations on the class. 1369 /// List of the meta annotations on the class.
1346 List<Annotation> annotations; 1370 List<Annotation> annotations;
1347 1371
1348 /// Make sure that we don't check for inherited comments more than once. 1372 /// Make sure that we don't check for inherited comments more than once.
1349 bool _commentsEnsured = false; 1373 bool _commentsEnsured = false;
1350 1374
1351 Indexable owner;
1352
1353 /// Returns the [Class] for the given [mirror] if it has already been created, 1375 /// Returns the [Class] for the given [mirror] if it has already been created,
1354 /// else creates it. 1376 /// else creates it.
1355 factory Class(ClassMirror mirror, Library owner) { 1377 factory Class(ClassMirror mirror, Library owner) {
1356 var clazz = getDocgenObject(mirror, owner); 1378 var clazz = Indexable.getDocgenObject(mirror, owner);
1357 if (clazz is DummyMirror) { 1379 if (clazz is DummyMirror) {
1358 clazz = new Class._(mirror, owner); 1380 clazz = new Class._(mirror, owner);
1359 entityMap[clazz.docName] = clazz; 1381 entityMap[clazz.docName] = clazz;
1360 } 1382 }
1361 return clazz; 1383 return clazz;
1362 } 1384 }
1363 1385
1364 /// Called when we are constructing a superclass or interface class, but it 1386 /// Called when we are constructing a superclass or interface class, but it
1365 /// is not known if it belongs to the same owner as the original class. In 1387 /// is not known if it belongs to the same owner as the original class. In
1366 /// this case, we create an object whose owner is what the original mirror 1388 /// this case, we create an object whose owner is what the original mirror
1367 /// says it is. 1389 /// says it is.
1368 factory Class._possiblyDifferentOwner(ClassMirror mirror, 1390 factory Class._possiblyDifferentOwner(ClassMirror mirror,
1369 Library originalOwner) { 1391 Library originalOwner) {
1370 if (mirror.owner is LibraryMirror) { 1392 if (mirror.owner is LibraryMirror) {
1371 var realOwner = getDocgenObject(mirror.owner); 1393 var realOwner = Indexable.getDocgenObject(mirror.owner);
1372 if (realOwner is Library) { 1394 if (realOwner is Library) {
1373 return new Class(mirror, realOwner); 1395 return new Class(mirror, realOwner);
1374 } else { 1396 } else {
1375 return new Class(mirror, originalOwner); 1397 return new Class(mirror, originalOwner);
1376 } 1398 }
1377 } else { 1399 } else {
1378 return new Class(mirror, originalOwner); 1400 return new Class(mirror, originalOwner);
1379 } 1401 }
1380 } 1402 }
1381 1403
1382 Class._(ClassMirror classMirror, this.owner) : super(classMirror) { 1404 Class._(ClassMirror classMirror, Indexable owner) :
1405 super(classMirror, owner) {
1383 inheritedVariables = {}; 1406 inheritedVariables = {};
1384 1407
1385 // The reason we do this madness is the superclass and interface owners may 1408 // The reason we do this madness is the superclass and interface owners may
1386 // not be this class's owner!! Example: BaseClient in http pkg. 1409 // not be this class's owner!! Example: BaseClient in http pkg.
1387 var superinterfaces = classMirror.superinterfaces.map( 1410 var superinterfaces = classMirror.superinterfaces.map(
1388 (interface) => new Class._possiblyDifferentOwner(interface, owner)); 1411 (interface) => new Class._possiblyDifferentOwner(interface, owner));
1389 this.superclass = classMirror.superclass == null? null : 1412 this.superclass = classMirror.superclass == null? null :
1390 new Class._possiblyDifferentOwner(classMirror.superclass, owner); 1413 new Class._possiblyDifferentOwner(classMirror.superclass, owner);
1391 1414
1392 interfaces = superinterfaces.toList(); 1415 interfaces = superinterfaces.toList();
(...skipping 17 matching lines...) Expand all
1410 } 1433 }
1411 1434
1412 String get packagePrefix => owner.packagePrefix; 1435 String get packagePrefix => owner.packagePrefix;
1413 1436
1414 String _lookupInClassAndSuperclasses(String name) { 1437 String _lookupInClassAndSuperclasses(String name) {
1415 var lookupFunc = Indexable.determineLookupFunc(name); 1438 var lookupFunc = Indexable.determineLookupFunc(name);
1416 var classScope = this; 1439 var classScope = this;
1417 while (classScope != null) { 1440 while (classScope != null) {
1418 var classFunc = lookupFunc(classScope.mirror, name); 1441 var classFunc = lookupFunc(classScope.mirror, name);
1419 if (classFunc != null) { 1442 if (classFunc != null) {
1420 return packagePrefix + getDocgenObject(classFunc, owner).docName; 1443 return packagePrefix + Indexable.getDocgenObject(classFunc, owner).docNa me;
1421 } 1444 }
1422 classScope = classScope.superclass; 1445 classScope = classScope.superclass;
1423 } 1446 }
1424 return null; 1447 return null;
1425 } 1448 }
1426 1449
1427 /// Look for the specified name starting with the current member, and 1450 /// Look for the specified name starting with the current member, and
1428 /// progressively working outward to the current library scope. 1451 /// progressively working outward to the current library scope.
1429 String findElementInScope(String name) { 1452 String findElementInScope(String name) {
1430 var lookupFunc = Indexable.determineLookupFunc(name); 1453 var lookupFunc = Indexable.determineLookupFunc(name);
(...skipping 24 matching lines...) Expand all
1455 inheritedVariables.addAll(_allButStatics(superclass.variables)); 1478 inheritedVariables.addAll(_allButStatics(superclass.variables));
1456 addInheritedMethod(superclass, this); 1479 addInheritedMethod(superclass, this);
1457 } 1480 }
1458 1481
1459 /** [newParent] refers to the actual class is currently using these methods. 1482 /** [newParent] refers to the actual class is currently using these methods.
1460 * which may be different because with the mirror system, we only point to the 1483 * which may be different because with the mirror system, we only point to the
1461 * original canonical superclasse's method. 1484 * original canonical superclasse's method.
1462 */ 1485 */
1463 void addInheritedMethod(Class parent, Class newParent) { 1486 void addInheritedMethod(Class parent, Class newParent) {
1464 parent.inheritedMethods.forEach((name, method) { 1487 parent.inheritedMethods.forEach((name, method) {
1465 if(!method.isConstructor){ 1488 if(!method.mirror.isConstructor){
1466 inheritedMethods[name] = new Method(method.mirror, newParent, method); 1489 inheritedMethods[name] = new Method(method.mirror, newParent, method);
1467 }} 1490 }}
1468 ); 1491 );
1469 _allButStatics(parent.methods).forEach((name, method) { 1492 _allButStatics(parent.methods).forEach((name, method) {
1470 if (!method.isConstructor) { 1493 if (!method.mirror.isConstructor) {
1471 inheritedMethods[name] = new Method(method.mirror, newParent, method); 1494 inheritedMethods[name] = new Method(method.mirror, newParent, method);
1472 }} 1495 }}
1473 ); 1496 );
1474 } 1497 }
1475 1498
1476 /// Remove statics from the map of inherited items before adding them. 1499 /// Remove statics from the map of inherited items before adding them.
1477 Map _allButStatics(Map items) { 1500 Map _allButStatics(Map items) {
1478 var result = {}; 1501 var result = {};
1479 items.forEach((name, item) { 1502 items.forEach((name, item) {
1480 if (!item.isStatic) { 1503 if (!item.isStatic) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 .map((x) => x.qualifiedName).toList(), 1577 .map((x) => x.qualifiedName).toList(),
1555 'variables': recurseMap(variables), 1578 'variables': recurseMap(variables),
1556 'inheritedVariables': recurseMap(inheritedVariables), 1579 'inheritedVariables': recurseMap(inheritedVariables),
1557 'methods': expandMethodMap(methods), 1580 'methods': expandMethodMap(methods),
1558 'inheritedMethods': expandMethodMap(inheritedMethods), 1581 'inheritedMethods': expandMethodMap(inheritedMethods),
1559 'annotations': annotations.map((a) => a.toMap()).toList(), 1582 'annotations': annotations.map((a) => a.toMap()).toList(),
1560 'generics': recurseMap(generics) 1583 'generics': recurseMap(generics)
1561 }; 1584 };
1562 1585
1563 int compareTo(aClass) => name.compareTo(aClass.name); 1586 int compareTo(aClass) => name.compareTo(aClass.name);
1587
1588 bool _isValidMirror(DeclarationMirror mirror) => mirror is ClassMirror;
1564 } 1589 }
1565 1590
1566 class Typedef extends Indexable { 1591 class Typedef extends OwnedIndexable {
1567 String returnType; 1592 String returnType;
1568 1593
1569 Map<String, Parameter> parameters; 1594 Map<String, Parameter> parameters;
1570 1595
1571 /// Generic information about the typedef. 1596 /// Generic information about the typedef.
1572 Map<String, Generic> generics; 1597 Map<String, Generic> generics;
1573 1598
1574 /// List of the meta annotations on the typedef. 1599 /// List of the meta annotations on the typedef.
1575 List<Annotation> annotations; 1600 List<Annotation> annotations;
1576 1601
1577 /// Returns the [Library] for the given [mirror] if it has already been 1602 /// Returns the [Library] for the given [mirror] if it has already been
1578 /// created, else creates it. 1603 /// created, else creates it.
1579 factory Typedef(TypedefMirror mirror, Library owningLibrary) { 1604 factory Typedef(TypedefMirror mirror, Library owningLibrary) {
1580 var aTypedef = getDocgenObject(mirror, owningLibrary); 1605 var aTypedef = Indexable.getDocgenObject(mirror, owningLibrary);
1581 if (aTypedef is DummyMirror) { 1606 if (aTypedef is DummyMirror) {
1582 aTypedef = new Typedef._(mirror, owningLibrary); 1607 aTypedef = new Typedef._(mirror, owningLibrary);
1583 } 1608 }
1584 return aTypedef; 1609 return aTypedef;
1585 } 1610 }
1586 1611
1587 Typedef._(TypedefMirror mirror, Library owningLibrary) : super(mirror) { 1612 Typedef._(TypedefMirror mirror, Library owningLibrary) :
1588 owner = owningLibrary; 1613 super(mirror, owningLibrary) {
1589 returnType = getDocgenObject(mirror.value.returnType).docName; 1614 returnType = Indexable.getDocgenObject(mirror.value.returnType).docName;
1590 generics = _createGenerics(mirror); 1615 generics = _createGenerics(mirror);
1591 parameters = _createParameters(mirror.value.parameters, owningLibrary); 1616 parameters = _createParameters(mirror.value.parameters, owningLibrary);
1592 annotations = _createAnnotations(mirror, owningLibrary); 1617 annotations = _createAnnotations(mirror, owningLibrary);
1593 } 1618 }
1594 1619
1595 Map toMap() => { 1620 Map toMap() => {
1596 'name': name, 1621 'name': name,
1597 'qualifiedName': qualifiedName, 1622 'qualifiedName': qualifiedName,
1598 'comment': comment, 1623 'comment': comment,
1599 'return': returnType, 1624 'return': returnType,
1600 'parameters': recurseMap(parameters), 1625 'parameters': recurseMap(parameters),
1601 'annotations': annotations.map((a) => a.toMap()).toList(), 1626 'annotations': annotations.map((a) => a.toMap()).toList(),
1602 'generics': recurseMap(generics) 1627 'generics': recurseMap(generics)
1603 }; 1628 };
1604 1629
1605 String get typeName => 'typedef'; 1630 String get typeName => 'typedef';
1631
1632 bool _isValidMirror(DeclarationMirror mirror) => mirror is TypedefMirror;
1606 } 1633 }
1607 1634
1608 /// A class containing properties of a Dart variable. 1635 /// A class containing properties of a Dart variable.
1609 class Variable extends Indexable { 1636 class Variable extends OwnedIndexable {
1610 1637
1611 bool isFinal; 1638 bool isFinal;
1612 bool isStatic; 1639 bool isStatic;
1613 bool isConst; 1640 bool isConst;
1614 Type type; 1641 Type type;
1615 String _variableName; 1642 String _variableName;
1616 Indexable owner;
1617 1643
1618 /// List of the meta annotations on the variable. 1644 /// List of the meta annotations on the variable.
1619 List<Annotation> annotations; 1645 List<Annotation> annotations;
1620 1646
1621 factory Variable(String variableName, VariableMirror mirror, 1647 factory Variable(String variableName, VariableMirror mirror,
1622 Indexable owner) { 1648 Indexable owner) {
1623 var variable = getDocgenObject(mirror); 1649 var variable = Indexable.getDocgenObject(mirror);
1624 if (variable is DummyMirror) { 1650 if (variable is DummyMirror) {
1625 return new Variable._(variableName, mirror, owner); 1651 return new Variable._(variableName, mirror, owner);
1626 } 1652 }
1627 return variable; 1653 return variable;
1628 } 1654 }
1629 1655
1630 Variable._(this._variableName, VariableMirror mirror, this.owner) : 1656 Variable._(this._variableName, VariableMirror mirror, Indexable owner) :
1631 super(mirror) { 1657 super(mirror, owner) {
1632 isFinal = mirror.isFinal; 1658 isFinal = mirror.isFinal;
1633 isStatic = mirror.isStatic; 1659 isStatic = mirror.isStatic;
1634 isConst = mirror.isConst; 1660 isConst = mirror.isConst;
1635 type = new Type(mirror.type, _getOwningLibrary(owner)); 1661 type = new Type(mirror.type, _getOwningLibrary(owner));
1636 annotations = _createAnnotations(mirror, _getOwningLibrary(owner)); 1662 annotations = _createAnnotations(mirror, _getOwningLibrary(owner));
1637 } 1663 }
1638 1664
1639 String get name => _variableName; 1665 String get name => _variableName;
1640 1666
1641 /// Generates a map describing the [Variable] object. 1667 /// Generates a map describing the [Variable] object.
(...skipping 19 matching lines...) Expand all
1661 } 1687 }
1662 return super.comment; 1688 return super.comment;
1663 } 1689 }
1664 1690
1665 markdown.Node fixReferenceWithScope(String name) => fixReference(name); 1691 markdown.Node fixReferenceWithScope(String name) => fixReference(name);
1666 1692
1667 String findElementInScope(String name) { 1693 String findElementInScope(String name) {
1668 var lookupFunc = Indexable.determineLookupFunc(name); 1694 var lookupFunc = Indexable.determineLookupFunc(name);
1669 var result = lookupFunc(mirror, name); 1695 var result = lookupFunc(mirror, name);
1670 if (result != null) { 1696 if (result != null) {
1671 result = getDocgenObject(result); 1697 result = Indexable.getDocgenObject(result);
1672 if (result is DummyMirror) return packagePrefix + result.docName; 1698 if (result is DummyMirror) return packagePrefix + result.docName;
1673 return result.packagePrefix + result.docName; 1699 return result.packagePrefix + result.docName;
1674 } 1700 }
1675 1701
1676 if (owner != null) { 1702 if (owner != null) {
1677 var result = owner.findElementInScope(name); 1703 var result = owner.findElementInScope(name);
1678 if (result != null) { 1704 if (result != null) {
1679 return result; 1705 return result;
1680 } 1706 }
1681 } 1707 }
1682 return super.findElementInScope(name); 1708 return super.findElementInScope(name);
1683 } 1709 }
1710
1711 bool _isValidMirror(DeclarationMirror mirror) => mirror is VariableMirror;
1684 } 1712 }
1685 1713
1686 /// A class containing properties of a Dart method. 1714 /// A class containing properties of a Dart method.
1687 class Method extends Indexable { 1715 class Method extends OwnedIndexable {
1688 1716
1689 /// Parameters for this method. 1717 /// Parameters for this method.
1690 Map<String, Parameter> parameters; 1718 Map<String, Parameter> parameters;
1691 1719
1692 bool isStatic; 1720 bool isStatic;
1693 bool isAbstract; 1721 bool isAbstract;
1694 bool isConst; 1722 bool isConst;
1695 bool isConstructor;
1696 bool isGetter;
1697 bool isSetter;
1698 bool isOperator;
1699 Type returnType; 1723 Type returnType;
1700 Method methodInheritedFrom; 1724 Method methodInheritedFrom;
1701 1725
1702 /// Qualified name to state where the comment is inherited from. 1726 /// Qualified name to state where the comment is inherited from.
1703 String commentInheritedFrom = ""; 1727 String commentInheritedFrom = "";
1704 1728
1705 /// List of the meta annotations on the method. 1729 /// List of the meta annotations on the method.
1706 List<Annotation> annotations; 1730 List<Annotation> annotations;
1707 1731
1708 Indexable owner;
1709
1710 factory Method(MethodMirror mirror, Indexable owner, // Indexable newOwner. 1732 factory Method(MethodMirror mirror, Indexable owner, // Indexable newOwner.
1711 [Method methodInheritedFrom]) { 1733 [Method methodInheritedFrom]) {
1712 var method = getDocgenObject(mirror, owner); 1734 var method = Indexable.getDocgenObject(mirror, owner);
1713 if (method is DummyMirror) { 1735 if (method is DummyMirror) {
1714 method = new Method._(mirror, owner, methodInheritedFrom); 1736 method = new Method._(mirror, owner, methodInheritedFrom);
1715 } 1737 }
1716 return method; 1738 return method;
1717 } 1739 }
1718 1740
1719 Method._(MethodMirror mirror, this.owner, this.methodInheritedFrom) 1741 Method._(MethodMirror mirror, Indexable owner, this.methodInheritedFrom)
1720 : super(mirror) { 1742 : super(mirror, owner) {
1721 this.isStatic = mirror.isStatic; 1743 isStatic = mirror.isStatic;
1722 this.isAbstract = mirror.isAbstract; 1744 isAbstract = mirror.isAbstract;
1723 this.isConst = mirror.isConstConstructor; 1745 isConst = mirror.isConstConstructor;
1724 this.returnType = new Type(mirror.returnType, _getOwningLibrary(owner)); 1746 returnType = new Type(mirror.returnType, _getOwningLibrary(owner));
1725 this.parameters = _createParameters(mirror.parameters, owner); 1747 parameters = _createParameters(mirror.parameters, owner);
1726 this.annotations = _createAnnotations(mirror, _getOwningLibrary(owner)); 1748 annotations = _createAnnotations(mirror, _getOwningLibrary(owner));
1727 this.isConstructor = mirror.isConstructor;
1728 this.isGetter = mirror.isGetter;
1729 this.isSetter = mirror.isSetter;
1730 this.isOperator = mirror.isOperator;
1731 } 1749 }
1732 1750
1733 String get packagePrefix => owner.packagePrefix; 1751 String get packagePrefix => owner.packagePrefix;
1734 1752
1735 Method get originallyInheritedFrom => methodInheritedFrom == null ? 1753 Method get originallyInheritedFrom => methodInheritedFrom == null ?
1736 this : methodInheritedFrom.originallyInheritedFrom; 1754 this : methodInheritedFrom.originallyInheritedFrom;
1737 1755
1738 markdown.Node fixReferenceWithScope(String name) => fixReference(name); 1756 markdown.Node fixReferenceWithScope(String name) => fixReference(name);
1739 1757
1740 /// Look for the specified name starting with the current member, and 1758 /// Look for the specified name starting with the current member, and
1741 /// progressively working outward to the current library scope. 1759 /// progressively working outward to the current library scope.
1742 String findElementInScope(String name) { 1760 String findElementInScope(String name) {
1743 var lookupFunc = Indexable.determineLookupFunc(name); 1761 var lookupFunc = Indexable.determineLookupFunc(name);
1744 1762
1745 var memberScope = lookupFunc(this.mirror, name); 1763 var memberScope = lookupFunc(this.mirror, name);
1746 if (memberScope != null) { 1764 if (memberScope != null) {
1747 // do we check for a dummy mirror returned here and look up with an owner 1765 // do we check for a dummy mirror returned here and look up with an owner
1748 // higher ooooor in getDocgenObject do we include more things in our 1766 // higher ooooor in getDocgenObject do we include more things in our
1749 // lookup 1767 // lookup
1750 var result = getDocgenObject(memberScope, owner); 1768 var result = Indexable.getDocgenObject(memberScope, owner);
1751 if (result is DummyMirror && owner.owner != null 1769 if (result is DummyMirror && owner.owner != null
1752 && owner.owner is! DummyMirror) { 1770 && owner.owner is! DummyMirror) {
1753 var aresult = getDocgenObject(memberScope, owner.owner); 1771 var aresult = Indexable.getDocgenObject(memberScope, owner.owner);
1754 if (aresult is! DummyMirror) result = aresult; 1772 if (aresult is! DummyMirror) result = aresult;
1755 } 1773 }
1756 if (result is DummyMirror) return packagePrefix + result.docName; 1774 if (result is DummyMirror) return packagePrefix + result.docName;
1757 return result.packagePrefix + result.docName; 1775 return result.packagePrefix + result.docName;
1758 } 1776 }
1759 1777
1760 if (owner != null) { 1778 if (owner != null) {
1761 var result = owner.findElementInScope(name); 1779 var result = owner.findElementInScope(name);
1762 if (result != null) return result; 1780 if (result != null) return result;
1763 } 1781 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1797 'inheritedFrom': (methodInheritedFrom == null? '' : 1815 'inheritedFrom': (methodInheritedFrom == null? '' :
1798 originallyInheritedFrom.docName), 1816 originallyInheritedFrom.docName),
1799 'static': isStatic.toString(), 1817 'static': isStatic.toString(),
1800 'abstract': isAbstract.toString(), 1818 'abstract': isAbstract.toString(),
1801 'constant': isConst.toString(), 1819 'constant': isConst.toString(),
1802 'return': new List.filled(1, returnType.toMap()), 1820 'return': new List.filled(1, returnType.toMap()),
1803 'parameters': recurseMap(parameters), 1821 'parameters': recurseMap(parameters),
1804 'annotations': annotations.map((a) => a.toMap()).toList() 1822 'annotations': annotations.map((a) => a.toMap()).toList()
1805 }; 1823 };
1806 1824
1807 String get typeName => isConstructor ? 'constructor' : 1825 String get typeName {
1808 isGetter ? 'getter' : isSetter ? 'setter' : 1826 MethodMirror theMirror = mirror;
1809 isOperator ? 'operator' : 'method'; 1827 if (theMirror.isConstructor) return 'constructor';
1828 if (theMirror.isGetter) return 'getter';
1829 if (theMirror.isSetter) return'setter';
1830 if (theMirror.isOperator) return 'operator';
1831 return 'method';
1832 }
1810 1833
1811 get comment { 1834 get comment {
1812 if (_comment != null) return _comment; 1835 if (_comment != null) return _comment;
1813 if (owner is Class) { 1836 if (owner is Class) {
1814 (owner as Class).ensureComments(); 1837 (owner as Class).ensureComments();
1815 } 1838 }
1816 var result = super.comment; 1839 var result = super.comment;
1817 if (result == '' && methodInheritedFrom != null) { 1840 if (result == '' && methodInheritedFrom != null) {
1818 // this should be NOT from the MIRROR, but from the COMMENT 1841 // this should be NOT from the MIRROR, but from the COMMENT
1819 _unresolvedComment = methodInheritedFrom._unresolvedComment; 1842 _unresolvedComment = methodInheritedFrom._unresolvedComment;
1820 1843
1821 var linkResolver = (name) => fixReferenceWithScope(name); 1844 var linkResolver = (name) => fixReferenceWithScope(name);
1822 comment = _unresolvedComment == null ? '' : 1845 comment = _unresolvedComment == null ? '' :
1823 markdown.markdownToHtml(_unresolvedComment.trim(), 1846 markdown.markdownToHtml(_unresolvedComment.trim(),
1824 linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES); 1847 linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES);
1825 commentInheritedFrom = methodInheritedFrom.commentInheritedFrom; 1848 commentInheritedFrom = methodInheritedFrom.commentInheritedFrom;
1826 result = comment; 1849 result = comment;
1827 } 1850 }
1828 return result; 1851 return result;
1829 } 1852 }
1853
1854 bool _isValidMirror(DeclarationMirror mirror) => mirror is MethodMirror;
1830 } 1855 }
1831 1856
1832 /// Docgen wrapper around the dart2js mirror for a Dart 1857 /// Docgen wrapper around the dart2js mirror for a Dart
1833 /// method/function parameter. 1858 /// method/function parameter.
1834 class Parameter extends MirrorBased { 1859 class Parameter extends MirrorBased {
1835 ParameterMirror mirror; 1860 ParameterMirror mirror;
1836 String name; 1861 String name;
1837 bool isOptional; 1862 bool isOptional;
1838 bool isNamed; 1863 bool isNamed;
1839 bool hasDefaultValue; 1864 bool hasDefaultValue;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1898 /// - "outer" : "dart-core.Map" 1923 /// - "outer" : "dart-core.Map"
1899 /// "inner" : 1924 /// "inner" :
1900 /// - "outer" : "dart-core.String" 1925 /// - "outer" : "dart-core.String"
1901 /// "inner" : 1926 /// "inner" :
1902 /// - "outer" : "dart-core.List" 1927 /// - "outer" : "dart-core.List"
1903 /// "inner" : 1928 /// "inner" :
1904 /// - "outer" : "dart-core.int" 1929 /// - "outer" : "dart-core.int"
1905 /// "inner" : 1930 /// "inner" :
1906 class Type extends MirrorBased { 1931 class Type extends MirrorBased {
1907 TypeMirror mirror; 1932 TypeMirror mirror;
1908 MirrorBased owningLibrary; 1933 Library owningLibrary;
1909 1934
1910 Type(this.mirror, this.owningLibrary); 1935 Type(this.mirror, this.owningLibrary);
1911 1936
1912 /// Returns a list of [Type] objects constructed from TypeMirrors. 1937 /// Returns a list of [Type] objects constructed from TypeMirrors.
1913 List<Type> _createTypeGenerics(TypeMirror mirror) { 1938 List<Type> _createTypeGenerics(TypeMirror mirror) {
1914 if (mirror is ClassMirror && !mirror.isTypedef) { 1939 if (mirror is ClassMirror && !mirror.isTypedef) {
1915 var innerList = []; 1940 var innerList = [];
1916 mirror.typeArguments.forEach((e) { 1941 mirror.typeArguments.forEach((e) {
1917 innerList.add(new Type(e, owningLibrary)); 1942 innerList.add(new Type(e, owningLibrary));
1918 }); 1943 });
1919 return innerList; 1944 return innerList;
1920 } 1945 }
1921 return []; 1946 return [];
1922 } 1947 }
1923 1948
1924 Map toMap() => { 1949 Map toMap() {
1925 // We may encounter types whose corresponding library has not been 1950 var result = Indexable.getDocgenObject(mirror, owningLibrary);
1926 // processed yet, so look up with the owningLibrary at the last moment. 1951 return {
1927 'outer': getDocgenObject(mirror, owningLibrary).docName, 1952 // We may encounter types whose corresponding library has not been
1928 'inner': _createTypeGenerics(mirror).map((e) => e.toMap()).toList(), 1953 // processed yet, so look up with the owningLibrary at the last moment.
1929 }; 1954 'outer': result.packagePrefix + result.docName,
1955 'inner': _createTypeGenerics(mirror).map((e) => e.toMap()).toList(),
1956 };
1957 }
1930 } 1958 }
1931 1959
1932 /// Holds the name of the annotation, and its parameters. 1960 /// Holds the name of the annotation, and its parameters.
1933 class Annotation extends MirrorBased { 1961 class Annotation extends MirrorBased {
1934 List<String> parameters; 1962 List<String> parameters;
1935 /// The class of this annotation. 1963 /// The class of this annotation.
1936 ClassMirror mirror; 1964 ClassMirror mirror;
1937 Library owningLibrary; 1965 Library owningLibrary;
1938 1966
1939 Annotation(InstanceMirror originalMirror, this.owningLibrary) { 1967 Annotation(InstanceMirror originalMirror, this.owningLibrary) {
1940 mirror = originalMirror.type; 1968 mirror = originalMirror.type;
1941 parameters = originalMirror.type.variables.values 1969 parameters = originalMirror.type.variables.values
1942 .where((e) => e.isFinal) 1970 .where((e) => e.isFinal)
1943 .map((e) => originalMirror.getField(e.simpleName).reflectee) 1971 .map((e) => originalMirror.getField(e.simpleName).reflectee)
1944 .where((e) => e != null) 1972 .where((e) => e != null)
1945 .toList(); 1973 .toList();
1946 } 1974 }
1947 1975
1948 Map toMap() => { 1976 Map toMap() => {
1949 'name': getDocgenObject(mirror, owningLibrary).docName, 1977 'name': Indexable.getDocgenObject(mirror, owningLibrary).docName,
1950 'parameters': parameters 1978 'parameters': parameters
1951 }; 1979 };
1952 } 1980 }
OLDNEW
« no previous file with comments | « no previous file | pkg/docgen/test/multi_library_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698