| 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 12 matching lines...) Expand all Loading... |
| 23 #import('mirrors/mirrors.dart'); | 23 #import('mirrors/mirrors.dart'); |
| 24 #import('mirrors/mirrors_util.dart'); | 24 #import('mirrors/mirrors_util.dart'); |
| 25 #import('mirrors/dart2js_mirror.dart', prefix: 'dart2js'); | 25 #import('mirrors/dart2js_mirror.dart', prefix: 'dart2js'); |
| 26 #import('classify.dart'); | 26 #import('classify.dart'); |
| 27 #import('markdown.dart', prefix: 'md'); | 27 #import('markdown.dart', prefix: 'md'); |
| 28 #import('../../lib/compiler/implementation/scanner/scannerlib.dart', | 28 #import('../../lib/compiler/implementation/scanner/scannerlib.dart', |
| 29 prefix: 'dart2js'); | 29 prefix: 'dart2js'); |
| 30 #import('../../lib/compiler/implementation/library_map.dart'); | 30 #import('../../lib/compiler/implementation/library_map.dart'); |
| 31 | 31 |
| 32 #source('comment_map.dart'); | 32 #source('comment_map.dart'); |
| 33 #source('nav.dart'); |
| 33 #source('utils.dart'); | 34 #source('utils.dart'); |
| 34 | 35 |
| 35 // TODO(johnniwinther): Note that [IN_SDK] gets initialized to true when this | 36 // TODO(johnniwinther): Note that [IN_SDK] gets initialized to true when this |
| 36 // file is modified by the SDK deployment script. If you change, be sure to test | 37 // file is modified by the SDK deployment script. If you change, be sure to test |
| 37 // that dartdoc still works when run from the built SDK directory. | 38 // that dartdoc still works when run from the built SDK directory. |
| 38 final bool IN_SDK = false; | 39 final bool IN_SDK = false; |
| 39 | 40 |
| 40 /** | 41 /** |
| 41 * Generates completely static HTML containing everything you need to browse | 42 * Generates completely static HTML containing everything you need to browse |
| 42 * the docs. The only client side behavior is trivial stuff like syntax | 43 * the docs. The only client side behavior is trivial stuff like syntax |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 // Compile the client-side code to JS. | 154 // Compile the client-side code to JS. |
| 154 final clientScript = (dartdoc.mode == MODE_STATIC) ? 'static' : 'live-nav'; | 155 final clientScript = (dartdoc.mode == MODE_STATIC) ? 'static' : 'live-nav'; |
| 155 Future compiled = compileScript( | 156 Future compiled = compileScript( |
| 156 scriptDir.append('client-$clientScript.dart'), | 157 scriptDir.append('client-$clientScript.dart'), |
| 157 dartdoc.outputDir.append('client-$clientScript.js')); | 158 dartdoc.outputDir.append('client-$clientScript.js')); |
| 158 | 159 |
| 159 Future filesCopied = copyDirectory(scriptDir.append('static'), | 160 Future filesCopied = copyDirectory(scriptDir.append('static'), |
| 160 dartdoc.outputDir); | 161 dartdoc.outputDir); |
| 161 | 162 |
| 162 Futures.wait([compiled, filesCopied]).then((_) { | 163 Futures.wait([compiled, filesCopied]).then((_) { |
| 164 dartdoc.cleanup(); |
| 163 print('Documented ${dartdoc._totalLibraries} libraries, ' | 165 print('Documented ${dartdoc._totalLibraries} libraries, ' |
| 164 '${dartdoc._totalTypes} types, and ' | 166 '${dartdoc._totalTypes} types, and ' |
| 165 '${dartdoc._totalMembers} members.'); | 167 '${dartdoc._totalMembers} members.'); |
| 166 }); | 168 }); |
| 167 } | 169 } |
| 168 | 170 |
| 169 void printUsage() { | 171 void printUsage() { |
| 170 print(''' | 172 print(''' |
| 171 Usage dartdoc [options] <entrypoint(s)> | 173 Usage dartdoc [options] <entrypoint(s)> |
| 172 [options] include | 174 [options] include |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 * want the client-side behavior to be. The value for this should be one of | 309 * want the client-side behavior to be. The value for this should be one of |
| 308 * the `MODE_` constants. | 310 * the `MODE_` constants. |
| 309 */ | 311 */ |
| 310 int mode = MODE_LIVE_NAV; | 312 int mode = MODE_LIVE_NAV; |
| 311 | 313 |
| 312 /** | 314 /** |
| 313 * Generates the App Cache manifest file, enabling offline doc viewing. | 315 * Generates the App Cache manifest file, enabling offline doc viewing. |
| 314 */ | 316 */ |
| 315 bool generateAppCache = false; | 317 bool generateAppCache = false; |
| 316 | 318 |
| 319 /** Path to the dartdoc directory. */ |
| 320 Path dartdocPath; |
| 321 |
| 317 /** Path to generate HTML files into. */ | 322 /** Path to generate HTML files into. */ |
| 318 Path outputDir = const Path('docs'); | 323 Path outputDir = const Path('docs'); |
| 319 | 324 |
| 320 /** | 325 /** |
| 321 * The title used for the overall generated output. Set this to change it. | 326 * The title used for the overall generated output. Set this to change it. |
| 322 */ | 327 */ |
| 323 String mainTitle = 'Dart Documentation'; | 328 String mainTitle = 'Dart Documentation'; |
| 324 | 329 |
| 325 /** | 330 /** |
| 326 * The URL that the Dart logo links to. Defaults "index.html", the main | 331 * The URL that the Dart logo links to. Defaults "index.html", the main |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 Path _filePath; | 386 Path _filePath; |
| 382 | 387 |
| 383 /** The file currently being written to. */ | 388 /** The file currently being written to. */ |
| 384 StringBuffer _file; | 389 StringBuffer _file; |
| 385 | 390 |
| 386 int _totalLibraries = 0; | 391 int _totalLibraries = 0; |
| 387 int _totalTypes = 0; | 392 int _totalTypes = 0; |
| 388 int _totalMembers = 0; | 393 int _totalMembers = 0; |
| 389 | 394 |
| 390 Dartdoc() | 395 Dartdoc() |
| 391 : _comments = new CommentMap() { | 396 : _comments = new CommentMap(), |
| 397 dartdocPath = scriptDir { |
| 398 |
| 392 // Patch in support for [:...:]-style code to the markdown parser. | 399 // Patch in support for [:...:]-style code to the markdown parser. |
| 393 // TODO(rnystrom): Markdown already has syntax for this. Phase this out? | 400 // TODO(rnystrom): Markdown already has syntax for this. Phase this out? |
| 394 md.InlineParser.syntaxes.insertRange(0, 1, | 401 md.InlineParser.syntaxes.insertRange(0, 1, |
| 395 new md.CodeSyntax(@'\[\:((?:.|\n)*?)\:\]')); | 402 new md.CodeSyntax(@'\[\:((?:.|\n)*?)\:\]')); |
| 396 | 403 |
| 397 md.setImplicitLinkResolver((name) => resolveNameReference(name, | 404 md.setImplicitLinkResolver((name) => resolveNameReference(name, |
| 398 currentLibrary: _currentLibrary, currentType: _currentType, | 405 currentLibrary: _currentLibrary, currentType: _currentType, |
| 399 currentMember: _currentMember)); | 406 currentMember: _currentMember)); |
| 400 } | 407 } |
| 401 | 408 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 // Sort the libraries by name (not key). | 484 // Sort the libraries by name (not key). |
| 478 _sortedLibraries = new List<LibraryMirror>.from( | 485 _sortedLibraries = new List<LibraryMirror>.from( |
| 479 compilation.mirrors.libraries.getValues().filter( | 486 compilation.mirrors.libraries.getValues().filter( |
| 480 shouldIncludeLibrary)); | 487 shouldIncludeLibrary)); |
| 481 _sortedLibraries.sort((x, y) { | 488 _sortedLibraries.sort((x, y) { |
| 482 return x.simpleName.toUpperCase().compareTo( | 489 return x.simpleName.toUpperCase().compareTo( |
| 483 y.simpleName.toUpperCase()); | 490 y.simpleName.toUpperCase()); |
| 484 }); | 491 }); |
| 485 | 492 |
| 486 // Generate the docs. | 493 // Generate the docs. |
| 487 if (mode == MODE_LIVE_NAV) docNavigationJson(); | 494 if (mode == MODE_LIVE_NAV) { |
| 495 docNavigationJson(); |
| 496 } else { |
| 497 docNavigationDart(); |
| 498 } |
| 488 | 499 |
| 489 docIndex(); | 500 docIndex(); |
| 490 for (final library in _sortedLibraries) { | 501 for (final library in _sortedLibraries) { |
| 491 docLibrary(library); | 502 docLibrary(library); |
| 492 } | 503 } |
| 493 | 504 |
| 494 if (generateAppCache) { | 505 if (generateAppCache) { |
| 495 generateAppCacheManifest(); | 506 generateAppCacheManifest(); |
| 496 } | 507 } |
| 497 } | 508 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 } | 594 } |
| 584 | 595 |
| 585 if (searchEngineId != null) { | 596 if (searchEngineId != null) { |
| 586 writeln( | 597 writeln( |
| 587 ''' | 598 ''' |
| 588 <form action="$searchResultsUrl" id="search-box"> | 599 <form action="$searchResultsUrl" id="search-box"> |
| 589 <input type="hidden" name="cx" value="$searchEngineId"> | 600 <input type="hidden" name="cx" value="$searchEngineId"> |
| 590 <input type="hidden" name="ie" value="UTF-8"> | 601 <input type="hidden" name="ie" value="UTF-8"> |
| 591 <input type="hidden" name="hl" value="en"> | 602 <input type="hidden" name="hl" value="en"> |
| 592 <input type="search" name="q" id="q" autocomplete="off" | 603 <input type="search" name="q" id="q" autocomplete="off" |
| 593 placeholder="Search"> | 604 class="search-input" placeholder="Search API"> |
| 594 </form> | 605 </form> |
| 595 '''); | 606 '''); |
| 607 } else { |
| 608 writeln( |
| 609 ''' |
| 610 <div id="search-box"> |
| 611 <input type="search" name="q" id="q" autocomplete="off" |
| 612 class="search-input" placeholder="Search API"> |
| 613 </div> |
| 614 '''); |
| 596 } | 615 } |
| 597 | 616 |
| 598 writeln('</div>'); | 617 writeln( |
| 618 ''' |
| 619 </div> |
| 620 <div class="drop-down" id="drop-down"></div> |
| 621 '''); |
| 599 | 622 |
| 600 docNavigation(); | 623 docNavigation(); |
| 601 writeln('<div class="content">'); | 624 writeln('<div class="content">'); |
| 602 } | 625 } |
| 603 | 626 |
| 604 String get clientScript() { | 627 String get clientScript() { |
| 605 switch (mode) { | 628 switch (mode) { |
| 606 case MODE_STATIC: return 'client-static'; | 629 case MODE_STATIC: return 'client-static'; |
| 607 case MODE_LIVE_NAV: return 'client-live-nav'; | 630 case MODE_LIVE_NAV: return 'client-live-nav'; |
| 608 default: throw 'Unknown mode $mode.'; | 631 default: throw 'Unknown mode $mode.'; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 void docIndexLibrary(LibraryMirror library) { | 678 void docIndexLibrary(LibraryMirror library) { |
| 656 writeln('<h4>${a(libraryUrl(library), library.simpleName)}</h4>'); | 679 writeln('<h4>${a(libraryUrl(library), library.simpleName)}</h4>'); |
| 657 } | 680 } |
| 658 | 681 |
| 659 /** | 682 /** |
| 660 * Walks the libraries and creates a JSON object containing the data needed | 683 * Walks the libraries and creates a JSON object containing the data needed |
| 661 * to generate navigation for them. | 684 * to generate navigation for them. |
| 662 */ | 685 */ |
| 663 void docNavigationJson() { | 686 void docNavigationJson() { |
| 664 startFile('nav.json'); | 687 startFile('nav.json'); |
| 665 | 688 writeln(JSON.stringify(createNavigationInfo())); |
| 666 final libraryMap = {}; | |
| 667 | |
| 668 for (final library in _sortedLibraries) { | |
| 669 docLibraryNavigationJson(library, libraryMap); | |
| 670 } | |
| 671 | |
| 672 writeln(JSON.stringify(libraryMap)); | |
| 673 endFile(); | 689 endFile(); |
| 674 } | 690 } |
| 675 | 691 |
| 676 void docLibraryNavigationJson(LibraryMirror library, Map libraryMap) { | 692 void docNavigationDart() { |
| 693 final dir = new Directory.fromPath(tmpPath); |
| 694 if (!dir.existsSync()) { |
| 695 // TODO(3914): Hack to avoid 'file already exists' exception |
| 696 // thrown due to invalid result from dir.existsSync() (probably due to |
| 697 // race conditions). |
| 698 try { |
| 699 dir.createSync(); |
| 700 } catch (DirectoryIOException e) { |
| 701 // Ignore. |
| 702 } |
| 703 } |
| 704 String jsonString = JSON.stringify(createNavigationInfo()); |
| 705 String dartString = jsonString.replaceAll(@"$", @"\$"); |
| 706 final filePath = tmpPath.append('nav.dart'); |
| 707 writeString(new File.fromPath(filePath), |
| 708 'get json() => $dartString;'); |
| 709 } |
| 710 |
| 711 Path get tmpPath() => dartdocPath.append('tmp'); |
| 712 |
| 713 void cleanup() { |
| 714 final dir = new Directory.fromPath(tmpPath); |
| 715 if (dir.existsSync()) { |
| 716 dir.deleteRecursivelySync(); |
| 717 } |
| 718 } |
| 719 |
| 720 List createNavigationInfo() { |
| 721 final libraryList = []; |
| 722 for (final library in _sortedLibraries) { |
| 723 docLibraryNavigationJson(library, libraryList); |
| 724 } |
| 725 return libraryList; |
| 726 } |
| 727 |
| 728 void docLibraryNavigationJson(LibraryMirror library, List libraryList) { |
| 729 var libraryInfo = {}; |
| 730 libraryInfo[NAME] = library.simpleName; |
| 731 final List members = docMembersJson(library.declaredMembers); |
| 732 if (!members.isEmpty()) { |
| 733 libraryInfo[MEMBERS] = members; |
| 734 } |
| 735 |
| 677 final types = []; | 736 final types = []; |
| 678 | |
| 679 for (InterfaceMirror type in orderByName(library.types.getValues())) { | 737 for (InterfaceMirror type in orderByName(library.types.getValues())) { |
| 680 if (type.isPrivate) continue; | 738 if (type.isPrivate) continue; |
| 681 | 739 |
| 682 final kind = type.isClass ? 'class' : 'interface'; | 740 var typeInfo = {}; |
| 683 final url = typeUrl(type); | 741 typeInfo[NAME] = type.simpleName; |
| 684 types.add({ 'name': typeName(type), 'kind': kind, 'url': url }); | 742 if (type.isClass) { |
| 743 typeInfo[KIND] = CLASS; |
| 744 } else if (type.isInterface) { |
| 745 typeInfo[KIND] = INTERFACE; |
| 746 } else { |
| 747 assert(type.isTypedef); |
| 748 typeInfo[KIND] = TYPEDEF; |
| 749 } |
| 750 final List typeMembers = docMembersJson(type.declaredMembers); |
| 751 if (!typeMembers.isEmpty()) { |
| 752 typeInfo[MEMBERS] = typeMembers; |
| 753 } |
| 754 |
| 755 if (!type.declaration.typeVariables.isEmpty()) { |
| 756 final typeVariables = []; |
| 757 for (final typeVariable in type.declaration.typeVariables) { |
| 758 typeVariables.add(typeVariable.simpleName); |
| 759 } |
| 760 typeInfo[ARGS] = Strings.join(typeVariables, ', '); |
| 761 } |
| 762 types.add(typeInfo); |
| 763 } |
| 764 if (!types.isEmpty()) { |
| 765 libraryInfo[TYPES] = types; |
| 685 } | 766 } |
| 686 | 767 |
| 687 libraryMap[library.simpleName] = types; | 768 libraryList.add(libraryInfo); |
| 769 } |
| 770 |
| 771 List docMembersJson(Map<Object,MemberMirror> memberMap) { |
| 772 final members = []; |
| 773 for (MemberMirror member in orderByName(memberMap.getValues())) { |
| 774 if (member.isPrivate) continue; |
| 775 |
| 776 var memberInfo = {}; |
| 777 if (member.isField) { |
| 778 memberInfo[NAME] = member.simpleName; |
| 779 memberInfo[KIND] = FIELD; |
| 780 } else { |
| 781 MethodMirror method = member; |
| 782 if (method.isConstructor) { |
| 783 if (method.constructorName != '') { |
| 784 memberInfo[NAME] = '${method.simpleName}.${method.constructorName}'; |
| 785 memberInfo[KIND] = CONSTRUCTOR; |
| 786 } else { |
| 787 memberInfo[NAME] = member.simpleName; |
| 788 memberInfo[KIND] = CONSTRUCTOR; |
| 789 } |
| 790 } else if (method.isOperator) { |
| 791 memberInfo[NAME] = '${method.simpleName} ${method.operatorName}'; |
| 792 memberInfo[KIND] = METHOD; |
| 793 } else if (method.isSetter) { |
| 794 memberInfo[NAME] = member.simpleName; |
| 795 memberInfo[KIND] = SETTER; |
| 796 } else if (method.isGetter) { |
| 797 memberInfo[NAME] = member.simpleName; |
| 798 memberInfo[KIND] = GETTER; |
| 799 } else { |
| 800 memberInfo[NAME] = member.simpleName; |
| 801 memberInfo[KIND] = METHOD; |
| 802 } |
| 803 } |
| 804 var anchor = memberAnchor(member); |
| 805 if (anchor != memberInfo[NAME]) { |
| 806 memberInfo[LINK_NAME] = anchor; |
| 807 } |
| 808 members.add(memberInfo); |
| 809 } |
| 810 return members; |
| 688 } | 811 } |
| 689 | 812 |
| 690 void docNavigation() { | 813 void docNavigation() { |
| 691 writeln( | 814 writeln( |
| 692 ''' | 815 ''' |
| 693 <div class="nav"> | 816 <div class="nav"> |
| 694 '''); | 817 '''); |
| 695 | 818 |
| 696 if (mode == MODE_STATIC) { | 819 if (mode == MODE_STATIC) { |
| 697 for (final library in _sortedLibraries) { | 820 for (final library in _sortedLibraries) { |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1286 // Always get the generic type to strip off any type parameters or | 1409 // Always get the generic type to strip off any type parameters or |
| 1287 // arguments. If the type isn't generic, genericType returns `this`, so it | 1410 // arguments. If the type isn't generic, genericType returns `this`, so it |
| 1288 // works for non-generic types too. | 1411 // works for non-generic types too. |
| 1289 return '${sanitize(type.library.simpleName)}/' | 1412 return '${sanitize(type.library.simpleName)}/' |
| 1290 '${type.declaration.simpleName}.html'; | 1413 '${type.declaration.simpleName}.html'; |
| 1291 } | 1414 } |
| 1292 | 1415 |
| 1293 /** Gets the URL for the documentation for [member]. */ | 1416 /** Gets the URL for the documentation for [member]. */ |
| 1294 String memberUrl(MemberMirror member) { | 1417 String memberUrl(MemberMirror member) { |
| 1295 String url = typeUrl(member.surroundingDeclaration); | 1418 String url = typeUrl(member.surroundingDeclaration); |
| 1296 if (!member.isConstructor) { | 1419 return '$url#${memberAnchor(member)}'; |
| 1297 return '$url#${member.simpleName}'; | |
| 1298 } | |
| 1299 assert (member is MethodMirror); | |
| 1300 if (member.constructorName == '') { | |
| 1301 return '$url#new:${member.simpleName}'; | |
| 1302 } | |
| 1303 return '$url#new:${member.simpleName}.${member.constructorName}'; | |
| 1304 } | 1420 } |
| 1305 | 1421 |
| 1306 /** Gets the anchor id for the document for [member]. */ | 1422 /** Gets the anchor id for the document for [member]. */ |
| 1307 String memberAnchor(MemberMirror member) { | 1423 String memberAnchor(MemberMirror member) { |
| 1308 return '${member.simpleName}'; | 1424 if (member.isField) { |
| 1425 return member.simpleName; |
| 1426 } |
| 1427 MethodMirror method = member; |
| 1428 if (method.isConstructor) { |
| 1429 if (method.constructorName == '') { |
| 1430 return method.simpleName; |
| 1431 } else { |
| 1432 return '${method.simpleName}.${method.constructorName}'; |
| 1433 } |
| 1434 } else if (method.isOperator) { |
| 1435 return '${method.simpleName} ${method.operatorName}'; |
| 1436 } else if (method.isSetter) { |
| 1437 return '${method.simpleName}='; |
| 1438 } else { |
| 1439 return method.simpleName; |
| 1440 } |
| 1309 } | 1441 } |
| 1310 | 1442 |
| 1311 /** | 1443 /** |
| 1312 * Creates a hyperlink. Handles turning the [href] into an appropriate | 1444 * Creates a hyperlink. Handles turning the [href] into an appropriate |
| 1313 * relative path from the current file. | 1445 * relative path from the current file. |
| 1314 */ | 1446 */ |
| 1315 String a(String href, String contents, [String css]) { | 1447 String a(String href, String contents, [String css]) { |
| 1316 // Mark outgoing external links, mainly so we can style them. | 1448 // Mark outgoing external links, mainly so we can style them. |
| 1317 final rel = isAbsolute(href) ? ' ref="external"' : ''; | 1449 final rel = isAbsolute(href) ? ' ref="external"' : ''; |
| 1318 final cssClass = css == null ? '' : ' class="$css"'; | 1450 final cssClass = css == null ? '' : ' class="$css"'; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 } | 1537 } |
| 1406 | 1538 |
| 1407 /** Generates a human-friendly string representation for a type. */ | 1539 /** Generates a human-friendly string representation for a type. */ |
| 1408 typeName(TypeMirror type, [bool showBounds = false]) { | 1540 typeName(TypeMirror type, [bool showBounds = false]) { |
| 1409 if (type.isVoid) { | 1541 if (type.isVoid) { |
| 1410 return 'void'; | 1542 return 'void'; |
| 1411 } | 1543 } |
| 1412 if (type is TypeVariableMirror) { | 1544 if (type is TypeVariableMirror) { |
| 1413 return type.simpleName; | 1545 return type.simpleName; |
| 1414 } | 1546 } |
| 1415 assert (type is InterfaceMirror); | 1547 assert(type is InterfaceMirror); |
| 1416 | 1548 |
| 1417 // See if it's a generic type. | 1549 // See if it's a generic type. |
| 1418 if (type.isDeclaration) { | 1550 if (type.isDeclaration) { |
| 1419 final typeParams = []; | 1551 final typeParams = []; |
| 1420 for (final typeParam in type.declaration.typeVariables) { | 1552 for (final typeParam in type.declaration.typeVariables) { |
| 1421 if (showBounds && | 1553 if (showBounds && |
| 1422 (typeParam.bound != null) && | 1554 (typeParam.bound != null) && |
| 1423 !typeParam.bound.isObject) { | 1555 !typeParam.bound.isObject) { |
| 1424 final bound = typeName(typeParam.bound, showBounds: true); | 1556 final bound = typeName(typeParam.bound, showBounds: true); |
| 1425 typeParams.add('${typeParam.simpleName} extends $bound'); | 1557 typeParams.add('${typeParam.simpleName} extends $bound'); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1589 } | 1721 } |
| 1590 | 1722 |
| 1591 /** | 1723 /** |
| 1592 * Returns [:true:] if [type] should be regarded as an exception. | 1724 * Returns [:true:] if [type] should be regarded as an exception. |
| 1593 */ | 1725 */ |
| 1594 bool isException(TypeMirror type) { | 1726 bool isException(TypeMirror type) { |
| 1595 return type.simpleName.endsWith('Exception'); | 1727 return type.simpleName.endsWith('Exception'); |
| 1596 } | 1728 } |
| 1597 } | 1729 } |
| 1598 | 1730 |
| OLD | NEW |