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

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

Issue 63193006: Resolve comments lazily and re-evaluate inherited comments for subclasses (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 '_js_helper.Returns']; 44 '_js_helper.Returns'];
45 45
46 /// Set of libraries declared in the SDK, so libraries that can be accessed 46 /// Set of libraries declared in the SDK, so libraries that can be accessed
47 /// when running dart by default. 47 /// when running dart by default.
48 Iterable<LibraryMirror> _sdkLibraries; 48 Iterable<LibraryMirror> _sdkLibraries;
49 49
50 /// The dart:core library, which contains all types that are always available 50 /// The dart:core library, which contains all types that are always available
51 /// without import. 51 /// without import.
52 LibraryMirror _coreLibrary; 52 LibraryMirror _coreLibrary;
53 53
54 /// Current library being documented to be used for comment links.
55 LibraryMirror _currentLibrary;
Emily Fortuna 2013/11/18 21:00:41 yay! :-)
56
57 /// Current class being documented to be used for comment links.
58 ClassMirror _currentClass;
59
60 /// Current member being documented to be used for comment links.
61 MemberMirror _currentMember;
62
63 /// Support for [:foo:]-style code comments to the markdown parser. 54 /// Support for [:foo:]-style code comments to the markdown parser.
64 List<markdown.InlineSyntax> markdownSyntaxes = 55 List<markdown.InlineSyntax> markdownSyntaxes =
65 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')]; 56 [new markdown.CodeSyntax(r'\[:\s?((?:.|\n)*?)\s?:\]')];
66 57
67 /// Resolves reference links in doc comments.
68 markdown.Resolver linkResolver;
69
70 /// Index of all indexable items. This also ensures that no class is 58 /// Index of all indexable items. This also ensures that no class is
71 /// created more than once. 59 /// created more than once.
72 Map<String, Indexable> entityMap = new Map<String, Indexable>(); 60 Map<String, Indexable> entityMap = new Map<String, Indexable>();
73 61
74 /// This is set from the command line arguments flag --include-private 62 /// This is set from the command line arguments flag --include-private
75 bool _includePrivate = false; 63 bool _includePrivate = false;
76 64
77 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move 65 // TODO(janicejl): Make MDN content generic or pluggable. Maybe move
78 // MDN-specific code to its own library that is imported into the default impl? 66 // MDN-specific code to its own library that is imported into the default impl?
79 /// Map of all the comments for dom elements from MDN. 67 /// Map of all the comments for dom elements from MDN.
(...skipping 21 matching lines...) Expand all
101 if (packageRoot == null && !parseSdk) { 89 if (packageRoot == null && !parseSdk) {
102 var type = FileSystemEntity.typeSync(files.first); 90 var type = FileSystemEntity.typeSync(files.first);
103 if (type == FileSystemEntityType.DIRECTORY) { 91 if (type == FileSystemEntityType.DIRECTORY) {
104 packageRoot = _findPackageRoot(files.first); 92 packageRoot = _findPackageRoot(files.first);
105 } else if (type == FileSystemEntityType.FILE) { 93 } else if (type == FileSystemEntityType.FILE) {
106 logger.warning('WARNING: No package root defined. If Docgen fails, try ' 94 logger.warning('WARNING: No package root defined. If Docgen fails, try '
107 'again by setting the --package-root option.'); 95 'again by setting the --package-root option.');
108 } 96 }
109 } 97 }
110 logger.info('Package Root: ${packageRoot}'); 98 logger.info('Package Root: ${packageRoot}');
111 linkResolver = (name) =>
112 fixReference(name, _currentLibrary, _currentClass, _currentMember);
113 99
114 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk) 100 return getMirrorSystem(files, packageRoot: packageRoot, parseSdk: parseSdk)
115 .then((MirrorSystem mirrorSystem) { 101 .then((MirrorSystem mirrorSystem) {
116 if (mirrorSystem.libraries.isEmpty) { 102 if (mirrorSystem.libraries.isEmpty) {
117 throw new StateError('No library mirrors were created.'); 103 throw new StateError('No library mirrors were created.');
118 } 104 }
119 var librariesWeAskedFor = _listLibraries(files); 105 var librariesWeAskedFor = _listLibraries(files);
120 var librariesWeGot = mirrorSystem.libraries.values.where( 106 var librariesWeGot = mirrorSystem.libraries.values.where(
121 (each) => each.uri.scheme == 'file'); 107 (each) => each.uri.scheme == 'file');
122 _sdkLibraries = mirrorSystem.libraries.values.where( 108 _sdkLibraries = mirrorSystem.libraries.values.where(
(...skipping 13 matching lines...) Expand all
136 return true; 122 return true;
137 }); 123 });
138 } 124 }
139 125
140 /// For a library's [mirror], determine the name of the package (if any) we 126 /// For a library's [mirror], determine the name of the package (if any) we
141 /// believe it came from (because of its file URI). 127 /// believe it came from (because of its file URI).
142 /// 128 ///
143 /// If [library] is specified, we set the packageName field. If no package could 129 /// If [library] is specified, we set the packageName field. If no package could
144 /// be determined, we return an empty string. 130 /// be determined, we return an empty string.
145 String _findPackage(LibraryMirror mirror, [Library library]) { 131 String _findPackage(LibraryMirror mirror, [Library library]) {
132 if (mirror == null) return '';
146 if (mirror.uri.scheme != 'file') return ''; 133 if (mirror.uri.scheme != 'file') return '';
147 var filePath = mirror.uri.toFilePath(); 134 var filePath = mirror.uri.toFilePath();
148 // We assume that we are documenting only libraries under package/lib 135 // We assume that we are documenting only libraries under package/lib
149 var rootdir = path.dirname((path.dirname(filePath))); 136 var rootdir = path.dirname((path.dirname(filePath)));
150 var pubspec = path.join(rootdir, 'pubspec.yaml'); 137 var pubspec = path.join(rootdir, 'pubspec.yaml');
151 var packageName = _packageName(pubspec); 138 var packageName = _packageName(pubspec);
152 if (library != null) { 139 if (library != null) {
153 library.packageName = packageName; 140 library.packageName = packageName;
154 // If we are the main library in a package, associate the package readme 141 // If we are the main library in a package, associate the package readme
155 // with us. 142 // with us.
156 // TODO(alanknight): We can't really rely on all packages having a library 143 // TODO(alanknight): We can't really rely on all packages having a library
157 // that matches the package name. Need a better way to store this. 144 // that matches the package name. Need a better way to store this.
158 if (library.packageName == library.name) { 145 if (library.packageName == library.name) {
159 library.packageIntro = _packageIntro(rootdir); 146 library.packageIntro = _packageIntro(rootdir);
160 } 147 }
161 } 148 }
162 return packageName; 149 return packageName;
163 } 150 }
164 151
165 String _packageIntro(packageDir) { 152 String _packageIntro(packageDir) {
166 var dir = new Directory(packageDir); 153 var dir = new Directory(packageDir);
167 var files = dir.listSync(); 154 var files = dir.listSync();
168 var readmes = files.where((FileSystemEntity each) => (each is File && 155 var readmes = files.where((FileSystemEntity each) => (each is File &&
169 each.path.substring(packageDir.length + 1, each.path.length) 156 each.path.substring(packageDir.length + 1, each.path.length)
170 .startsWith('README'))).toList(); 157 .startsWith('README'))).toList();
171 if (readmes.isEmpty) return ''; 158 if (readmes.isEmpty) return '';
172 // If there are multiples, pick the shortest name. 159 // If there are multiples, pick the shortest name.
173 readmes.sort((a, b) => a.length.compareTo(b.length)); 160 readmes.sort((a, b) => a.length.compareTo(b.length));
174 var readme = readmes.first; 161 var readme = readmes.first;
162 var linkResolver = (name) => fixReference(name, null, null, null);
175 var contents = markdown.markdownToHtml(readme 163 var contents = markdown.markdownToHtml(readme
176 .readAsStringSync(), linkResolver: linkResolver, 164 .readAsStringSync(), linkResolver: linkResolver,
177 inlineSyntaxes: markdownSyntaxes); 165 inlineSyntaxes: markdownSyntaxes);
178 return contents; 166 return contents;
179 } 167 }
180 168
181
182 List<String> _listLibraries(List<String> args) { 169 List<String> _listLibraries(List<String> args) {
183 var libraries = new List<String>(); 170 var libraries = new List<String>();
184 for (var arg in args) { 171 for (var arg in args) {
185 var type = FileSystemEntity.typeSync(arg); 172 var type = FileSystemEntity.typeSync(arg);
186 173
187 if (type == FileSystemEntityType.FILE) { 174 if (type == FileSystemEntityType.FILE) {
188 if (arg.endsWith('.dart')) { 175 if (arg.endsWith('.dart')) {
189 libraries.add(path.absolute(arg)); 176 libraries.add(path.absolute(arg));
190 logger.info('Added to libraries: ${libraries.last}'); 177 logger.info('Added to libraries: ${libraries.last}');
191 } 178 }
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid()); 310 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid());
324 // Everything is a subclass of Object, therefore empty the list to avoid a 311 // Everything is a subclass of Object, therefore empty the list to avoid a
325 // giant list of subclasses to be printed out. 312 // giant list of subclasses to be printed out.
326 if (includeSdk) (entityMap['dart-core.Object'] as Class).subclasses.clear(); 313 if (includeSdk) (entityMap['dart-core.Object'] as Class).subclasses.clear();
327 314
328 var filteredEntities = entityMap.values.where(_isVisible); 315 var filteredEntities = entityMap.values.where(_isVisible);
329 316
330 // Outputs a JSON file with all libraries and their preview comments. 317 // Outputs a JSON file with all libraries and their preview comments.
331 // This will help the viewer know what libraries are available to read in. 318 // This will help the viewer know what libraries are available to read in.
332 var libraryMap; 319 var libraryMap;
320 var linkResolver = (name) => fixReference(name, null, null, null);
333 if (append) { 321 if (append) {
334 var docsDir = listDir('docs'); 322 var docsDir = listDir('docs');
335 if (!docsDir.contains('docs/library_list.json')) { 323 if (!docsDir.contains('docs/library_list.json')) {
336 throw new StateError('No library_list.json'); 324 throw new StateError('No library_list.json');
337 } 325 }
338 libraryMap = 326 libraryMap =
339 JSON.decode(new File('docs/library_list.json').readAsStringSync()); 327 JSON.decode(new File('docs/library_list.json').readAsStringSync());
340 libraryMap['libraries'].addAll(filteredEntities 328 libraryMap['libraries'].addAll(filteredEntities
341 .where((e) => e is Library) 329 .where((e) => e is Library)
342 .map((e) => e.previewMap)); 330 .map((e) => e.previewMap));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 filteredEntities.map((e) => e.typeName)); 365 filteredEntities.map((e) => e.typeName));
378 if (append) { 366 if (append) {
379 var previousIndex = 367 var previousIndex =
380 JSON.decode(new File('docs/index.json').readAsStringSync()); 368 JSON.decode(new File('docs/index.json').readAsStringSync());
381 index.addAll(previousIndex); 369 index.addAll(previousIndex);
382 } 370 }
383 _writeToFile(JSON.encode(index), 'index.json'); 371 _writeToFile(JSON.encode(index), 'index.json');
384 } 372 }
385 373
386 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { 374 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) {
387 _currentLibrary = library; 375 var result = new Library(docName(library),
388 var result = new Library(docName(library), _commentToHtml(library), 376 (actualLibrary) => _commentToHtml(library, actualLibrary),
389 _classes(library.classes), 377 _classes(library.classes),
390 _methods(library.functions), 378 _methods(library.functions),
391 _variables(library.variables), 379 _variables(library.variables),
392 _isHidden(library)); 380 _isHidden(library), library);
393 _findPackage(library, result); 381 _findPackage(library, result);
394 logger.fine('Generated library for ${result.name}'); 382 logger.fine('Generated library for ${result.name}');
395 return result; 383 return result;
396 } 384 }
397 385
398 void _writeIndexableToFile(Indexable result, bool outputToYaml) { 386 void _writeIndexableToFile(Indexable result, bool outputToYaml) {
399 var outputFile = result.fileName; 387 var outputFile = result.fileName;
400 var output; 388 var output;
401 if (outputToYaml) { 389 if (outputToYaml) {
402 output = getYamlString(result.toMap()); 390 output = getYamlString(result.toMap());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 .where((e) => e != null) 441 .where((e) => e != null)
454 .toList(); 442 .toList();
455 if (!skippedAnnotations.contains(docName(annotation.type))) { 443 if (!skippedAnnotations.contains(docName(annotation.type))) {
456 annotations.add(new Annotation(docName(annotation.type), 444 annotations.add(new Annotation(docName(annotation.type),
457 parameterList)); 445 parameterList));
458 } 446 }
459 }); 447 });
460 return annotations; 448 return annotations;
461 } 449 }
462 450
463 /// Update the global pointers to the current mirror to the particular mirror
464 /// we're documenting.
465 void _updateCurrentMirror(DeclarationMirror mirror) {
466 if (mirror is LibraryMirror) {
467 _currentLibrary = mirror;
468 } else if (mirror is ClassMirror) {
469 _currentClass = mirror;
470 } else if (mirror is MethodMirror) {
471 _currentMember = mirror;
472 }
473 }
474
475 /// Returns any documentation comments associated with a mirror with 451 /// Returns any documentation comments associated with a mirror with
476 /// simple markdown converted to html. 452 /// simple markdown converted to html.
477 String _commentToHtml(DeclarationMirror mirror) { 453 ///
454 /// It's possible to have a comment that comes from one mirror applied to
455 /// another, in the case of an inherited comment.
456 String _commentToHtml(DeclarationMirror mirror, [DeclarationMirror appliedTo]) {
457 if (appliedTo == null) appliedTo = mirror;
478 String commentText; 458 String commentText;
479 _updateCurrentMirror(mirror);
480 mirror.metadata.forEach((metadata) { 459 mirror.metadata.forEach((metadata) {
481 if (metadata is CommentInstanceMirror) { 460 if (metadata is CommentInstanceMirror) {
482 CommentInstanceMirror comment = metadata; 461 CommentInstanceMirror comment = metadata;
483 if (comment.isDocComment) { 462 if (comment.isDocComment) {
484 if (commentText == null) { 463 if (commentText == null) {
485 commentText = comment.trimmedText; 464 commentText = comment.trimmedText;
486 } else { 465 } else {
487 commentText = '$commentText\n${comment.trimmedText}'; 466 commentText = '$commentText\n${comment.trimmedText}';
488 } 467 }
489 } 468 }
490 } 469 }
491 }); 470 });
492 471
472 var linkResolver = (name) => fixReferenceWithScope(name, appliedTo);
493 commentText = commentText == null ? '' : 473 commentText = commentText == null ? '' :
494 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver, 474 markdown.markdownToHtml(commentText.trim(), linkResolver: linkResolver,
495 inlineSyntaxes: markdownSyntaxes); 475 inlineSyntaxes: markdownSyntaxes);
496 return commentText; 476 return commentText;
497 } 477 }
498 478
499 /// Generates MDN comments from database.json. 479 /// Generates MDN comments from database.json.
500 void _mdnComment(Indexable item) { 480 void _mdnComment(Indexable item) {
501 //Check if MDN is loaded. 481 //Check if MDN is loaded.
502 if (_mdn == null) { 482 if (_mdn == null) {
503 // Reading in MDN related json file. 483 // Reading in MDN related json file.
504 var root = findRootDirectory(); 484 var root = findRootDirectory();
505 var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json'); 485 var mdnPath = path.join(root, 'utils/apidoc/mdn/database.json');
506 _mdn = JSON.decode(new File(mdnPath).readAsStringSync()); 486 _mdn = JSON.decode(new File(mdnPath).readAsStringSync());
507 } 487 }
508 if (item.comment.isNotEmpty) return; 488 if (item is Library) return;
509 var domAnnotation = item.annotations.firstWhere( 489 var domAnnotation = item.annotations.firstWhere(
510 (e) => e.qualifiedName == 'metadata.DomName', orElse: () => null); 490 (e) => e.qualifiedName == 'metadata.DomName', orElse: () => null);
511 if (domAnnotation == null) return; 491 if (domAnnotation == null) return;
512 var domName = domAnnotation.parameters.single; 492 var domName = domAnnotation.parameters.single;
513 var parts = domName.split('.'); 493 var parts = domName.split('.');
514 if (parts.length == 2) item.comment = _mdnMemberComment(parts[0], parts[1]); 494 if (parts.length == 2) item.comment = _mdnMemberComment(parts[0], parts[1]);
515 if (parts.length == 1) item.comment = _mdnTypeComment(parts[0]); 495 if (parts.length == 1) item.comment = _mdnTypeComment(parts[0]);
516 } 496 }
517 497
518 /// Generates the MDN Comment for variables and method DOM elements. 498 /// Generates the MDN Comment for variables and method DOM elements.
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 ClassMirror currentClass, MemberMirror currentMember) { 648 ClassMirror currentClass, MemberMirror currentMember) {
669 // Attempt the look up the whole name up in the scope. 649 // Attempt the look up the whole name up in the scope.
670 String elementName = 650 String elementName =
671 findElementInScope(name, currentLibrary, currentClass, currentMember); 651 findElementInScope(name, currentLibrary, currentClass, currentMember);
672 if (elementName != null) { 652 if (elementName != null) {
673 return new markdown.Element.text('a', elementName); 653 return new markdown.Element.text('a', elementName);
674 } 654 }
675 return _fixComplexReference(name, currentLibrary, currentClass, currentMember) ; 655 return _fixComplexReference(name, currentLibrary, currentClass, currentMember) ;
676 } 656 }
677 657
658 markdown.Node fixReferenceWithScope(String name, DeclarationMirror scope) {
659 if (scope is LibraryMirror) return fixReference(name, scope, null, null);
660 if (scope is ClassMirror)
661 return fixReference(name, scope.library, scope, null);
662 if (scope is MemberMirror) {
663 var owner = scope.owner;
664 if (owner is ClassMirror) {
665 return fixReference(name, owner.library, owner, scope);
666 } else {
667 return fixReference(name, owner, null, scope);
668 }
669 }
670 return null;
671 }
672
678 /// Returns a map of [Variable] objects constructed from [mirrorMap]. 673 /// Returns a map of [Variable] objects constructed from [mirrorMap].
679 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) { 674 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) {
680 var data = {}; 675 var data = {};
681 // TODO(janicejl): When map to map feature is created, replace the below with 676 // TODO(janicejl): When map to map feature is created, replace the below with
682 // a filter. Issue(#9590). 677 // a filter. Issue(#9590).
683 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { 678 mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
684 _currentMember = mirror;
685 if (_includePrivate || !_isHidden(mirror)) { 679 if (_includePrivate || !_isHidden(mirror)) {
686 entityMap[docName(mirror)] = new Variable(mirrorName, mirror.isFinal, 680 entityMap[docName(mirror)] = new Variable(mirrorName, mirror.isFinal,
687 mirror.isStatic, mirror.isConst, _type(mirror.type), 681 mirror.isStatic, mirror.isConst, _type(mirror.type),
688 _commentToHtml(mirror), _annotations(mirror), docName(mirror), 682 (actualVariable) => _commentToHtml(mirror, actualVariable),
689 _isHidden(mirror), docName(mirror.owner)); 683 _annotations(mirror), docName(mirror),
684 _isHidden(mirror), docName(mirror.owner), mirror);
690 data[mirrorName] = entityMap[docName(mirror)]; 685 data[mirrorName] = entityMap[docName(mirror)];
691 } 686 }
692 }); 687 });
693 return data; 688 return data;
694 } 689 }
695 690
696 /// Returns a map of [Method] objects constructed from [mirrorMap]. 691 /// Returns a map of [Method] objects constructed from [mirrorMap].
697 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) { 692 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) {
698 var group = new MethodGroup(); 693 var group = new MethodGroup();
699 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { 694 mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
700 if (_includePrivate || !mirror.isPrivate) { 695 if (_includePrivate || !mirror.isPrivate) {
701 group.addMethod(mirror); 696 group.addMethod(mirror);
702 } 697 }
703 }); 698 });
704 return group; 699 return group;
705 } 700 }
706 701
707 /// Returns the [Class] for the given [mirror] has already been created, and if 702 /// Returns the [Class] for the given [mirror] has already been created, and if
708 /// it does not exist, creates it. 703 /// it does not exist, creates it.
709 Class _class(ClassMirror mirror) { 704 Class _class(ClassMirror mirror) {
710 var clazz = entityMap[docName(mirror)]; 705 var clazz = entityMap[docName(mirror)];
711 if (clazz == null) { 706 if (clazz == null) {
712 var superclass = mirror.superclass != null ? 707 var superclass = mirror.superclass != null ?
713 _class(mirror.superclass) : null; 708 _class(mirror.superclass) : null;
714 var interfaces = 709 var interfaces =
715 mirror.superinterfaces.map((interface) => _class(interface)); 710 mirror.superinterfaces.map((interface) => _class(interface));
716 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror), 711 clazz = new Class(mirror.simpleName, superclass,
712 (actualClass) => _commentToHtml(mirror, actualClass),
717 interfaces.toList(), _variables(mirror.variables), 713 interfaces.toList(), _variables(mirror.variables),
718 _methods(mirror.methods), _annotations(mirror), _generics(mirror), 714 _methods(mirror.methods), _annotations(mirror), _generics(mirror),
719 docName(mirror), _isHidden(mirror), docName(mirror.owner), 715 docName(mirror), _isHidden(mirror), docName(mirror.owner),
720 mirror.isAbstract); 716 mirror.isAbstract, mirror);
721 if (superclass != null) clazz.addInherited(superclass); 717 if (superclass != null) clazz.addInherited(superclass);
722 interfaces.forEach((interface) => clazz.addInherited(interface)); 718 interfaces.forEach((interface) => clazz.addInherited(interface));
723 entityMap[docName(mirror)] = clazz; 719 entityMap[docName(mirror)] = clazz;
724 } 720 }
725 return clazz; 721 return clazz;
726 } 722 }
727 723
728 /// Returns a map of [Class] objects constructed from [mirrorMap]. 724 /// Returns a map of [Class] objects constructed from [mirrorMap].
729 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) { 725 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) {
730 var group = new ClassGroup(); 726 var group = new ClassGroup();
731 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { 727 mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
732 group.addClass(mirror); 728 group.addClass(mirror);
733 }); 729 });
734 return group; 730 return group;
735 } 731 }
736 732
737 /// Returns a map of [Parameter] objects constructed from [mirrorList]. 733 /// Returns a map of [Parameter] objects constructed from [mirrorList].
738 Map<String, Parameter> _parameters(List<ParameterMirror> mirrorList) { 734 Map<String, Parameter> _parameters(List<ParameterMirror> mirrorList) {
739 var data = {}; 735 var data = {};
740 mirrorList.forEach((ParameterMirror mirror) { 736 mirrorList.forEach((ParameterMirror mirror) {
741 _currentMember = mirror;
742 data[mirror.simpleName] = new Parameter(mirror.simpleName, 737 data[mirror.simpleName] = new Parameter(mirror.simpleName,
743 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, 738 mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue,
744 _type(mirror.type), mirror.defaultValue, 739 _type(mirror.type), mirror.defaultValue,
745 _annotations(mirror)); 740 _annotations(mirror));
746 }); 741 });
747 return data; 742 return data;
748 } 743 }
749 744
750 /// Returns a map of [Generic] objects constructed from the class mirror. 745 /// Returns a map of [Generic] objects constructed from the class mirror.
751 Map<String, Generic> _generics(ClassMirror mirror) { 746 Map<String, Generic> _generics(ClassMirror mirror) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 inputMap.forEach((key, value) { 794 inputMap.forEach((key, value) {
800 if (value is Map) { 795 if (value is Map) {
801 outputMap[key] = recurseMap(value); 796 outputMap[key] = recurseMap(value);
802 } else { 797 } else {
803 outputMap[key] = value.toMap(); 798 outputMap[key] = value.toMap();
804 } 799 }
805 }); 800 });
806 return outputMap; 801 return outputMap;
807 } 802 }
808 803
804 /// A type for the function that generates a comment from a mirror.
805 typedef String CommentGenerator(Mirror m);
806
809 /// A class representing all programming constructs, like library or class. 807 /// A class representing all programming constructs, like library or class.
810 class Indexable { 808 class Indexable {
811 String name; 809 String name;
812 String get qualifiedName => fileName; 810 String get qualifiedName => fileName;
813 bool isPrivate; 811 bool isPrivate;
812 Mirror mirror;
814 813
815 // The qualified name (for URL purposes) and the file name are the same, 814 // The qualified name (for URL purposes) and the file name are the same,
816 // of the form packageName/ClassName or packageName/ClassName.methodName. 815 // of the form packageName/ClassName or packageName/ClassName.methodName.
817 // This defines both the URL and the directory structure. 816 // This defines both the URL and the directory structure.
818 String get fileName => packagePrefix + ownerPrefix + name; 817 String get fileName => packagePrefix + ownerPrefix + name;
819 818
820 Indexable get owningEntity { 819 Indexable get owningEntity => entityMap[owner];
821 var result = entityMap[owner]; 820
822 return result;
823 }
824 String get ownerPrefix => owningEntity == null 821 String get ownerPrefix => owningEntity == null
825 ? (owner == null || owner.isEmpty ? '' : owner + '.') 822 ? (owner == null || owner.isEmpty ? '' : owner + '.')
826 : owningEntity.qualifiedName + '.'; 823 : owningEntity.qualifiedName + '.';
827 824
828 String get packagePrefix => ''; 825 String get packagePrefix => '';
826
829 /// Documentation comment with converted markdown. 827 /// Documentation comment with converted markdown.
830 String comment; 828 String _comment;
829
830 String get comment {
831 if (_comment != null) return _comment;
832 _comment = _commentFunction(mirror);
833 if (_comment.isEmpty) {
834 _mdnComment(this);
835 }
836 return _comment;
837 }
838
839 set comment(x) => _comment = x;
840
841 /// We defer evaluating the comment until we have all the context available
842 CommentGenerator _commentFunction;
831 843
832 /// Qualified Name of the owner of this Indexable Item. 844 /// Qualified Name of the owner of this Indexable Item.
833 /// For Library, owner will be ""; 845 /// For Library, owner will be "";
834 String owner; 846 String owner;
835 847
836 Indexable(this.name, this.comment, this.isPrivate, this.owner); 848 Indexable(this.name, this._commentFunction, this.isPrivate, this.owner,
849 this.mirror);
837 850
838 /// The type of this member to be used in index.txt. 851 /// The type of this member to be used in index.txt.
839 String get typeName => ''; 852 String get typeName => '';
840 853
841 /// Creates a [Map] with this [Indexable]'s name and a preview comment. 854 /// Creates a [Map] with this [Indexable]'s name and a preview comment.
842 Map get previewMap { 855 Map get previewMap {
843 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; 856 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName };
844 if (comment != '') { 857 if (comment != '') {
845 var index = comment.indexOf('</p>'); 858 var index = comment.indexOf('</p>');
846 finalMap['preview'] = '${comment.substring(0, index)}</p>'; 859 finalMap['preview'] = '${comment.substring(0, index)}</p>';
(...skipping 30 matching lines...) Expand all
877 890
878 Map get previewMap { 891 Map get previewMap {
879 var basic = super.previewMap; 892 var basic = super.previewMap;
880 basic['packageName'] = packageName; 893 basic['packageName'] = packageName;
881 if (packageIntro != null) { 894 if (packageIntro != null) {
882 basic['packageIntro'] = packageIntro; 895 basic['packageIntro'] = packageIntro;
883 } 896 }
884 return basic; 897 return basic;
885 } 898 }
886 899
887 Library(String name, String comment, this.classes, this.functions, 900 Library(String name, Function commentFunction, this.classes, this.functions,
888 this.variables, bool isPrivate) : super(name, comment, 901 this.variables, bool isPrivate, Mirror mirror)
889 isPrivate, ""); 902 : super(name, commentFunction, isPrivate, "", mirror);
890 903
891 /// Generates a map describing the [Library] object. 904 /// Generates a map describing the [Library] object.
892 Map toMap() => { 905 Map toMap() => {
893 'name': name, 906 'name': name,
894 'qualifiedName': qualifiedName, 907 'qualifiedName': qualifiedName,
895 'comment': comment, 908 'comment': comment,
896 'variables': recurseMap(variables), 909 'variables': recurseMap(variables),
897 'functions': functions.toMap(), 910 'functions': functions.toMap(),
898 'classes': classes.toMap(), 911 'classes': classes.toMap(),
899 'packageName': packageName, 912 'packageName': packageName,
(...skipping 26 matching lines...) Expand all
926 939
927 /// Generic infomation about the class. 940 /// Generic infomation about the class.
928 Map<String, Generic> generics; 941 Map<String, Generic> generics;
929 942
930 Class superclass; 943 Class superclass;
931 bool isAbstract; 944 bool isAbstract;
932 945
933 /// List of the meta annotations on the class. 946 /// List of the meta annotations on the class.
934 List<Annotation> annotations; 947 List<Annotation> annotations;
935 948
936 Class(String name, this.superclass, String comment, this.interfaces, 949 bool _commentsEnsured = false;
Emily Fortuna 2013/11/18 21:00:41 comment explaining this variable?
Alan Knight 2013/11/18 22:04:46 Done.
950
951 Class(String name, this.superclass, Function commentFunction, this.interfaces,
937 this.variables, this.methods, this.annotations, this.generics, 952 this.variables, this.methods, this.annotations, this.generics,
938 String qualifiedName, bool isPrivate, String owner, this.isAbstract) 953 String qualifiedName, bool isPrivate, String owner, this.isAbstract,
939 : super(name, comment, isPrivate, owner) { 954 Mirror mirror)
940 _mdnComment(this); 955 : super(name, commentFunction, isPrivate, owner, mirror) {
Emily Fortuna 2013/11/18 21:00:41 you can take out the { } and just have a semicolon
Alan Knight 2013/11/18 22:04:46 Done.
941 } 956 }
942 957
943 String get typeName => 'class'; 958 String get typeName => 'class';
944 959
945 /// Returns a list of all the parent classes. 960 /// Returns a list of all the parent classes.
946 List<Class> parent() { 961 List<Class> parent() {
947 var parent = superclass == null ? [] : [superclass]; 962 var parent = superclass == null ? [] : [superclass];
948 parent.addAll(interfaces); 963 parent.addAll(interfaces);
949 return parent; 964 return parent;
950 } 965 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 // with the mixin as an owner private too. 1012 // with the mixin as an owner private too.
998 entityMap.values.where((e) => e.owner == qualifiedName) 1013 entityMap.values.where((e) => e.owner == qualifiedName)
999 .forEach((element) => element.isPrivate = true); 1014 .forEach((element) => element.isPrivate = true);
1000 // Move the subclass up to the next public superclass 1015 // Move the subclass up to the next public superclass
1001 subclasses.forEach((subclass) => addSubclass(subclass)); 1016 subclasses.forEach((subclass) => addSubclass(subclass));
1002 } 1017 }
1003 } 1018 }
1004 1019
1005 /// Makes sure that all methods with inherited equivalents have comments. 1020 /// Makes sure that all methods with inherited equivalents have comments.
1006 void ensureComments() { 1021 void ensureComments() {
1022 if (_commentsEnsured) return;
1023 _commentsEnsured = true;
1007 inheritedMethods.forEach((qualifiedName, inheritedMethod) { 1024 inheritedMethods.forEach((qualifiedName, inheritedMethod) {
1008 var method = methods[qualifiedName]; 1025 var method = methods[qualifiedName];
1009 if (method != null) method.ensureCommentFor(inheritedMethod); 1026 if (method != null) method.ensureCommentFor(inheritedMethod);
1010 }); 1027 });
1011 } 1028 }
1012 1029
1013 /// If a class extends a private superclass, find the closest public superclas s 1030 /// If a class extends a private superclass, find the closest public superclas s
1014 /// of the private superclass. 1031 /// of the private superclass.
1015 String validSuperclass() { 1032 String validSuperclass() {
1016 if (superclass == null) return 'dart.core.Object'; 1033 if (superclass == null) return 'dart.core.Object';
(...skipping 23 matching lines...) Expand all
1040 int compareTo(aClass) => name.compareTo(aClass.name); 1057 int compareTo(aClass) => name.compareTo(aClass.name);
1041 } 1058 }
1042 1059
1043 /// A container to categorize classes into the following groups: abstract 1060 /// A container to categorize classes into the following groups: abstract
1044 /// classes, regular classes, typedefs, and errors. 1061 /// classes, regular classes, typedefs, and errors.
1045 class ClassGroup { 1062 class ClassGroup {
1046 Map<String, Class> classes = {}; 1063 Map<String, Class> classes = {};
1047 Map<String, Typedef> typedefs = {}; 1064 Map<String, Typedef> typedefs = {};
1048 Map<String, Class> errors = {}; 1065 Map<String, Class> errors = {};
1049 1066
1050 void addClass(ClassMirror mirror) { 1067 void addClass(ClassMirror classMirror) {
1051 _currentClass = mirror; 1068 if (classMirror.isTypedef) {
1052 if (mirror.isTypedef) {
1053 // This is actually a Dart2jsTypedefMirror, and it does define value, 1069 // This is actually a Dart2jsTypedefMirror, and it does define value,
1054 // but we don't have visibility to that type. 1070 // but we don't have visibility to that type.
1055 var mirror = _currentClass; 1071 var mirror = classMirror;
1056 if (_includePrivate || !mirror.isPrivate) { 1072 if (_includePrivate || !mirror.isPrivate) {
1057 entityMap[docName(mirror)] = new Typedef(mirror.simpleName, 1073 entityMap[docName(mirror)] = new Typedef(mirror.simpleName,
1058 docName(mirror.value.returnType), _commentToHtml(mirror), 1074 docName(mirror.value.returnType),
1075 (actualTypedef) => _commentToHtml(mirror, actualTypedef),
1059 _generics(mirror), _parameters(mirror.value.parameters), 1076 _generics(mirror), _parameters(mirror.value.parameters),
1060 _annotations(mirror), docName(mirror), _isHidden(mirror), 1077 _annotations(mirror), docName(mirror), _isHidden(mirror),
1061 docName(mirror.owner)); 1078 docName(mirror.owner), mirror);
1062 typedefs[mirror.simpleName] = entityMap[docName(mirror)]; 1079 typedefs[mirror.simpleName] = entityMap[docName(mirror)];
1063 } 1080 }
1064 } else { 1081 } else {
1065 var clazz = _class(mirror); 1082 var clazz = _class(classMirror);
1066 1083
1067 // Adding inherited parent variables and methods. 1084 // Adding inherited parent variables and methods.
1068 clazz.parent().forEach((parent) { 1085 clazz.parent().forEach((parent) {
1069 if (_isVisible(clazz)) { 1086 if (_isVisible(clazz)) {
1070 parent.addSubclass(clazz); 1087 parent.addSubclass(clazz);
1071 } 1088 }
1072 }); 1089 });
1073 1090
1074 clazz.ensureComments();
1075
1076 if (clazz.isError()) { 1091 if (clazz.isError()) {
1077 errors[mirror.simpleName] = clazz; 1092 errors[classMirror.simpleName] = clazz;
1078 } else if (mirror.isClass) { 1093 } else if (classMirror.isClass) {
1079 classes[mirror.simpleName] = clazz; 1094 classes[classMirror.simpleName] = clazz;
1080 } else { 1095 } else {
1081 throw new ArgumentError('${mirror.simpleName} - no class type match. '); 1096 throw new ArgumentError(
1097 '${classMirror.simpleName} - no class type match. ');
1082 } 1098 }
1083 } 1099 }
1084 } 1100 }
1085 1101
1086 /// Checks if the given name is a key for any of the Class Maps. 1102 /// Checks if the given name is a key for any of the Class Maps.
1087 bool containsKey(String name) { 1103 bool containsKey(String name) {
1088 return classes.containsKey(name) || errors.containsKey(name); 1104 return classes.containsKey(name) || errors.containsKey(name);
1089 } 1105 }
1090 1106
1091 Map toMap() => { 1107 Map toMap() => {
1092 'class': classes.values.where(_isVisible) 1108 'class': classes.values.where(_isVisible)
1093 .map((e) => e.previewMap).toList(), 1109 .map((e) => e.previewMap).toList(),
1094 'typedef': recurseMap(typedefs), 1110 'typedef': recurseMap(typedefs),
1095 'error': errors.values.where(_isVisible) 1111 'error': errors.values.where(_isVisible)
1096 .map((e) => e.previewMap).toList() 1112 .map((e) => e.previewMap).toList()
1097 }; 1113 };
1098 } 1114 }
1099 1115
1100 class Typedef extends Indexable { 1116 class Typedef extends Indexable {
1101 String returnType; 1117 String returnType;
1102 1118
1103 Map<String, Parameter> parameters; 1119 Map<String, Parameter> parameters;
1104 1120
1105 /// Generic information about the typedef. 1121 /// Generic information about the typedef.
1106 Map<String, Generic> generics; 1122 Map<String, Generic> generics;
1107 1123
1108 /// List of the meta annotations on the typedef. 1124 /// List of the meta annotations on the typedef.
1109 List<Annotation> annotations; 1125 List<Annotation> annotations;
1110 1126
1111 Typedef(String name, this.returnType, String comment, this.generics, 1127 Typedef(String name, this.returnType, Function commentFunction, this.generics,
1112 this.parameters, this.annotations, 1128 this.parameters, this.annotations,
1113 String qualifiedName, bool isPrivate, String owner) 1129 String qualifiedName, bool isPrivate, String owner, Mirror mirror)
1114 : super(name, comment, isPrivate, owner); 1130 : super(name, commentFunction, isPrivate, owner, mirror);
1115 1131
1116 Map toMap() => { 1132 Map toMap() => {
1117 'name': name, 1133 'name': name,
1118 'qualifiedName': qualifiedName, 1134 'qualifiedName': qualifiedName,
1119 'comment': comment, 1135 'comment': comment,
1120 'return': returnType, 1136 'return': returnType,
1121 'parameters': recurseMap(parameters), 1137 'parameters': recurseMap(parameters),
1122 'annotations': annotations.map((a) => a.toMap()).toList(), 1138 'annotations': annotations.map((a) => a.toMap()).toList(),
1123 'generics': recurseMap(generics) 1139 'generics': recurseMap(generics)
1124 }; 1140 };
1125 1141
1126 String get typeName => 'typedef'; 1142 String get typeName => 'typedef';
1127 } 1143 }
1128 1144
1129 /// A class containing properties of a Dart variable. 1145 /// A class containing properties of a Dart variable.
1130 class Variable extends Indexable { 1146 class Variable extends Indexable {
1131 1147
1132 bool isFinal; 1148 bool isFinal;
1133 bool isStatic; 1149 bool isStatic;
1134 bool isConst; 1150 bool isConst;
1135 Type type; 1151 Type type;
1136 1152
1137 /// List of the meta annotations on the variable. 1153 /// List of the meta annotations on the variable.
1138 List<Annotation> annotations; 1154 List<Annotation> annotations;
1139 1155
1140 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type, 1156 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type,
1141 String comment, this.annotations, String qualifiedName, bool isPrivate, 1157 Function commentFunction, this.annotations, String qualifiedName,
1142 String owner) : super(name, comment, isPrivate, owner) { 1158 bool isPrivate, String owner, Mirror mirror)
1143 _mdnComment(this); 1159 : super(name, commentFunction, isPrivate, owner, mirror) {
1144 } 1160 }
1145 1161
1146 /// Generates a map describing the [Variable] object. 1162 /// Generates a map describing the [Variable] object.
1147 Map toMap() => { 1163 Map toMap() => {
1148 'name': name, 1164 'name': name,
1149 'qualifiedName': qualifiedName, 1165 'qualifiedName': qualifiedName,
1150 'comment': comment, 1166 'comment': comment,
1151 'final': isFinal.toString(), 1167 'final': isFinal.toString(),
1152 'static': isStatic.toString(), 1168 'static': isStatic.toString(),
1153 'constant': isConst.toString(), 1169 'constant': isConst.toString(),
1154 'type': new List.filled(1, type.toMap()), 1170 'type': new List.filled(1, type.toMap()),
1155 'annotations': annotations.map((a) => a.toMap()).toList() 1171 'annotations': annotations.map((a) => a.toMap()).toList()
1156 }; 1172 };
1157 1173
1158 String get typeName => 'property'; 1174 String get typeName => 'property';
1175
1176 get comment {
1177 if (_comment != null) return _comment;
1178 var owningClass = owningEntity;
1179 if (owningClass is Class) {
1180 owningClass.ensureComments();
1181 }
1182 return super.comment;
1183 }
1159 } 1184 }
1160 1185
1161 /// A class containing properties of a Dart method. 1186 /// A class containing properties of a Dart method.
1162 class Method extends Indexable { 1187 class Method extends Indexable {
1163 1188
1164 /// Parameters for this method. 1189 /// Parameters for this method.
1165 Map<String, Parameter> parameters; 1190 Map<String, Parameter> parameters;
1166 1191
1167 bool isStatic; 1192 bool isStatic;
1168 bool isAbstract; 1193 bool isAbstract;
1169 bool isConst; 1194 bool isConst;
1170 bool isConstructor; 1195 bool isConstructor;
1171 bool isGetter; 1196 bool isGetter;
1172 bool isSetter; 1197 bool isSetter;
1173 bool isOperator; 1198 bool isOperator;
1174 Type returnType; 1199 Type returnType;
1175 1200
1176 /// Qualified name to state where the comment is inherited from. 1201 /// Qualified name to state where the comment is inherited from.
1177 String commentInheritedFrom = ""; 1202 String commentInheritedFrom = "";
1178 1203
1179 /// List of the meta annotations on the method. 1204 /// List of the meta annotations on the method.
1180 List<Annotation> annotations; 1205 List<Annotation> annotations;
1181 1206
1182 Method(String name, this.isStatic, this.isAbstract, this.isConst, 1207 Method(String name, this.isStatic, this.isAbstract, this.isConst,
1183 this.returnType, String comment, this.parameters, this.annotations, 1208 this.returnType, Function commentFunction, this.parameters,
1209 this.annotations,
1184 String qualifiedName, bool isPrivate, String owner, this.isConstructor, 1210 String qualifiedName, bool isPrivate, String owner, this.isConstructor,
1185 this.isGetter, this.isSetter, this.isOperator) 1211 this.isGetter, this.isSetter, this.isOperator, Mirror mirror)
1186 : super(name, comment, isPrivate, owner) { 1212 : super(name, commentFunction, isPrivate, owner, mirror) {
1187 _mdnComment(this);
1188 } 1213 }
1189 1214
1190 /// Makes sure that the method with an inherited equivalent have comments. 1215 /// Makes sure that the method with an inherited equivalent have comments.
1191 void ensureCommentFor(Method inheritedMethod) { 1216 void ensureCommentFor(Method inheritedMethod) {
1192 if (comment.isNotEmpty) return; 1217 if (comment.isNotEmpty) return;
1193 (entityMap[inheritedMethod.owner] as Class).ensureComments(); 1218 comment = inheritedMethod._commentFunction(mirror);
1194 comment = inheritedMethod.comment;
1195 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? 1219 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ?
1196 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; 1220 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom;
1197 } 1221 }
1198 1222
1199 /// Generates a map describing the [Method] object. 1223 /// Generates a map describing the [Method] object.
1200 Map toMap() => { 1224 Map toMap() => {
1201 'name': name, 1225 'name': name,
1202 'qualifiedName': qualifiedName, 1226 'qualifiedName': qualifiedName,
1203 'comment': comment, 1227 'comment': comment,
1204 'commentFrom': commentInheritedFrom, 1228 'commentFrom': commentInheritedFrom,
1205 'static': isStatic.toString(), 1229 'static': isStatic.toString(),
1206 'abstract': isAbstract.toString(), 1230 'abstract': isAbstract.toString(),
1207 'constant': isConst.toString(), 1231 'constant': isConst.toString(),
1208 'return': new List.filled(1, returnType.toMap()), 1232 'return': new List.filled(1, returnType.toMap()),
1209 'parameters': recurseMap(parameters), 1233 'parameters': recurseMap(parameters),
1210 'annotations': annotations.map((a) => a.toMap()).toList() 1234 'annotations': annotations.map((a) => a.toMap()).toList()
1211 }; 1235 };
1212 1236
1213 String get typeName => isConstructor ? 'constructor' : 1237 String get typeName => isConstructor ? 'constructor' :
1214 isGetter ? 'getter' : isSetter ? 'setter' : 1238 isGetter ? 'getter' : isSetter ? 'setter' :
1215 isOperator ? 'operator' : 'method'; 1239 isOperator ? 'operator' : 'method';
1240
1241 get comment {
1242 if (_comment != null) return _comment;
1243 var owningClass = owningEntity;
1244 if (owningClass is Class) {
1245 owningClass.ensureComments();
1246 }
1247 return super.comment;
1248 }
1216 } 1249 }
1217 1250
1218 /// A container to categorize methods into the following groups: setters, 1251 /// A container to categorize methods into the following groups: setters,
1219 /// getters, constructors, operators, regular methods. 1252 /// getters, constructors, operators, regular methods.
1220 class MethodGroup { 1253 class MethodGroup {
1221 Map<String, Method> setters = {}; 1254 Map<String, Method> setters = {};
1222 Map<String, Method> getters = {}; 1255 Map<String, Method> getters = {};
1223 Map<String, Method> constructors = {}; 1256 Map<String, Method> constructors = {};
1224 Map<String, Method> operators = {}; 1257 Map<String, Method> operators = {};
1225 Map<String, Method> regularMethods = {}; 1258 Map<String, Method> regularMethods = {};
1226 1259
1227 void addMethod(MethodMirror mirror) { 1260 void addMethod(MethodMirror mirror) {
1228 var method = new Method(mirror.simpleName, mirror.isStatic, 1261 var method = new Method(mirror.simpleName, mirror.isStatic,
1229 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType), 1262 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType),
1230 _commentToHtml(mirror), _parameters(mirror.parameters), 1263 (actualMethod) => _commentToHtml(mirror, actualMethod),
1264 _parameters(mirror.parameters),
1231 _annotations(mirror), docName(mirror), _isHidden(mirror), 1265 _annotations(mirror), docName(mirror), _isHidden(mirror),
1232 docName(mirror.owner), mirror.isConstructor, mirror.isGetter, 1266 docName(mirror.owner), mirror.isConstructor, mirror.isGetter,
1233 mirror.isSetter, mirror.isOperator); 1267 mirror.isSetter, mirror.isOperator, mirror);
1234 entityMap[docName(mirror)] = method; 1268 entityMap[docName(mirror)] = method;
1235 _currentMember = mirror;
1236 if (mirror.isSetter) { 1269 if (mirror.isSetter) {
1237 setters[mirror.simpleName] = method; 1270 setters[mirror.simpleName] = method;
1238 } else if (mirror.isGetter) { 1271 } else if (mirror.isGetter) {
1239 getters[mirror.simpleName] = method; 1272 getters[mirror.simpleName] = method;
1240 } else if (mirror.isConstructor) { 1273 } else if (mirror.isConstructor) {
1241 constructors[mirror.simpleName] = method; 1274 constructors[mirror.simpleName] = method;
1242 } else if (mirror.isOperator) { 1275 } else if (mirror.isOperator) {
1243 operators[mirror.simpleName] = method; 1276 operators[mirror.simpleName] = method;
1244 } else if (mirror.isRegularMethod) { 1277 } else if (mirror.isRegularMethod) {
1245 regularMethods[mirror.simpleName] = method; 1278 regularMethods[mirror.simpleName] = method;
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 /// Remove statics from the map of inherited items before adding them. 1429 /// Remove statics from the map of inherited items before adding them.
1397 Map _filterStatics(Map items) { 1430 Map _filterStatics(Map items) {
1398 var result = {}; 1431 var result = {};
1399 items.forEach((name, item) { 1432 items.forEach((name, item) {
1400 if (!item.isStatic) { 1433 if (!item.isStatic) {
1401 result[name] = item; 1434 result[name] = item;
1402 } 1435 }
1403 }); 1436 });
1404 return result; 1437 return result;
1405 } 1438 }
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