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

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

Issue 47603014: Further fixes for including package information in docs (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Commenting out an unused failing test 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 | « pkg/docgen/bin/upload_docgen.py ('k') | pkg/docgen/lib/dottedLibraryName.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * **docgen** is a tool for creating machine readable representations of Dart 6 * **docgen** is a tool for creating machine readable representations of Dart
7 * code metadata, including: classes, members, comments and annotations. 7 * code metadata, including: classes, members, comments and annotations.
8 * 8 *
9 * docgen is run on a `.dart` file or a directory containing `.dart` files. 9 * docgen is run on a `.dart` file or a directory containing `.dart` files.
10 * 10 *
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 _documentLibraries(librariesToDocument, includeSdk: includeSdk, 125 _documentLibraries(librariesToDocument, includeSdk: includeSdk,
126 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk, 126 outputToYaml: outputToYaml, append: append, parseSdk: parseSdk,
127 introduction: introduction); 127 introduction: introduction);
128 return true; 128 return true;
129 }); 129 });
130 } 130 }
131 131
132 /// For a [library] and its corresponding [mirror] that we believe come 132 /// For a [library] and its corresponding [mirror] that we believe come
133 /// from a package (because it has a file 133 /// from a package (because it has a file
134 /// URI) look for the package name and set it on [library]. 134 /// URI) look for the package name and set it on [library].
135 _findPackage(Library library, LibraryMirror mirror) { 135 void _findPackage(Library library, LibraryMirror mirror) {
136 if (mirror.uri.scheme != 'file') return; 136 if (mirror.uri.scheme != 'file') return;
137 var filePath = mirror.uri.toFilePath(); 137 var filePath = mirror.uri.toFilePath();
138 // We assume that we are documenting only libraries under package/lib 138 // We assume that we are documenting only libraries under package/lib
139 var rootdir = path.dirname((path.dirname(filePath))); 139 var rootdir = path.dirname((path.dirname(filePath)));
140 var pubspec = path.join(rootdir, 'pubspec.yaml'); 140 var pubspec = path.join(rootdir, 'pubspec.yaml');
141 library.packageName = _packageName(pubspec); 141 library.packageName = _packageName(pubspec);
142 // If we are the main library in a package, associate the package readme
143 // with us.
144 // TODO(alanknight): We can't really rely on all packages having a library
145 // that matches the package name. Need a better way to store this.
146 if (library.packageName == library.name) {
147 library.packageIntro = _packageIntro(rootdir);
148 }
142 } 149 }
143 150
151 String _packageIntro(packageDir) {
152 var dir = new Directory(packageDir);
153 var files = dir.listSync();
154 var readmes = files.where((FileSystemEntity each) => (each is File &&
155 each.path.substring(packageDir.length + 1, each.path.length)
156 .startsWith('README'))).toList();
157 if (readmes.isEmpty) return '';
158 // If there are multiples, pick the shortest name.
159 readmes.sort((a, b) => a.length.compareTo(b.length));
160 var readme = readmes.first;
161 var contents = markdown.markdownToHtml(readme
162 .readAsStringSync(), linkResolver: linkResolver,
163 inlineSyntaxes: markdownSyntaxes);
164 return contents;
165 }
166
167
144 List<String> _listLibraries(List<String> args) { 168 List<String> _listLibraries(List<String> args) {
145 var libraries = new List<String>(); 169 var libraries = new List<String>();
146 for (var arg in args) { 170 for (var arg in args) {
147 var type = FileSystemEntity.typeSync(arg); 171 var type = FileSystemEntity.typeSync(arg);
148 172
149 if (type == FileSystemEntityType.FILE) { 173 if (type == FileSystemEntityType.FILE) {
150 if (arg.endsWith('.dart')) { 174 if (arg.endsWith('.dart')) {
151 libraries.add(path.absolute(arg)); 175 libraries.add(path.absolute(arg));
152 logger.info('Added to libraries: ${libraries.last}'); 176 logger.info('Added to libraries: ${libraries.last}');
153 } 177 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 /** 292 /**
269 * Creates documentation for filtered libraries. 293 * Creates documentation for filtered libraries.
270 */ 294 */
271 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false, 295 void _documentLibraries(List<LibraryMirror> libs, {bool includeSdk: false,
272 bool outputToYaml: true, bool append: false, bool parseSdk: false, 296 bool outputToYaml: true, bool append: false, bool parseSdk: false,
273 String introduction: ''}) { 297 String introduction: ''}) {
274 libs.forEach((lib) { 298 libs.forEach((lib) {
275 // Files belonging to the SDK have a uri that begins with 'dart:'. 299 // Files belonging to the SDK have a uri that begins with 'dart:'.
276 if (includeSdk || !lib.uri.toString().startsWith('dart:')) { 300 if (includeSdk || !lib.uri.toString().startsWith('dart:')) {
277 var library = generateLibrary(lib); 301 var library = generateLibrary(lib);
278 entityMap[library.qualifiedName] = library; 302 entityMap[library.name] = library;
279 } 303 }
280 }); 304 });
281 // After everything is created, do a pass through all classes to make sure no 305 // After everything is created, do a pass through all classes to make sure no
282 // intermediate classes created by mixins are included. 306 // intermediate classes created by mixins are included.
283 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid()); 307 entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid());
284 // Everything is a subclass of Object, therefore empty the list to avoid a 308 // Everything is a subclass of Object, therefore empty the list to avoid a
285 // giant list of subclasses to be printed out. 309 // giant list of subclasses to be printed out.
286 if (parseSdk) entityMap['dart.core.Object'].subclasses.clear(); 310 if (parseSdk) (entityMap['dart-core.Object'] as Class).subclasses.clear();
287 311
288 var filteredEntities = entityMap.values.where(_isVisible); 312 var filteredEntities = entityMap.values.where(_isVisible);
289 313
290 // Outputs a JSON file with all libraries and their preview comments. 314 // Outputs a JSON file with all libraries and their preview comments.
291 // This will help the viewer know what libraries are available to read in. 315 // This will help the viewer know what libraries are available to read in.
292 var libraryMap; 316 var libraryMap;
293 if (append) { 317 if (append) {
294 var docsDir = listDir('docs'); 318 var docsDir = listDir('docs');
295 if (!docsDir.contains('docs/library_list.json')) { 319 if (!docsDir.contains('docs/library_list.json')) {
296 throw new StateError('No library_list.json'); 320 throw new StateError('No library_list.json');
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 if (append) { 360 if (append) {
337 var previousIndex = 361 var previousIndex =
338 JSON.decode(new File('docs/index.json').readAsStringSync()); 362 JSON.decode(new File('docs/index.json').readAsStringSync());
339 index.addAll(previousIndex); 363 index.addAll(previousIndex);
340 } 364 }
341 _writeToFile(JSON.encode(index), 'index.json'); 365 _writeToFile(JSON.encode(index), 'index.json');
342 } 366 }
343 367
344 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) { 368 Library generateLibrary(dart2js.Dart2JsLibraryMirror library) {
345 _currentLibrary = library; 369 _currentLibrary = library;
346 var result = new Library(library.qualifiedName, _commentToHtml(library), 370 var result = new Library(docName(library), _commentToHtml(library),
347 _variables(library.variables), 371 _variables(library.variables),
348 _methods(library.functions), 372 _methods(library.functions),
349 _classes(library.classes), _isHidden(library)); 373 _classes(library.classes), _isHidden(library));
350 _findPackage(result, library); 374 _findPackage(result, library);
351 logger.fine('Generated library for ${result.name}'); 375 logger.fine('Generated library for ${result.name}');
352 return result; 376 return result;
353 } 377 }
354 378
355 void _writeIndexableToFile(Indexable result, bool outputToYaml) { 379 void _writeIndexableToFile(Indexable result, bool outputToYaml) {
380 var outputFile = result.fileName;
381 var output;
356 if (outputToYaml) { 382 if (outputToYaml) {
357 _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml'); 383 output = getYamlString(result.toMap());
384 outputFile = outputFile + '.yaml';
358 } else { 385 } else {
359 _writeToFile(JSON.encode(result.toMap()), '${result.qualifiedName}.json'); 386 output = JSON.encode(result.toMap());
387 outputFile = outputFile + '.json';
360 } 388 }
389 _writeToFile(output, outputFile);
361 } 390 }
362 391
363 /** 392 /**
364 * Returns true if a library name starts with an underscore, and false 393 * Returns true if a library name starts with an underscore, and false
365 * otherwise. 394 * otherwise.
366 * 395 *
367 * An example that starts with _ is _js_helper. 396 * An example that starts with _ is _js_helper.
368 * An example that contains ._ is dart._collection.dev 397 * An example that contains ._ is dart._collection.dev
369 */ 398 */
370 // This is because LibraryMirror.isPrivate returns `false` all the time. 399 // This is because LibraryMirror.isPrivate returns `false` all the time.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 List<Annotation> _annotations(DeclarationMirror mirror) { 432 List<Annotation> _annotations(DeclarationMirror mirror) {
404 var annotationMirrors = mirror.metadata.where((e) => 433 var annotationMirrors = mirror.metadata.where((e) =>
405 e is dart2js.Dart2JsConstructedConstantMirror); 434 e is dart2js.Dart2JsConstructedConstantMirror);
406 var annotations = []; 435 var annotations = [];
407 annotationMirrors.forEach((annotation) { 436 annotationMirrors.forEach((annotation) {
408 var parameterList = annotation.type.variables.values 437 var parameterList = annotation.type.variables.values
409 .where((e) => e.isFinal) 438 .where((e) => e.isFinal)
410 .map((e) => annotation.getField(e.simpleName).reflectee) 439 .map((e) => annotation.getField(e.simpleName).reflectee)
411 .where((e) => e != null) 440 .where((e) => e != null)
412 .toList(); 441 .toList();
413 if (validAnnotations.contains(annotation.type.qualifiedName)) { 442 if (validAnnotations.contains(docName(annotation.type))) {
414 annotations.add(new Annotation(annotation.type.qualifiedName, 443 annotations.add(new Annotation(docName(annotation.type),
415 parameterList)); 444 parameterList));
416 } 445 }
417 }); 446 });
418 return annotations; 447 return annotations;
419 } 448 }
420 449
421 /** 450 /**
422 * Returns any documentation comments associated with a mirror with 451 * Returns any documentation comments associated with a mirror with
423 * simple markdown converted to html. 452 * simple markdown converted to html.
424 */ 453 */
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 526
498 /** 527 /**
499 * Converts all [foo] references in comments to <a>libraryName.foo</a>. 528 * Converts all [foo] references in comments to <a>libraryName.foo</a>.
500 */ 529 */
501 markdown.Node fixReference(String name, LibraryMirror currentLibrary, 530 markdown.Node fixReference(String name, LibraryMirror currentLibrary,
502 ClassMirror currentClass, MemberMirror currentMember) { 531 ClassMirror currentClass, MemberMirror currentMember) {
503 var reference; 532 var reference;
504 var memberScope = currentMember == null ? 533 var memberScope = currentMember == null ?
505 null : currentMember.lookupInScope(name); 534 null : currentMember.lookupInScope(name);
506 if (memberScope != null) { 535 if (memberScope != null) {
507 reference = memberScope.qualifiedName; 536 reference = docName(memberScope);
508 } else { 537 } else {
509 var classScope = currentClass == null ? 538 var classScope = currentClass == null ?
510 null : currentClass.lookupInScope(name); 539 null : currentClass.lookupInScope(name);
511 if (classScope != null) { 540 if (classScope != null) {
512 reference = classScope.qualifiedName; 541 reference = docName(classScope);
513 } else { 542 } else {
514 var libraryScope = currentLibrary == null ? 543 var libraryScope = currentLibrary == null ?
515 null : currentLibrary.lookupInScope(name); 544 null : currentLibrary.lookupInScope(name);
516 reference = libraryScope != null ? libraryScope.qualifiedName : name; 545 reference = libraryScope != null ? docName(libraryScope) : name;
517 } 546 }
518 } 547 }
519 return new markdown.Element.text('a', reference); 548 return new markdown.Element.text('a', reference);
520 } 549 }
521 550
522 /** 551 /**
523 * Returns a map of [Variable] objects constructed from [mirrorMap]. 552 * Returns a map of [Variable] objects constructed from [mirrorMap].
524 */ 553 */
525 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) { 554 Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) {
526 var data = {}; 555 var data = {};
527 // TODO(janicejl): When map to map feature is created, replace the below with 556 // TODO(janicejl): When map to map feature is created, replace the below with
528 // a filter. Issue(#9590). 557 // a filter. Issue(#9590).
529 mirrorMap.forEach((String mirrorName, VariableMirror mirror) { 558 mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
530 _currentMember = mirror; 559 _currentMember = mirror;
531 if (_includePrivate || !_isHidden(mirror)) { 560 if (_includePrivate || !_isHidden(mirror)) {
532 entityMap[mirror.qualifiedName] = new Variable(mirrorName, mirror.isFinal, 561 entityMap[docName(mirror)] = new Variable(mirrorName, mirror.isFinal,
533 mirror.isStatic, mirror.isConst, _type(mirror.type), 562 mirror.isStatic, mirror.isConst, _type(mirror.type),
534 _commentToHtml(mirror), _annotations(mirror), mirror.qualifiedName, 563 _commentToHtml(mirror), _annotations(mirror), docName(mirror),
535 _isHidden(mirror), mirror.owner.qualifiedName); 564 _isHidden(mirror), docName(mirror.owner));
536 data[mirrorName] = entityMap[mirror.qualifiedName]; 565 data[mirrorName] = entityMap[docName(mirror)];
537 } 566 }
538 }); 567 });
539 return data; 568 return data;
540 } 569 }
541 570
542 /** 571 /**
543 * Returns a map of [Method] objects constructed from [mirrorMap]. 572 * Returns a map of [Method] objects constructed from [mirrorMap].
544 */ 573 */
545 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) { 574 MethodGroup _methods(Map<String, MethodMirror> mirrorMap) {
546 var group = new MethodGroup(); 575 var group = new MethodGroup();
547 mirrorMap.forEach((String mirrorName, MethodMirror mirror) { 576 mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
548 if (_includePrivate || !mirror.isPrivate) { 577 if (_includePrivate || !mirror.isPrivate) {
549 group.addMethod(mirror); 578 group.addMethod(mirror);
550 } 579 }
551 }); 580 });
552 return group; 581 return group;
553 } 582 }
554 583
555 /** 584 /**
556 * Returns the [Class] for the given [mirror] has already been created, and if 585 * Returns the [Class] for the given [mirror] has already been created, and if
557 * it does not exist, creates it. 586 * it does not exist, creates it.
558 */ 587 */
559 Class _class(ClassMirror mirror) { 588 Class _class(ClassMirror mirror) {
560 var clazz = entityMap[mirror.qualifiedName]; 589 var clazz = entityMap[docName(mirror)];
561 if (clazz == null) { 590 if (clazz == null) {
562 var superclass = mirror.superclass != null ? 591 var superclass = mirror.superclass != null ?
563 _class(mirror.superclass) : null; 592 _class(mirror.superclass) : null;
564 var interfaces = 593 var interfaces =
565 mirror.superinterfaces.map((interface) => _class(interface)); 594 mirror.superinterfaces.map((interface) => _class(interface));
566 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror), 595 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror),
567 interfaces.toList(), _variables(mirror.variables), 596 interfaces.toList(), _variables(mirror.variables),
568 _methods(mirror.methods), _annotations(mirror), _generics(mirror), 597 _methods(mirror.methods), _annotations(mirror), _generics(mirror),
569 mirror.qualifiedName, _isHidden(mirror), mirror.owner.qualifiedName, 598 docName(mirror), _isHidden(mirror), docName(mirror.owner),
570 mirror.isAbstract); 599 mirror.isAbstract);
571 if (superclass != null) clazz.addInherited(superclass); 600 if (superclass != null) clazz.addInherited(superclass);
572 interfaces.forEach((interface) => clazz.addInherited(interface)); 601 interfaces.forEach((interface) => clazz.addInherited(interface));
573 entityMap[mirror.qualifiedName] = clazz; 602 entityMap[docName(mirror)] = clazz;
574 } 603 }
575 return clazz; 604 return clazz;
576 } 605 }
577 606
578 /** 607 /**
579 * Returns a map of [Class] objects constructed from [mirrorMap]. 608 * Returns a map of [Class] objects constructed from [mirrorMap].
580 */ 609 */
581 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) { 610 ClassGroup _classes(Map<String, ClassMirror> mirrorMap) {
582 var group = new ClassGroup(); 611 var group = new ClassGroup();
583 mirrorMap.forEach((String mirrorName, ClassMirror mirror) { 612 mirrorMap.forEach((String mirrorName, ClassMirror mirror) {
(...skipping 24 matching lines...) Expand all
608 return new Map.fromIterable(mirror.typeVariables, 637 return new Map.fromIterable(mirror.typeVariables,
609 key: (e) => e.toString(), 638 key: (e) => e.toString(),
610 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName)); 639 value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName));
611 } 640 }
612 641
613 /** 642 /**
614 * Returns a single [Type] object constructed from the Method.returnType 643 * Returns a single [Type] object constructed from the Method.returnType
615 * Type mirror. 644 * Type mirror.
616 */ 645 */
617 Type _type(TypeMirror mirror) { 646 Type _type(TypeMirror mirror) {
618 return new Type(mirror.qualifiedName, _typeGenerics(mirror)); 647 return new Type(docName(mirror), _typeGenerics(mirror));
619 } 648 }
620 649
621 /** 650 /**
622 * Returns a list of [Type] objects constructed from TypeMirrors. 651 * Returns a list of [Type] objects constructed from TypeMirrors.
623 */ 652 */
624 List<Type> _typeGenerics(TypeMirror mirror) { 653 List<Type> _typeGenerics(TypeMirror mirror) {
625 if (mirror is ClassMirror && !mirror.isTypedef) { 654 if (mirror is ClassMirror && !mirror.isTypedef) {
626 var innerList = []; 655 var innerList = [];
627 mirror.typeArguments.forEach((e) { 656 mirror.typeArguments.forEach((e) {
628 innerList.add(new Type(e.qualifiedName, _typeGenerics(e))); 657 innerList.add(new Type(docName(e), _typeGenerics(e)));
629 }); 658 });
630 return innerList; 659 return innerList;
631 } 660 }
632 return []; 661 return [];
633 } 662 }
634 663
635 /** 664 /**
636 * Writes text to a file in the 'docs' directory. 665 * Writes text to a file in the 'docs' directory.
637 */ 666 */
638 void _writeToFile(String text, String filename, {bool append: false}) { 667 void _writeToFile(String text, String filename, {bool append: false}) {
639 Directory dir = new Directory('docs'); 668 Directory dir = new Directory('docs');
640 if (!dir.existsSync()) { 669 if (!dir.existsSync()) {
641 dir.createSync(); 670 dir.createSync();
642 } 671 }
672 // We assume there's a single extra level of directory structure for packages.
673 if (path.split(filename).length > 1) {
674 var subdir = new Directory(path.join('docs', path.dirname(filename)));
675 if (!subdir.existsSync()) {
676 subdir.createSync();
677 }
678 }
679
643 File file = new File('docs/$filename'); 680 File file = new File('docs/$filename');
644 if (!file.existsSync()) { 681 if (!file.existsSync()) {
645 file.createSync(); 682 file.createSync();
646 } 683 }
647 file.writeAsStringSync(text, mode: append ? FileMode.APPEND : FileMode.WRITE); 684 file.writeAsStringSync(text, mode: append ? FileMode.APPEND : FileMode.WRITE);
648 } 685 }
649 686
650 /** 687 /**
651 * Transforms the map by calling toMap on each value in it. 688 * Transforms the map by calling toMap on each value in it.
652 */ 689 */
653 Map recurseMap(Map inputMap) { 690 Map recurseMap(Map inputMap) {
654 var outputMap = {}; 691 var outputMap = {};
655 inputMap.forEach((key, value) { 692 inputMap.forEach((key, value) {
656 if (value is Map) { 693 if (value is Map) {
657 outputMap[key] = recurseMap(value); 694 outputMap[key] = recurseMap(value);
658 } else { 695 } else {
659 outputMap[key] = value.toMap(); 696 outputMap[key] = value.toMap();
660 } 697 }
661 }); 698 });
662 return outputMap; 699 return outputMap;
663 } 700 }
664 701
665 /** 702 /**
666 * A class representing all programming constructs, like library or class. 703 * A class representing all programming constructs, like library or class.
667 */ 704 */
668 class Indexable { 705 class Indexable {
669 String name; 706 String name;
670 String qualifiedName; 707 String get qualifiedName => fileName;
671 bool isPrivate; 708 bool isPrivate;
672 709
710 // The qualified name (for URL purposes) and the file name are the same,
711 // of the form packageName/ClassName or packageName/ClassName.methodName.
712 // This defines both the URL and the directory structure.
713 String get fileName => packagePrefix + ownerPrefix + name;
714
715 Indexable get owningEntity {
716 var result = entityMap[owner];
717 return result;
718 }
719 String get ownerPrefix => owningEntity == null
720 ? (owner == null || owner.isEmpty ? '' : owner + '.')
721 : owningEntity.qualifiedName + '.';
722
723 String get packagePrefix => '';
673 /// Documentation comment with converted markdown. 724 /// Documentation comment with converted markdown.
674 String comment; 725 String comment;
675 726
676 /// Qualified Name of the owner of this Indexable Item. 727 /// Qualified Name of the owner of this Indexable Item.
677 /// For Library, owner will be ""; 728 /// For Library, owner will be "";
678 String owner; 729 String owner;
679 730
680 Indexable(this.name, this.comment, this.qualifiedName, this.isPrivate, 731 Indexable(this.name, this.comment, this.isPrivate, this.owner);
681 this.owner);
682 732
683 /// The type of this member to be used in index.txt. 733 /// The type of this member to be used in index.txt.
684 String get typeName => ''; 734 String get typeName => '';
685 735
686 /** 736 /**
687 * Creates a [Map] with this [Indexable]'s name and a preview comment. 737 * Creates a [Map] with this [Indexable]'s name and a preview comment.
688 */ 738 */
689 Map get previewMap { 739 Map get previewMap {
690 var finalMap = { 'name' : qualifiedName }; 740 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName };
691 if (comment != '') { 741 if (comment != '') {
692 var index = comment.indexOf('</p>'); 742 var index = comment.indexOf('</p>');
693 finalMap['preview'] = '${comment.substring(0, index)}</p>'; 743 finalMap['preview'] = '${comment.substring(0, index)}</p>';
694 } 744 }
695 return finalMap; 745 return finalMap;
696 } 746 }
747
748 /// Return an informative [Object.toString] for debugging.
749 String toString() => "${super.toString()}(${name.toString()})";
750
751 /// Return a map representation of this type.
752 Map toMap() {}
697 } 753 }
698 754
699 /** 755 /**
700 * A class containing contents of a Dart library. 756 * A class containing contents of a Dart library.
701 */ 757 */
702 class Library extends Indexable { 758 class Library extends Indexable {
703 759
704 /// Top-level variables in the library. 760 /// Top-level variables in the library.
705 Map<String, Variable> variables; 761 Map<String, Variable> variables;
706 762
707 /// Top-level functions in the library. 763 /// Top-level functions in the library.
708 MethodGroup functions; 764 MethodGroup functions;
709 765
710 /// Classes defined within the library 766 /// Classes defined within the library
711 ClassGroup classes; 767 ClassGroup classes;
712 768
713 String packageName = ''; 769 String packageName = '';
714 770
715 Map get previewMap => super.previewMap..['packageName'] = packageName; 771 String get packagePrefix => packageName == null || packageName.isEmpty
772 ? ''
773 : '$packageName/';
774
775 String packageIntro;
776
777 Map get previewMap {
778 var basic = super.previewMap;
779 basic['packageName'] = packageName;
780 if (packageIntro != null) {
781 basic['packageIntro'] = packageIntro;
782 }
783 return basic;
784 }
716 785
717 Library(String name, String comment, this.variables, 786 Library(String name, String comment, this.variables,
718 this.functions, this.classes, bool isPrivate) : super(name, comment, 787 this.functions, this.classes, bool isPrivate) : super(name, comment,
719 name, isPrivate, "") {} 788 isPrivate, "");
720 789
721 /// Generates a map describing the [Library] object. 790 /// Generates a map describing the [Library] object.
722 Map toMap() => { 791 Map toMap() => {
723 'name': name, 792 'name': name,
724 'qualifiedName': qualifiedName, 793 'qualifiedName': qualifiedName,
725 'comment': comment, 794 'comment': comment,
726 'variables': recurseMap(variables), 795 'variables': recurseMap(variables),
727 'functions': functions.toMap(), 796 'functions': functions.toMap(),
728 'classes': classes.toMap(), 797 'classes': classes.toMap(),
729 'packageName': packageName, 798 'packageName': packageName,
799 'packageIntro' : packageIntro
730 }; 800 };
731 801
732 String get typeName => 'library'; 802 String get typeName => 'library';
733 } 803 }
734 804
735 /** 805 /**
736 * A class containing contents of a Dart class. 806 * A class containing contents of a Dart class.
737 */ 807 */
738 class Class extends Indexable { 808 class Class extends Indexable {
739 809
(...skipping 20 matching lines...) Expand all
760 830
761 Class superclass; 831 Class superclass;
762 bool isAbstract; 832 bool isAbstract;
763 833
764 /// List of the meta annotations on the class. 834 /// List of the meta annotations on the class.
765 List<Annotation> annotations; 835 List<Annotation> annotations;
766 836
767 Class(String name, this.superclass, String comment, this.interfaces, 837 Class(String name, this.superclass, String comment, this.interfaces,
768 this.variables, this.methods, this.annotations, this.generics, 838 this.variables, this.methods, this.annotations, this.generics,
769 String qualifiedName, bool isPrivate, String owner, this.isAbstract) 839 String qualifiedName, bool isPrivate, String owner, this.isAbstract)
770 : super(name, comment, qualifiedName, isPrivate, owner) { 840 : super(name, comment, isPrivate, owner) {
771 _mdnComment(this); 841 _mdnComment(this);
772 } 842 }
773 843
774 String get typeName => 'class'; 844 String get typeName => 'class';
775 845
776 /** 846 /**
777 * Returns a list of all the parent classes. 847 * Returns a list of all the parent classes.
778 */ 848 */
779 List<Class> parent() { 849 List<Class> parent() {
780 var parent = superclass == null ? [] : [superclass]; 850 var parent = superclass == null ? [] : [superclass];
(...skipping 26 matching lines...) Expand all
807 }); 877 });
808 } else { 878 } else {
809 subclasses.add(subclass.qualifiedName); 879 subclasses.add(subclass.qualifiedName);
810 } 880 }
811 } 881 }
812 882
813 /** 883 /**
814 * Check if this [Class] is an error or exception. 884 * Check if this [Class] is an error or exception.
815 */ 885 */
816 bool isError() { 886 bool isError() {
817 if (qualifiedName == 'dart.core.Error' || 887 if (qualifiedName == 'dart-core.Error' ||
818 qualifiedName == 'dart.core.Exception') 888 qualifiedName == 'dart-core.Exception')
819 return true; 889 return true;
820 for (var interface in interfaces) { 890 for (var interface in interfaces) {
821 if (interface.isError()) return true; 891 if (interface.isError()) return true;
822 } 892 }
823 if (superclass == null) return false; 893 if (superclass == null) return false;
824 return superclass.isError(); 894 return superclass.isError();
825 } 895 }
826 896
827 /** 897 /**
828 * Check that the class exists in the owner library. 898 * Check that the class exists in the owner library.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 * classes, regular classes, typedefs, and errors. 957 * classes, regular classes, typedefs, and errors.
888 */ 958 */
889 class ClassGroup { 959 class ClassGroup {
890 Map<String, Class> classes = {}; 960 Map<String, Class> classes = {};
891 Map<String, Typedef> typedefs = {}; 961 Map<String, Typedef> typedefs = {};
892 Map<String, Class> errors = {}; 962 Map<String, Class> errors = {};
893 963
894 void addClass(ClassMirror mirror) { 964 void addClass(ClassMirror mirror) {
895 _currentClass = mirror; 965 _currentClass = mirror;
896 if (mirror.isTypedef) { 966 if (mirror.isTypedef) {
967 // This is actually a Dart2jsTypedefMirror, and it does define value,
968 // but we don't have visibility to that type.
969 var mirror = _currentClass;
897 if (_includePrivate || !mirror.isPrivate) { 970 if (_includePrivate || !mirror.isPrivate) {
898 entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName, 971 entityMap[docName(mirror)] = new Typedef(mirror.simpleName,
899 mirror.value.returnType.qualifiedName, _commentToHtml(mirror), 972 docName(mirror.value.returnType), _commentToHtml(mirror),
900 _generics(mirror), _parameters(mirror.value.parameters), 973 _generics(mirror), _parameters(mirror.value.parameters),
901 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), 974 _annotations(mirror), docName(mirror), _isHidden(mirror),
902 mirror.owner.qualifiedName); 975 docName(mirror.owner));
903 typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName]; 976 typedefs[mirror.simpleName] = entityMap[docName(mirror)];
904 } 977 }
905 } else { 978 } else {
906 var clazz = _class(mirror); 979 var clazz = _class(mirror);
907 980
908 // Adding inherited parent variables and methods. 981 // Adding inherited parent variables and methods.
909 clazz.parent().forEach((parent) { 982 clazz.parent().forEach((parent) {
910 if (_isVisible(clazz)) { 983 if (_isVisible(clazz)) {
911 parent.addSubclass(clazz); 984 parent.addSubclass(clazz);
912 } 985 }
913 }); 986 });
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 1020
948 /// Generic information about the typedef. 1021 /// Generic information about the typedef.
949 Map<String, Generic> generics; 1022 Map<String, Generic> generics;
950 1023
951 /// List of the meta annotations on the typedef. 1024 /// List of the meta annotations on the typedef.
952 List<Annotation> annotations; 1025 List<Annotation> annotations;
953 1026
954 Typedef(String name, this.returnType, String comment, this.generics, 1027 Typedef(String name, this.returnType, String comment, this.generics,
955 this.parameters, this.annotations, 1028 this.parameters, this.annotations,
956 String qualifiedName, bool isPrivate, String owner) 1029 String qualifiedName, bool isPrivate, String owner)
957 : super(name, comment, qualifiedName, isPrivate, owner); 1030 : super(name, comment, isPrivate, owner);
958 1031
959 Map toMap() => { 1032 Map toMap() => {
960 'name': name, 1033 'name': name,
961 'qualifiedName': qualifiedName, 1034 'qualifiedName': qualifiedName,
962 'comment': comment, 1035 'comment': comment,
963 'return': returnType, 1036 'return': returnType,
964 'parameters': recurseMap(parameters), 1037 'parameters': recurseMap(parameters),
965 'annotations': annotations.map((a) => a.toMap()).toList(), 1038 'annotations': annotations.map((a) => a.toMap()).toList(),
966 'generics': recurseMap(generics) 1039 'generics': recurseMap(generics)
967 }; 1040 };
968 1041
969 String get typeName => 'typedef'; 1042 String get typeName => 'typedef';
970 } 1043 }
971 1044
972 /** 1045 /**
973 * A class containing properties of a Dart variable. 1046 * A class containing properties of a Dart variable.
974 */ 1047 */
975 class Variable extends Indexable { 1048 class Variable extends Indexable {
976 1049
977 bool isFinal; 1050 bool isFinal;
978 bool isStatic; 1051 bool isStatic;
979 bool isConst; 1052 bool isConst;
980 Type type; 1053 Type type;
981 1054
982 /// List of the meta annotations on the variable. 1055 /// List of the meta annotations on the variable.
983 List<Annotation> annotations; 1056 List<Annotation> annotations;
984 1057
985 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type, 1058 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type,
986 String comment, this.annotations, String qualifiedName, bool isPrivate, 1059 String comment, this.annotations, String qualifiedName, bool isPrivate,
987 String owner) : super(name, comment, qualifiedName, isPrivate, owner) { 1060 String owner) : super(name, comment, isPrivate, owner) {
988 _mdnComment(this); 1061 _mdnComment(this);
989 } 1062 }
990 1063
991 /// Generates a map describing the [Variable] object. 1064 /// Generates a map describing the [Variable] object.
992 Map toMap() => { 1065 Map toMap() => {
993 'name': name, 1066 'name': name,
994 'qualifiedName': qualifiedName, 1067 'qualifiedName': qualifiedName,
995 'comment': comment, 1068 'comment': comment,
996 'final': isFinal.toString(), 1069 'final': isFinal.toString(),
997 'static': isStatic.toString(), 1070 'static': isStatic.toString(),
(...skipping 25 matching lines...) Expand all
1023 /// Qualified name to state where the comment is inherited from. 1096 /// Qualified name to state where the comment is inherited from.
1024 String commentInheritedFrom = ""; 1097 String commentInheritedFrom = "";
1025 1098
1026 /// List of the meta annotations on the method. 1099 /// List of the meta annotations on the method.
1027 List<Annotation> annotations; 1100 List<Annotation> annotations;
1028 1101
1029 Method(String name, this.isStatic, this.isAbstract, this.isConst, 1102 Method(String name, this.isStatic, this.isAbstract, this.isConst,
1030 this.returnType, String comment, this.parameters, this.annotations, 1103 this.returnType, String comment, this.parameters, this.annotations,
1031 String qualifiedName, bool isPrivate, String owner, this.isConstructor, 1104 String qualifiedName, bool isPrivate, String owner, this.isConstructor,
1032 this.isGetter, this.isSetter, this.isOperator) 1105 this.isGetter, this.isSetter, this.isOperator)
1033 : super(name, comment, qualifiedName, isPrivate, owner) { 1106 : super(name, comment, isPrivate, owner) {
1034 _mdnComment(this); 1107 _mdnComment(this);
1035 } 1108 }
1036 1109
1037 /** 1110 /**
1038 * Makes sure that the method with an inherited equivalent have comments. 1111 * Makes sure that the method with an inherited equivalent have comments.
1039 */ 1112 */
1040 void ensureCommentFor(Method inheritedMethod) { 1113 void ensureCommentFor(Method inheritedMethod) {
1041 if (comment.isNotEmpty) return; 1114 if (comment.isNotEmpty) return;
1042 entityMap[inheritedMethod.owner].ensureComments(); 1115 (entityMap[inheritedMethod.owner] as Class).ensureComments();
1043 comment = inheritedMethod.comment; 1116 comment = inheritedMethod.comment;
1044 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? 1117 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ?
1045 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; 1118 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom;
1046 } 1119 }
1047 1120
1048 /// Generates a map describing the [Method] object. 1121 /// Generates a map describing the [Method] object.
1049 Map toMap() => { 1122 Map toMap() => {
1050 'name': name, 1123 'name': name,
1051 'qualifiedName': qualifiedName, 1124 'qualifiedName': qualifiedName,
1052 'comment': comment, 1125 'comment': comment,
(...skipping 19 matching lines...) Expand all
1072 Map<String, Method> setters = {}; 1145 Map<String, Method> setters = {};
1073 Map<String, Method> getters = {}; 1146 Map<String, Method> getters = {};
1074 Map<String, Method> constructors = {}; 1147 Map<String, Method> constructors = {};
1075 Map<String, Method> operators = {}; 1148 Map<String, Method> operators = {};
1076 Map<String, Method> regularMethods = {}; 1149 Map<String, Method> regularMethods = {};
1077 1150
1078 void addMethod(MethodMirror mirror) { 1151 void addMethod(MethodMirror mirror) {
1079 var method = new Method(mirror.simpleName, mirror.isStatic, 1152 var method = new Method(mirror.simpleName, mirror.isStatic,
1080 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType), 1153 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType),
1081 _commentToHtml(mirror), _parameters(mirror.parameters), 1154 _commentToHtml(mirror), _parameters(mirror.parameters),
1082 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), 1155 _annotations(mirror), docName(mirror), _isHidden(mirror),
1083 mirror.owner.qualifiedName, mirror.isConstructor, mirror.isGetter, 1156 docName(mirror.owner), mirror.isConstructor, mirror.isGetter,
1084 mirror.isSetter, mirror.isOperator); 1157 mirror.isSetter, mirror.isOperator);
1085 entityMap[mirror.qualifiedName] = method; 1158 entityMap[docName(mirror)] = method;
1086 _currentMember = mirror; 1159 _currentMember = mirror;
1087 if (mirror.isSetter) { 1160 if (mirror.isSetter) {
1088 setters[mirror.simpleName] = method; 1161 setters[mirror.simpleName] = method;
1089 } else if (mirror.isGetter) { 1162 } else if (mirror.isGetter) {
1090 getters[mirror.simpleName] = method; 1163 getters[mirror.simpleName] = method;
1091 } else if (mirror.isConstructor) { 1164 } else if (mirror.isConstructor) {
1092 constructors[mirror.simpleName] = method; 1165 constructors[mirror.simpleName] = method;
1093 } else if (mirror.isOperator) { 1166 } else if (mirror.isOperator) {
1094 operators[mirror.simpleName] = method; 1167 operators[mirror.simpleName] = method;
1095 } else if (mirror.isRegularMethod) { 1168 } else if (mirror.isRegularMethod) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 1256
1184 /** 1257 /**
1185 * Holds the name of a return type, and its generic type parameters. 1258 * Holds the name of a return type, and its generic type parameters.
1186 * 1259 *
1187 * Return types are of a form [outer]<[inner]>. 1260 * Return types are of a form [outer]<[inner]>.
1188 * If there is no [inner] part, [inner] will be an empty list. 1261 * If there is no [inner] part, [inner] will be an empty list.
1189 * 1262 *
1190 * For example: 1263 * For example:
1191 * int size() 1264 * int size()
1192 * "return" : 1265 * "return" :
1193 * - "outer" : "dart.core.int" 1266 * - "outer" : "dart-core.int"
1194 * "inner" : 1267 * "inner" :
1195 * 1268 *
1196 * List<String> toList() 1269 * List<String> toList()
1197 * "return" : 1270 * "return" :
1198 * - "outer" : "dart.core.List" 1271 * - "outer" : "dart-core.List"
1199 * "inner" : 1272 * "inner" :
1200 * - "outer" : "dart.core.String" 1273 * - "outer" : "dart-core.String"
1201 * "inner" : 1274 * "inner" :
1202 * 1275 *
1203 * Map<String, List<int>> 1276 * Map<String, List<int>>
1204 * "return" : 1277 * "return" :
1205 * - "outer" : "dart.core.Map" 1278 * - "outer" : "dart-core.Map"
1206 * "inner" : 1279 * "inner" :
1207 * - "outer" : "dart.core.String" 1280 * - "outer" : "dart-core.String"
1208 * "inner" : 1281 * "inner" :
1209 * - "outer" : "dart.core.List" 1282 * - "outer" : "dart-core.List"
1210 * "inner" : 1283 * "inner" :
1211 * - "outer" : "dart.core.int" 1284 * - "outer" : "dart-core.int"
1212 * "inner" : 1285 * "inner" :
1213 */ 1286 */
1214 class Type { 1287 class Type {
1215 String outer; 1288 String outer;
1216 List<Type> inner; 1289 List<Type> inner;
1217 1290
1218 Type(this.outer, this.inner); 1291 Type(this.outer, this.inner);
1219 1292
1220 Map toMap() => { 1293 Map toMap() => {
1221 'outer': outer, 1294 'outer': outer,
1222 'inner': inner.map((e) => e.toMap()).toList() 1295 'inner': inner.map((e) => e.toMap()).toList()
1223 }; 1296 };
1224 } 1297 }
1225 1298
1226 /** 1299 /**
1227 * Holds the name of the annotation, and its parameters. 1300 * Holds the name of the annotation, and its parameters.
1228 */ 1301 */
1229 class Annotation { 1302 class Annotation {
1230 String qualifiedName; 1303 String qualifiedName;
1231 List<String> parameters; 1304 List<String> parameters;
1232 1305
1233 Annotation(this.qualifiedName, this.parameters); 1306 Annotation(this.qualifiedName, this.parameters);
1234 1307
1235 Map toMap() => { 1308 Map toMap() => {
1236 'name': qualifiedName, 1309 'name': qualifiedName,
1237 'parameters': parameters 1310 'parameters': parameters
1238 }; 1311 };
1239 } 1312 }
1313
1314 /// Given a mirror, returns its qualified name, but following the conventions
1315 /// we're using in Dartdoc, which is that library names with dots in them
1316 /// have them replaced with hyphens.
1317 String docName(DeclarationMirror m) {
1318 if (m is LibraryMirror) {
1319 return (m as LibraryMirror).qualifiedName.replaceAll('.','-');
1320 }
1321 var owner = m.owner;
1322 if (owner == null) return m.qualifiedName;
1323 // For the unnamed constructor we just return the class name.
1324 if (m.simpleName == '') return docName(owner);
1325 return docName(owner) + '.' + m.simpleName;
1326 }
OLDNEW
« no previous file with comments | « pkg/docgen/bin/upload_docgen.py ('k') | pkg/docgen/lib/dottedLibraryName.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698