| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 * To generate docs for a library, run this script with the path to an | 6 * To generate docs for a library, run this script with the path to an |
| 7 * entrypoint .dart file, like: | 7 * entrypoint .dart file, like: |
| 8 * | 8 * |
| 9 * $ dart dartdoc.dart foo.dart | 9 * $ dart dartdoc.dart foo.dart |
| 10 * | 10 * |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 } | 398 } |
| 399 | 399 |
| 400 /** | 400 /** |
| 401 * Returns `true` if [library] is included in the generated documentation. | 401 * Returns `true` if [library] is included in the generated documentation. |
| 402 */ | 402 */ |
| 403 bool shouldIncludeLibrary(LibraryMirror library) { | 403 bool shouldIncludeLibrary(LibraryMirror library) { |
| 404 if (shouldLinkToPublicApi(library)) { | 404 if (shouldLinkToPublicApi(library)) { |
| 405 return false; | 405 return false; |
| 406 } | 406 } |
| 407 var includeByDefault = true; | 407 var includeByDefault = true; |
| 408 String libraryName = library.simpleName(); | 408 String libraryName = library.simpleName; |
| 409 if (!includedLibraries.isEmpty()) { | 409 if (!includedLibraries.isEmpty()) { |
| 410 includeByDefault = false; | 410 includeByDefault = false; |
| 411 if (includedLibraries.indexOf(libraryName) != -1) { | 411 if (includedLibraries.indexOf(libraryName) != -1) { |
| 412 return true; | 412 return true; |
| 413 } | 413 } |
| 414 } | 414 } |
| 415 if (excludedLibraries.indexOf(libraryName) != -1) { | 415 if (excludedLibraries.indexOf(libraryName) != -1) { |
| 416 return false; | 416 return false; |
| 417 } | 417 } |
| 418 if (libraryName.startsWith('dart:')) { | 418 if (libraryName.startsWith('dart:')) { |
| 419 String suffix = libraryName.substring('dart:'.length); | 419 String suffix = libraryName.substring('dart:'.length); |
| 420 LibraryInfo info = DART2JS_LIBRARY_MAP[suffix]; | 420 LibraryInfo info = DART2JS_LIBRARY_MAP[suffix]; |
| 421 if (info != null) { | 421 if (info != null) { |
| 422 return !info.isInternal && includeApi; | 422 return !info.isInternal && includeApi; |
| 423 } | 423 } |
| 424 } | 424 } |
| 425 return includeByDefault; | 425 return includeByDefault; |
| 426 } | 426 } |
| 427 | 427 |
| 428 /** | 428 /** |
| 429 * Returns `true` if links to the public API should be generated for | 429 * Returns `true` if links to the public API should be generated for |
| 430 * [library]. | 430 * [library]. |
| 431 */ | 431 */ |
| 432 bool shouldLinkToPublicApi(LibraryMirror library) { | 432 bool shouldLinkToPublicApi(LibraryMirror library) { |
| 433 if (linkToApi) { | 433 if (linkToApi) { |
| 434 String libraryName = library.simpleName(); | 434 String libraryName = library.simpleName; |
| 435 if (libraryName.startsWith('dart:')) { | 435 if (libraryName.startsWith('dart:')) { |
| 436 String suffix = libraryName.substring('dart:'.length); | 436 String suffix = libraryName.substring('dart:'.length); |
| 437 LibraryInfo info = DART2JS_LIBRARY_MAP[suffix]; | 437 LibraryInfo info = DART2JS_LIBRARY_MAP[suffix]; |
| 438 if (info != null) { | 438 if (info != null) { |
| 439 return !info.isInternal; | 439 return !info.isInternal; |
| 440 } | 440 } |
| 441 } | 441 } |
| 442 } | 442 } |
| 443 return false; | 443 return false; |
| 444 } | 444 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 467 } | 467 } |
| 468 | 468 |
| 469 void documentLibraries(List<Path> libraryList, Path libPath) { | 469 void documentLibraries(List<Path> libraryList, Path libPath) { |
| 470 final compilation = new Compilation.library(libraryList, libPath); | 470 final compilation = new Compilation.library(libraryList, libPath); |
| 471 _document(compilation); | 471 _document(compilation); |
| 472 } | 472 } |
| 473 | 473 |
| 474 void _document(Compilation compilation) { | 474 void _document(Compilation compilation) { |
| 475 // Sort the libraries by name (not key). | 475 // Sort the libraries by name (not key). |
| 476 _sortedLibraries = new List<LibraryMirror>.from( | 476 _sortedLibraries = new List<LibraryMirror>.from( |
| 477 compilation.mirrors().libraries().getValues().filter( | 477 compilation.mirrors.libraries.getValues().filter( |
| 478 shouldIncludeLibrary)); | 478 shouldIncludeLibrary)); |
| 479 _sortedLibraries.sort((x, y) { | 479 _sortedLibraries.sort((x, y) { |
| 480 return x.simpleName().toUpperCase().compareTo( | 480 return x.simpleName.toUpperCase().compareTo( |
| 481 y.simpleName().toUpperCase()); | 481 y.simpleName.toUpperCase()); |
| 482 }); | 482 }); |
| 483 | 483 |
| 484 // Generate the docs. | 484 // Generate the docs. |
| 485 if (mode == MODE_LIVE_NAV) docNavigationJson(); | 485 if (mode == MODE_LIVE_NAV) docNavigationJson(); |
| 486 | 486 |
| 487 docIndex(); | 487 docIndex(); |
| 488 for (final library in _sortedLibraries) { | 488 for (final library in _sortedLibraries) { |
| 489 docLibrary(library); | 489 docLibrary(library); |
| 490 } | 490 } |
| 491 | 491 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 <!DOCTYPE html> | 547 <!DOCTYPE html> |
| 548 <html${htmlAttributes == '' ? '' : ' $htmlAttributes'}> | 548 <html${htmlAttributes == '' ? '' : ' $htmlAttributes'}> |
| 549 <head> | 549 <head> |
| 550 '''); | 550 '''); |
| 551 writeHeadContents(title); | 551 writeHeadContents(title); |
| 552 | 552 |
| 553 // Add data attributes describing what the page documents. | 553 // Add data attributes describing what the page documents. |
| 554 var data = ''; | 554 var data = ''; |
| 555 if (_currentLibrary != null) { | 555 if (_currentLibrary != null) { |
| 556 data = '$data data-library=' | 556 data = '$data data-library=' |
| 557 '"${md.escapeHtml(_currentLibrary.simpleName())}"'; | 557 '"${md.escapeHtml(_currentLibrary.simpleName)}"'; |
| 558 } | 558 } |
| 559 | 559 |
| 560 if (_currentType != null) { | 560 if (_currentType != null) { |
| 561 data = '$data data-type="${md.escapeHtml(typeName(_currentType))}"'; | 561 data = '$data data-type="${md.escapeHtml(typeName(_currentType))}"'; |
| 562 } | 562 } |
| 563 | 563 |
| 564 write( | 564 write( |
| 565 ''' | 565 ''' |
| 566 </head> | 566 </head> |
| 567 <body$data> | 567 <body$data> |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 | 644 |
| 645 for (final library in _sortedLibraries) { | 645 for (final library in _sortedLibraries) { |
| 646 docIndexLibrary(library); | 646 docIndexLibrary(library); |
| 647 } | 647 } |
| 648 | 648 |
| 649 writeFooter(); | 649 writeFooter(); |
| 650 endFile(); | 650 endFile(); |
| 651 } | 651 } |
| 652 | 652 |
| 653 void docIndexLibrary(LibraryMirror library) { | 653 void docIndexLibrary(LibraryMirror library) { |
| 654 writeln('<h4>${a(libraryUrl(library), library.simpleName())}</h4>'); | 654 writeln('<h4>${a(libraryUrl(library), library.simpleName)}</h4>'); |
| 655 } | 655 } |
| 656 | 656 |
| 657 /** | 657 /** |
| 658 * Walks the libraries and creates a JSON object containing the data needed | 658 * Walks the libraries and creates a JSON object containing the data needed |
| 659 * to generate navigation for them. | 659 * to generate navigation for them. |
| 660 */ | 660 */ |
| 661 void docNavigationJson() { | 661 void docNavigationJson() { |
| 662 startFile('nav.json'); | 662 startFile('nav.json'); |
| 663 | 663 |
| 664 final libraryMap = {}; | 664 final libraryMap = {}; |
| 665 | 665 |
| 666 for (final library in _sortedLibraries) { | 666 for (final library in _sortedLibraries) { |
| 667 docLibraryNavigationJson(library, libraryMap); | 667 docLibraryNavigationJson(library, libraryMap); |
| 668 } | 668 } |
| 669 | 669 |
| 670 writeln(JSON.stringify(libraryMap)); | 670 writeln(JSON.stringify(libraryMap)); |
| 671 endFile(); | 671 endFile(); |
| 672 } | 672 } |
| 673 | 673 |
| 674 void docLibraryNavigationJson(LibraryMirror library, Map libraryMap) { | 674 void docLibraryNavigationJson(LibraryMirror library, Map libraryMap) { |
| 675 final types = []; | 675 final types = []; |
| 676 | 676 |
| 677 for (InterfaceMirror type in orderByName(library.types().getValues())) { | 677 for (InterfaceMirror type in orderByName(library.types.getValues())) { |
| 678 if (type.isPrivate) continue; | 678 if (type.isPrivate) continue; |
| 679 | 679 |
| 680 final kind = type.isClass ? 'class' : 'interface'; | 680 final kind = type.isClass ? 'class' : 'interface'; |
| 681 final url = typeUrl(type); | 681 final url = typeUrl(type); |
| 682 types.add({ 'name': typeName(type), 'kind': kind, 'url': url }); | 682 types.add({ 'name': typeName(type), 'kind': kind, 'url': url }); |
| 683 } | 683 } |
| 684 | 684 |
| 685 libraryMap[library.simpleName()] = types; | 685 libraryMap[library.simpleName] = types; |
| 686 } | 686 } |
| 687 | 687 |
| 688 void docNavigation() { | 688 void docNavigation() { |
| 689 writeln( | 689 writeln( |
| 690 ''' | 690 ''' |
| 691 <div class="nav"> | 691 <div class="nav"> |
| 692 '''); | 692 '''); |
| 693 | 693 |
| 694 if (mode == MODE_STATIC) { | 694 if (mode == MODE_STATIC) { |
| 695 for (final library in _sortedLibraries) { | 695 for (final library in _sortedLibraries) { |
| 696 write('<h2><div class="icon-library"></div>'); | 696 write('<h2><div class="icon-library"></div>'); |
| 697 | 697 |
| 698 if ((_currentLibrary == library) && (_currentType == null)) { | 698 if ((_currentLibrary == library) && (_currentType == null)) { |
| 699 write('<strong>${library.simpleName()}</strong>'); | 699 write('<strong>${library.simpleName}</strong>'); |
| 700 } else { | 700 } else { |
| 701 write('${a(libraryUrl(library), library.simpleName())}'); | 701 write('${a(libraryUrl(library), library.simpleName)}'); |
| 702 } | 702 } |
| 703 write('</h2>'); | 703 write('</h2>'); |
| 704 | 704 |
| 705 // Only expand classes in navigation for current library. | 705 // Only expand classes in navigation for current library. |
| 706 if (_currentLibrary == library) docLibraryNavigation(library); | 706 if (_currentLibrary == library) docLibraryNavigation(library); |
| 707 } | 707 } |
| 708 } | 708 } |
| 709 | 709 |
| 710 writeln('</div>'); | 710 writeln('</div>'); |
| 711 } | 711 } |
| 712 | 712 |
| 713 /** Writes the navigation for the types contained by the given library. */ | 713 /** Writes the navigation for the types contained by the given library. */ |
| 714 void docLibraryNavigation(LibraryMirror library) { | 714 void docLibraryNavigation(LibraryMirror library) { |
| 715 // Show the exception types separately. | 715 // Show the exception types separately. |
| 716 final types = <InterfaceMirror>[]; | 716 final types = <InterfaceMirror>[]; |
| 717 final exceptions = <InterfaceMirror>[]; | 717 final exceptions = <InterfaceMirror>[]; |
| 718 | 718 |
| 719 for (InterfaceMirror type in orderByName(library.types().getValues())) { | 719 for (InterfaceMirror type in orderByName(library.types.getValues())) { |
| 720 if (type.isPrivate) continue; | 720 if (type.isPrivate) continue; |
| 721 | 721 |
| 722 if (isException(type)) { | 722 if (isException(type)) { |
| 723 exceptions.add(type); | 723 exceptions.add(type); |
| 724 } else { | 724 } else { |
| 725 types.add(type); | 725 types.add(type); |
| 726 } | 726 } |
| 727 } | 727 } |
| 728 | 728 |
| 729 if ((types.length == 0) && (exceptions.length == 0)) return; | 729 if ((types.length == 0) && (exceptions.length == 0)) return; |
| 730 | 730 |
| 731 writeln('<ul class="icon">'); | 731 writeln('<ul class="icon">'); |
| 732 types.forEach(docTypeNavigation); | 732 types.forEach(docTypeNavigation); |
| 733 exceptions.forEach(docTypeNavigation); | 733 exceptions.forEach(docTypeNavigation); |
| 734 writeln('</ul>'); | 734 writeln('</ul>'); |
| 735 } | 735 } |
| 736 | 736 |
| 737 /** Writes a linked navigation list item for the given type. */ | 737 /** Writes a linked navigation list item for the given type. */ |
| 738 void docTypeNavigation(InterfaceMirror type) { | 738 void docTypeNavigation(InterfaceMirror type) { |
| 739 var icon = 'interface'; | 739 var icon = 'interface'; |
| 740 if (type.simpleName().endsWith('Exception')) { | 740 if (type.simpleName.endsWith('Exception')) { |
| 741 icon = 'exception'; | 741 icon = 'exception'; |
| 742 } else if (type.isClass) { | 742 } else if (type.isClass) { |
| 743 icon = 'class'; | 743 icon = 'class'; |
| 744 } | 744 } |
| 745 | 745 |
| 746 write('<li>'); | 746 write('<li>'); |
| 747 if (_currentType == type) { | 747 if (_currentType == type) { |
| 748 write( | 748 write( |
| 749 '<div class="icon-$icon"></div><strong>${typeName(type)}</strong>'); | 749 '<div class="icon-$icon"></div><strong>${typeName(type)}</strong>'); |
| 750 } else { | 750 } else { |
| 751 write(a(typeUrl(type), | 751 write(a(typeUrl(type), |
| 752 '<div class="icon-$icon"></div>${typeName(type)}')); | 752 '<div class="icon-$icon"></div>${typeName(type)}')); |
| 753 } | 753 } |
| 754 writeln('</li>'); | 754 writeln('</li>'); |
| 755 } | 755 } |
| 756 | 756 |
| 757 void docLibrary(LibraryMirror library) { | 757 void docLibrary(LibraryMirror library) { |
| 758 if (verbose) { | 758 if (verbose) { |
| 759 print('Library \'${library.simpleName()}\':'); | 759 print('Library \'${library.simpleName}\':'); |
| 760 } | 760 } |
| 761 _totalLibraries++; | 761 _totalLibraries++; |
| 762 _currentLibrary = library; | 762 _currentLibrary = library; |
| 763 _currentType = null; | 763 _currentType = null; |
| 764 | 764 |
| 765 startFile(libraryUrl(library)); | 765 startFile(libraryUrl(library)); |
| 766 writeHeader('${library.simpleName()} Library', | 766 writeHeader('${library.simpleName} Library', |
| 767 [library.simpleName(), libraryUrl(library)]); | 767 [library.simpleName, libraryUrl(library)]); |
| 768 writeln('<h2><strong>${library.simpleName()}</strong> library</h2>'); | 768 writeln('<h2><strong>${library.simpleName}</strong> library</h2>'); |
| 769 | 769 |
| 770 // Look for a comment for the entire library. | 770 // Look for a comment for the entire library. |
| 771 final comment = getLibraryComment(library); | 771 final comment = getLibraryComment(library); |
| 772 if (comment != null) { | 772 if (comment != null) { |
| 773 writeln('<div class="doc">$comment</div>'); | 773 writeln('<div class="doc">$comment</div>'); |
| 774 } | 774 } |
| 775 | 775 |
| 776 // Document the top-level members. | 776 // Document the top-level members. |
| 777 docMembers(library); | 777 docMembers(library); |
| 778 | 778 |
| 779 // Document the types. | 779 // Document the types. |
| 780 final classes = <InterfaceMirror>[]; | 780 final classes = <InterfaceMirror>[]; |
| 781 final interfaces = <InterfaceMirror>[]; | 781 final interfaces = <InterfaceMirror>[]; |
| 782 final exceptions = <InterfaceMirror>[]; | 782 final exceptions = <InterfaceMirror>[]; |
| 783 | 783 |
| 784 for (InterfaceMirror type in orderByName(library.types().getValues())) { | 784 for (InterfaceMirror type in orderByName(library.types.getValues())) { |
| 785 if (type.isPrivate) continue; | 785 if (type.isPrivate) continue; |
| 786 | 786 |
| 787 if (isException(type)) { | 787 if (isException(type)) { |
| 788 exceptions.add(type); | 788 exceptions.add(type); |
| 789 } else if (type.isClass) { | 789 } else if (type.isClass) { |
| 790 classes.add(type); | 790 classes.add(type); |
| 791 } else { | 791 } else { |
| 792 interfaces.add(type); | 792 interfaces.add(type); |
| 793 } | 793 } |
| 794 } | 794 } |
| 795 | 795 |
| 796 docTypes(classes, 'Classes'); | 796 docTypes(classes, 'Classes'); |
| 797 docTypes(interfaces, 'Interfaces'); | 797 docTypes(interfaces, 'Interfaces'); |
| 798 docTypes(exceptions, 'Exceptions'); | 798 docTypes(exceptions, 'Exceptions'); |
| 799 | 799 |
| 800 writeFooter(); | 800 writeFooter(); |
| 801 endFile(); | 801 endFile(); |
| 802 | 802 |
| 803 for (final type in library.types().getValues()) { | 803 for (final type in library.types.getValues()) { |
| 804 if (type.isPrivate) continue; | 804 if (type.isPrivate) continue; |
| 805 | 805 |
| 806 docType(type); | 806 docType(type); |
| 807 } | 807 } |
| 808 } | 808 } |
| 809 | 809 |
| 810 void docTypes(List<InterfaceMirror> types, String header) { | 810 void docTypes(List<InterfaceMirror> types, String header) { |
| 811 if (types.length == 0) return; | 811 if (types.length == 0) return; |
| 812 | 812 |
| 813 writeln('<h3>$header</h3>'); | 813 writeln('<h3>$header</h3>'); |
| 814 | 814 |
| 815 for (final type in types) { | 815 for (final type in types) { |
| 816 writeln( | 816 writeln( |
| 817 ''' | 817 ''' |
| 818 <div class="type"> | 818 <div class="type"> |
| 819 <h4> | 819 <h4> |
| 820 ${a(typeUrl(type), "<strong>${typeName(type)}</strong>")} | 820 ${a(typeUrl(type), "<strong>${typeName(type)}</strong>")} |
| 821 </h4> | 821 </h4> |
| 822 </div> | 822 </div> |
| 823 '''); | 823 '''); |
| 824 } | 824 } |
| 825 } | 825 } |
| 826 | 826 |
| 827 void docType(InterfaceMirror type) { | 827 void docType(InterfaceMirror type) { |
| 828 if (verbose) { | 828 if (verbose) { |
| 829 print('- ${type.simpleName()}'); | 829 print('- ${type.simpleName}'); |
| 830 } | 830 } |
| 831 _totalTypes++; | 831 _totalTypes++; |
| 832 _currentType = type; | 832 _currentType = type; |
| 833 | 833 |
| 834 startFile(typeUrl(type)); | 834 startFile(typeUrl(type)); |
| 835 | 835 |
| 836 var kind = 'Interface'; | 836 var kind = 'Interface'; |
| 837 if (type.isTypedef) { | 837 if (type.isTypedef) { |
| 838 kind = 'Typedef'; | 838 kind = 'Typedef'; |
| 839 } else if (type.isClass) { | 839 } else if (type.isClass) { |
| 840 kind = 'Class'; | 840 kind = 'Class'; |
| 841 } | 841 } |
| 842 | 842 |
| 843 final typeTitle = | 843 final typeTitle = |
| 844 '${typeName(type)} ${kind}'; | 844 '${typeName(type)} ${kind}'; |
| 845 writeHeader('$typeTitle / ${type.library().simpleName()} Library', | 845 writeHeader('$typeTitle / ${type.library.simpleName} Library', |
| 846 [type.library().simpleName(), libraryUrl(type.library()), | 846 [type.library.simpleName, libraryUrl(type.library), |
| 847 typeName(type), typeUrl(type)]); | 847 typeName(type), typeUrl(type)]); |
| 848 writeln( | 848 writeln( |
| 849 ''' | 849 ''' |
| 850 <h2><strong>${typeName(type, showBounds: true)}</strong> | 850 <h2><strong>${typeName(type, showBounds: true)}</strong> |
| 851 $kind | 851 $kind |
| 852 </h2> | 852 </h2> |
| 853 '''); | 853 '''); |
| 854 | 854 |
| 855 docCode(type.location(), getTypeComment(type)); | 855 docCode(type.location, getTypeComment(type)); |
| 856 docInheritance(type); | 856 docInheritance(type); |
| 857 docTypedef(type); | 857 docTypedef(type); |
| 858 docConstructors(type); | 858 docConstructors(type); |
| 859 docMembers(type); | 859 docMembers(type); |
| 860 | 860 |
| 861 writeTypeFooter(); | 861 writeTypeFooter(); |
| 862 writeFooter(); | 862 writeFooter(); |
| 863 endFile(); | 863 endFile(); |
| 864 } | 864 } |
| 865 | 865 |
| 866 /** Override this to write additional content at the end of a type's page. */ | 866 /** Override this to write additional content at the end of a type's page. */ |
| 867 void writeTypeFooter() { | 867 void writeTypeFooter() { |
| 868 // Do nothing. | 868 // Do nothing. |
| 869 } | 869 } |
| 870 | 870 |
| 871 /** | 871 /** |
| 872 * Writes an inline type span for the given type. This is a little box with | 872 * Writes an inline type span for the given type. This is a little box with |
| 873 * an icon and the type's name. It's similar to how types appear in the | 873 * an icon and the type's name. It's similar to how types appear in the |
| 874 * navigation, but is suitable for inline (as opposed to in a `<ul>`) use. | 874 * navigation, but is suitable for inline (as opposed to in a `<ul>`) use. |
| 875 */ | 875 */ |
| 876 void typeSpan(InterfaceMirror type) { | 876 void typeSpan(InterfaceMirror type) { |
| 877 var icon = 'interface'; | 877 var icon = 'interface'; |
| 878 if (type.simpleName().endsWith('Exception')) { | 878 if (type.simpleName.endsWith('Exception')) { |
| 879 icon = 'exception'; | 879 icon = 'exception'; |
| 880 } else if (type.isClass) { | 880 } else if (type.isClass) { |
| 881 icon = 'class'; | 881 icon = 'class'; |
| 882 } | 882 } |
| 883 | 883 |
| 884 write('<span class="type-box"><span class="icon-$icon"></span>'); | 884 write('<span class="type-box"><span class="icon-$icon"></span>'); |
| 885 if (_currentType == type) { | 885 if (_currentType == type) { |
| 886 write('<strong>${typeName(type)}</strong>'); | 886 write('<strong>${typeName(type)}</strong>'); |
| 887 } else { | 887 } else { |
| 888 write(a(typeUrl(type), typeName(type))); | 888 write(a(typeUrl(type), typeName(type))); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 916 typeSpan(t); | 916 typeSpan(t); |
| 917 first = false; | 917 first = false; |
| 918 } | 918 } |
| 919 writeln('</p>'); | 919 writeln('</p>'); |
| 920 } | 920 } |
| 921 | 921 |
| 922 final subtypes = []; | 922 final subtypes = []; |
| 923 for (final subtype in computeSubdeclarations(type)) { | 923 for (final subtype in computeSubdeclarations(type)) { |
| 924 subtypes.add(subtype); | 924 subtypes.add(subtype); |
| 925 } | 925 } |
| 926 subtypes.sort((x, y) => x.simpleName().compareTo(y.simpleName())); | 926 subtypes.sort((x, y) => x.simpleName.compareTo(y.simpleName)); |
| 927 if (type.isClass) { | 927 if (type.isClass) { |
| 928 // Show the chain of superclasses. | 928 // Show the chain of superclasses. |
| 929 if (!type.superclass().isObject) { | 929 if (!type.superclass.isObject) { |
| 930 final supertypes = []; | 930 final supertypes = []; |
| 931 var thisType = type.superclass(); | 931 var thisType = type.superclass; |
| 932 // As a sanity check, only show up to five levels of nesting, otherwise | 932 // As a sanity check, only show up to five levels of nesting, otherwise |
| 933 // the box starts to get hideous. | 933 // the box starts to get hideous. |
| 934 do { | 934 do { |
| 935 supertypes.add(thisType); | 935 supertypes.add(thisType); |
| 936 thisType = thisType.superclass(); | 936 thisType = thisType.superclass; |
| 937 } while (!thisType.isObject); | 937 } while (!thisType.isObject); |
| 938 | 938 |
| 939 writeln('<h3>Extends</h3>'); | 939 writeln('<h3>Extends</h3>'); |
| 940 writeln('<p>'); | 940 writeln('<p>'); |
| 941 for (var i = supertypes.length - 1; i >= 0; i--) { | 941 for (var i = supertypes.length - 1; i >= 0; i--) { |
| 942 typeSpan(supertypes[i]); | 942 typeSpan(supertypes[i]); |
| 943 write(' > '); | 943 write(' > '); |
| 944 } | 944 } |
| 945 | 945 |
| 946 // Write this class. | 946 // Write this class. |
| 947 typeSpan(type); | 947 typeSpan(type); |
| 948 writeln('</p>'); | 948 writeln('</p>'); |
| 949 } | 949 } |
| 950 | 950 |
| 951 listTypes(subtypes, 'Subclasses'); | 951 listTypes(subtypes, 'Subclasses'); |
| 952 listTypes(type.interfaces().getValues(), 'Implements'); | 952 listTypes(type.interfaces.getValues(), 'Implements'); |
| 953 } else { | 953 } else { |
| 954 // Show the default class. | 954 // Show the default class. |
| 955 if (type.defaultType() != null) { | 955 if (type.defaultType != null) { |
| 956 listTypes([type.defaultType()], 'Default class'); | 956 listTypes([type.defaultType], 'Default class'); |
| 957 } | 957 } |
| 958 | 958 |
| 959 // List extended interfaces. | 959 // List extended interfaces. |
| 960 listTypes(type.interfaces().getValues(), 'Extends'); | 960 listTypes(type.interfaces.getValues(), 'Extends'); |
| 961 | 961 |
| 962 // List subinterfaces and implementing classes. | 962 // List subinterfaces and implementing classes. |
| 963 final subinterfaces = []; | 963 final subinterfaces = []; |
| 964 final implementing = []; | 964 final implementing = []; |
| 965 | 965 |
| 966 for (final subtype in subtypes) { | 966 for (final subtype in subtypes) { |
| 967 if (subtype.isClass) { | 967 if (subtype.isClass) { |
| 968 implementing.add(subtype); | 968 implementing.add(subtype); |
| 969 } else { | 969 } else { |
| 970 subinterfaces.add(subtype); | 970 subinterfaces.add(subtype); |
| 971 } | 971 } |
| 972 } | 972 } |
| 973 | 973 |
| 974 listTypes(subinterfaces, 'Subinterfaces'); | 974 listTypes(subinterfaces, 'Subinterfaces'); |
| 975 listTypes(implementing, 'Implemented by'); | 975 listTypes(implementing, 'Implemented by'); |
| 976 } | 976 } |
| 977 } | 977 } |
| 978 | 978 |
| 979 /** | 979 /** |
| 980 * Documents the definition of [type] if it is a typedef. | 980 * Documents the definition of [type] if it is a typedef. |
| 981 */ | 981 */ |
| 982 void docTypedef(TypeMirror type) { | 982 void docTypedef(TypeMirror type) { |
| 983 if (type is! TypedefMirror) { | 983 if (type is! TypedefMirror) { |
| 984 return; | 984 return; |
| 985 } | 985 } |
| 986 writeln('<div class="method"><h4 id="${type.simpleName()}">'); | 986 writeln('<div class="method"><h4 id="${type.simpleName}">'); |
| 987 | 987 |
| 988 if (includeSource) { | 988 if (includeSource) { |
| 989 writeln('<span class="show-code">Code</span>'); | 989 writeln('<span class="show-code">Code</span>'); |
| 990 } | 990 } |
| 991 | 991 |
| 992 if (type.definition() !== null) { | 992 if (type.definition !== null) { |
| 993 // TODO(johnniwinther): Implement [:TypedefMirror.definition():]. | 993 // TODO(johnniwinther): Implement [:TypedefMirror.definition():]. |
| 994 write('typedef '); | 994 write('typedef '); |
| 995 annotateType(type, type.definition(), type.simpleName()); | 995 annotateType(type, type.definition, type.simpleName); |
| 996 | 996 |
| 997 write(''' <a class="anchor-link" href="#${type.simpleName()}" | 997 write(''' <a class="anchor-link" href="#${type.simpleName}" |
| 998 title="Permalink to ${type.simpleName()}">#</a>'''); | 998 title="Permalink to ${type.simpleName}">#</a>'''); |
| 999 } | 999 } |
| 1000 writeln('</h4>'); | 1000 writeln('</h4>'); |
| 1001 | 1001 |
| 1002 docCode(type.location(), null, showCode: true); | 1002 docCode(type.location, null, showCode: true); |
| 1003 | 1003 |
| 1004 writeln('</div>'); | 1004 writeln('</div>'); |
| 1005 } | 1005 } |
| 1006 | 1006 |
| 1007 /** Document the constructors for [Type], if any. */ | 1007 /** Document the constructors for [Type], if any. */ |
| 1008 void docConstructors(InterfaceMirror type) { | 1008 void docConstructors(InterfaceMirror type) { |
| 1009 final constructors = <MethodMirror>[]; | 1009 final constructors = <MethodMirror>[]; |
| 1010 for (var constructor in type.constructors().getValues()) { | 1010 for (var constructor in type.constructors.getValues()) { |
| 1011 if (!constructor.isPrivate) { | 1011 if (!constructor.isPrivate) { |
| 1012 constructors.add(constructor); | 1012 constructors.add(constructor); |
| 1013 } | 1013 } |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 if (constructors.length > 0) { | 1016 if (constructors.length > 0) { |
| 1017 writeln('<h3>Constructors</h3>'); | 1017 writeln('<h3>Constructors</h3>'); |
| 1018 constructors.sort((x, y) => x.simpleName().toUpperCase().compareTo( | 1018 constructors.sort((x, y) => x.simpleName.toUpperCase().compareTo( |
| 1019 y.simpleName().toUpperCase())); | 1019 y.simpleName.toUpperCase())); |
| 1020 | 1020 |
| 1021 for (final constructor in constructors) { | 1021 for (final constructor in constructors) { |
| 1022 docMethod(type, constructor); | 1022 docMethod(type, constructor); |
| 1023 } | 1023 } |
| 1024 } | 1024 } |
| 1025 } | 1025 } |
| 1026 | 1026 |
| 1027 void docMembers(ObjectMirror host) { | 1027 void docMembers(ObjectMirror host) { |
| 1028 // Collect the different kinds of members. | 1028 // Collect the different kinds of members. |
| 1029 final staticMethods = []; | 1029 final staticMethods = []; |
| 1030 final staticFields = []; | 1030 final staticFields = []; |
| 1031 final instanceMethods = []; | 1031 final instanceMethods = []; |
| 1032 final instanceFields = []; | 1032 final instanceFields = []; |
| 1033 | 1033 |
| 1034 for (MemberMirror member in orderByName(host.declaredMembers().getValues()))
{ | 1034 for (MemberMirror member in orderByName(host.declaredMembers.getValues())) { |
| 1035 if (member.isPrivate) continue; | 1035 if (member.isPrivate) continue; |
| 1036 | 1036 |
| 1037 final methods = member.isStatic ? staticMethods : instanceMethods; | 1037 final methods = member.isStatic ? staticMethods : instanceMethods; |
| 1038 final fields = member.isStatic ? staticFields : instanceFields; | 1038 final fields = member.isStatic ? staticFields : instanceFields; |
| 1039 | 1039 |
| 1040 if (member.isMethod) { | 1040 if (member.isMethod) { |
| 1041 methods.add(member); | 1041 methods.add(member); |
| 1042 } else if (member.isField) { | 1042 } else if (member.isField) { |
| 1043 fields.add(member); | 1043 fields.add(member); |
| 1044 } | 1044 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 | 1091 |
| 1092 if (method.isConstructor) { | 1092 if (method.isConstructor) { |
| 1093 if (method.isFactory) { | 1093 if (method.isFactory) { |
| 1094 write('factory '); | 1094 write('factory '); |
| 1095 } else { | 1095 } else { |
| 1096 write(method.isConst ? 'const ' : 'new '); | 1096 write(method.isConst ? 'const ' : 'new '); |
| 1097 } | 1097 } |
| 1098 } | 1098 } |
| 1099 | 1099 |
| 1100 if (method.constructorName == null) { | 1100 if (method.constructorName == null) { |
| 1101 annotateType(host, method.returnType()); | 1101 annotateType(host, method.returnType); |
| 1102 } | 1102 } |
| 1103 | 1103 |
| 1104 var name = method.simpleName(); | 1104 var name = method.simpleName; |
| 1105 // Translate specially-named methods: getters, setters, operators. | 1105 // Translate specially-named methods: getters, setters, operators. |
| 1106 if (method.isGetter) { | 1106 if (method.isGetter) { |
| 1107 // Getter. | 1107 // Getter. |
| 1108 name = 'get $name'; | 1108 name = 'get $name'; |
| 1109 } else if (method.isSetter) { | 1109 } else if (method.isSetter) { |
| 1110 // Setter. | 1110 // Setter. |
| 1111 name = 'set $name'; | 1111 name = 'set $name'; |
| 1112 } else if (method.isOperator) { | 1112 } else if (method.isOperator) { |
| 1113 name = 'operator ${method.operatorName}'; | 1113 name = 'operator ${method.operatorName}'; |
| 1114 } | 1114 } |
| 1115 | 1115 |
| 1116 write('<strong>$name</strong>'); | 1116 write('<strong>$name</strong>'); |
| 1117 | 1117 |
| 1118 // Named constructors. | 1118 // Named constructors. |
| 1119 if (method.constructorName != null && method.constructorName != '') { | 1119 if (method.constructorName != null && method.constructorName != '') { |
| 1120 write('.'); | 1120 write('.'); |
| 1121 write(method.constructorName); | 1121 write(method.constructorName); |
| 1122 } | 1122 } |
| 1123 | 1123 |
| 1124 docParamList(host, method.parameters()); | 1124 docParamList(host, method.parameters); |
| 1125 | 1125 |
| 1126 var prefix = host is LibraryMirror ? '' : '${typeName(host)}.'; | 1126 var prefix = host is LibraryMirror ? '' : '${typeName(host)}.'; |
| 1127 write(''' <a class="anchor-link" href="#${memberAnchor(method)}" | 1127 write(''' <a class="anchor-link" href="#${memberAnchor(method)}" |
| 1128 title="Permalink to $prefix$name">#</a>'''); | 1128 title="Permalink to $prefix$name">#</a>'''); |
| 1129 writeln('</h4>'); | 1129 writeln('</h4>'); |
| 1130 | 1130 |
| 1131 docCode(method.location(), getMethodComment(method), showCode: true); | 1131 docCode(method.location, getMethodComment(method), showCode: true); |
| 1132 | 1132 |
| 1133 writeln('</div>'); | 1133 writeln('</div>'); |
| 1134 } | 1134 } |
| 1135 | 1135 |
| 1136 /** Documents the field [field] of type [type]. */ | 1136 /** Documents the field [field] of type [type]. */ |
| 1137 void docField(ObjectMirror host, FieldMirror field) { | 1137 void docField(ObjectMirror host, FieldMirror field) { |
| 1138 _totalMembers++; | 1138 _totalMembers++; |
| 1139 _currentMember = field; | 1139 _currentMember = field; |
| 1140 | 1140 |
| 1141 writeln('<div class="field"><h4 id="${memberAnchor(field)}">'); | 1141 writeln('<div class="field"><h4 id="${memberAnchor(field)}">'); |
| 1142 | 1142 |
| 1143 if (includeSource) { | 1143 if (includeSource) { |
| 1144 writeln('<span class="show-code">Code</span>'); | 1144 writeln('<span class="show-code">Code</span>'); |
| 1145 } | 1145 } |
| 1146 | 1146 |
| 1147 if (field.isFinal) { | 1147 if (field.isFinal) { |
| 1148 write('final '); | 1148 write('final '); |
| 1149 } else if (field.type().isDynamic) { | 1149 } else if (field.type.isDynamic) { |
| 1150 write('var '); | 1150 write('var '); |
| 1151 } | 1151 } |
| 1152 | 1152 |
| 1153 annotateType(host, field.type()); | 1153 annotateType(host, field.type); |
| 1154 var prefix = host is LibraryMirror ? '' : '${typeName(host)}.'; | 1154 var prefix = host is LibraryMirror ? '' : '${typeName(host)}.'; |
| 1155 write( | 1155 write( |
| 1156 ''' | 1156 ''' |
| 1157 <strong>${field.simpleName()}</strong> <a class="anchor-link" | 1157 <strong>${field.simpleName}</strong> <a class="anchor-link" |
| 1158 href="#${memberAnchor(field)}" | 1158 href="#${memberAnchor(field)}" |
| 1159 title="Permalink to $prefix${field.simpleName()}">#</a> | 1159 title="Permalink to $prefix${field.simpleName}">#</a> |
| 1160 </h4> | 1160 </h4> |
| 1161 '''); | 1161 '''); |
| 1162 | 1162 |
| 1163 docCode(field.location(), getFieldComment(field), showCode: true); | 1163 docCode(field.location, getFieldComment(field), showCode: true); |
| 1164 writeln('</div>'); | 1164 writeln('</div>'); |
| 1165 } | 1165 } |
| 1166 | 1166 |
| 1167 void docParamList(ObjectMirror enclosingType, | 1167 void docParamList(ObjectMirror enclosingType, |
| 1168 List<ParameterMirror> parameters) { | 1168 List<ParameterMirror> parameters) { |
| 1169 write('('); | 1169 write('('); |
| 1170 bool first = true; | 1170 bool first = true; |
| 1171 bool inOptionals = false; | 1171 bool inOptionals = false; |
| 1172 for (final parameter in parameters) { | 1172 for (final parameter in parameters) { |
| 1173 if (!first) write(', '); | 1173 if (!first) write(', '); |
| 1174 | 1174 |
| 1175 if (!inOptionals && parameter.isOptional()) { | 1175 if (!inOptionals && parameter.isOptional) { |
| 1176 write('['); | 1176 write('['); |
| 1177 inOptionals = true; | 1177 inOptionals = true; |
| 1178 } | 1178 } |
| 1179 | 1179 |
| 1180 annotateType(enclosingType, parameter.type(), parameter.simpleName()); | 1180 annotateType(enclosingType, parameter.type, parameter.simpleName); |
| 1181 | 1181 |
| 1182 // Show the default value for named optional parameters. | 1182 // Show the default value for named optional parameters. |
| 1183 if (parameter.isOptional() && parameter.hasDefaultValue()) { | 1183 if (parameter.isOptional && parameter.hasDefaultValue) { |
| 1184 write(' = '); | 1184 write(' = '); |
| 1185 write(parameter.defaultValue()); | 1185 write(parameter.defaultValue); |
| 1186 } | 1186 } |
| 1187 | 1187 |
| 1188 first = false; | 1188 first = false; |
| 1189 } | 1189 } |
| 1190 | 1190 |
| 1191 if (inOptionals) write(']'); | 1191 if (inOptionals) write(']'); |
| 1192 write(')'); | 1192 write(')'); |
| 1193 } | 1193 } |
| 1194 | 1194 |
| 1195 /** | 1195 /** |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1208 writeln('</pre>'); | 1208 writeln('</pre>'); |
| 1209 } | 1209 } |
| 1210 | 1210 |
| 1211 writeln('</div>'); | 1211 writeln('</div>'); |
| 1212 } | 1212 } |
| 1213 | 1213 |
| 1214 | 1214 |
| 1215 /** Get the doc comment associated with the given library. */ | 1215 /** Get the doc comment associated with the given library. */ |
| 1216 String getLibraryComment(LibraryMirror library) { | 1216 String getLibraryComment(LibraryMirror library) { |
| 1217 // Look for a comment for the entire library. | 1217 // Look for a comment for the entire library. |
| 1218 final comment = _comments.findLibrary(library.location().source()); | 1218 final comment = _comments.findLibrary(library.location.source); |
| 1219 if (comment != null) { | 1219 if (comment != null) { |
| 1220 return md.markdownToHtml(comment); | 1220 return md.markdownToHtml(comment); |
| 1221 } | 1221 } |
| 1222 return null; | 1222 return null; |
| 1223 } | 1223 } |
| 1224 | 1224 |
| 1225 /** Get the doc comment associated with the given type. */ | 1225 /** Get the doc comment associated with the given type. */ |
| 1226 String getTypeComment(TypeMirror type) { | 1226 String getTypeComment(TypeMirror type) { |
| 1227 String comment = _comments.find(type.location()); | 1227 String comment = _comments.find(type.location); |
| 1228 if (comment == null) return null; | 1228 if (comment == null) return null; |
| 1229 return commentToHtml(comment); | 1229 return commentToHtml(comment); |
| 1230 } | 1230 } |
| 1231 | 1231 |
| 1232 /** Get the doc comment associated with the given method. */ | 1232 /** Get the doc comment associated with the given method. */ |
| 1233 String getMethodComment(MethodMirror method) { | 1233 String getMethodComment(MethodMirror method) { |
| 1234 String comment = _comments.find(method.location()); | 1234 String comment = _comments.find(method.location); |
| 1235 if (comment == null) return null; | 1235 if (comment == null) return null; |
| 1236 return commentToHtml(comment); | 1236 return commentToHtml(comment); |
| 1237 } | 1237 } |
| 1238 | 1238 |
| 1239 /** Get the doc comment associated with the given field. */ | 1239 /** Get the doc comment associated with the given field. */ |
| 1240 String getFieldComment(FieldMirror field) { | 1240 String getFieldComment(FieldMirror field) { |
| 1241 String comment = _comments.find(field.location()); | 1241 String comment = _comments.find(field.location); |
| 1242 if (comment == null) return null; | 1242 if (comment == null) return null; |
| 1243 return commentToHtml(comment); | 1243 return commentToHtml(comment); |
| 1244 } | 1244 } |
| 1245 | 1245 |
| 1246 String commentToHtml(String comment) => md.markdownToHtml(comment); | 1246 String commentToHtml(String comment) => md.markdownToHtml(comment); |
| 1247 | 1247 |
| 1248 /** | 1248 /** |
| 1249 * Converts [fullPath] which is understood to be a full path from the root of | 1249 * Converts [fullPath] which is understood to be a full path from the root of |
| 1250 * the generated docs to one relative to the current file. | 1250 * the generated docs to one relative to the current file. |
| 1251 */ | 1251 */ |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1262 /** Gets whether or not the given URL is absolute or relative. */ | 1262 /** Gets whether or not the given URL is absolute or relative. */ |
| 1263 bool isAbsolute(String url) { | 1263 bool isAbsolute(String url) { |
| 1264 // TODO(rnystrom): Why don't we have a nice type in the platform for this? | 1264 // TODO(rnystrom): Why don't we have a nice type in the platform for this? |
| 1265 // TODO(rnystrom): This is a bit hackish. We consider any URL that lacks | 1265 // TODO(rnystrom): This is a bit hackish. We consider any URL that lacks |
| 1266 // a scheme to be relative. | 1266 // a scheme to be relative. |
| 1267 return const RegExp(@'^\w+:').hasMatch(url); | 1267 return const RegExp(@'^\w+:').hasMatch(url); |
| 1268 } | 1268 } |
| 1269 | 1269 |
| 1270 /** Gets the URL to the documentation for [library]. */ | 1270 /** Gets the URL to the documentation for [library]. */ |
| 1271 String libraryUrl(LibraryMirror library) { | 1271 String libraryUrl(LibraryMirror library) { |
| 1272 return '${sanitize(library.simpleName())}.html'; | 1272 return '${sanitize(library.simpleName)}.html'; |
| 1273 } | 1273 } |
| 1274 | 1274 |
| 1275 /** Gets the URL for the documentation for [type]. */ | 1275 /** Gets the URL for the documentation for [type]. */ |
| 1276 String typeUrl(ObjectMirror type) { | 1276 String typeUrl(ObjectMirror type) { |
| 1277 if (type is LibraryMirror) { | 1277 if (type is LibraryMirror) { |
| 1278 return '${sanitize(type.simpleName())}.html'; | 1278 return '${sanitize(type.simpleName)}.html'; |
| 1279 } | 1279 } |
| 1280 assert (type is TypeMirror); | 1280 assert (type is TypeMirror); |
| 1281 // Always get the generic type to strip off any type parameters or | 1281 // Always get the generic type to strip off any type parameters or |
| 1282 // arguments. If the type isn't generic, genericType returns `this`, so it | 1282 // arguments. If the type isn't generic, genericType returns `this`, so it |
| 1283 // works for non-generic types too. | 1283 // works for non-generic types too. |
| 1284 return '${sanitize(type.library().simpleName())}/' | 1284 return '${sanitize(type.library.simpleName)}/' |
| 1285 '${type.declaration.simpleName()}.html'; | 1285 '${type.declaration.simpleName}.html'; |
| 1286 } | 1286 } |
| 1287 | 1287 |
| 1288 /** Gets the URL for the documentation for [member]. */ | 1288 /** Gets the URL for the documentation for [member]. */ |
| 1289 String memberUrl(MemberMirror member) { | 1289 String memberUrl(MemberMirror member) { |
| 1290 String url = typeUrl(member.surroundingDeclaration()); | 1290 String url = typeUrl(member.surroundingDeclaration); |
| 1291 if (!member.isConstructor) { | 1291 if (!member.isConstructor) { |
| 1292 return '$url#${member.simpleName()}'; | 1292 return '$url#${member.simpleName}'; |
| 1293 } | 1293 } |
| 1294 assert (member is MethodMirror); | 1294 assert (member is MethodMirror); |
| 1295 if (member.constructorName == '') { | 1295 if (member.constructorName == '') { |
| 1296 return '$url#new:${member.simpleName()}'; | 1296 return '$url#new:${member.simpleName}'; |
| 1297 } | 1297 } |
| 1298 return '$url#new:${member.simpleName()}.${member.constructorName}'; | 1298 return '$url#new:${member.simpleName}.${member.constructorName}'; |
| 1299 } | 1299 } |
| 1300 | 1300 |
| 1301 /** Gets the anchor id for the document for [member]. */ | 1301 /** Gets the anchor id for the document for [member]. */ |
| 1302 String memberAnchor(MemberMirror member) { | 1302 String memberAnchor(MemberMirror member) { |
| 1303 return '${member.simpleName()}'; | 1303 return '${member.simpleName}'; |
| 1304 } | 1304 } |
| 1305 | 1305 |
| 1306 /** | 1306 /** |
| 1307 * Creates a hyperlink. Handles turning the [href] into an appropriate | 1307 * Creates a hyperlink. Handles turning the [href] into an appropriate |
| 1308 * relative path from the current file. | 1308 * relative path from the current file. |
| 1309 */ | 1309 */ |
| 1310 String a(String href, String contents, [String css]) { | 1310 String a(String href, String contents, [String css]) { |
| 1311 // Mark outgoing external links, mainly so we can style them. | 1311 // Mark outgoing external links, mainly so we can style them. |
| 1312 final rel = isAbsolute(href) ? ' ref="external"' : ''; | 1312 final rel = isAbsolute(href) ? ' ref="external"' : ''; |
| 1313 final cssClass = css == null ? '' : ' class="$css"'; | 1313 final cssClass = css == null ? '' : ' class="$css"'; |
| 1314 return '<a href="${relativePath(href)}"$cssClass$rel>$contents</a>'; | 1314 return '<a href="${relativePath(href)}"$cssClass$rel>$contents</a>'; |
| 1315 } | 1315 } |
| 1316 | 1316 |
| 1317 /** | 1317 /** |
| 1318 * Writes a type annotation for the given type and (optional) parameter name. | 1318 * Writes a type annotation for the given type and (optional) parameter name. |
| 1319 */ | 1319 */ |
| 1320 annotateType(ObjectMirror enclosingType, | 1320 annotateType(ObjectMirror enclosingType, |
| 1321 TypeMirror type, | 1321 TypeMirror type, |
| 1322 [String paramName = null]) { | 1322 [String paramName = null]) { |
| 1323 // Don't bother explicitly displaying Dynamic. | 1323 // Don't bother explicitly displaying Dynamic. |
| 1324 if (type.isDynamic) { | 1324 if (type.isDynamic) { |
| 1325 if (paramName !== null) write(paramName); | 1325 if (paramName !== null) write(paramName); |
| 1326 return; | 1326 return; |
| 1327 } | 1327 } |
| 1328 | 1328 |
| 1329 // For parameters, handle non-typedefed function types. | 1329 // For parameters, handle non-typedefed function types. |
| 1330 if (paramName !== null && type is FunctionTypeMirror) { | 1330 if (paramName !== null && type is FunctionTypeMirror) { |
| 1331 annotateType(enclosingType, type.returnType()); | 1331 annotateType(enclosingType, type.returnType); |
| 1332 write(paramName); | 1332 write(paramName); |
| 1333 | 1333 |
| 1334 docParamList(enclosingType, type.parameters()); | 1334 docParamList(enclosingType, type.parameters); |
| 1335 return; | 1335 return; |
| 1336 } | 1336 } |
| 1337 | 1337 |
| 1338 linkToType(enclosingType, type); | 1338 linkToType(enclosingType, type); |
| 1339 | 1339 |
| 1340 write(' '); | 1340 write(' '); |
| 1341 if (paramName !== null) write(paramName); | 1341 if (paramName !== null) write(paramName); |
| 1342 } | 1342 } |
| 1343 | 1343 |
| 1344 /** Writes a link to a human-friendly string representation for a type. */ | 1344 /** Writes a link to a human-friendly string representation for a type. */ |
| 1345 linkToType(ObjectMirror enclosingType, TypeMirror type) { | 1345 linkToType(ObjectMirror enclosingType, TypeMirror type) { |
| 1346 if (type.isVoid) { | 1346 if (type.isVoid) { |
| 1347 // Do not generate links for void. | 1347 // Do not generate links for void. |
| 1348 // TODO(johnniwinter): Generate span for specific style? | 1348 // TODO(johnniwinter): Generate span for specific style? |
| 1349 write('void'); | 1349 write('void'); |
| 1350 return; | 1350 return; |
| 1351 } | 1351 } |
| 1352 if (type.isDynamic) { | 1352 if (type.isDynamic) { |
| 1353 // Do not generate links for Dynamic. | 1353 // Do not generate links for Dynamic. |
| 1354 write('Dynamic'); | 1354 write('Dynamic'); |
| 1355 return; | 1355 return; |
| 1356 } | 1356 } |
| 1357 | 1357 |
| 1358 if (type.isTypeVariable) { | 1358 if (type.isTypeVariable) { |
| 1359 // If we're using a type parameter within the body of a generic class then | 1359 // If we're using a type parameter within the body of a generic class then |
| 1360 // just link back up to the class. | 1360 // just link back up to the class. |
| 1361 write(a(typeUrl(enclosingType), type.simpleName())); | 1361 write(a(typeUrl(enclosingType), type.simpleName)); |
| 1362 return; | 1362 return; |
| 1363 } | 1363 } |
| 1364 | 1364 |
| 1365 assert(type is InterfaceMirror); | 1365 assert(type is InterfaceMirror); |
| 1366 | 1366 |
| 1367 // Link to the type. | 1367 // Link to the type. |
| 1368 if (shouldLinkToPublicApi(type.library())) { | 1368 if (shouldLinkToPublicApi(type.library)) { |
| 1369 write('<a href="$API_LOCATION${typeUrl(type)}">${type.simpleName()}</a>'); | 1369 write('<a href="$API_LOCATION${typeUrl(type)}">${type.simpleName}</a>'); |
| 1370 } else if (shouldIncludeLibrary(type.library())) { | 1370 } else if (shouldIncludeLibrary(type.library)) { |
| 1371 write(a(typeUrl(type), type.simpleName())); | 1371 write(a(typeUrl(type), type.simpleName)); |
| 1372 } else { | 1372 } else { |
| 1373 write(type.simpleName()); | 1373 write(type.simpleName); |
| 1374 } | 1374 } |
| 1375 | 1375 |
| 1376 if (type.isDeclaration) { | 1376 if (type.isDeclaration) { |
| 1377 // Avoid calling [:typeArguments():] on a declaration. | 1377 // Avoid calling [:typeArguments():] on a declaration. |
| 1378 return; | 1378 return; |
| 1379 } | 1379 } |
| 1380 | 1380 |
| 1381 // See if it's an instantiation of a generic type. | 1381 // See if it's an instantiation of a generic type. |
| 1382 final typeArgs = type.typeArguments(); | 1382 final typeArgs = type.typeArguments; |
| 1383 if (typeArgs.length > 0) { | 1383 if (typeArgs.length > 0) { |
| 1384 write('<'); | 1384 write('<'); |
| 1385 bool first = true; | 1385 bool first = true; |
| 1386 for (final arg in typeArgs) { | 1386 for (final arg in typeArgs) { |
| 1387 if (!first) write(', '); | 1387 if (!first) write(', '); |
| 1388 first = false; | 1388 first = false; |
| 1389 linkToType(enclosingType, arg); | 1389 linkToType(enclosingType, arg); |
| 1390 } | 1390 } |
| 1391 write('>'); | 1391 write('>'); |
| 1392 } | 1392 } |
| 1393 } | 1393 } |
| 1394 | 1394 |
| 1395 /** Creates a linked cross reference to [type]. */ | 1395 /** Creates a linked cross reference to [type]. */ |
| 1396 typeReference(InterfaceMirror type) { | 1396 typeReference(InterfaceMirror type) { |
| 1397 // TODO(rnystrom): Do we need to handle ParameterTypes here like | 1397 // TODO(rnystrom): Do we need to handle ParameterTypes here like |
| 1398 // annotation() does? | 1398 // annotation() does? |
| 1399 return a(typeUrl(type), typeName(type), css: 'crossref'); | 1399 return a(typeUrl(type), typeName(type), css: 'crossref'); |
| 1400 } | 1400 } |
| 1401 | 1401 |
| 1402 /** Generates a human-friendly string representation for a type. */ | 1402 /** Generates a human-friendly string representation for a type. */ |
| 1403 typeName(TypeMirror type, [bool showBounds = false]) { | 1403 typeName(TypeMirror type, [bool showBounds = false]) { |
| 1404 if (type.isVoid) { | 1404 if (type.isVoid) { |
| 1405 return 'void'; | 1405 return 'void'; |
| 1406 } | 1406 } |
| 1407 if (type is TypeVariableMirror) { | 1407 if (type is TypeVariableMirror) { |
| 1408 return type.simpleName(); | 1408 return type.simpleName; |
| 1409 } | 1409 } |
| 1410 assert (type is InterfaceMirror); | 1410 assert (type is InterfaceMirror); |
| 1411 | 1411 |
| 1412 // See if it's a generic type. | 1412 // See if it's a generic type. |
| 1413 if (type.isDeclaration) { | 1413 if (type.isDeclaration) { |
| 1414 final typeParams = []; | 1414 final typeParams = []; |
| 1415 for (final typeParam in type.declaration.typeVariables()) { | 1415 for (final typeParam in type.declaration.typeVariables) { |
| 1416 if (showBounds && | 1416 if (showBounds && |
| 1417 (typeParam.bound() != null) && | 1417 (typeParam.bound != null) && |
| 1418 !typeParam.bound().isObject) { | 1418 !typeParam.bound.isObject) { |
| 1419 final bound = typeName(typeParam.bound(), showBounds: true); | 1419 final bound = typeName(typeParam.bound, showBounds: true); |
| 1420 typeParams.add('${typeParam.simpleName()} extends $bound'); | 1420 typeParams.add('${typeParam.simpleName} extends $bound'); |
| 1421 } else { | 1421 } else { |
| 1422 typeParams.add(typeParam.simpleName()); | 1422 typeParams.add(typeParam.simpleName); |
| 1423 } | 1423 } |
| 1424 } | 1424 } |
| 1425 if (typeParams.isEmpty()) { | 1425 if (typeParams.isEmpty()) { |
| 1426 return type.simpleName(); | 1426 return type.simpleName; |
| 1427 } | 1427 } |
| 1428 final params = Strings.join(typeParams, ', '); | 1428 final params = Strings.join(typeParams, ', '); |
| 1429 return '${type.simpleName()}<$params>'; | 1429 return '${type.simpleName}<$params>'; |
| 1430 } | 1430 } |
| 1431 | 1431 |
| 1432 // See if it's an instantiation of a generic type. | 1432 // See if it's an instantiation of a generic type. |
| 1433 final typeArgs = type.typeArguments(); | 1433 final typeArgs = type.typeArguments; |
| 1434 if (typeArgs.length > 0) { | 1434 if (typeArgs.length > 0) { |
| 1435 final args = Strings.join(typeArgs.map((arg) => typeName(arg)), ', '); | 1435 final args = Strings.join(typeArgs.map((arg) => typeName(arg)), ', '); |
| 1436 return '${type.declaration.simpleName()}<$args>'; | 1436 return '${type.declaration.simpleName}<$args>'; |
| 1437 } | 1437 } |
| 1438 | 1438 |
| 1439 // Regular type. | 1439 // Regular type. |
| 1440 return type.simpleName(); | 1440 return type.simpleName; |
| 1441 } | 1441 } |
| 1442 | 1442 |
| 1443 /** | 1443 /** |
| 1444 * Remove leading indentation to line up with first line. | 1444 * Remove leading indentation to line up with first line. |
| 1445 */ | 1445 */ |
| 1446 unindentCode(Location span) { | 1446 unindentCode(Location span) { |
| 1447 final column = getLocationColumn(span); | 1447 final column = getLocationColumn(span); |
| 1448 final lines = span.text().split('\n'); | 1448 final lines = span.text.split('\n'); |
| 1449 // TODO(rnystrom): Dirty hack. | 1449 // TODO(rnystrom): Dirty hack. |
| 1450 for (var i = 1; i < lines.length; i++) { | 1450 for (var i = 1; i < lines.length; i++) { |
| 1451 lines[i] = unindent(lines[i], column); | 1451 lines[i] = unindent(lines[i], column); |
| 1452 } | 1452 } |
| 1453 | 1453 |
| 1454 final code = Strings.join(lines, '\n'); | 1454 final code = Strings.join(lines, '\n'); |
| 1455 return code; | 1455 return code; |
| 1456 } | 1456 } |
| 1457 | 1457 |
| 1458 /** | 1458 /** |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1476 LibraryMirror currentLibrary = null]) { | 1476 LibraryMirror currentLibrary = null]) { |
| 1477 makeLink(String href) { | 1477 makeLink(String href) { |
| 1478 final anchor = new md.Element.text('a', name); | 1478 final anchor = new md.Element.text('a', name); |
| 1479 anchor.attributes['href'] = relativePath(href); | 1479 anchor.attributes['href'] = relativePath(href); |
| 1480 anchor.attributes['class'] = 'crossref'; | 1480 anchor.attributes['class'] = 'crossref'; |
| 1481 return anchor; | 1481 return anchor; |
| 1482 } | 1482 } |
| 1483 | 1483 |
| 1484 // See if it's a parameter of the current method. | 1484 // See if it's a parameter of the current method. |
| 1485 if (currentMember is MethodMirror) { | 1485 if (currentMember is MethodMirror) { |
| 1486 for (final parameter in currentMember.parameters()) { | 1486 for (final parameter in currentMember.parameters) { |
| 1487 if (parameter.simpleName() == name) { | 1487 if (parameter.simpleName == name) { |
| 1488 final element = new md.Element.text('span', name); | 1488 final element = new md.Element.text('span', name); |
| 1489 element.attributes['class'] = 'param'; | 1489 element.attributes['class'] = 'param'; |
| 1490 return element; | 1490 return element; |
| 1491 } | 1491 } |
| 1492 } | 1492 } |
| 1493 } | 1493 } |
| 1494 | 1494 |
| 1495 // See if it's another member of the current type. | 1495 // See if it's another member of the current type. |
| 1496 if (currentType != null) { | 1496 if (currentType != null) { |
| 1497 final foundMember = findMirror(currentType.declaredMembers(), name); | 1497 final foundMember = findMirror(currentType.declaredMembers, name); |
| 1498 if (foundMember != null) { | 1498 if (foundMember != null) { |
| 1499 return makeLink(memberUrl(foundMember)); | 1499 return makeLink(memberUrl(foundMember)); |
| 1500 } | 1500 } |
| 1501 } | 1501 } |
| 1502 | 1502 |
| 1503 // See if it's another type or a member of another type in the current | 1503 // See if it's another type or a member of another type in the current |
| 1504 // library. | 1504 // library. |
| 1505 if (currentLibrary != null) { | 1505 if (currentLibrary != null) { |
| 1506 // See if it's a constructor | 1506 // See if it's a constructor |
| 1507 final constructorLink = (() { | 1507 final constructorLink = (() { |
| 1508 final match = | 1508 final match = |
| 1509 new RegExp(@'new ([\w$]+)(?:\.([\w$]+))?').firstMatch(name); | 1509 new RegExp(@'new ([\w$]+)(?:\.([\w$]+))?').firstMatch(name); |
| 1510 if (match == null) return; | 1510 if (match == null) return; |
| 1511 InterfaceMirror foundtype = findMirror(currentLibrary.types(), match[1])
; | 1511 InterfaceMirror foundtype = findMirror(currentLibrary.types, match[1]); |
| 1512 if (foundtype == null) return; | 1512 if (foundtype == null) return; |
| 1513 final constructor = | 1513 final constructor = |
| 1514 findMirror(foundtype.constructors(), | 1514 findMirror(foundtype.constructors, |
| 1515 match[2] == null ? '' : match[2]); | 1515 match[2] == null ? '' : match[2]); |
| 1516 if (constructor == null) return; | 1516 if (constructor == null) return; |
| 1517 return makeLink(memberUrl(constructor)); | 1517 return makeLink(memberUrl(constructor)); |
| 1518 })(); | 1518 })(); |
| 1519 if (constructorLink != null) return constructorLink; | 1519 if (constructorLink != null) return constructorLink; |
| 1520 | 1520 |
| 1521 // See if it's a member of another type | 1521 // See if it's a member of another type |
| 1522 final foreignMemberLink = (() { | 1522 final foreignMemberLink = (() { |
| 1523 final match = new RegExp(@'([\w$]+)\.([\w$]+)').firstMatch(name); | 1523 final match = new RegExp(@'([\w$]+)\.([\w$]+)').firstMatch(name); |
| 1524 if (match == null) return; | 1524 if (match == null) return; |
| 1525 InterfaceMirror foundtype = findMirror(currentLibrary.types(), match[1])
; | 1525 InterfaceMirror foundtype = findMirror(currentLibrary.types, match[1]); |
| 1526 if (foundtype == null) return; | 1526 if (foundtype == null) return; |
| 1527 MemberMirror foundMember = findMirror(foundtype.declaredMembers(), match
[2]); | 1527 MemberMirror foundMember = findMirror(foundtype.declaredMembers, match[2
]); |
| 1528 if (foundMember == null) return; | 1528 if (foundMember == null) return; |
| 1529 return makeLink(memberUrl(foundMember)); | 1529 return makeLink(memberUrl(foundMember)); |
| 1530 })(); | 1530 })(); |
| 1531 if (foreignMemberLink != null) return foreignMemberLink; | 1531 if (foreignMemberLink != null) return foreignMemberLink; |
| 1532 | 1532 |
| 1533 InterfaceMirror foundType = findMirror(currentLibrary.types(), name); | 1533 InterfaceMirror foundType = findMirror(currentLibrary.types, name); |
| 1534 if (foundType != null) { | 1534 if (foundType != null) { |
| 1535 return makeLink(typeUrl(foundType)); | 1535 return makeLink(typeUrl(foundType)); |
| 1536 } | 1536 } |
| 1537 | 1537 |
| 1538 // See if it's a top-level member in the current library. | 1538 // See if it's a top-level member in the current library. |
| 1539 MemberMirror foundMember = findMirror(currentLibrary.declaredMembers(), na
me); | 1539 MemberMirror foundMember = findMirror(currentLibrary.declaredMembers, name
); |
| 1540 if (foundMember != null) { | 1540 if (foundMember != null) { |
| 1541 return makeLink(memberUrl(foundMember)); | 1541 return makeLink(memberUrl(foundMember)); |
| 1542 } | 1542 } |
| 1543 } | 1543 } |
| 1544 | 1544 |
| 1545 // TODO(rnystrom): Should also consider: | 1545 // TODO(rnystrom): Should also consider: |
| 1546 // * Names imported by libraries this library imports. | 1546 // * Names imported by libraries this library imports. |
| 1547 // * Type parameters of the enclosing type. | 1547 // * Type parameters of the enclosing type. |
| 1548 | 1548 |
| 1549 return new md.Element.text('code', name); | 1549 return new md.Element.text('code', name); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1580 Path relativeFilePath = filePath.relativeTo(outputDir); | 1580 Path relativeFilePath = filePath.relativeTo(outputDir); |
| 1581 write("$relativeFilePath\n"); | 1581 write("$relativeFilePath\n"); |
| 1582 }; | 1582 }; |
| 1583 toCacheLister.onDone = (done) => endFile(); | 1583 toCacheLister.onDone = (done) => endFile(); |
| 1584 } | 1584 } |
| 1585 | 1585 |
| 1586 /** | 1586 /** |
| 1587 * Returns [:true:] if [type] should be regarded as an exception. | 1587 * Returns [:true:] if [type] should be regarded as an exception. |
| 1588 */ | 1588 */ |
| 1589 bool isException(TypeMirror type) { | 1589 bool isException(TypeMirror type) { |
| 1590 return type.simpleName().endsWith('Exception'); | 1590 return type.simpleName.endsWith('Exception'); |
| 1591 } | 1591 } |
| 1592 } | 1592 } |
| 1593 | 1593 |
| OLD | NEW |