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

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

Issue 139993008: Additional refactoring for docgen. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 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 | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// **docgen** is a tool for creating machine readable representations of Dart 5 /// **docgen** is a tool for creating machine readable representations of Dart
6 /// code metadata, including: classes, members, comments and annotations. 6 /// code metadata, including: classes, members, comments and annotations.
7 /// 7 ///
8 /// docgen is run on a `.dart` file or a directory containing `.dart` files. 8 /// docgen is run on a `.dart` file or a directory containing `.dart` files.
9 /// 9 ///
10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR] 10 /// $ dart docgen.dart [OPTIONS] [FILE/DIR]
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 * [A Tour of the Dart Libraries](http://www.dartlang.org/docs/dart-up-and-runn ing/contents/ch03.html) 89 * [A Tour of the Dart Libraries](http://www.dartlang.org/docs/dart-up-and-runn ing/contents/ch03.html)
90 90
91 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
92 [Dart project](https://code.google.com/p/dart/). 92 [Dart project](https://code.google.com/p/dart/).
93 If you'd like to contribute to this documentation, see 93 If you'd like to contribute to this documentation, see
94 [Contributing](https://code.google.com/p/dart/wiki/Contributing) 94 [Contributing](https://code.google.com/p/dart/wiki/Contributing)
95 and 95 and
96 [Writing API Documentation](https://code.google.com/p/dart/wiki/WritingApiDocume ntation). 96 [Writing API Documentation](https://code.google.com/p/dart/wiki/WritingApiDocume ntation).
97 """; 97 """;
98 98
99 // TODO(efortuna): The use of this field is odd (this is based on how it was
100 // originally used. Try to cleanup.
101 /// Index of all indexable items. This also ensures that no class is
102 /// created more than once.
103 Map<String, Indexable> entityMap = new Map<String, Indexable>();
104
105 /// Docgen constructor initializes the link resolver for markdown parsing. 99 /// Docgen constructor initializes the link resolver for markdown parsing.
106 /// Also initializes the command line arguments. 100 /// Also initializes the command line arguments.
107 /// 101 ///
108 /// [packageRoot] is the packages directory of the directory being analyzed. 102 /// [packageRoot] is the packages directory of the directory being analyzed.
109 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will 103 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will
110 /// also be documented. 104 /// also be documented.
111 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented. 105 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented.
112 /// This option is useful when only the SDK libraries are needed. 106 /// This option is useful when only the SDK libraries are needed.
113 /// 107 ///
114 /// Returned Future completes with true if document generation is successful. 108 /// Returned Future completes with true if document generation is successful.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 LibraryMirror _getOwningLibraryFromMirror(DeclarationMirror mirror) { 176 LibraryMirror _getOwningLibraryFromMirror(DeclarationMirror mirror) {
183 if (mirror is LibraryMirror) return mirror; 177 if (mirror is LibraryMirror) return mirror;
184 if (mirror == null) return null; 178 if (mirror == null) return null;
185 return _getOwningLibraryFromMirror(mirror.owner); 179 return _getOwningLibraryFromMirror(mirror.owner);
186 } 180 }
187 } 181 }
188 182
189 /// Docgen representation of an item to be documented, that wraps around a 183 /// Docgen representation of an item to be documented, that wraps around a
190 /// dart2js mirror. 184 /// dart2js mirror.
191 abstract class MirrorBased { 185 abstract class MirrorBased {
186 /// The original dart2js mirror around which this object wraps.
192 DeclarationMirror get mirror; 187 DeclarationMirror get mirror;
193 188
194 /// Returns a list of meta annotations assocated with a mirror. 189 /// Returns a list of meta annotations assocated with a mirror.
195 List<Annotation> _createAnnotations(DeclarationMirror mirror, 190 List<Annotation> _createAnnotations(DeclarationMirror mirror,
196 Library owningLibrary) { 191 Library owningLibrary) {
197 var annotationMirrors = mirror.metadata.where((e) => 192 var annotationMirrors = mirror.metadata.where((e) =>
198 e is dart2js.Dart2JsConstructedConstantMirror); 193 e is dart2js.Dart2JsConstructedConstantMirror);
199 var annotations = []; 194 var annotations = [];
200 annotationMirrors.forEach((annotation) { 195 annotationMirrors.forEach((annotation) {
201 var docgenAnnotation = new Annotation(annotation, owningLibrary); 196 var docgenAnnotation = new Annotation(annotation, owningLibrary);
202 if (!_SKIPPED_ANNOTATIONS.contains( 197 if (!_SKIPPED_ANNOTATIONS.contains(
203 docgenAnnotation.mirror.qualifiedName)) { 198 docgenAnnotation.mirror.qualifiedName)) {
204 annotations.add(docgenAnnotation); 199 annotations.add(docgenAnnotation);
205 } 200 }
206 }); 201 });
207 return annotations; 202 return annotations;
208 } 203 }
209 } 204 }
210 205
206 /// Top level documentation traversal and generation object.
207 ///
208 /// Yes, everything in this class is used statically so this technically need
Alan Knight 2014/01/31 17:48:53 missing "doesn't" ?
Emily Fortuna 2014/02/01 02:06:48 Done
209 /// to be its own class, but it's grouped together for semantic separation from
210 /// the other classes and functionality in this library.
211 class _Generator { 211 class _Generator {
212 /// The directory where the output docs are generated.
212 static var _outputDirectory; 213 static var _outputDirectory;
213 214
214 /// This is set from the command line arguments flag --include-private 215 /// This is set from the command line arguments flag --include-private
215 static bool _includePrivate = false; 216 static bool _includePrivate = false;
216 217
217 /// Library names to explicitly exclude. 218 /// Library names to explicitly exclude.
218 /// 219 ///
219 /// Set from the command line option 220 /// Set from the command line option
220 /// --exclude-lib. 221 /// --exclude-lib.
221 static List<String> _excluded; 222 static List<String> _excluded;
222 223
224 /// Logger for printing out progress of documentation generation.
223 static Logger logger = new Logger('Docgen'); 225 static Logger logger = new Logger('Docgen');
224 226
225 /// Docgen constructor initializes the link resolver for markdown parsing. 227 /// Docgen constructor initializes the link resolver for markdown parsing.
226 /// Also initializes the command line arguments. 228 /// Also initializes the command line arguments.
227 /// 229 ///
228 /// [packageRoot] is the packages directory of the directory being analyzed. 230 /// [packageRoot] is the packages directory of the directory being analyzed.
229 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will 231 /// If [includeSdk] is `true`, then any SDK libraries explicitly imported will
230 /// also be documented. 232 /// also be documented.
231 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented. 233 /// If [parseSdk] is `true`, then all Dart SDK libraries will be documented.
232 /// This option is useful when only the SDK libraries are needed. 234 /// This option is useful when only the SDK libraries are needed.
(...skipping 19 matching lines...) Expand all
252 if (includeSdk) { 254 if (includeSdk) {
253 allLibraries.addAll(_listSdk()); 255 allLibraries.addAll(_listSdk());
254 } 256 }
255 257
256 return getMirrorSystem(allLibraries, packageRoot: updatedPackageRoot, 258 return getMirrorSystem(allLibraries, packageRoot: updatedPackageRoot,
257 parseSdk: parseSdk) 259 parseSdk: parseSdk)
258 .then((MirrorSystem mirrorSystem) { 260 .then((MirrorSystem mirrorSystem) {
259 if (mirrorSystem.libraries.isEmpty) { 261 if (mirrorSystem.libraries.isEmpty) {
260 throw new StateError('No library mirrors were created.'); 262 throw new StateError('No library mirrors were created.');
261 } 263 }
262 Indexable.initializeTopLevelLibraries(mirrorSystem); 264 Indexable._initializeTopLevelLibraries(mirrorSystem);
263 265
264 var availableLibraries = mirrorSystem.libraries.values.where( 266 var availableLibraries = mirrorSystem.libraries.values.where(
265 (each) => each.uri.scheme == 'file'); 267 (each) => each.uri.scheme == 'file');
266 var availableLibrariesByPath = new Map.fromIterables( 268 var availableLibrariesByPath = new Map.fromIterables(
267 availableLibraries.map((each) => each.uri), 269 availableLibraries.map((each) => each.uri),
268 availableLibraries); 270 availableLibraries);
269 var librariesToDocument = requestedLibraries.map( 271 var librariesToDocument = requestedLibraries.map(
270 (each) => availableLibrariesByPath.putIfAbsent(each, 272 (each) => availableLibrariesByPath.putIfAbsent(each,
271 () => throw "Missing library $each")).toList(); 273 () => throw "Missing library $each")).toList();
272 librariesToDocument.addAll( 274 librariesToDocument.addAll(
(...skipping 25 matching lines...) Expand all
298 if (!subdir.existsSync()) { 300 if (!subdir.existsSync()) {
299 subdir.createSync(); 301 subdir.createSync();
300 } 302 }
301 } 303 }
302 } 304 }
303 File file = new File(path.join(_outputDirectory, filename)); 305 File file = new File(path.join(_outputDirectory, filename));
304 file.writeAsStringSync(text, 306 file.writeAsStringSync(text,
305 mode: append ? FileMode.APPEND : FileMode.WRITE); 307 mode: append ? FileMode.APPEND : FileMode.WRITE);
306 } 308 }
307 309
310 /// Resolve all the links in the introductory comments for a given library or
311 /// package as specified by [filename].
312 static String _readIntroductionFile(String fileName, bool includeSdk) {
313 var linkResolver = (name) => Indexable.globalFixReference(name);
314 var defaultText = includeSdk ? _DEFAULT_SDK_INTRODUCTION : '';
315 var introText = defaultText;
316 if (fileName.isNotEmpty) {
317 var introFile = new File(fileName);
318 introText = introFile.existsSync() ? introFile.readAsStringSync() :
319 defaultText;
320 }
321 return markdown.markdownToHtml(introText,
322 linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES);
323 }
324
308 /// Creates documentation for filtered libraries. 325 /// Creates documentation for filtered libraries.
309 static void _documentLibraries(List<LibraryMirror> libs, 326 static void _documentLibraries(List<LibraryMirror> libs,
310 {bool includeSdk: false, bool outputToYaml: true, bool append: false, 327 {bool includeSdk: false, bool outputToYaml: true, bool append: false,
311 bool parseSdk: false, String introFileName: ''}) { 328 bool parseSdk: false, String introFileName: ''}) {
312 libs.forEach((lib) { 329 libs.forEach((lib) {
313 // Files belonging to the SDK have a uri that begins with 'dart:'. 330 // Files belonging to the SDK have a uri that begins with 'dart:'.
314 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { 331 if (includeSdk || !lib.uri.toString().startsWith('dart:')) {
315 var library = generateLibrary(lib); 332 var library = generateLibrary(lib);
316 entityMap[library.name] = library;
317 } 333 }
318 }); 334 });
319 335
320 var filteredEntities = entityMap.values.where(_isFullChainVisible); 336 var filteredEntities = new Set<Indexable>();
321 337 for (Map<String, Set<Indexable>> firstLevel in
322 /*var filteredEntities2 = new Set<MirrorBased>(); 338 Indexable._mirrorToDocgen.values) {
323 for (Map<String, Set<MirrorBased>> firstLevel in mirrorToDocgen.values) { 339 for (Set<Indexable> items in firstLevel.values) {
324 for (Set<MirrorBased> items in firstLevel.values) { 340 for (Indexable item in items) {
325 for (MirrorBased item in items) {
326 if (_isFullChainVisible(item)) { 341 if (_isFullChainVisible(item)) {
327 filteredEntities2.add(item); 342 if (item is! Method ||
343 (item is Method && item.methodInheritedFrom == null)) {
344 filteredEntities.add(item);
345 }
328 } 346 }
329 } 347 }
330 } 348 }
331 }*/ 349 }
332
333 /*print('THHHHHEEE DIFFERENCE IS');
334 var set1 = new Set.from(filteredEntities);
335 var set2 = new Set.from(filteredEntities2);
336 var aResult = set2.difference(set1);
337 for (MirrorBased r in aResult) {
338 print(' a result is $r and ${r.docName}');
339 }*/
340 //print(set1.difference(set2));
341 350
342 // Outputs a JSON file with all libraries and their preview comments. 351 // Outputs a JSON file with all libraries and their preview comments.
343 // This will help the viewer know what libraries are available to read in. 352 // This will help the viewer know what libraries are available to read in.
344 var libraryMap; 353 var libraryMap;
345 var linkResolver = (name) => Indexable.globalFixReference(name);
346
347 String readIntroductionFile(String fileName, includeSdk) {
348 var defaultText = includeSdk ? _DEFAULT_SDK_INTRODUCTION : '';
349 var introText = defaultText;
350 if (fileName.isNotEmpty) {
351 var introFile = new File(fileName);
352 introText = introFile.existsSync() ? introFile.readAsStringSync() :
353 defaultText;
354 }
355 return markdown.markdownToHtml(introText,
356 linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES);
357 }
358 354
359 if (append) { 355 if (append) {
360 var docsDir = listDir(_outputDirectory); 356 var docsDir = listDir(_outputDirectory);
361 if (!docsDir.contains('$_outputDirectory/library_list.json')) { 357 if (!docsDir.contains('$_outputDirectory/library_list.json')) {
362 throw new StateError('No library_list.json'); 358 throw new StateError('No library_list.json');
363 } 359 }
364 libraryMap = 360 libraryMap =
365 JSON.decode(new File( 361 JSON.decode(new File(
366 '$_outputDirectory/library_list.json').readAsStringSync()); 362 '$_outputDirectory/library_list.json').readAsStringSync());
367 libraryMap['libraries'].addAll(filteredEntities 363 libraryMap['libraries'].addAll(filteredEntities
368 .where((e) => e is Library) 364 .where((e) => e is Library)
369 .map((e) => e.previewMap)); 365 .map((e) => e.previewMap));
370 var intro = libraryMap['introduction']; 366 var intro = libraryMap['introduction'];
371 var spacing = intro.isEmpty ? '' : '<br/><br/>'; 367 var spacing = intro.isEmpty ? '' : '<br/><br/>';
372 libraryMap['introduction'] = 368 libraryMap['introduction'] =
373 "$intro$spacing${readIntroductionFile(introFileName, includeSdk)}"; 369 "$intro$spacing${_readIntroductionFile(introFileName, includeSdk)}";
374 outputToYaml = libraryMap['filetype'] == 'yaml'; 370 outputToYaml = libraryMap['filetype'] == 'yaml';
375 } else { 371 } else {
376 libraryMap = { 372 libraryMap = {
377 'libraries' : filteredEntities.where((e) => 373 'libraries' : filteredEntities.where((e) =>
378 e is Library).map((e) => e.previewMap).toList(), 374 e is Library).map((e) => e.previewMap).toList(),
379 'introduction' : readIntroductionFile(introFileName, includeSdk), 375 'introduction' : _readIntroductionFile(introFileName, includeSdk),
380 'filetype' : outputToYaml ? 'yaml' : 'json' 376 'filetype' : outputToYaml ? 'yaml' : 'json'
381 }; 377 };
382 } 378 }
379 _writeOutputFiles(libraryMap, filteredEntities, outputToYaml, append);
380 }
381
382 /// Output all of the libraries and classes into json or yaml files for
383 /// consumption by a viewer.
384 static void _writeOutputFiles(libraryMap,
385 Iterable<Indexable> filteredEntities, bool outputToYaml, bool append) {
383 _writeToFile(JSON.encode(libraryMap), 'library_list.json'); 386 _writeToFile(JSON.encode(libraryMap), 'library_list.json');
384 387
385 // Output libraries and classes to file after all information is generated. 388 // Output libraries and classes to file after all information is generated.
386 filteredEntities.where((e) => e is Class || e is Library).forEach((output) { 389 filteredEntities.where((e) => e is Class || e is Library).forEach((output) {
387 _writeIndexableToFile(output, outputToYaml); 390 _writeIndexableToFile(output, outputToYaml);
388 }); 391 });
389 392
390 // Outputs all the qualified names documented with their type. 393 // Outputs all the qualified names documented with their type.
391 // This will help generate search results. 394 // This will help generate search results.
392 _writeToFile(filteredEntities.map((e) => 395 _writeToFile(filteredEntities.map((e) =>
393 '${e.qualifiedName} ${e.typeName}').join('\n') + '\n', 396 '${e.qualifiedName} ${e.typeName}').join('\n') + '\n',
394 'index.txt', append: append); 397 'index.txt', append: append);
395 var index = new Map.fromIterables( 398 var index = new Map.fromIterables(
396 filteredEntities.map((e) => e.qualifiedName), 399 filteredEntities.map((e) => e.qualifiedName),
397 filteredEntities.map((e) => e.typeName)); 400 filteredEntities.map((e) => e.typeName));
398 if (append) { 401 if (append) {
399 var previousIndex = 402 var previousIndex =
400 JSON.decode(new File( 403 JSON.decode(new File(
401 '$_outputDirectory/index.json').readAsStringSync()); 404 '$_outputDirectory/index.json').readAsStringSync());
402 index.addAll(previousIndex); 405 index.addAll(previousIndex);
403 } 406 }
404 _writeToFile(JSON.encode(index), 'index.json'); 407 _writeToFile(JSON.encode(index), 'index.json');
405 } 408 }
406 409
410 /// Helper method to serialize the given Indexable out to a file.
407 static void _writeIndexableToFile(Indexable result, bool outputToYaml) { 411 static void _writeIndexableToFile(Indexable result, bool outputToYaml) {
408 var outputFile = result.fileName; 412 var outputFile = result.fileName;
409 var output; 413 var output;
410 if (outputToYaml) { 414 if (outputToYaml) {
411 output = getYamlString(result.toMap()); 415 output = getYamlString(result.toMap());
412 outputFile = outputFile + '.yaml'; 416 outputFile = outputFile + '.yaml';
413 } else { 417 } else {
414 output = JSON.encode(result.toMap()); 418 output = JSON.encode(result.toMap());
415 outputFile = outputFile + '.json'; 419 outputFile = outputFile + '.json';
416 } 420 }
417 _writeToFile(output, outputFile); 421 _writeToFile(output, outputFile);
418 } 422 }
419 423
420 /// Set the location of the ouput directory, and ensure that the location is 424 /// Set the location of the ouput directory, and ensure that the location is
421 /// available on the file system. 425 /// available on the file system.
422 static void _ensureOutputDirectory(String outputDirectory, bool append) { 426 static void _ensureOutputDirectory(String outputDirectory, bool append) {
423 _outputDirectory = outputDirectory; 427 _outputDirectory = outputDirectory;
424 if (!append) { 428 if (!append) {
425 var dir = new Directory(_outputDirectory); 429 var dir = new Directory(_outputDirectory);
426 if (dir.existsSync()) dir.deleteSync(recursive: true); 430 if (dir.existsSync()) dir.deleteSync(recursive: true);
427 } 431 }
428 } 432 }
429 433
430 434 /// Helper accessor to determine the full pathname of the root of the dart
435 /// checkout.
431 static String get _rootDirectory { 436 static String get _rootDirectory {
432 var scriptDir = path.absolute(path.dirname(Platform.script.toFilePath())); 437 var scriptDir = path.absolute(path.dirname(Platform.script.toFilePath()));
433 var root = scriptDir; 438 var root = scriptDir;
434 while(path.basename(root) != 'dart') { 439 while(path.basename(root) != 'dart') {
435 root = path.dirname(root); 440 root = path.dirname(root);
436 } 441 }
437 return root; 442 return root;
438 } 443 }
439 444
440 /// Analyzes set of libraries and provides a mirror system which can be used 445 /// Analyzes set of libraries and provides a mirror system which can be used
(...skipping 24 matching lines...) Expand all
465 }); 470 });
466 } 471 }
467 472
468 /// For this run of docgen, determine the packageRoot value. 473 /// For this run of docgen, determine the packageRoot value.
469 /// 474 ///
470 /// If packageRoot is not explicitly passed, we examine the files we're 475 /// If packageRoot is not explicitly passed, we examine the files we're
471 /// documenting to attempt to find a package root. 476 /// documenting to attempt to find a package root.
472 static String _obtainPackageRoot(String packageRoot, bool parseSdk, 477 static String _obtainPackageRoot(String packageRoot, bool parseSdk,
473 List<String> files) { 478 List<String> files) {
474 if (packageRoot == null && !parseSdk) { 479 if (packageRoot == null && !parseSdk) {
475 // TODO(efortuna): This logic seems not very robust, but it's from the
476 // original version of the code, pre-refactor, so I'm leavingt it for now.
477 // Revisit to make more robust.
478 // TODO(efortuna): See lines 303-311 in
479 // https://codereview.chromium.org/116043013/diff/390001/pkg/docgen/lib/do cgen.dart
480 var type = FileSystemEntity.typeSync(files.first); 480 var type = FileSystemEntity.typeSync(files.first);
481 if (type == FileSystemEntityType.DIRECTORY) { 481 if (type == FileSystemEntityType.DIRECTORY) {
482 var files2 = listDir(files.first, recursive: true); 482 var files2 = listDir(files.first, recursive: true);
483 // Return '' means that there was no pubspec.yaml and therefor no p 483 // Return '' means that there was no pubspec.yaml and therefor no p
484 // ackageRoot. 484 // ackageRoot.
485 packageRoot = files2.firstWhere((f) => 485 packageRoot = files2.firstWhere((f) =>
486 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => ''); 486 f.endsWith('${path.separator}pubspec.yaml'), orElse: () => '');
487 if (packageRoot != '') { 487 if (packageRoot != '') {
488 packageRoot = path.join(path.dirname(packageRoot), 'packages'); 488 packageRoot = path.join(path.dirname(packageRoot), 'packages');
489 } 489 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 var sdk = new List<Uri>(); 563 var sdk = new List<Uri>();
564 LIBRARIES.forEach((String name, LibraryInfo info) { 564 LIBRARIES.forEach((String name, LibraryInfo info) {
565 if (info.documented) { 565 if (info.documented) {
566 sdk.add(Uri.parse('dart:$name')); 566 sdk.add(Uri.parse('dart:$name'));
567 logger.info('Add to SDK: ${sdk.last}'); 567 logger.info('Add to SDK: ${sdk.last}');
568 } 568 }
569 }); 569 });
570 return sdk; 570 return sdk;
571 } 571 }
572 572
573 /// Return true if this item and all of its owners are all visible.
573 static bool _isFullChainVisible(Indexable item) { 574 static bool _isFullChainVisible(Indexable item) {
574 // TODO: reconcile with isVisible. 575 return _includePrivate || (!item.isPrivate && (item.owner != null ?
575 // TODO: Also should be able to take MirrorBased items in general probably.
576 var result = _includePrivate || (!item.isPrivate && (item.owner != null ?
577 _isFullChainVisible(item.owner) : true)); 576 _isFullChainVisible(item.owner) : true));
578 return result;
579 } 577 }
580 578
581 /// Currently left public for testing purposes. :-/ 579 /// Currently left public for testing purposes. :-/
582 static Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { 580 static Library generateLibrary(dart2js.Dart2JsLibraryMirror library) {
583 var result = new Library(library); 581 var result = new Library(library);
584 result._findPackage(library); 582 result._findPackage(library);
585 logger.fine('Generated library for ${result.name}'); 583 logger.fine('Generated library for ${result.name}');
586 return result; 584 return result;
587 } 585 }
588 } 586 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 map[owner.docName] = set; 638 map[owner.docName] = set;
641 _mirrorToDocgen[this.mirror.qualifiedName] = map; 639 _mirrorToDocgen[this.mirror.qualifiedName] = map;
642 } 640 }
643 641
644 /** Walk up the owner chain to find the owning library. */ 642 /** Walk up the owner chain to find the owning library. */
645 Library _getOwningLibrary(Indexable indexable) { 643 Library _getOwningLibrary(Indexable indexable) {
646 if (indexable is Library) return indexable; 644 if (indexable is Library) return indexable;
647 return _getOwningLibrary(indexable.owner); 645 return _getOwningLibrary(indexable.owner);
648 } 646 }
649 647
650 static initializeTopLevelLibraries(MirrorSystem mirrorSystem) { 648 static _initializeTopLevelLibraries(MirrorSystem mirrorSystem) {
651 _sdkLibraries = mirrorSystem.libraries.values.where( 649 _sdkLibraries = mirrorSystem.libraries.values.where(
652 (each) => each.uri.scheme == 'dart'); 650 (each) => each.uri.scheme == 'dart');
653 _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) => 651 _coreLibrary = new Library(_sdkLibraries.singleWhere((lib) =>
654 lib.uri.toString().startsWith('dart:core'))); 652 lib.uri.toString().startsWith('dart:core')));
655 } 653 }
656 654
657 /// Returns this object's qualified name, but following the conventions 655 /// 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 656 /// we're using in Dartdoc, which is that library names with dots in them
659 /// have them replaced with hyphens. 657 /// have them replaced with hyphens.
660 String get docName; 658 String get docName;
661 659
662 markdown.Node fixReferenceWithScope(String name) => null;
663
664 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. 660 /// Converts all [foo] references in comments to <a>libraryName.foo</a>.
665 markdown.Node fixReference(String name) { 661 markdown.Node fixReference(String name) {
666 // Attempt the look up the whole name up in the scope. 662 // Attempt the look up the whole name up in the scope.
667 String elementName = findElementInScope(name); 663 String elementName = findElementInScope(name);
668 if (elementName != null) { 664 if (elementName != null) {
669 return new markdown.Element.text('a', elementName); 665 return new markdown.Element.text('a', elementName);
670 } 666 }
671 return _fixComplexReference(name); 667 return _fixComplexReference(name);
672 } 668 }
673 669
674 /// Look for the specified name starting with the current member, and 670 /// Look for the specified name starting with the current member, and
675 /// progressively working outward to the current library scope. 671 /// progressively working outward to the current library scope.
676 String findElementInScope(String name) => 672 String findElementInScope(String name) =>
677 _findElementInScope(name, packagePrefix); 673 _findElementInScope(name, packagePrefix);
678 674
675 /// For a given name, determine if we need to resolve it as a qualified name
676 /// or a simple name in the source mirors.
679 static determineLookupFunc(name) => name.contains('.') ? 677 static determineLookupFunc(name) => name.contains('.') ?
680 dart2js_util.lookupQualifiedInScope : 678 dart2js_util.lookupQualifiedInScope :
681 (mirror, name) => mirror.lookupInScope(name); 679 (mirror, name) => mirror.lookupInScope(name);
682 680
683 // The qualified name (for URL purposes) and the file name are the same, 681 /// The reference to this element based on where it is printed as a
684 // of the form packageName/ClassName or packageName/ClassName.methodName. 682 /// documentation file and also the unique URL to refer to this item.
685 // This defines both the URL and the directory structure. 683 ///
686 String get fileName { 684 /// The qualified name (for URL purposes) and the file name are the same,
687 return packagePrefix + ownerPrefix + name; 685 /// of the form packageName/ClassName or packageName/ClassName.methodName.
688 } 686 /// This defines both the URL and the directory structure.
687 String get fileName => packagePrefix + ownerPrefix + name;
689 688
689 /// The full docName of the owner element, appended with a '.' for this
690 /// object's name to be appended.
690 String get ownerPrefix => owner.docName != '' ? owner.docName + '.' : ''; 691 String get ownerPrefix => owner.docName != '' ? owner.docName + '.' : '';
691 692
693 /// The prefix String to refer to the package that this item is in, for URLs
694 /// and comment resolution.
695 ///
696 /// The prefix can be prepended to a qualified name to get a fully unique
697 /// name among all packages.
692 String get packagePrefix => ''; 698 String get packagePrefix => '';
693 699
694 /// Documentation comment with converted markdown. 700 /// Documentation comment with converted markdown and all links resolved.
695 String _comment; 701 String _comment;
696 702
703 /// Accessor to documentation comment with markdown converted to html and all
704 /// links resolved.
697 String get comment { 705 String get comment {
698 if (_comment != null) return _comment; 706 if (_comment != null) return _comment;
699 707
700 _comment = _commentToHtml(); 708 _comment = _commentToHtml();
701 if (_comment.isEmpty) { 709 if (_comment.isEmpty) {
702 _comment = _mdnComment(); 710 _comment = _mdnComment();
703 } 711 }
704 return _comment; 712 return _comment;
705 } 713 }
706 714
707 set comment(x) => _comment = x; 715 set comment(x) => _comment = x;
708 716
717 /// The simple name to refer to this item.
709 String get name => mirror.simpleName; 718 String get name => mirror.simpleName;
710 719
720 /// Accessor to the parent item that owns this item.
721 ///
722 /// "Owning" is defined as the object one scope-level above which this item
723 /// is defined. Ex: The owner for a top level class, would be its enclosing
724 /// library. The owner of a local variable in a method would be the enclosing
725 /// method.
711 Indexable get owner => new DummyMirror(mirror.owner); 726 Indexable get owner => new DummyMirror(mirror.owner);
712 727
713 /// Generates MDN comments from database.json. 728 /// Generates MDN comments from database.json.
714 String _mdnComment() { 729 String _mdnComment();
715 //Check if MDN is loaded.
716 if (_mdn == null) {
717 // Reading in MDN related json file.
718 var root = _Generator._rootDirectory;
719 var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json');
720 _mdn = JSON.decode(new File(mdnPath).readAsStringSync());
721 }
722 // TODO: refactor OOP
723 if (this is Library) return '';
724 var domAnnotation = this.annotations.firstWhere(
725 (e) => e.mirror.qualifiedName == 'metadata.DomName',
726 orElse: () => null);
727 if (domAnnotation == null) return '';
728 var domName = domAnnotation.parameters.single;
729 var parts = domName.split('.');
730 if (parts.length == 2) return _mdnMemberComment(parts[0], parts[1]);
731 if (parts.length == 1) return _mdnTypeComment(parts[0]);
732 }
733 730
734 /// Generates the MDN Comment for variables and method DOM elements. 731 /// Generates the MDN Comment for variables and method DOM elements.
735 String _mdnMemberComment(String type, String member) { 732 String _mdnMemberComment(String type, String member) {
736 var mdnType = _mdn[type]; 733 var mdnType = _mdn[type];
737 if (mdnType == null) return ''; 734 if (mdnType == null) return '';
738 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member, 735 var mdnMember = mdnType['members'].firstWhere((e) => e['name'] == member,
739 orElse: () => null); 736 orElse: () => null);
740 if (mdnMember == null) return ''; 737 if (mdnMember == null) return '';
741 if (mdnMember['help'] == null || mdnMember['help'] == '') return ''; 738 if (mdnMember['help'] == null || mdnMember['help'] == '') return '';
742 if (mdnMember['url'] == null) return ''; 739 if (mdnMember['url'] == null) return '';
743 return _htmlMdn(mdnMember['help'], mdnMember['url']); 740 return _htmlifyMdn(mdnMember['help'], mdnMember['url']);
744 } 741 }
745 742
746 /// Generates the MDN Comment for class DOM elements. 743 /// Generates the MDN Comment for class DOM elements.
747 String _mdnTypeComment(String type) { 744 String _mdnTypeComment(String type) {
748 var mdnType = _mdn[type]; 745 var mdnType = _mdn[type];
749 if (mdnType == null) return ''; 746 if (mdnType == null) return '';
750 if (mdnType['summary'] == null || mdnType['summary'] == "") return ''; 747 if (mdnType['summary'] == null || mdnType['summary'] == "") return '';
751 if (mdnType['srcUrl'] == null) return ''; 748 if (mdnType['srcUrl'] == null) return '';
752 return _htmlMdn(mdnType['summary'], mdnType['srcUrl']); 749 return _htmlifyMdn(mdnType['summary'], mdnType['srcUrl']);
753 } 750 }
754 751
755 String _htmlMdn(String content, String url) { 752 /// Encloses the given content in an MDN div and the original source link.
753 String _htmlifyMdn(String content, String url) {
756 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">' 754 return '<div class="mdn">' + content.trim() + '<p class="mdn-note">'
757 '<a href="' + url.trim() + '">from Mdn</a></p></div>'; 755 '<a href="' + url.trim() + '">from Mdn</a></p></div>';
758 } 756 }
759 757
760 /// The type of this member to be used in index.txt. 758 /// The type of this member to be used in index.txt.
761 String get typeName => ''; 759 String get typeName => '';
762 760
763 /// Creates a [Map] with this [Indexable]'s name and a preview comment. 761 /// Creates a [Map] with this [Indexable]'s name and a preview comment.
764 Map get previewMap { 762 Map get previewMap {
765 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; 763 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName };
766 if (comment != '') { 764 if (comment != '') {
767 var index = comment.indexOf('</p>'); 765 var index = comment.indexOf('</p>');
768 finalMap['preview'] = '${comment.substring(0, index)}</p>'; 766 finalMap['preview'] = '${comment.substring(0, index)}</p>';
769 } 767 }
770 return finalMap; 768 return finalMap;
771 } 769 }
772 770
773 String _getCommentText() { 771 /// Accessor to obtain the raw comment text for a given item, _without_ any
772 /// of the links resolved.
773 String get _commentText {
774 String commentText; 774 String commentText;
775 mirror.metadata.forEach((metadata) { 775 mirror.metadata.forEach((metadata) {
776 if (metadata is CommentInstanceMirror) { 776 if (metadata is CommentInstanceMirror) {
777 CommentInstanceMirror comment = metadata; 777 CommentInstanceMirror comment = metadata;
778 if (comment.isDocComment) { 778 if (comment.isDocComment) {
779 if (commentText == null) { 779 if (commentText == null) {
780 commentText = comment.trimmedText; 780 commentText = comment.trimmedText;
781 } else { 781 } else {
782 commentText = '$commentText\n${comment.trimmedText}'; 782 commentText = '$commentText\n${comment.trimmedText}';
783 } 783 }
784 } 784 }
785 } 785 }
786 }); 786 });
787 return commentText; 787 return commentText;
788 } 788 }
789 789
790 /// Returns any documentation comments associated with a mirror with 790 /// Returns any documentation comments associated with a mirror with
791 /// simple markdown converted to html. 791 /// simple markdown converted to html.
792 /// 792 ///
793 /// By default we resolve any comment references within our own scope. 793 /// By default we resolve any comment references within our own scope.
794 /// However, if a method is inherited, we want the inherited comments, but 794 /// However, if a method is inherited, we want the inherited comments, but
795 /// links to the subclasses's version of the methods. 795 /// links to the subclasses's version of the methods.
796 String _commentToHtml([Indexable resolvingScope]) { 796 String _commentToHtml([Indexable resolvingScope]) {
797 if (resolvingScope == null) resolvingScope = this; 797 if (resolvingScope == null) resolvingScope = this;
798 var commentText = _getCommentText(); 798 var commentText = _commentText;
799 _unresolvedComment = commentText; 799 _unresolvedComment = commentText;
800 800
801 var linkResolver = (name) => resolvingScope.fixReferenceWithScope(name); 801 var linkResolver = (name) => resolvingScope.fixReference(name);
802 commentText = commentText == null ? '' : 802 commentText = commentText == null ? '' :
803 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver, 803 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver,
804 inlineSyntaxes: _MARKDOWN_SYNTAXES); 804 inlineSyntaxes: _MARKDOWN_SYNTAXES);
805 return commentText; 805 return commentText;
806 } 806 }
807 807
808 /// Returns a map of [Variable] objects constructed from [mirrorMap]. 808 /// Returns a map of [Variable] objects constructed from [mirrorMap].
809 /// The optional parameter [containingLibrary] is contains data for variables 809 /// The optional parameter [containingLibrary] is contains data for variables
810 /// defined at the top level of a library (potentially for exporting 810 /// defined at the top level of a library (potentially for exporting
811 /// purposes). 811 /// purposes).
812 Map<String, Variable> _createVariables(Map<String, VariableMirror> mirrorMap, 812 Map<String, Variable> _createVariables(Map<String, VariableMirror> mirrorMap,
813 Indexable owner) { 813 Indexable owner) {
814 var data = {}; 814 var data = {};
815 // TODO(janicejl): When map to map feature is created, replace the below 815 // TODO(janicejl): When map to map feature is created, replace the below
816 // with a filter. Issue(#9590). 816 // with a filter. Issue(#9590).
817 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { 817 mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
818 if (_Generator._includePrivate || !_isHidden(mirror)) { 818 if (_Generator._includePrivate || !_isHidden(mirror)) {
819 var variable = new Variable(mirrorName, mirror, owner); 819 data[mirrorName] = new Variable(mirrorName, mirror, owner);
820 entityMap[variable.docName] = variable;
821 data[mirrorName] = entityMap[variable.docName];
822 } 820 }
823 }); 821 });
824 return data; 822 return data;
825 } 823 }
826 824
827 /// Returns a map of [Method] objects constructed from [mirrorMap]. 825 /// Returns a map of [Method] objects constructed from [mirrorMap].
828 /// The optional parameter [containingLibrary] is contains data for variables 826 /// The optional parameter [containingLibrary] is contains data for variables
829 /// defined at the top level of a library (potentially for exporting 827 /// defined at the top level of a library (potentially for exporting
830 /// purposes). 828 /// purposes).
831 Map<String, Method> _createMethods(Map<String, MethodMirror> mirrorMap, 829 Map<String, Method> _createMethods(Map<String, MethodMirror> mirrorMap,
832 Indexable owner) { 830 Indexable owner) {
833 var group = new Map<String, Method>(); 831 var group = new Map<String, Method>();
834 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { 832 mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
835 if (_Generator._includePrivate || !mirror.isPrivate) { 833 if (_Generator._includePrivate || !mirror.isPrivate) {
836 var method = new Method(mirror, owner); 834 group[mirror.simpleName] = new Method(mirror, owner);
837 entityMap[method.docName] = method;
838 group[mirror.simpleName] = method;
839 } 835 }
840 }); 836 });
841 return group; 837 return group;
842 } 838 }
843 839
844 /// Returns a map of [Parameter] objects constructed from [mirrorList]. 840 /// Returns a map of [Parameter] objects constructed from [mirrorList].
845 Map<String, Parameter> _createParameters(List<ParameterMirror> mirrorList, 841 Map<String, Parameter> _createParameters(List<ParameterMirror> mirrorList,
846 Indexable owner) { 842 Indexable owner) {
847 var data = {}; 843 var data = {};
848 mirrorList.forEach((ParameterMirror mirror) { 844 mirrorList.forEach((ParameterMirror mirror) {
849 data[mirror.simpleName] = new Parameter(mirror, _getOwningLibrary(owner)); 845 data[mirror.simpleName] = new Parameter(mirror, _getOwningLibrary(owner));
850 }); 846 });
851 return data; 847 return data;
852 } 848 }
853 849
854 /// Returns a map of [Generic] objects constructed from the class mirror. 850 /// Returns a map of [Generic] objects constructed from the class mirror.
855 Map<String, Generic> _createGenerics(ClassMirror mirror) { 851 Map<String, Generic> _createGenerics(ClassMirror mirror) {
856 return new Map.fromIterable(mirror.typeVariables, 852 return new Map.fromIterable(mirror.typeVariables,
857 key: (e) => e.toString(), 853 key: (e) => e.toString(),
858 value: (e) => new Generic(e)); 854 value: (e) => new Generic(e));
859 } 855 }
860 856
861 /// Return an informative [Object.toString] for debugging. 857 /// Return an informative [Object.toString] for debugging.
862 String toString() => "${super.toString()}(${name.toString()})"; 858 String toString() => "${super.toString()}(${name.toString()})";
863 859
864 /// Return a map representation of this type. 860 /// Return a map representation of this type.
865 Map toMap() {} 861 Map toMap();
866
867 862
868 /// A declaration is private if itself is private, or the owner is private. 863 /// A declaration is private if itself is private, or the owner is private.
869 // Issue(12202) - A declaration is public even if it's owner is private. 864 // Issue(12202) - A declaration is public even if it's owner is private.
870 bool _isHidden(DeclarationMirror mirror) { 865 bool _isHidden(DeclarationMirror mirror) {
871 if (mirror is LibraryMirror) { 866 if (mirror is LibraryMirror) {
872 return _isLibraryPrivate(mirror); 867 return _isLibraryPrivate(mirror);
873 } else if (mirror.owner is LibraryMirror) { 868 } else if (mirror.owner is LibraryMirror) {
874 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner) 869 return (mirror.isPrivate || _isLibraryPrivate(mirror.owner)
875 || mirror.isNameSynthetic); 870 || mirror.isNameSynthetic);
876 } else { 871 } else {
877 return (mirror.isPrivate || _isHidden(mirror.owner) 872 return (mirror.isPrivate || _isHidden(mirror.owner)
878 || owner.mirror.isNameSynthetic); 873 || owner.mirror.isNameSynthetic);
879 } 874 }
880 } 875 }
881 876
882 /// Returns true if a library name starts with an underscore, and false 877 /// Returns true if a library name starts with an underscore, and false
883 /// otherwise. 878 /// otherwise.
884 /// 879 ///
885 /// An example that starts with _ is _js_helper. 880 /// An example that starts with _ is _js_helper.
886 /// An example that contains ._ is dart._collection.dev 881 /// An example that contains ._ is dart._collection.dev
887 // This is because LibraryMirror.isPrivate returns `false` all the time.
888 bool _isLibraryPrivate(LibraryMirror mirror) { 882 bool _isLibraryPrivate(LibraryMirror mirror) {
883 // This method is needed because LibraryMirror.isPrivate returns `false` all
884 // the time.
889 var sdkLibrary = LIBRARIES[mirror.simpleName]; 885 var sdkLibrary = LIBRARIES[mirror.simpleName];
890 if (sdkLibrary != null) { 886 if (sdkLibrary != null) {
891 return !sdkLibrary.documented; 887 return !sdkLibrary.documented;
892 } else if (mirror.simpleName.startsWith('_') || 888 } else if (mirror.simpleName.startsWith('_') ||
893 mirror.simpleName.contains('._')) { 889 mirror.simpleName.contains('._')) {
894 return true; 890 return true;
895 } 891 }
896 return false; 892 return false;
897 } 893 }
898 894
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 return packagePrefix + result.docName; 1000 return packagePrefix + result.docName;
1005 } else { 1001 } else {
1006 return result.packagePrefix + result.docName; 1002 return result.packagePrefix + result.docName;
1007 } 1003 }
1008 } 1004 }
1009 } 1005 }
1010 } 1006 }
1011 return null; 1007 return null;
1012 } 1008 }
1013 1009
1014 Map expandMethodMap(Map<String, Method> mapToExpand) => { 1010 /// Expand the method map [mapToExpand] into a more detailed map that
1015 'setters': recurseMap(_filterMap(new Map(), mapToExpand, 1011 /// separates out setters, getters, constructors, operators, and methods.
1012 Map _expandMethodMap(Map<String, Method> mapToExpand) => {
1013 'setters': recurseMap(_filterMap(mapToExpand,
1016 (key, val) => val.mirror.isSetter)), 1014 (key, val) => val.mirror.isSetter)),
1017 'getters': recurseMap(_filterMap(new Map(), mapToExpand, 1015 'getters': recurseMap(_filterMap(mapToExpand,
1018 (key, val) => val.mirror.isGetter)), 1016 (key, val) => val.mirror.isGetter)),
1019 'constructors': recurseMap(_filterMap(new Map(), mapToExpand, 1017 'constructors': recurseMap(_filterMap(mapToExpand,
1020 (key, val) => val.mirror.isConstructor)), 1018 (key, val) => val.mirror.isConstructor)),
1021 'operators': recurseMap(_filterMap(new Map(), mapToExpand, 1019 'operators': recurseMap(_filterMap(mapToExpand,
1022 (key, val) => val.mirror.isOperator)), 1020 (key, val) => val.mirror.isOperator)),
1023 'methods': recurseMap(_filterMap(new Map(), mapToExpand, 1021 'methods': recurseMap(_filterMap(mapToExpand,
1024 (key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator)) 1022 (key, val) => val.mirror.isRegularMethod && !val.mirror.isOperator))
1025 }; 1023 };
1026 1024
1027 /// Transforms the map by calling toMap on each value in it. 1025 /// Transforms the map by calling toMap on each value in it.
1028 Map recurseMap(Map inputMap) { 1026 Map recurseMap(Map inputMap) {
1029 var outputMap = {}; 1027 var outputMap = {};
1030 inputMap.forEach((key, value) { 1028 inputMap.forEach((key, value) {
1031 if (value is Map) { 1029 if (value is Map) {
1032 outputMap[key] = recurseMap(value); 1030 outputMap[key] = recurseMap(value);
1033 } else { 1031 } else {
1034 outputMap[key] = value.toMap(); 1032 outputMap[key] = value.toMap();
1035 } 1033 }
1036 }); 1034 });
1037 return outputMap; 1035 return outputMap;
1038 } 1036 }
1039 1037
1040 Map _filterMap(exported, map, test) { 1038 Map _filterMap(Map map, Function test) {
1039 var exported = new Map();
1041 map.forEach((key, value) { 1040 map.forEach((key, value) {
1042 if (test(key, value)) exported[key] = value; 1041 if (test(key, value)) exported[key] = value;
1043 }); 1042 });
1044 return exported; 1043 return exported;
1045 } 1044 }
1046 1045
1047 bool get _isVisible => _Generator._includePrivate || !isPrivate; 1046 /// Accessor to determine if this item and all of its owners are visible.
1047 bool get _isVisible => _Generator._isFullChainVisible(this);
1048 1048
1049 /// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object. 1049 /// Given a Dart2jsMirror, find the corresponding Docgen [MirrorBased] object.
1050 /// 1050 ///
1051 /// We have this global lookup function to avoid re-implementing looking up 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 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 1053 /// mirrors). If no corresponding MirrorBased object is found, we return a
1054 /// [DummyMirror] that simply returns the original mirror's qualifiedName 1054 /// [DummyMirror] that simply returns the original mirror's qualifiedName
1055 /// while behaving like a MirrorBased object. 1055 /// while behaving like a MirrorBased object.
1056 static Indexable getDocgenObject(DeclarationMirror mirror, 1056 static Indexable getDocgenObject(DeclarationMirror mirror,
1057 [Indexable owner]) { 1057 [Indexable owner]) {
(...skipping 25 matching lines...) Expand all
1083 } 1083 }
1084 } 1084 }
1085 1085
1086 if (results.length > 0) { 1086 if (results.length > 0) {
1087 // This might occur if we didn't specify an "owner." 1087 // This might occur if we didn't specify an "owner."
1088 return results.first; 1088 return results.first;
1089 } 1089 }
1090 return new DummyMirror(mirror, owner); 1090 return new DummyMirror(mirror, owner);
1091 } 1091 }
1092 1092
1093 /// Returns true if [mirror] is the correct type of mirror that this Docgen
1094 /// object wraps. (Workaround for the fact that Types are not first class.)
1093 bool _isValidMirror(DeclarationMirror mirror); 1095 bool _isValidMirror(DeclarationMirror mirror);
1094 } 1096 }
1095 1097
1096 /// A class containing contents of a Dart library. 1098 /// A class containing contents of a Dart library.
1097 class Library extends Indexable { 1099 class Library extends Indexable {
1098 1100
1099 /// Top-level variables in the library. 1101 /// Top-level variables in the library.
1100 Map<String, Variable> variables; 1102 Map<String, Variable> variables;
1101 1103
1102 /// Top-level functions in the library. 1104 /// Top-level functions in the library.
1103 Map<String, Method> functions; 1105 Map<String, Method> functions;
1104 1106
1105 Map<String, Class> classes = {}; 1107 Map<String, Class> classes = {};
1106 Map<String, Typedef> typedefs = {}; 1108 Map<String, Typedef> typedefs = {};
1107 Map<String, Class> errors = {}; 1109 Map<String, Class> errors = {};
1108 1110
1109 String packageName = ''; 1111 String packageName = '';
1110 bool hasBeenCheckedForPackage = false; 1112 bool _hasBeenCheckedForPackage = false;
1111 String packageIntro; 1113 String packageIntro;
1112 1114
1113 /// Returns the [Library] for the given [mirror] if it has already been 1115 /// Returns the [Library] for the given [mirror] if it has already been
1114 /// created, else creates it. 1116 /// created, else creates it.
1115 factory Library(LibraryMirror mirror) { 1117 factory Library(LibraryMirror mirror) {
1116 var library = Indexable.getDocgenObject(mirror); 1118 var library = Indexable.getDocgenObject(mirror);
1117 if (library is DummyMirror) { 1119 if (library is DummyMirror) {
1118 library = new Library._(mirror); 1120 library = new Library._(mirror);
1119 } 1121 }
1120 return library; 1122 return library;
1121 } 1123 }
1122 1124
1123 Library._(LibraryMirror libraryMirror) : super(libraryMirror) { 1125 Library._(LibraryMirror libraryMirror) : super(libraryMirror) {
1124 var exported = _calcExportedItems(libraryMirror); 1126 var exported = _calcExportedItems(libraryMirror);
1125 var exportedClasses = exported['classes']..addAll(libraryMirror.classes); 1127 var exportedClasses = exported['classes']..addAll(libraryMirror.classes);
1126 _findPackage(mirror); 1128 _findPackage(mirror);
1127 classes = {}; 1129 classes = {};
1128 typedefs = {}; 1130 typedefs = {};
1129 errors = {}; 1131 errors = {};
1130 exportedClasses.forEach((String mirrorName, ClassMirror classMirror) { 1132 exportedClasses.forEach((String mirrorName, ClassMirror classMirror) {
1131 if (classMirror.isTypedef) { 1133 if (classMirror.isTypedef) {
1132 // This is actually a Dart2jsTypedefMirror, and it does define value, 1134 // This is actually a Dart2jsTypedefMirror, and it does define value,
1133 // but we don't have visibility to that type. 1135 // but we don't have visibility to that type.
1134 var mirror = classMirror; 1136 var mirror = classMirror;
1135 if (_Generator._includePrivate || !mirror.isPrivate) { 1137 if (_Generator._includePrivate || !mirror.isPrivate) {
1136 var aTypedef = new Typedef(mirror, this); 1138 typedefs[mirror.simpleName] = new Typedef(mirror, this);
1137 entityMap[Indexable.getDocgenObject(mirror).docName] = aTypedef;
1138 typedefs[mirror.simpleName] = aTypedef;
1139 } 1139 }
1140 } else { 1140 } else {
1141 var clazz = new Class(classMirror, this); 1141 var clazz = new Class(classMirror, this);
1142 1142
1143 if (clazz.isError()) { 1143 if (clazz.isError()) {
1144 errors[classMirror.simpleName] = clazz; 1144 errors[classMirror.simpleName] = clazz;
1145 } else if (classMirror.isClass) { 1145 } else if (classMirror.isClass) {
1146 classes[classMirror.simpleName] = clazz; 1146 classes[classMirror.simpleName] = clazz;
1147 } else { 1147 } else {
1148 throw new ArgumentError( 1148 throw new ArgumentError(
(...skipping 13 matching lines...) Expand all
1162 var lookupFunc = Indexable.determineLookupFunc(name); 1162 var lookupFunc = Indexable.determineLookupFunc(name);
1163 var libraryScope = lookupFunc(mirror, name); 1163 var libraryScope = lookupFunc(mirror, name);
1164 if (libraryScope != null) { 1164 if (libraryScope != null) {
1165 var result = Indexable.getDocgenObject(libraryScope, this); 1165 var result = Indexable.getDocgenObject(libraryScope, this);
1166 if (result is DummyMirror) return packagePrefix + result.docName; 1166 if (result is DummyMirror) return packagePrefix + result.docName;
1167 return result.packagePrefix + result.docName; 1167 return result.packagePrefix + result.docName;
1168 } 1168 }
1169 return super.findElementInScope(name); 1169 return super.findElementInScope(name);
1170 } 1170 }
1171 1171
1172 String _mdnComment() => '';
1173
1172 /// For a library's [mirror], determine the name of the package (if any) we 1174 /// For a library's [mirror], determine the name of the package (if any) we
1173 /// believe it came from (because of its file URI). 1175 /// believe it came from (because of its file URI).
1174 /// 1176 ///
1175 /// If no package could be determined, we return an empty string. 1177 /// If no package could be determined, we return an empty string.
1176 String _findPackage(LibraryMirror mirror) { 1178 String _findPackage(LibraryMirror mirror) {
1177 if (mirror == null) return ''; 1179 if (mirror == null) return '';
1178 if (hasBeenCheckedForPackage) return packageName; 1180 if (_hasBeenCheckedForPackage) return packageName;
1179 hasBeenCheckedForPackage = true; 1181 _hasBeenCheckedForPackage = true;
1180 if (mirror.uri.scheme != 'file') return ''; 1182 if (mirror.uri.scheme != 'file') return '';
1181 // We assume that we are documenting only libraries under package/lib 1183 // We assume that we are documenting only libraries under package/lib
1182 packageName = _packageName(mirror); 1184 packageName = _packageName(mirror);
1183 // Associate the package readme with all the libraries. This is a bit 1185 // Associate the package readme with all the libraries. This is a bit
1184 // wasteful, but easier than trying to figure out which partial match 1186 // wasteful, but easier than trying to figure out which partial match
1185 // is best. 1187 // is best.
1186 packageIntro = _packageIntro(_getRootdir(mirror)); 1188 packageIntro = _packageIntro(_getRootdir(mirror));
1187 return packageName; 1189 return packageName;
1188 } 1190 }
1189 1191
(...skipping 24 matching lines...) Expand all
1214 if (mirror.uri.scheme != 'file') return ''; 1216 if (mirror.uri.scheme != 'file') return '';
1215 var rootdir = _getRootdir(mirror); 1217 var rootdir = _getRootdir(mirror);
1216 var pubspecName = path.join(rootdir, 'pubspec.yaml'); 1218 var pubspecName = path.join(rootdir, 'pubspec.yaml');
1217 File pubspec = new File(pubspecName); 1219 File pubspec = new File(pubspecName);
1218 if (!pubspec.existsSync()) return ''; 1220 if (!pubspec.existsSync()) return '';
1219 var contents = pubspec.readAsStringSync(); 1221 var contents = pubspec.readAsStringSync();
1220 var spec = loadYaml(contents); 1222 var spec = loadYaml(contents);
1221 return spec["name"]; 1223 return spec["name"];
1222 } 1224 }
1223 1225
1224 markdown.Node fixReferenceWithScope(String name) => fixReference(name);
1225
1226 String get packagePrefix => packageName == null || packageName.isEmpty ? 1226 String get packagePrefix => packageName == null || packageName.isEmpty ?
1227 '' : '$packageName/'; 1227 '' : '$packageName/';
1228 1228
1229 Map get previewMap { 1229 Map get previewMap {
1230 var basic = super.previewMap; 1230 var basic = super.previewMap;
1231 basic['packageName'] = packageName; 1231 basic['packageName'] = packageName;
1232 if (packageIntro != null) { 1232 if (packageIntro != null) {
1233 basic['packageIntro'] = packageIntro; 1233 basic['packageIntro'] = packageIntro;
1234 } 1234 }
1235 return basic; 1235 return basic;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 // library. Ex: "export foo show bar" 1295 // library. Ex: "export foo show bar"
1296 // Otherwise, add all items, and then remove the hidden ones. 1296 // Otherwise, add all items, and then remove the hidden ones.
1297 // Ex: "export foo hide bar" 1297 // Ex: "export foo hide bar"
1298 _populateExports(export, 1298 _populateExports(export,
1299 export.combinators.any((combinator) => combinator.isShow)); 1299 export.combinators.any((combinator) => combinator.isShow));
1300 } 1300 }
1301 return exports; 1301 return exports;
1302 } 1302 }
1303 1303
1304 /// Checks if the given name is a key for any of the Class Maps. 1304 /// Checks if the given name is a key for any of the Class Maps.
1305 bool containsKey(String name) { 1305 bool containsKey(String name) =>
1306 return classes.containsKey(name) || errors.containsKey(name); 1306 classes.containsKey(name) || errors.containsKey(name);
1307 }
1308 1307
1309 /// Generates a map describing the [Library] object. 1308 /// Generates a map describing the [Library] object.
1310 Map toMap() => { 1309 Map toMap() => {
1311 'name': name, 1310 'name': name,
1312 'qualifiedName': qualifiedName, 1311 'qualifiedName': qualifiedName,
1313 'comment': comment, 1312 'comment': comment,
1314 'variables': recurseMap(variables), 1313 'variables': recurseMap(variables),
1315 'functions': expandMethodMap(functions), 1314 'functions': _expandMethodMap(functions),
1316 'classes': { 1315 'classes': {
1317 'class': classes.values.where((c) => c._isVisible) 1316 'class': classes.values.where((c) => c._isVisible)
1318 .map((e) => e.previewMap).toList(), 1317 .map((e) => e.previewMap).toList(),
1319 'typedef': recurseMap(typedefs), 1318 'typedef': recurseMap(typedefs),
1320 'error': errors.values.where((e) => e._isVisible) 1319 'error': errors.values.where((e) => e._isVisible)
1321 .map((e) => e.previewMap).toList() 1320 .map((e) => e.previewMap).toList()
1322 }, 1321 },
1323 'packageName': packageName, 1322 'packageName': packageName,
1324 'packageIntro' : packageIntro 1323 'packageIntro' : packageIntro
1325 }; 1324 };
1326 1325
1327 String get typeName => 'library'; 1326 String get typeName => 'library';
1328 1327
1329 bool _isValidMirror(DeclarationMirror mirror) => mirror is LibraryMirror; 1328 bool _isValidMirror(DeclarationMirror mirror) => mirror is LibraryMirror;
1330 } 1329 }
1331 1330
1332 abstract class OwnedIndexable extends Indexable { 1331 abstract class OwnedIndexable extends Indexable {
1332 /// The object one scope-level above which this item is defined.
1333 ///
1334 /// Ex: The owner for a top level class, would be its enclosing library.
1335 /// The owner of a local variable in a method would be the enclosing method.
1333 Indexable owner; 1336 Indexable owner;
1334 1337
1338 /// List of the meta annotations on this item.
1339 List<Annotation> annotations;
1340
1335 /// Returns this object's qualified name, but following the conventions 1341 /// 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 1342 /// we're using in Dartdoc, which is that library names with dots in them
1337 /// have them replaced with hyphens. 1343 /// have them replaced with hyphens.
1338 String get docName => owner.docName + '.' + mirror.simpleName; 1344 String get docName => owner.docName + '.' + mirror.simpleName;
1339 1345
1340 OwnedIndexable(DeclarationMirror mirror, this.owner) : super(mirror); 1346 OwnedIndexable(DeclarationMirror mirror, this.owner) : super(mirror);
1347
1348 /// Generates MDN comments from database.json.
1349 String _mdnComment() {
1350 //Check if MDN is loaded.
1351 if (Indexable._mdn == null) {
1352 // Reading in MDN related json file.
1353 var root = _Generator._rootDirectory;
1354 var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json');
1355 Indexable._mdn = JSON.decode(new File(mdnPath).readAsStringSync());
1356 }
1357 var domAnnotation = this.annotations.firstWhere(
1358 (e) => e.mirror.qualifiedName == 'metadata.DomName',
1359 orElse: () => null);
1360 if (domAnnotation == null) return '';
1361 var domName = domAnnotation.parameters.single;
1362 var parts = domName.split('.');
1363 if (parts.length == 2) return _mdnMemberComment(parts[0], parts[1]);
1364 if (parts.length == 1) return _mdnTypeComment(parts[0]);
1365 }
1341 } 1366 }
1342 1367
1343 /// A class containing contents of a Dart class. 1368 /// A class containing contents of a Dart class.
1344 class Class extends OwnedIndexable implements Comparable { 1369 class Class extends OwnedIndexable implements Comparable {
1345 1370
1346 /// List of the names of interfaces that this class implements. 1371 /// List of the names of interfaces that this class implements.
1347 List<Class> interfaces = []; 1372 List<Class> interfaces = [];
1348 1373
1349 /// Names of classes that extends or implements this class. 1374 /// Names of classes that extends or implements this class.
1350 Set<Class> subclasses = new Set<Class>(); 1375 Set<Class> subclasses = new Set<Class>();
1351 1376
1352 /// Top-level variables in the class. 1377 /// Top-level variables in the class.
1353 Map<String, Variable> variables; 1378 Map<String, Variable> variables;
1354 1379
1355 /// Inherited variables in the class. 1380 /// Inherited variables in the class.
1356 Map<String, Variable> inheritedVariables; 1381 Map<String, Variable> inheritedVariables;
1357 1382
1358 /// Methods in the class. 1383 /// Methods in the class.
1359 Map<String, Method> methods; 1384 Map<String, Method> methods;
1360 1385
1361 Map<String, Method> inheritedMethods; 1386 Map<String, Method> inheritedMethods;
1362 1387
1363 /// Generic infomation about the class. 1388 /// Generic infomation about the class.
1364 Map<String, Generic> generics; 1389 Map<String, Generic> generics;
1365 1390
1366 Class superclass; 1391 Class superclass;
1367 bool isAbstract; 1392 bool isAbstract;
1368 1393
1369 /// List of the meta annotations on the class.
1370 List<Annotation> annotations;
1371
1372 /// Make sure that we don't check for inherited comments more than once. 1394 /// Make sure that we don't check for inherited comments more than once.
1373 bool _commentsEnsured = false; 1395 bool _commentsEnsured = false;
1374 1396
1375 /// Returns the [Class] for the given [mirror] if it has already been created, 1397 /// Returns the [Class] for the given [mirror] if it has already been created,
1376 /// else creates it. 1398 /// else creates it.
1377 factory Class(ClassMirror mirror, Library owner) { 1399 factory Class(ClassMirror mirror, Library owner) {
1378 var clazz = Indexable.getDocgenObject(mirror, owner); 1400 var clazz = Indexable.getDocgenObject(mirror, owner);
1379 if (clazz is DummyMirror) { 1401 if (clazz is DummyMirror) {
1380 clazz = new Class._(mirror, owner); 1402 clazz = new Class._(mirror, owner);
1381 entityMap[clazz.docName] = clazz;
1382 } 1403 }
1383 return clazz; 1404 return clazz;
1384 } 1405 }
1385 1406
1386 /// Called when we are constructing a superclass or interface class, but it 1407 /// Called when we are constructing a superclass or interface class, but it
1387 /// is not known if it belongs to the same owner as the original class. In 1408 /// is not known if it belongs to the same owner as the original class. In
1388 /// this case, we create an object whose owner is what the original mirror 1409 /// this case, we create an object whose owner is what the original mirror
1389 /// says it is. 1410 /// says it is.
1390 factory Class._possiblyDifferentOwner(ClassMirror mirror, 1411 factory Class._possiblyDifferentOwner(ClassMirror mirror,
1391 Library originalOwner) { 1412 Library originalOwner) {
(...skipping 21 matching lines...) Expand all
1413 new Class._possiblyDifferentOwner(classMirror.superclass, owner); 1434 new Class._possiblyDifferentOwner(classMirror.superclass, owner);
1414 1435
1415 interfaces = superinterfaces.toList(); 1436 interfaces = superinterfaces.toList();
1416 variables = _createVariables(classMirror.variables, this); 1437 variables = _createVariables(classMirror.variables, this);
1417 methods = _createMethods(classMirror.methods, this); 1438 methods = _createMethods(classMirror.methods, this);
1418 annotations = _createAnnotations(classMirror, _getOwningLibrary(owner)); 1439 annotations = _createAnnotations(classMirror, _getOwningLibrary(owner));
1419 generics = _createGenerics(classMirror); 1440 generics = _createGenerics(classMirror);
1420 isAbstract = classMirror.isAbstract; 1441 isAbstract = classMirror.isAbstract;
1421 inheritedMethods = new Map<String, Method>(); 1442 inheritedMethods = new Map<String, Method>();
1422 1443
1423 // Tell all superclasses that you are a subclass, unless you are not 1444 // Tell superclass that you are a subclass, unless you are not
1424 // visible or an intermediary mixin class. 1445 // visible or an intermediary mixin class.
1425 if (!classMirror.isNameSynthetic && _isVisible) { 1446 if (!classMirror.isNameSynthetic && _isVisible && superclass != null) {
1426 parentChain().forEach((parentClass) { 1447 superclass.addSubclass(this);
1427 parentClass.addSubclass(this);
1428 });
1429 } 1448 }
1430 1449
1431 if (this.superclass != null) addInherited(superclass); 1450 if (this.superclass != null) addInherited(superclass);
1432 interfaces.forEach((interface) => addInherited(interface)); 1451 interfaces.forEach((interface) => addInherited(interface));
1433 } 1452 }
1434 1453
1435 String get packagePrefix => owner.packagePrefix; 1454 String get packagePrefix => owner.packagePrefix;
1436 1455
1437 String _lookupInClassAndSuperclasses(String name) { 1456 String _lookupInClassAndSuperclasses(String name) {
1438 var lookupFunc = Indexable.determineLookupFunc(name); 1457 var lookupFunc = Indexable.determineLookupFunc(name);
(...skipping 13 matching lines...) Expand all
1452 String findElementInScope(String name) { 1471 String findElementInScope(String name) {
1453 var lookupFunc = Indexable.determineLookupFunc(name); 1472 var lookupFunc = Indexable.determineLookupFunc(name);
1454 var result = _lookupInClassAndSuperclasses(name); 1473 var result = _lookupInClassAndSuperclasses(name);
1455 if (result != null) { 1474 if (result != null) {
1456 return result; 1475 return result;
1457 } 1476 }
1458 result = owner.findElementInScope(name); 1477 result = owner.findElementInScope(name);
1459 return result == null ? super.findElementInScope(name) : result; 1478 return result == null ? super.findElementInScope(name) : result;
1460 } 1479 }
1461 1480
1462 markdown.Node fixReferenceWithScope(String name) => fixReference(name);
1463
1464 String get typeName => 'class'; 1481 String get typeName => 'class';
1465 1482
1466 /// Returns a list of all the parent classes.
1467 List<Class> parentChain() {
1468 // TODO(efortuna): Seems like we can get rid of this method.
1469 var parent = superclass == null ? [] : [superclass];
1470 return parent;
1471 }
1472
1473 /// Add all inherited variables and methods from the provided superclass. 1483 /// Add all inherited variables and methods from the provided superclass.
1474 /// If [_includePrivate] is true, it also adds the variables and methods from 1484 /// If [_includePrivate] is true, it also adds the variables and methods from
1475 /// the superclass. 1485 /// the superclass.
1476 void addInherited(Class superclass) { 1486 void addInherited(Class superclass) {
1477 inheritedVariables.addAll(superclass.inheritedVariables); 1487 inheritedVariables.addAll(superclass.inheritedVariables);
1478 inheritedVariables.addAll(_allButStatics(superclass.variables)); 1488 inheritedVariables.addAll(_allButStatics(superclass.variables));
1479 addInheritedMethod(superclass, this); 1489 addInheritedMethod(superclass, this);
1480 } 1490 }
1481 1491
1482 /** [newParent] refers to the actual class is currently using these methods. 1492 /** [newParent] refers to the actual class is currently using these methods.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1570 'qualifiedName': qualifiedName, 1580 'qualifiedName': qualifiedName,
1571 'comment': comment, 1581 'comment': comment,
1572 'isAbstract' : isAbstract, 1582 'isAbstract' : isAbstract,
1573 'superclass': validSuperclass(), 1583 'superclass': validSuperclass(),
1574 'implements': interfaces.where((i) => i._isVisible) 1584 'implements': interfaces.where((i) => i._isVisible)
1575 .map((e) => e.qualifiedName).toList(), 1585 .map((e) => e.qualifiedName).toList(),
1576 'subclass': (subclasses.toList()..sort()) 1586 'subclass': (subclasses.toList()..sort())
1577 .map((x) => x.qualifiedName).toList(), 1587 .map((x) => x.qualifiedName).toList(),
1578 'variables': recurseMap(variables), 1588 'variables': recurseMap(variables),
1579 'inheritedVariables': recurseMap(inheritedVariables), 1589 'inheritedVariables': recurseMap(inheritedVariables),
1580 'methods': expandMethodMap(methods), 1590 'methods': _expandMethodMap(methods),
1581 'inheritedMethods': expandMethodMap(inheritedMethods), 1591 'inheritedMethods': _expandMethodMap(inheritedMethods),
1582 'annotations': annotations.map((a) => a.toMap()).toList(), 1592 'annotations': annotations.map((a) => a.toMap()).toList(),
1583 'generics': recurseMap(generics) 1593 'generics': recurseMap(generics)
1584 }; 1594 };
1585 1595
1586 int compareTo(aClass) => name.compareTo(aClass.name); 1596 int compareTo(aClass) => name.compareTo(aClass.name);
1587 1597
1588 bool _isValidMirror(DeclarationMirror mirror) => mirror is ClassMirror; 1598 bool _isValidMirror(DeclarationMirror mirror) => mirror is ClassMirror;
1589 } 1599 }
1590 1600
1591 class Typedef extends OwnedIndexable { 1601 class Typedef extends OwnedIndexable {
1592 String returnType; 1602 String returnType;
1593 1603
1594 Map<String, Parameter> parameters; 1604 Map<String, Parameter> parameters;
1595 1605
1596 /// Generic information about the typedef. 1606 /// Generic information about the typedef.
1597 Map<String, Generic> generics; 1607 Map<String, Generic> generics;
1598 1608
1599 /// List of the meta annotations on the typedef.
1600 List<Annotation> annotations;
1601
1602 /// Returns the [Library] for the given [mirror] if it has already been 1609 /// Returns the [Library] for the given [mirror] if it has already been
1603 /// created, else creates it. 1610 /// created, else creates it.
1604 factory Typedef(TypedefMirror mirror, Library owningLibrary) { 1611 factory Typedef(TypedefMirror mirror, Library owningLibrary) {
1605 var aTypedef = Indexable.getDocgenObject(mirror, owningLibrary); 1612 var aTypedef = Indexable.getDocgenObject(mirror, owningLibrary);
1606 if (aTypedef is DummyMirror) { 1613 if (aTypedef is DummyMirror) {
1607 aTypedef = new Typedef._(mirror, owningLibrary); 1614 aTypedef = new Typedef._(mirror, owningLibrary);
1608 } 1615 }
1609 return aTypedef; 1616 return aTypedef;
1610 } 1617 }
1611 1618
1612 Typedef._(TypedefMirror mirror, Library owningLibrary) : 1619 Typedef._(TypedefMirror mirror, Library owningLibrary) :
1613 super(mirror, owningLibrary) { 1620 super(mirror, owningLibrary) {
1614 returnType = Indexable.getDocgenObject(mirror.value.returnType).docName; 1621 returnType = Indexable.getDocgenObject(mirror.value.returnType).docName;
1615 generics = _createGenerics(mirror); 1622 generics = _createGenerics(mirror);
1616 parameters = _createParameters(mirror.value.parameters, owningLibrary); 1623 parameters = _createParameters(mirror.value.parameters, owningLibrary);
1617 annotations = _createAnnotations(mirror, owningLibrary); 1624 annotations = _createAnnotations(mirror, owningLibrary);
1618 } 1625 }
1619 1626
1620 Map toMap() => { 1627 Map toMap() => {
1621 'name': name, 1628 'name': name,
1622 'qualifiedName': qualifiedName, 1629 'qualifiedName': qualifiedName,
1623 'comment': comment, 1630 'comment': comment,
1624 'return': returnType, 1631 'return': returnType,
1625 'parameters': recurseMap(parameters), 1632 'parameters': recurseMap(parameters),
1626 'annotations': annotations.map((a) => a.toMap()).toList(), 1633 'annotations': annotations.map((a) => a.toMap()).toList(),
1627 'generics': recurseMap(generics) 1634 'generics': recurseMap(generics)
1628 }; 1635 };
1629 1636
1637 markdown.Node fixReference(String name) => null;
1638
1630 String get typeName => 'typedef'; 1639 String get typeName => 'typedef';
1631 1640
1632 bool _isValidMirror(DeclarationMirror mirror) => mirror is TypedefMirror; 1641 bool _isValidMirror(DeclarationMirror mirror) => mirror is TypedefMirror;
1633 } 1642 }
1634 1643
1635 /// A class containing properties of a Dart variable. 1644 /// A class containing properties of a Dart variable.
1636 class Variable extends OwnedIndexable { 1645 class Variable extends OwnedIndexable {
1637 1646
1638 bool isFinal; 1647 bool isFinal;
1639 bool isStatic; 1648 bool isStatic;
1640 bool isConst; 1649 bool isConst;
1641 Type type; 1650 Type type;
1642 String _variableName; 1651 String _variableName;
1643 1652
1644 /// List of the meta annotations on the variable.
1645 List<Annotation> annotations;
1646
1647 factory Variable(String variableName, VariableMirror mirror, 1653 factory Variable(String variableName, VariableMirror mirror,
1648 Indexable owner) { 1654 Indexable owner) {
1649 var variable = Indexable.getDocgenObject(mirror); 1655 var variable = Indexable.getDocgenObject(mirror);
1650 if (variable is DummyMirror) { 1656 if (variable is DummyMirror) {
1651 return new Variable._(variableName, mirror, owner); 1657 return new Variable._(variableName, mirror, owner);
1652 } 1658 }
1653 return variable; 1659 return variable;
1654 } 1660 }
1655 1661
1656 Variable._(this._variableName, VariableMirror mirror, Indexable owner) : 1662 Variable._(this._variableName, VariableMirror mirror, Indexable owner) :
(...skipping 24 matching lines...) Expand all
1681 String get typeName => 'property'; 1687 String get typeName => 'property';
1682 1688
1683 get comment { 1689 get comment {
1684 if (_comment != null) return _comment; 1690 if (_comment != null) return _comment;
1685 if (owner is Class) { 1691 if (owner is Class) {
1686 (owner as Class).ensureComments(); 1692 (owner as Class).ensureComments();
1687 } 1693 }
1688 return super.comment; 1694 return super.comment;
1689 } 1695 }
1690 1696
1691 markdown.Node fixReferenceWithScope(String name) => fixReference(name);
1692
1693 String findElementInScope(String name) { 1697 String findElementInScope(String name) {
1694 var lookupFunc = Indexable.determineLookupFunc(name); 1698 var lookupFunc = Indexable.determineLookupFunc(name);
1695 var result = lookupFunc(mirror, name); 1699 var result = lookupFunc(mirror, name);
1696 if (result != null) { 1700 if (result != null) {
1697 result = Indexable.getDocgenObject(result); 1701 result = Indexable.getDocgenObject(result);
1698 if (result is DummyMirror) return packagePrefix + result.docName; 1702 if (result is DummyMirror) return packagePrefix + result.docName;
1699 return result.packagePrefix + result.docName; 1703 return result.packagePrefix + result.docName;
1700 } 1704 }
1701 1705
1702 if (owner != null) { 1706 if (owner != null) {
(...skipping 16 matching lines...) Expand all
1719 1723
1720 bool isStatic; 1724 bool isStatic;
1721 bool isAbstract; 1725 bool isAbstract;
1722 bool isConst; 1726 bool isConst;
1723 Type returnType; 1727 Type returnType;
1724 Method methodInheritedFrom; 1728 Method methodInheritedFrom;
1725 1729
1726 /// Qualified name to state where the comment is inherited from. 1730 /// Qualified name to state where the comment is inherited from.
1727 String commentInheritedFrom = ""; 1731 String commentInheritedFrom = "";
1728 1732
1729 /// List of the meta annotations on the method. 1733 factory Method(MethodMirror mirror, Indexable owner,
1730 List<Annotation> annotations;
1731
1732 factory Method(MethodMirror mirror, Indexable owner, // Indexable newOwner.
1733 [Method methodInheritedFrom]) { 1734 [Method methodInheritedFrom]) {
1734 var method = Indexable.getDocgenObject(mirror, owner); 1735 var method = Indexable.getDocgenObject(mirror, owner);
1735 if (method is DummyMirror) { 1736 if (method is DummyMirror) {
1736 method = new Method._(mirror, owner, methodInheritedFrom); 1737 method = new Method._(mirror, owner, methodInheritedFrom);
1737 } 1738 }
1738 return method; 1739 return method;
1739 } 1740 }
1740 1741
1741 Method._(MethodMirror mirror, Indexable owner, this.methodInheritedFrom) 1742 Method._(MethodMirror mirror, Indexable owner, this.methodInheritedFrom)
1742 : super(mirror, owner) { 1743 : super(mirror, owner) {
1743 isStatic = mirror.isStatic; 1744 isStatic = mirror.isStatic;
1744 isAbstract = mirror.isAbstract; 1745 isAbstract = mirror.isAbstract;
1745 isConst = mirror.isConstConstructor; 1746 isConst = mirror.isConstConstructor;
1746 returnType = new Type(mirror.returnType, _getOwningLibrary(owner)); 1747 returnType = new Type(mirror.returnType, _getOwningLibrary(owner));
1747 parameters = _createParameters(mirror.parameters, owner); 1748 parameters = _createParameters(mirror.parameters, owner);
1748 annotations = _createAnnotations(mirror, _getOwningLibrary(owner)); 1749 annotations = _createAnnotations(mirror, _getOwningLibrary(owner));
1749 } 1750 }
1750 1751
1751 String get packagePrefix => owner.packagePrefix; 1752 String get packagePrefix => owner.packagePrefix;
1752 1753
1753 Method get originallyInheritedFrom => methodInheritedFrom == null ? 1754 Method get originallyInheritedFrom => methodInheritedFrom == null ?
1754 this : methodInheritedFrom.originallyInheritedFrom; 1755 this : methodInheritedFrom.originallyInheritedFrom;
1755 1756
1756 markdown.Node fixReferenceWithScope(String name) => fixReference(name);
1757
1758 /// Look for the specified name starting with the current member, and 1757 /// Look for the specified name starting with the current member, and
1759 /// progressively working outward to the current library scope. 1758 /// progressively working outward to the current library scope.
1760 String findElementInScope(String name) { 1759 String findElementInScope(String name) {
1761 var lookupFunc = Indexable.determineLookupFunc(name); 1760 var lookupFunc = Indexable.determineLookupFunc(name);
1762 1761
1763 var memberScope = lookupFunc(this.mirror, name); 1762 var memberScope = lookupFunc(this.mirror, name);
1764 if (memberScope != null) { 1763 if (memberScope != null) {
1765 // do we check for a dummy mirror returned here and look up with an owner 1764 // do we check for a dummy mirror returned here and look up with an owner
1766 // higher ooooor in getDocgenObject do we include more things in our 1765 // higher ooooor in getDocgenObject do we include more things in our
1767 // lookup 1766 // lookup
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1831 return 'method'; 1830 return 'method';
1832 } 1831 }
1833 1832
1834 get comment { 1833 get comment {
1835 if (_comment != null) return _comment; 1834 if (_comment != null) return _comment;
1836 if (owner is Class) { 1835 if (owner is Class) {
1837 (owner as Class).ensureComments(); 1836 (owner as Class).ensureComments();
1838 } 1837 }
1839 var result = super.comment; 1838 var result = super.comment;
1840 if (result == '' && methodInheritedFrom != null) { 1839 if (result == '' && methodInheritedFrom != null) {
1841 // this should be NOT from the MIRROR, but from the COMMENT 1840 // This should be NOT from the MIRROR, but from the COMMENT.
1841 methodInheritedFrom.comment; // Ensure comment field has been populated.
1842 _unresolvedComment = methodInheritedFrom._unresolvedComment; 1842 _unresolvedComment = methodInheritedFrom._unresolvedComment;
1843 1843
1844 var linkResolver = (name) => fixReferenceWithScope(name); 1844 var linkResolver = (name) => fixReference(name);
1845 comment = _unresolvedComment == null ? '' : 1845 comment = _unresolvedComment == null ? '' :
1846 markdown.markdownToHtml(_unresolvedComment.trim(), 1846 markdown.markdownToHtml(_unresolvedComment.trim(),
1847 linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES); 1847 linkResolver: linkResolver, inlineSyntaxes: _MARKDOWN_SYNTAXES);
1848 commentInheritedFrom = methodInheritedFrom.commentInheritedFrom; 1848 commentInheritedFrom = comment != '' ?
1849 methodInheritedFrom.commentInheritedFrom : '';
1849 result = comment; 1850 result = comment;
1850 } 1851 }
1851 return result; 1852 return result;
1852 } 1853 }
1853 1854
1854 bool _isValidMirror(DeclarationMirror mirror) => mirror is MethodMirror; 1855 bool _isValidMirror(DeclarationMirror mirror) => mirror is MethodMirror;
1855 } 1856 }
1856 1857
1857 /// Docgen wrapper around the dart2js mirror for a Dart 1858 /// Docgen wrapper around the dart2js mirror for a Dart
1858 /// method/function parameter. 1859 /// method/function parameter.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1971 .map((e) => originalMirror.getField(e.simpleName).reflectee) 1972 .map((e) => originalMirror.getField(e.simpleName).reflectee)
1972 .where((e) => e != null) 1973 .where((e) => e != null)
1973 .toList(); 1974 .toList();
1974 } 1975 }
1975 1976
1976 Map toMap() => { 1977 Map toMap() => {
1977 'name': Indexable.getDocgenObject(mirror, owningLibrary).docName, 1978 'name': Indexable.getDocgenObject(mirror, owningLibrary).docName,
1978 'parameters': parameters 1979 'parameters': parameters
1979 }; 1980 };
1980 } 1981 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698