| OLD | NEW |
| 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 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 Class _class(ClassMirror mirror) { | 395 Class _class(ClassMirror mirror) { |
| 396 var clazz = entityMap[mirror.qualifiedName]; | 396 var clazz = entityMap[mirror.qualifiedName]; |
| 397 if (clazz == null) { | 397 if (clazz == null) { |
| 398 var superclass = mirror.superclass != null ? | 398 var superclass = mirror.superclass != null ? |
| 399 _class(mirror.superclass) : null; | 399 _class(mirror.superclass) : null; |
| 400 var interfaces = | 400 var interfaces = |
| 401 mirror.superinterfaces.map((interface) => _class(interface)); | 401 mirror.superinterfaces.map((interface) => _class(interface)); |
| 402 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror), | 402 clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror), |
| 403 interfaces.toList(), _variables(mirror.variables), | 403 interfaces.toList(), _variables(mirror.variables), |
| 404 _methods(mirror.methods), _annotations(mirror), _generics(mirror), | 404 _methods(mirror.methods), _annotations(mirror), _generics(mirror), |
| 405 mirror.qualifiedName, _isHidden(mirror), mirror.owner.qualifiedName, | 405 mirror.qualifiedName, _isHidden(mirror), mirror.owner.qualifiedName); |
| 406 mirror.isAbstract); | |
| 407 if (superclass != null) | 406 if (superclass != null) |
| 408 clazz.addInherited(superclass); | 407 clazz.addInherited(superclass); |
| 409 interfaces.forEach((interface) { | 408 interfaces.forEach((interface) { |
| 410 clazz.addInherited(interface); | 409 clazz.addInherited(interface); |
| 411 }); | 410 }); |
| 412 entityMap[mirror.qualifiedName] = clazz; | 411 entityMap[mirror.qualifiedName] = clazz; |
| 413 } | 412 } |
| 414 return clazz; | 413 return clazz; |
| 415 } | 414 } |
| 416 | 415 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 inputMap.forEach((key, value) { | 493 inputMap.forEach((key, value) { |
| 495 if (value is Map) { | 494 if (value is Map) { |
| 496 outputMap[key] = recurseMap(value); | 495 outputMap[key] = recurseMap(value); |
| 497 } else { | 496 } else { |
| 498 outputMap[key] = value.toMap(); | 497 outputMap[key] = value.toMap(); |
| 499 } | 498 } |
| 500 }); | 499 }); |
| 501 return outputMap; | 500 return outputMap; |
| 502 } | 501 } |
| 503 | 502 |
| 503 bool isError(String qualifiedName) { |
| 504 return qualifiedName.toLowerCase().contains('error') || |
| 505 qualifiedName.toLowerCase().contains('exception'); |
| 506 } |
| 507 |
| 504 /** | 508 /** |
| 505 * A class representing all programming constructs, like library or class. | 509 * A class representing all programming constructs, like library or class. |
| 506 */ | 510 */ |
| 507 class Indexable { | 511 class Indexable { |
| 508 String name; | 512 String name; |
| 509 String qualifiedName; | 513 String qualifiedName; |
| 510 bool isPrivate; | 514 bool isPrivate; |
| 511 | 515 |
| 512 /// Documentation comment with converted markdown. | 516 /// Documentation comment with converted markdown. |
| 513 String comment; | 517 String comment; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 /// Methods in the class. | 573 /// Methods in the class. |
| 570 MethodGroup methods; | 574 MethodGroup methods; |
| 571 | 575 |
| 572 /// Inherited methods in the class. | 576 /// Inherited methods in the class. |
| 573 MethodGroup inheritedMethods = new MethodGroup(); | 577 MethodGroup inheritedMethods = new MethodGroup(); |
| 574 | 578 |
| 575 /// Generic infomation about the class. | 579 /// Generic infomation about the class. |
| 576 Map<String, Generic> generics; | 580 Map<String, Generic> generics; |
| 577 | 581 |
| 578 Class superclass; | 582 Class superclass; |
| 579 bool isAbstract; | |
| 580 | 583 |
| 581 /// List of the meta annotations on the class. | 584 /// List of the meta annotations on the class. |
| 582 List<String> annotations; | 585 List<String> annotations; |
| 583 | 586 |
| 584 Class(String name, this.superclass, String comment, this.interfaces, | 587 Class(String name, this.superclass, String comment, this.interfaces, |
| 585 this.variables, this.methods, this.annotations, this.generics, | 588 this.variables, this.methods, this.annotations, this.generics, |
| 586 String qualifiedName, bool isPrivate, String owner, this.isAbstract) | 589 String qualifiedName, bool isPrivate, String owner) : super(name, comment, |
| 587 : super(name, comment, qualifiedName, isPrivate, owner); | 590 qualifiedName, isPrivate, owner) {} |
| 588 | 591 |
| 589 /** | 592 /** |
| 590 * Returns a list of all the parent classes. | 593 * Returns a list of all the parent classes. |
| 591 */ | 594 */ |
| 592 List<Class> parent() { | 595 List<Class> parent() { |
| 593 var parent = superclass == null ? [] : [superclass]; | 596 var parent = superclass == null ? [] : [superclass]; |
| 594 parent.addAll(interfaces); | 597 parent.addAll(interfaces); |
| 595 return parent; | 598 return parent; |
| 596 } | 599 } |
| 597 | 600 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 617 void addSubclass(Class subclass) { | 620 void addSubclass(Class subclass) { |
| 618 if (!_includePrivate && isPrivate) { | 621 if (!_includePrivate && isPrivate) { |
| 619 if (superclass != null) superclass.addSubclass(subclass); | 622 if (superclass != null) superclass.addSubclass(subclass); |
| 620 interfaces.forEach((interface) { | 623 interfaces.forEach((interface) { |
| 621 interface.addSubclass(subclass); | 624 interface.addSubclass(subclass); |
| 622 }); | 625 }); |
| 623 } else { | 626 } else { |
| 624 subclasses.add(subclass.qualifiedName); | 627 subclasses.add(subclass.qualifiedName); |
| 625 } | 628 } |
| 626 } | 629 } |
| 627 | |
| 628 /** | |
| 629 * Check if this [Class] is an error or exception. | |
| 630 */ | |
| 631 bool isError() { | |
| 632 if (qualifiedName == 'dart.core.Error' || | |
| 633 qualifiedName == 'dart.core.Exception') | |
| 634 return true; | |
| 635 for (var interface in interfaces) { | |
| 636 if (interface.isError()) return true; | |
| 637 } | |
| 638 if (superclass == null) return false; | |
| 639 return superclass.isError(); | |
| 640 } | |
| 641 | 630 |
| 642 /** | 631 /** |
| 643 * Check that the class exists in the owner library. | 632 * Check that the class exists in the owner library. |
| 644 * | 633 * |
| 645 * If it does not exist in the owner library, it is a mixin applciation and | 634 * If it does not exist in the owner library, it is a mixin applciation and |
| 646 * should be removed. | 635 * should be removed. |
| 647 */ | 636 */ |
| 648 void makeValid() { | 637 void makeValid() { |
| 649 var library = entityMap[owner]; | 638 var library = entityMap[owner]; |
| 650 if (library != null && !library.classes.containsKey(name)) { | 639 if (library != null && !library.classes.containsKey(name)) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 676 if (superclass == null) return 'dart.core.Object'; | 665 if (superclass == null) return 'dart.core.Object'; |
| 677 if (_isVisible(superclass)) return superclass.qualifiedName; | 666 if (_isVisible(superclass)) return superclass.qualifiedName; |
| 678 return superclass.validSuperclass(); | 667 return superclass.validSuperclass(); |
| 679 } | 668 } |
| 680 | 669 |
| 681 /// Generates a map describing the [Class] object. | 670 /// Generates a map describing the [Class] object. |
| 682 Map toMap() => { | 671 Map toMap() => { |
| 683 'name': name, | 672 'name': name, |
| 684 'qualifiedName': qualifiedName, | 673 'qualifiedName': qualifiedName, |
| 685 'comment': comment, | 674 'comment': comment, |
| 686 'isAbstract' : isAbstract, | |
| 687 'superclass': validSuperclass(), | 675 'superclass': validSuperclass(), |
| 688 'implements': interfaces.where(_isVisible) | 676 'implements': interfaces.where(_isVisible) |
| 689 .map((e) => e.qualifiedName).toList(), | 677 .map((e) => e.qualifiedName).toList(), |
| 690 'subclass': subclasses.toList(), | 678 'subclass': subclasses.toList(), |
| 691 'variables': recurseMap(variables), | 679 'variables': recurseMap(variables), |
| 692 'inheritedVariables': recurseMap(inheritedVariables), | 680 'inheritedVariables': recurseMap(inheritedVariables), |
| 693 'methods': methods.toMap(), | 681 'methods': methods.toMap(), |
| 694 'inheritedMethods': inheritedMethods.toMap(), | 682 'inheritedMethods': inheritedMethods.toMap(), |
| 695 'annotations': annotations.map((a) => a.toMap()).toList(), | 683 'annotations': annotations.map((a) => a.toMap()).toList(), |
| 696 'generics': recurseMap(generics) | 684 'generics': recurseMap(generics) |
| 697 }; | 685 }; |
| 698 } | 686 } |
| 699 | 687 |
| 700 /** | 688 /** |
| 701 * A container to categorize classes into the following groups: abstract | 689 * A container to categorize classes into the following groups: abstract |
| 702 * classes, regular classes, typedefs, and errors. | 690 * classes, regular classes, typedefs, and errors. |
| 703 */ | 691 */ |
| 704 class ClassGroup { | 692 class ClassGroup { |
| 705 Map<String, Class> classes = {}; | 693 Map<String, Class> abstractClasses = {}; |
| 694 Map<String, Class> regularClasses = {}; |
| 706 Map<String, Typedef> typedefs = {}; | 695 Map<String, Typedef> typedefs = {}; |
| 707 Map<String, Class> errors = {}; | 696 Map<String, Class> errors = {}; |
| 708 | 697 |
| 709 void addClass(ClassMirror mirror) { | 698 void addClass(ClassMirror mirror) { |
| 710 _currentClass = mirror; | 699 _currentClass = mirror; |
| 711 var clazz = _class(mirror); | 700 var clazz = _class(mirror); |
| 712 | 701 |
| 713 // Adding inherited parent variables and methods. | 702 // Adding inherited parent variables and methods. |
| 714 clazz.parent().forEach((parent) { | 703 clazz.parent().forEach((parent) { |
| 715 if (_isVisible(clazz)) { | 704 if (_isVisible(clazz)) { |
| 716 parent.addSubclass(clazz); | 705 parent.addSubclass(clazz); |
| 717 } | 706 } |
| 718 }); | 707 }); |
| 719 | 708 |
| 720 clazz.ensureComments(); | 709 clazz.ensureComments(); |
| 721 | 710 |
| 722 if (clazz.isError()) { | 711 if (isError(mirror.qualifiedName)) { |
| 723 errors[mirror.simpleName] = clazz; | 712 errors[mirror.simpleName] = clazz; |
| 724 } else if (mirror.isTypedef) { | 713 } else if (mirror.isTypedef) { |
| 725 if (_includePrivate || !mirror.isPrivate) { | 714 if (_includePrivate || !mirror.isPrivate) { |
| 726 entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName, | 715 entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName, |
| 727 mirror.value.returnType.qualifiedName, _commentToHtml(mirror), | 716 mirror.value.returnType.qualifiedName, _commentToHtml(mirror), |
| 728 _generics(mirror), _parameters(mirror.value.parameters), | 717 _generics(mirror), _parameters(mirror.value.parameters), |
| 729 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), | 718 _annotations(mirror), mirror.qualifiedName, _isHidden(mirror), |
| 730 mirror.owner.qualifiedName); | 719 mirror.owner.qualifiedName); |
| 731 typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName]; | 720 typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName]; |
| 732 } | 721 } |
| 722 } else if (mirror.isAbstract) { |
| 723 abstractClasses[mirror.simpleName] = clazz; |
| 733 } else if (mirror.isClass) { | 724 } else if (mirror.isClass) { |
| 734 classes[mirror.simpleName] = clazz; | 725 regularClasses[mirror.simpleName] = clazz; |
| 735 } else { | 726 } else { |
| 736 throw new ArgumentError('${mirror.simpleName} - no class type match. '); | 727 throw new ArgumentError('${mirror.simpleName} - no class type match. '); |
| 737 } | 728 } |
| 738 } | 729 } |
| 739 | 730 |
| 740 /** | 731 /** |
| 741 * Checks if the given name is a key for any of the Class Maps. | 732 * Checks if the given name is a key for any of the Class Maps. |
| 742 */ | 733 */ |
| 743 bool containsKey(String name) { | 734 bool containsKey(String name) { |
| 744 return classes.containsKey(name) || errors.containsKey(name); | 735 return abstractClasses.containsKey(name) || |
| 736 regularClasses.containsKey(name) || |
| 737 errors.containsKey(name); |
| 745 } | 738 } |
| 746 | 739 |
| 747 /** | |
| 748 * Creates a [Map] with [Class] names and a preview comment. | |
| 749 */ | |
| 750 Map classMap(Class clazz) { | |
| 751 var finalMap = { 'name' : clazz.qualifiedName }; | |
| 752 if (clazz.comment != '') { | |
| 753 var index = clazz.comment.indexOf('</p>'); | |
| 754 finalMap['preview'] = '${clazz.comment.substring(0, index)}</p>'; | |
| 755 } | |
| 756 return finalMap; | |
| 757 } | |
| 758 | |
| 759 Map toMap() => { | 740 Map toMap() => { |
| 760 'class': classes.values.where(_isVisible) | 741 'abstract': abstractClasses.values.where(_isVisible) |
| 761 .map((e) => classMap(e)).toList(), | 742 .map((e) => e.qualifiedName).toList(), |
| 743 'class': regularClasses.values.where(_isVisible) |
| 744 .map((e) => e.qualifiedName).toList(), |
| 762 'typedef': recurseMap(typedefs), | 745 'typedef': recurseMap(typedefs), |
| 763 'error': errors.values.where(_isVisible) | 746 'error': errors.values.where(_isVisible) |
| 764 .map((e) => classMap(e)).toList() | 747 .map((e) => e.qualifiedName).toList() |
| 765 }; | 748 }; |
| 766 } | 749 } |
| 767 | 750 |
| 768 class Typedef extends Indexable { | 751 class Typedef extends Indexable { |
| 769 String returnType; | 752 String returnType; |
| 770 | 753 |
| 771 Map<String, Parameter> parameters; | 754 Map<String, Parameter> parameters; |
| 772 | 755 |
| 773 /// Generic information about the typedef. | 756 /// Generic information about the typedef. |
| 774 Map<String, Generic> generics; | 757 Map<String, Generic> generics; |
| 775 | 758 |
| 776 /// List of the meta annotations on the typedef. | 759 /// List of the meta annotations on the typedef. |
| 777 List<String> annotations; | 760 List<String> annotations; |
| 778 | 761 |
| 779 Typedef(String name, this.returnType, String comment, this.generics, | 762 Typedef(String name, this.returnType, String comment, this.generics, |
| 780 this.parameters, this.annotations, | 763 this.parameters, this.annotations, |
| 781 String qualifiedName, bool isPrivate, String owner) | 764 String qualifiedName, bool isPrivate, String owner) : super(name, comment, |
| 782 : super(name, comment, qualifiedName, isPrivate, owner); | 765 qualifiedName, isPrivate, owner) {} |
| 783 | 766 |
| 784 Map toMap() => { | 767 Map toMap() => { |
| 785 'name': name, | 768 'name': name, |
| 786 'qualifiedName': qualifiedName, | 769 'qualifiedName': qualifiedName, |
| 787 'comment': comment, | 770 'comment': comment, |
| 788 'return': returnType, | 771 'return': returnType, |
| 789 'parameters': recurseMap(parameters), | 772 'parameters': recurseMap(parameters), |
| 790 'annotations': annotations.map((a) => a.toMap()).toList(), | 773 'annotations': annotations.map((a) => a.toMap()).toList(), |
| 791 'generics': recurseMap(generics) | 774 'generics': recurseMap(generics) |
| 792 }; | 775 }; |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 String qualifiedName; | 1022 String qualifiedName; |
| 1040 List<String> parameters; | 1023 List<String> parameters; |
| 1041 | 1024 |
| 1042 Annotation(this.qualifiedName, this.parameters); | 1025 Annotation(this.qualifiedName, this.parameters); |
| 1043 | 1026 |
| 1044 Map toMap() => { | 1027 Map toMap() => { |
| 1045 'name': qualifiedName, | 1028 'name': qualifiedName, |
| 1046 'parameters': parameters | 1029 'parameters': parameters |
| 1047 }; | 1030 }; |
| 1048 } | 1031 } |
| OLD | NEW |