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

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: Also make the upload script upload the additional data 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
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) =>
155 (each is File && each.path.substring(packageDir.length + 1, each.path.leng th)
terry 2013/10/30 18:11:31 > 80
Alan Knight 2013/10/30 18:31:33 Done.
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));
terry 2013/10/30 18:11:31 Nice using sort.
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();
terry 2013/10/30 18:11:31 Is there a reason we can't use the name we see in
Alan Knight 2013/10/30 18:31:33 That is the name in the JSON files now, we're usin
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 String toString() => super.toString() + '(' + name.toString() + ')';
terry 2013/10/30 18:11:31 String toString() => '${super.toString()}($name)'
Alan Knight 2013/10/30 18:31:33 Done.
749
750 // Return a map representation of this type.
751 Map toMap() {}
697 } 752 }
698 753
699 /** 754 /**
700 * A class containing contents of a Dart library. 755 * A class containing contents of a Dart library.
701 */ 756 */
702 class Library extends Indexable { 757 class Library extends Indexable {
703 758
704 /// Top-level variables in the library. 759 /// Top-level variables in the library.
705 Map<String, Variable> variables; 760 Map<String, Variable> variables;
706 761
707 /// Top-level functions in the library. 762 /// Top-level functions in the library.
708 MethodGroup functions; 763 MethodGroup functions;
709 764
710 /// Classes defined within the library 765 /// Classes defined within the library
711 ClassGroup classes; 766 ClassGroup classes;
712 767
713 String packageName = ''; 768 String packageName = '';
714 769
715 Map get previewMap => super.previewMap..['packageName'] = packageName; 770 String get packagePrefix => packageName == null || packageName.isEmpty
771 ? ''
772 : packageName + '/';
terry 2013/10/30 18:11:31 '$packageName/';
Alan Knight 2013/10/30 18:31:33 Done.
773
774 String packageIntro;
775
776 Map get previewMap {
777 var basic = super.previewMap;
778 basic['packageName'] = packageName;
779 if (packageIntro != null) {
780 basic['packageIntro'] = packageIntro;
781 }
782 return basic;
783 }
716 784
717 Library(String name, String comment, this.variables, 785 Library(String name, String comment, this.variables,
718 this.functions, this.classes, bool isPrivate) : super(name, comment, 786 this.functions, this.classes, bool isPrivate) : super(name, comment,
719 name, isPrivate, "") {} 787 isPrivate, "");
720 788
721 /// Generates a map describing the [Library] object. 789 /// Generates a map describing the [Library] object.
722 Map toMap() => { 790 Map toMap() => {
723 'name': name, 791 'name': name,
724 'qualifiedName': qualifiedName, 792 'qualifiedName': qualifiedName,
725 'comment': comment, 793 'comment': comment,
726 'variables': recurseMap(variables), 794 'variables': recurseMap(variables),
727 'functions': functions.toMap(), 795 'functions': functions.toMap(),
728 'classes': classes.toMap(), 796 'classes': classes.toMap(),
729 'packageName': packageName, 797 'packageName': packageName,
798 'packageIntro' : packageIntro
730 }; 799 };
731 800
732 String get typeName => 'library'; 801 String get typeName => 'library';
733 } 802 }
734 803
735 /** 804 /**
736 * A class containing contents of a Dart class. 805 * A class containing contents of a Dart class.
737 */ 806 */
738 class Class extends Indexable { 807 class Class extends Indexable {
739 808
(...skipping 20 matching lines...) Expand all
760 829
761 Class superclass; 830 Class superclass;
762 bool isAbstract; 831 bool isAbstract;
763 832
764 /// List of the meta annotations on the class. 833 /// List of the meta annotations on the class.
765 List<Annotation> annotations; 834 List<Annotation> annotations;
766 835
767 Class(String name, this.superclass, String comment, this.interfaces, 836 Class(String name, this.superclass, String comment, this.interfaces,
768 this.variables, this.methods, this.annotations, this.generics, 837 this.variables, this.methods, this.annotations, this.generics,
769 String qualifiedName, bool isPrivate, String owner, this.isAbstract) 838 String qualifiedName, bool isPrivate, String owner, this.isAbstract)
770 : super(name, comment, qualifiedName, isPrivate, owner) { 839 : super(name, comment, isPrivate, owner) {
771 _mdnComment(this); 840 _mdnComment(this);
772 } 841 }
773 842
774 String get typeName => 'class'; 843 String get typeName => 'class';
775 844
776 /** 845 /**
777 * Returns a list of all the parent classes. 846 * Returns a list of all the parent classes.
778 */ 847 */
779 List<Class> parent() { 848 List<Class> parent() {
780 var parent = superclass == null ? [] : [superclass]; 849 var parent = superclass == null ? [] : [superclass];
(...skipping 26 matching lines...) Expand all
807 }); 876 });
808 } else { 877 } else {
809 subclasses.add(subclass.qualifiedName); 878 subclasses.add(subclass.qualifiedName);
810 } 879 }
811 } 880 }
812 881
813 /** 882 /**
814 * Check if this [Class] is an error or exception. 883 * Check if this [Class] is an error or exception.
815 */ 884 */
816 bool isError() { 885 bool isError() {
817 if (qualifiedName == 'dart.core.Error' || 886 if (qualifiedName == 'dart-core.Error' ||
818 qualifiedName == 'dart.core.Exception') 887 qualifiedName == 'dart-core.Exception')
819 return true; 888 return true;
820 for (var interface in interfaces) { 889 for (var interface in interfaces) {
821 if (interface.isError()) return true; 890 if (interface.isError()) return true;
822 } 891 }
823 if (superclass == null) return false; 892 if (superclass == null) return false;
824 return superclass.isError(); 893 return superclass.isError();
825 } 894 }
826 895
827 /** 896 /**
828 * Check that the class exists in the owner library. 897 * 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. 956 * classes, regular classes, typedefs, and errors.
888 */ 957 */
889 class ClassGroup { 958 class ClassGroup {
890 Map<String, Class> classes = {}; 959 Map<String, Class> classes = {};
891 Map<String, Typedef> typedefs = {}; 960 Map<String, Typedef> typedefs = {};
892 Map<String, Class> errors = {}; 961 Map<String, Class> errors = {};
893 962
894 void addClass(ClassMirror mirror) { 963 void addClass(ClassMirror mirror) {
895 _currentClass = mirror; 964 _currentClass = mirror;
896 if (mirror.isTypedef) { 965 if (mirror.isTypedef) {
966 // This is actually a Dart2jsTypedefMirror, and it does define value,
967 // but we don't have visibility to that type.
968 var mirror = _currentClass;
897 if (_includePrivate || !mirror.isPrivate) { 969 if (_includePrivate || !mirror.isPrivate) {
898 entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName, 970 entityMap[docName(mirror)] = new Typedef(mirror.simpleName,
899 mirror.value.returnType.qualifiedName, _commentToHtml(mirror), 971 docName(mirror.value.returnType), _commentToHtml(mirror),
900 _generics(mirror), _parameters(mirror.value.parameters), 972 _generics(mirror), _parameters(mirror.value.parameters),
901 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), 973 _annotations(mirror), docName(mirror), _isHidden(mirror),
902 mirror.owner.qualifiedName); 974 docName(mirror.owner));
903 typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName]; 975 typedefs[mirror.simpleName] = entityMap[docName(mirror)];
904 } 976 }
905 } else { 977 } else {
906 var clazz = _class(mirror); 978 var clazz = _class(mirror);
907 979
908 // Adding inherited parent variables and methods. 980 // Adding inherited parent variables and methods.
909 clazz.parent().forEach((parent) { 981 clazz.parent().forEach((parent) {
910 if (_isVisible(clazz)) { 982 if (_isVisible(clazz)) {
911 parent.addSubclass(clazz); 983 parent.addSubclass(clazz);
912 } 984 }
913 }); 985 });
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 1019
948 /// Generic information about the typedef. 1020 /// Generic information about the typedef.
949 Map<String, Generic> generics; 1021 Map<String, Generic> generics;
950 1022
951 /// List of the meta annotations on the typedef. 1023 /// List of the meta annotations on the typedef.
952 List<Annotation> annotations; 1024 List<Annotation> annotations;
953 1025
954 Typedef(String name, this.returnType, String comment, this.generics, 1026 Typedef(String name, this.returnType, String comment, this.generics,
955 this.parameters, this.annotations, 1027 this.parameters, this.annotations,
956 String qualifiedName, bool isPrivate, String owner) 1028 String qualifiedName, bool isPrivate, String owner)
957 : super(name, comment, qualifiedName, isPrivate, owner); 1029 : super(name, comment, isPrivate, owner);
958 1030
959 Map toMap() => { 1031 Map toMap() => {
960 'name': name, 1032 'name': name,
961 'qualifiedName': qualifiedName, 1033 'qualifiedName': qualifiedName,
962 'comment': comment, 1034 'comment': comment,
963 'return': returnType, 1035 'return': returnType,
964 'parameters': recurseMap(parameters), 1036 'parameters': recurseMap(parameters),
965 'annotations': annotations.map((a) => a.toMap()).toList(), 1037 'annotations': annotations.map((a) => a.toMap()).toList(),
966 'generics': recurseMap(generics) 1038 'generics': recurseMap(generics)
967 }; 1039 };
968 1040
969 String get typeName => 'typedef'; 1041 String get typeName => 'typedef';
970 } 1042 }
971 1043
972 /** 1044 /**
973 * A class containing properties of a Dart variable. 1045 * A class containing properties of a Dart variable.
974 */ 1046 */
975 class Variable extends Indexable { 1047 class Variable extends Indexable {
976 1048
977 bool isFinal; 1049 bool isFinal;
978 bool isStatic; 1050 bool isStatic;
979 bool isConst; 1051 bool isConst;
980 Type type; 1052 Type type;
981 1053
982 /// List of the meta annotations on the variable. 1054 /// List of the meta annotations on the variable.
983 List<Annotation> annotations; 1055 List<Annotation> annotations;
984 1056
985 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type, 1057 Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type,
986 String comment, this.annotations, String qualifiedName, bool isPrivate, 1058 String comment, this.annotations, String qualifiedName, bool isPrivate,
987 String owner) : super(name, comment, qualifiedName, isPrivate, owner) { 1059 String owner) : super(name, comment, isPrivate, owner) {
988 _mdnComment(this); 1060 _mdnComment(this);
989 } 1061 }
990 1062
991 /// Generates a map describing the [Variable] object. 1063 /// Generates a map describing the [Variable] object.
992 Map toMap() => { 1064 Map toMap() => {
993 'name': name, 1065 'name': name,
994 'qualifiedName': qualifiedName, 1066 'qualifiedName': qualifiedName,
995 'comment': comment, 1067 'comment': comment,
996 'final': isFinal.toString(), 1068 'final': isFinal.toString(),
997 'static': isStatic.toString(), 1069 'static': isStatic.toString(),
(...skipping 25 matching lines...) Expand all
1023 /// Qualified name to state where the comment is inherited from. 1095 /// Qualified name to state where the comment is inherited from.
1024 String commentInheritedFrom = ""; 1096 String commentInheritedFrom = "";
1025 1097
1026 /// List of the meta annotations on the method. 1098 /// List of the meta annotations on the method.
1027 List<Annotation> annotations; 1099 List<Annotation> annotations;
1028 1100
1029 Method(String name, this.isStatic, this.isAbstract, this.isConst, 1101 Method(String name, this.isStatic, this.isAbstract, this.isConst,
1030 this.returnType, String comment, this.parameters, this.annotations, 1102 this.returnType, String comment, this.parameters, this.annotations,
1031 String qualifiedName, bool isPrivate, String owner, this.isConstructor, 1103 String qualifiedName, bool isPrivate, String owner, this.isConstructor,
1032 this.isGetter, this.isSetter, this.isOperator) 1104 this.isGetter, this.isSetter, this.isOperator)
1033 : super(name, comment, qualifiedName, isPrivate, owner) { 1105 : super(name, comment, isPrivate, owner) {
1034 _mdnComment(this); 1106 _mdnComment(this);
1035 } 1107 }
1036 1108
1037 /** 1109 /**
1038 * Makes sure that the method with an inherited equivalent have comments. 1110 * Makes sure that the method with an inherited equivalent have comments.
1039 */ 1111 */
1040 void ensureCommentFor(Method inheritedMethod) { 1112 void ensureCommentFor(Method inheritedMethod) {
1041 if (comment.isNotEmpty) return; 1113 if (comment.isNotEmpty) return;
1042 entityMap[inheritedMethod.owner].ensureComments(); 1114 (entityMap[inheritedMethod.owner] as Class).ensureComments();
1043 comment = inheritedMethod.comment; 1115 comment = inheritedMethod.comment;
1044 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ? 1116 commentInheritedFrom = inheritedMethod.commentInheritedFrom == '' ?
1045 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom; 1117 inheritedMethod.qualifiedName : inheritedMethod.commentInheritedFrom;
1046 } 1118 }
1047 1119
1048 /// Generates a map describing the [Method] object. 1120 /// Generates a map describing the [Method] object.
1049 Map toMap() => { 1121 Map toMap() => {
1050 'name': name, 1122 'name': name,
1051 'qualifiedName': qualifiedName, 1123 'qualifiedName': qualifiedName,
1052 'comment': comment, 1124 'comment': comment,
(...skipping 19 matching lines...) Expand all
1072 Map<String, Method> setters = {}; 1144 Map<String, Method> setters = {};
1073 Map<String, Method> getters = {}; 1145 Map<String, Method> getters = {};
1074 Map<String, Method> constructors = {}; 1146 Map<String, Method> constructors = {};
1075 Map<String, Method> operators = {}; 1147 Map<String, Method> operators = {};
1076 Map<String, Method> regularMethods = {}; 1148 Map<String, Method> regularMethods = {};
1077 1149
1078 void addMethod(MethodMirror mirror) { 1150 void addMethod(MethodMirror mirror) {
1079 var method = new Method(mirror.simpleName, mirror.isStatic, 1151 var method = new Method(mirror.simpleName, mirror.isStatic,
1080 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType), 1152 mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType),
1081 _commentToHtml(mirror), _parameters(mirror.parameters), 1153 _commentToHtml(mirror), _parameters(mirror.parameters),
1082 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), 1154 _annotations(mirror), docName(mirror), _isHidden(mirror),
1083 mirror.owner.qualifiedName, mirror.isConstructor, mirror.isGetter, 1155 docName(mirror.owner), mirror.isConstructor, mirror.isGetter,
1084 mirror.isSetter, mirror.isOperator); 1156 mirror.isSetter, mirror.isOperator);
1085 entityMap[mirror.qualifiedName] = method; 1157 entityMap[docName(mirror)] = method;
1086 _currentMember = mirror; 1158 _currentMember = mirror;
1087 if (mirror.isSetter) { 1159 if (mirror.isSetter) {
1088 setters[mirror.simpleName] = method; 1160 setters[mirror.simpleName] = method;
1089 } else if (mirror.isGetter) { 1161 } else if (mirror.isGetter) {
1090 getters[mirror.simpleName] = method; 1162 getters[mirror.simpleName] = method;
1091 } else if (mirror.isConstructor) { 1163 } else if (mirror.isConstructor) {
1092 constructors[mirror.simpleName] = method; 1164 constructors[mirror.simpleName] = method;
1093 } else if (mirror.isOperator) { 1165 } else if (mirror.isOperator) {
1094 operators[mirror.simpleName] = method; 1166 operators[mirror.simpleName] = method;
1095 } else if (mirror.isRegularMethod) { 1167 } else if (mirror.isRegularMethod) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 1255
1184 /** 1256 /**
1185 * Holds the name of a return type, and its generic type parameters. 1257 * Holds the name of a return type, and its generic type parameters.
1186 * 1258 *
1187 * Return types are of a form [outer]<[inner]>. 1259 * Return types are of a form [outer]<[inner]>.
1188 * If there is no [inner] part, [inner] will be an empty list. 1260 * If there is no [inner] part, [inner] will be an empty list.
1189 * 1261 *
1190 * For example: 1262 * For example:
1191 * int size() 1263 * int size()
1192 * "return" : 1264 * "return" :
1193 * - "outer" : "dart.core.int" 1265 * - "outer" : "dart-core.int"
1194 * "inner" : 1266 * "inner" :
1195 * 1267 *
1196 * List<String> toList() 1268 * List<String> toList()
1197 * "return" : 1269 * "return" :
1198 * - "outer" : "dart.core.List" 1270 * - "outer" : "dart-core.List"
1199 * "inner" : 1271 * "inner" :
1200 * - "outer" : "dart.core.String" 1272 * - "outer" : "dart-core.String"
1201 * "inner" : 1273 * "inner" :
1202 * 1274 *
1203 * Map<String, List<int>> 1275 * Map<String, List<int>>
1204 * "return" : 1276 * "return" :
1205 * - "outer" : "dart.core.Map" 1277 * - "outer" : "dart-core.Map"
1206 * "inner" : 1278 * "inner" :
1207 * - "outer" : "dart.core.String" 1279 * - "outer" : "dart-core.String"
1208 * "inner" : 1280 * "inner" :
1209 * - "outer" : "dart.core.List" 1281 * - "outer" : "dart-core.List"
1210 * "inner" : 1282 * "inner" :
1211 * - "outer" : "dart.core.int" 1283 * - "outer" : "dart-core.int"
1212 * "inner" : 1284 * "inner" :
1213 */ 1285 */
1214 class Type { 1286 class Type {
1215 String outer; 1287 String outer;
1216 List<Type> inner; 1288 List<Type> inner;
1217 1289
1218 Type(this.outer, this.inner); 1290 Type(this.outer, this.inner);
1219 1291
1220 Map toMap() => { 1292 Map toMap() => {
1221 'outer': outer, 1293 'outer': outer,
1222 'inner': inner.map((e) => e.toMap()).toList() 1294 'inner': inner.map((e) => e.toMap()).toList()
1223 }; 1295 };
1224 } 1296 }
1225 1297
1226 /** 1298 /**
1227 * Holds the name of the annotation, and its parameters. 1299 * Holds the name of the annotation, and its parameters.
1228 */ 1300 */
1229 class Annotation { 1301 class Annotation {
1230 String qualifiedName; 1302 String qualifiedName;
1231 List<String> parameters; 1303 List<String> parameters;
1232 1304
1233 Annotation(this.qualifiedName, this.parameters); 1305 Annotation(this.qualifiedName, this.parameters);
1234 1306
1235 Map toMap() => { 1307 Map toMap() => {
1236 'name': qualifiedName, 1308 'name': qualifiedName,
1237 'parameters': parameters 1309 'parameters': parameters
1238 }; 1310 };
1239 } 1311 }
1312
1313 /// Given a mirror, returns its qualified name, but following the conventions
terry 2013/10/30 18:11:31 Is this an internal representation that isn't expo
Alan Knight 2013/10/30 18:31:33 This is what goes into the JSON now, and it's expo
1314 /// we're using in Dartdoc, which is that library names with dots in them
1315 /// have them replaced with hyphens.
1316 String docName(DeclarationMirror m) {
1317 if (m is LibraryMirror) {
1318 return (m as LibraryMirror).qualifiedName.replaceAll('.','-');
1319 }
1320 var owner = m.owner;
1321 if (owner == null) return m.qualifiedName;
1322 // For the unnamed constructor we just return the class name.
1323 if (m.simpleName == '') return docName(owner);
1324 return docName(owner) + '.' + m.simpleName;
1325 }
OLDNEW
« pkg/docgen/bin/upload_docgen.py ('K') | « pkg/docgen/bin/upload_docgen.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698