| 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 * |
| 11 * This will create a "docs" directory with the docs for your libraries. To | 11 * This will create a "docs" directory with the docs for your libraries. To |
| 12 * create these beautiful docs, dartdoc parses your library and every library | 12 * create these beautiful docs, dartdoc parses your library and every library |
| 13 * it imports (recursively). From each library, it parses all classes and | 13 * it imports (recursively). From each library, it parses all classes and |
| 14 * members, finds the associated doc comments and builds crosslinked docs from | 14 * members, finds the associated doc comments and builds crosslinked docs from |
| 15 * them. | 15 * them. |
| 16 */ | 16 */ |
| 17 #library('dartdoc'); | 17 #library('dartdoc'); |
| 18 | 18 |
| 19 #import('dart:io'); | 19 #import('dart:io'); |
| 20 #import('dart:uri'); | 20 #import('dart:uri'); |
| 21 #import('dart:json'); | 21 #import('dart:json'); |
| 22 #import('mirrors/mirrors.dart'); | 22 #import('mirrors/mirrors.dart'); |
| 23 #import('mirrors/mirrors_util.dart'); | 23 #import('mirrors/mirrors_util.dart'); |
| 24 #import('mirrors/dart2js_mirror.dart', prefix: 'dart2js'); | 24 #import('mirrors/dart2js_mirror.dart', prefix: 'dart2js'); |
| 25 #import('classify.dart'); | 25 #import('classify.dart'); |
| 26 #import('markdown.dart', prefix: 'md'); | 26 #import('markdown.dart', prefix: 'md'); |
| 27 #import('../compiler/implementation/scanner/scannerlib.dart', | 27 #import('../compiler/implementation/scanner/scannerlib.dart', |
| 28 prefix: 'dart2js'); | 28 prefix: 'dart2js'); |
| 29 #import('../compiler/implementation/library_map.dart'); |
| 29 | 30 |
| 30 #source('comment_map.dart'); | 31 #source('comment_map.dart'); |
| 31 #source('utils.dart'); | 32 #source('utils.dart'); |
| 32 | 33 |
| 33 // TODO(johnniwinther): Note that [IN_SDK] gets initialized to true when this | 34 // TODO(johnniwinther): Note that [IN_SDK] gets initialized to true when this |
| 34 // file is modified by the SDK deployment script. If you change, be sure to test | 35 // file is modified by the SDK deployment script. If you change, be sure to test |
| 35 // that dartdoc still works when run from the built SDK directory. | 36 // that dartdoc still works when run from the built SDK directory. |
| 36 final bool IN_SDK = false; | 37 final bool IN_SDK = false; |
| 37 | 38 |
| 38 /** | 39 /** |
| (...skipping 10 matching lines...) Expand all Loading... |
| 49 * | 50 * |
| 50 * This dramatically reduces the generated size of the HTML since a large | 51 * This dramatically reduces the generated size of the HTML since a large |
| 51 * fraction of each static page is just redundant navigation links. | 52 * fraction of each static page is just redundant navigation links. |
| 52 * | 53 * |
| 53 * In this mode, the browser will do a XHR for nav.json which means that to | 54 * In this mode, the browser will do a XHR for nav.json which means that to |
| 54 * preview docs locally, you will need to enable requesting file:// links in | 55 * preview docs locally, you will need to enable requesting file:// links in |
| 55 * your browser or run a little local server like `python -m SimpleHTTPServer`. | 56 * your browser or run a little local server like `python -m SimpleHTTPServer`. |
| 56 */ | 57 */ |
| 57 final MODE_LIVE_NAV = 1; | 58 final MODE_LIVE_NAV = 1; |
| 58 | 59 |
| 60 final API_LOCATION = 'http://api.dartlang.org/'; |
| 61 |
| 59 /** | 62 /** |
| 60 * Run this from the `lib/dartdoc` directory. | 63 * Run this from the `lib/dartdoc` directory. |
| 61 */ | 64 */ |
| 62 void main() { | 65 void main() { |
| 63 final args = new Options().arguments; | 66 final args = new Options().arguments; |
| 64 | 67 |
| 65 // Parse the dartdoc options. | 68 final dartdoc = new Dartdoc(); |
| 66 bool includeSource; | |
| 67 int mode; | |
| 68 Path outputDir; | |
| 69 bool generateAppCache; | |
| 70 bool omitGenerationTime; | |
| 71 bool verbose; | |
| 72 | 69 |
| 73 if (args.isEmpty()) { | 70 if (args.isEmpty()) { |
| 74 print('No arguments provided.'); | 71 print('No arguments provided.'); |
| 75 printUsage(); | 72 printUsage(); |
| 76 return; | 73 return; |
| 77 } | 74 } |
| 78 | 75 |
| 79 for (int i = 0; i < args.length - 1; i++) { | 76 final entrypoints = <Path>[]; |
| 77 |
| 78 var i = 0; |
| 79 while (i < args.length) { |
| 80 final arg = args[i]; | 80 final arg = args[i]; |
| 81 if (!arg.startsWith('--')) { |
| 82 // The remaining arguments must be entry points. |
| 83 break; |
| 84 } |
| 81 | 85 |
| 82 switch (arg) { | 86 switch (arg) { |
| 83 case '--no-code': | 87 case '--no-code': |
| 84 includeSource = false; | 88 dartdoc.includeSource = false; |
| 85 break; | 89 break; |
| 86 | 90 |
| 87 case '--mode=static': | 91 case '--mode=static': |
| 88 mode = MODE_STATIC; | 92 dartdoc.mode = MODE_STATIC; |
| 89 break; | 93 break; |
| 90 | 94 |
| 91 case '--mode=live-nav': | 95 case '--mode=live-nav': |
| 92 mode = MODE_LIVE_NAV; | 96 dartdoc.mode = MODE_LIVE_NAV; |
| 93 break; | 97 break; |
| 94 | 98 |
| 95 case '--generate-app-cache': | 99 case '--generate-app-cache': |
| 96 case '--generate-app-cache=true': | 100 case '--generate-app-cache=true': |
| 97 generateAppCache = true; | 101 dartdoc.generateAppCache = true; |
| 98 break; | 102 break; |
| 99 | 103 |
| 100 case '--omit-generation-time': | 104 case '--omit-generation-time': |
| 101 omitGenerationTime = true; | 105 dartdoc.omitGenerationTime = true; |
| 102 break; | 106 break; |
| 103 case '--verbose': | 107 case '--verbose': |
| 104 verbose = true; | 108 dartdoc.verbose = true; |
| 109 break; |
| 110 case '--include-api': |
| 111 dartdoc.includeApi = true; |
| 112 break; |
| 113 case '--link-api': |
| 114 dartdoc.linkToApi = true; |
| 105 break; | 115 break; |
| 106 | 116 |
| 107 default: | 117 default: |
| 108 if (arg.startsWith('--out=')) { | 118 if (arg.startsWith('--out=')) { |
| 109 outputDir = new Path.fromNative(arg.substring('--out='.length)); | 119 dartdoc.outputDir = |
| 120 new Path.fromNative(arg.substring('--out='.length)); |
| 121 } else if (arg.startsWith('--include-lib=')) { |
| 122 dartdoc.includedLibraries = |
| 123 arg.substring('--include-lib='.length).split(','); |
| 124 } else if (arg.startsWith('--exclude-lib=')) { |
| 125 dartdoc.excludedLibraries = |
| 126 arg.substring('--exclude-lib='.length).split(','); |
| 110 } else { | 127 } else { |
| 111 print('Unknown option: $arg'); | 128 print('Unknown option: $arg'); |
| 112 printUsage(); | 129 printUsage(); |
| 113 return; | 130 return; |
| 114 } | 131 } |
| 115 break; | 132 break; |
| 116 } | 133 } |
| 134 i++; |
| 135 } |
| 136 while (i < args.length) { |
| 137 final arg = args[i]; |
| 138 entrypoints.add(new Path.fromNative(arg)); |
| 139 i++; |
| 117 } | 140 } |
| 118 | 141 |
| 119 final entrypoint = new Path.fromNative(args[args.length - 1]); | 142 if (entrypoints.isEmpty()) { |
| 120 | 143 print('No entrypoints provided.'); |
| 121 final dartdoc = new Dartdoc(); | 144 printUsage(); |
| 122 | 145 return; |
| 123 if (includeSource != null) dartdoc.includeSource = includeSource; | |
| 124 if (mode != null) dartdoc.mode = mode; | |
| 125 if (outputDir != null) dartdoc.outputDir = outputDir; | |
| 126 if (generateAppCache != null) dartdoc.generateAppCache = generateAppCache; | |
| 127 if (omitGenerationTime != null) { | |
| 128 dartdoc.omitGenerationTime = omitGenerationTime; | |
| 129 } | 146 } |
| 130 if (verbose != null) dartdoc.verbose = verbose; | |
| 131 | 147 |
| 132 cleanOutputDirectory(dartdoc.outputDir); | 148 cleanOutputDirectory(dartdoc.outputDir); |
| 133 | 149 |
| 134 dartdoc.documentEntryPoint(entrypoint, libPath); | 150 dartdoc.documentLibraries(entrypoints, libPath); |
| 135 | 151 |
| 136 // Compile the client-side code to JS. | 152 // Compile the client-side code to JS. |
| 137 final clientScript = (dartdoc.mode == MODE_STATIC) ? 'static' : 'live-nav'; | 153 final clientScript = (dartdoc.mode == MODE_STATIC) ? 'static' : 'live-nav'; |
| 138 Future compiled = compileScript( | 154 Future compiled = compileScript( |
| 139 scriptDir.append('client-$clientScript.dart'), | 155 scriptDir.append('client-$clientScript.dart'), |
| 140 dartdoc.outputDir.append('client-$clientScript.js')); | 156 dartdoc.outputDir.append('client-$clientScript.js')); |
| 141 | 157 |
| 142 Future filesCopied = copyDirectory(scriptDir.append('static'), | 158 Future filesCopied = copyDirectory(scriptDir.append('static'), |
| 143 dartdoc.outputDir); | 159 dartdoc.outputDir); |
| 144 | 160 |
| 145 Futures.wait([compiled, filesCopied]).then((_) { | 161 Futures.wait([compiled, filesCopied]).then((_) { |
| 146 print('Documented ${dartdoc._totalLibraries} libraries, ' | 162 print('Documented ${dartdoc._totalLibraries} libraries, ' |
| 147 '${dartdoc._totalTypes} types, and ' | 163 '${dartdoc._totalTypes} types, and ' |
| 148 '${dartdoc._totalMembers} members.'); | 164 '${dartdoc._totalMembers} members.'); |
| 149 }); | 165 }); |
| 150 } | 166 } |
| 151 | 167 |
| 152 void printUsage() { | 168 void printUsage() { |
| 153 print(''' | 169 print(''' |
| 154 Usage dartdoc [options] <entrypoint> | 170 Usage dartdoc [options] <entrypoint(s)> |
| 155 [options] include | 171 [options] include |
| 156 --no-code Do not include source code in the documentation. | 172 --no-code Do not include source code in the documentation. |
| 157 | 173 |
| 158 --mode=static Generates completely static HTML containing | 174 --mode=static Generates completely static HTML containing |
| 159 everything you need to browse the docs. The only | 175 everything you need to browse the docs. The only |
| 160 client side behavior is trivial stuff like syntax | 176 client side behavior is trivial stuff like syntax |
| 161 highlighting code. | 177 highlighting code. |
| 162 | 178 |
| 163 --mode=live-nav (default) Generated docs do not include baked HTML | 179 --mode=live-nav (default) Generated docs do not include baked HTML |
| 164 navigation. Instead, a single `nav.json` file is | 180 navigation. Instead, a single `nav.json` file is |
| 165 created and the appropriate navigation is generated | 181 created and the appropriate navigation is generated |
| 166 client-side by parsing that and building HTML. | 182 client-side by parsing that and building HTML. |
| 167 This dramatically reduces the generated size of | 183 This dramatically reduces the generated size of |
| 168 the HTML since a large fraction of each static page | 184 the HTML since a large fraction of each static page |
| 169 is just redundant navigation links. | 185 is just redundant navigation links. |
| 170 In this mode, the browser will do a XHR for | 186 In this mode, the browser will do a XHR for |
| 171 nav.json which means that to preview docs locally, | 187 nav.json which means that to preview docs locally, |
| 172 you will need to enable requesting file:// links in | 188 you will need to enable requesting file:// links in |
| 173 your browser or run a little local server like | 189 your browser or run a little local server like |
| 174 `python -m SimpleHTTPServer`. | 190 `python -m SimpleHTTPServer`. |
| 175 | 191 |
| 176 --generate-app-cache Generates the App Cache manifest file, enabling | 192 --generate-app-cache Generates the App Cache manifest file, enabling |
| 177 offline doc viewing. | 193 offline doc viewing. |
| 178 | 194 |
| 179 --out=<dir> Generates files into directory <dir>. If omitted | 195 --out=<dir> Generates files into directory <dir>. If omitted |
| 180 the files are generated into ./docs/ | 196 the files are generated into ./docs/ |
| 181 | 197 |
| 198 --link-api Link to the online language API in the generated |
| 199 documentation. The option overrides inclusion |
| 200 through --include-api or --include-lib. |
| 201 |
| 202 --include-api Include the used API libraries in the generated |
| 203 documentation. If the --link-api option is used, |
| 204 this option is ignored. |
| 205 |
| 206 --include-lib=<libs> Use this option to explicitly specify which |
| 207 libraries to include in the documentation. If |
| 208 omitted, all used libraries are included by |
| 209 default. <libs> is comma-separated list of library |
| 210 names. |
| 211 |
| 212 --exclude-lib=<libs> Use this option to explicitly specify which |
| 213 libraries to exclude from the documentation. If |
| 214 omitted, no libraries are excluded. <libs> is |
| 215 comma-separated list of library names. |
| 216 |
| 182 --verbose Print verbose information during generation. | 217 --verbose Print verbose information during generation. |
| 183 '''); | 218 '''); |
| 184 } | 219 } |
| 185 | 220 |
| 186 /** | 221 /** |
| 187 * Gets the full path to the directory containing the entrypoint of the current | 222 * Gets the full path to the directory containing the entrypoint of the current |
| 188 * script. In other words, if you invoked dartdoc, directly, it will be the | 223 * script. In other words, if you invoked dartdoc, directly, it will be the |
| 189 * path to the directory containing `dartdoc.dart`. If you're running a script | 224 * path to the directory containing `dartdoc.dart`. If you're running a script |
| 190 * that imports dartdoc, it will be the path to that script. | 225 * that imports dartdoc, it will be the path to that script. |
| 191 */ | 226 */ |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 | 340 |
| 306 /** Set this to add content before the footer */ | 341 /** Set this to add content before the footer */ |
| 307 String preFooterText = ''; | 342 String preFooterText = ''; |
| 308 | 343 |
| 309 /** Set this to omit generation timestamp from output */ | 344 /** Set this to omit generation timestamp from output */ |
| 310 bool omitGenerationTime = false; | 345 bool omitGenerationTime = false; |
| 311 | 346 |
| 312 /** Set by Dartdoc user to print extra information during generation. */ | 347 /** Set by Dartdoc user to print extra information during generation. */ |
| 313 bool verbose = false; | 348 bool verbose = false; |
| 314 | 349 |
| 315 /** Set this to select the libraries to document */ | 350 /** Set this to include API libraries in the documentation. */ |
| 316 List<String> libraries = null; | 351 bool includeApi = false; |
| 352 |
| 353 /** Set this to generate links to the online API. */ |
| 354 bool linkToApi = false; |
| 355 |
| 356 /** Set this to select the libraries to include in the documentation. */ |
| 357 List<String> includedLibraries = const <String>[]; |
| 358 |
| 359 /** Set this to select the libraries to exclude from the documentation. */ |
| 360 List<String> excludedLibraries = const <String>[]; |
| 317 | 361 |
| 318 /** | 362 /** |
| 319 * This list contains the libraries sorted in by the library name. | 363 * This list contains the libraries sorted in by the library name. |
| 320 */ | 364 */ |
| 321 List<LibraryMirror> _sortedLibraries; | 365 List<LibraryMirror> _sortedLibraries; |
| 322 | 366 |
| 323 CommentMap _comments; | 367 CommentMap _comments; |
| 324 | 368 |
| 325 /** The library that we're currently generating docs for. */ | 369 /** The library that we're currently generating docs for. */ |
| 326 LibraryMirror _currentLibrary; | 370 LibraryMirror _currentLibrary; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 346 // Patch in support for [:...:]-style code to the markdown parser. | 390 // Patch in support for [:...:]-style code to the markdown parser. |
| 347 // TODO(rnystrom): Markdown already has syntax for this. Phase this out? | 391 // TODO(rnystrom): Markdown already has syntax for this. Phase this out? |
| 348 md.InlineParser.syntaxes.insertRange(0, 1, | 392 md.InlineParser.syntaxes.insertRange(0, 1, |
| 349 new md.CodeSyntax(@'\[\:((?:.|\n)*?)\:\]')); | 393 new md.CodeSyntax(@'\[\:((?:.|\n)*?)\:\]')); |
| 350 | 394 |
| 351 md.setImplicitLinkResolver((name) => resolveNameReference(name, | 395 md.setImplicitLinkResolver((name) => resolveNameReference(name, |
| 352 currentLibrary: _currentLibrary, currentType: _currentType, | 396 currentLibrary: _currentLibrary, currentType: _currentType, |
| 353 currentMember: _currentMember)); | 397 currentMember: _currentMember)); |
| 354 } | 398 } |
| 355 | 399 |
| 356 bool includeLibrary(LibraryMirror library) { | 400 /** |
| 357 if (libraries != null) { | 401 * Returns `true` if [library] is included in the generated documentation. |
| 358 return libraries.indexOf(library.simpleName()) != -1; | 402 */ |
| 403 bool shouldIncludeLibrary(LibraryMirror library) { |
| 404 if (shouldLinkToPublicApi(library)) { |
| 405 return false; |
| 359 } | 406 } |
| 360 return true; | 407 var includeByDefault = true; |
| 408 String libraryName = library.simpleName(); |
| 409 if (!includedLibraries.isEmpty()) { |
| 410 includeByDefault = false; |
| 411 if (includedLibraries.indexOf(libraryName) != -1) { |
| 412 return true; |
| 413 } |
| 414 } |
| 415 if (excludedLibraries.indexOf(libraryName) != -1) { |
| 416 return false; |
| 417 } |
| 418 if (libraryName.startsWith('dart:')) { |
| 419 String suffix = libraryName.substring('dart:'.length); |
| 420 LibraryInfo info = DART2JS_LIBRARY_MAP[suffix]; |
| 421 if (info != null) { |
| 422 return !info.isInternal && includeApi; |
| 423 } |
| 424 } |
| 425 return includeByDefault; |
| 426 } |
| 427 |
| 428 /** |
| 429 * Returns `true` if links to the public API should be generated for |
| 430 * [library]. |
| 431 */ |
| 432 bool shouldLinkToPublicApi(LibraryMirror library) { |
| 433 if (linkToApi) { |
| 434 String libraryName = library.simpleName(); |
| 435 if (libraryName.startsWith('dart:')) { |
| 436 String suffix = libraryName.substring('dart:'.length); |
| 437 LibraryInfo info = DART2JS_LIBRARY_MAP[suffix]; |
| 438 if (info != null) { |
| 439 return !info.isInternal; |
| 440 } |
| 441 } |
| 442 } |
| 443 return false; |
| 361 } | 444 } |
| 362 | 445 |
| 363 String get footerContent(){ | 446 String get footerContent(){ |
| 364 var footerItems = []; | 447 var footerItems = []; |
| 365 if(!omitGenerationTime) { | 448 if(!omitGenerationTime) { |
| 366 footerItems.add("This page was generated at ${new Date.now()}"); | 449 footerItems.add("This page was generated at ${new Date.now()}"); |
| 367 } | 450 } |
| 368 if(footerText != null) { | 451 if(footerText != null) { |
| 369 footerItems.add(footerText); | 452 footerItems.add(footerText); |
| 370 } | 453 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 384 } | 467 } |
| 385 | 468 |
| 386 void documentLibraries(List<Path> libraryList, Path libPath) { | 469 void documentLibraries(List<Path> libraryList, Path libPath) { |
| 387 final compilation = new Compilation.library(libraryList, libPath); | 470 final compilation = new Compilation.library(libraryList, libPath); |
| 388 _document(compilation); | 471 _document(compilation); |
| 389 } | 472 } |
| 390 | 473 |
| 391 void _document(Compilation compilation) { | 474 void _document(Compilation compilation) { |
| 392 // Sort the libraries by name (not key). | 475 // Sort the libraries by name (not key). |
| 393 _sortedLibraries = new List<LibraryMirror>.from( | 476 _sortedLibraries = new List<LibraryMirror>.from( |
| 394 compilation.mirrors().libraries().getValues().filter(includeLibrary)); | 477 compilation.mirrors().libraries().getValues().filter( |
| 478 shouldIncludeLibrary)); |
| 395 _sortedLibraries.sort((x, y) { | 479 _sortedLibraries.sort((x, y) { |
| 396 return x.simpleName().toUpperCase().compareTo( | 480 return x.simpleName().toUpperCase().compareTo( |
| 397 y.simpleName().toUpperCase()); | 481 y.simpleName().toUpperCase()); |
| 398 }); | 482 }); |
| 399 | 483 |
| 400 // Generate the docs. | 484 // Generate the docs. |
| 401 if (mode == MODE_LIVE_NAV) docNavigationJson(); | 485 if (mode == MODE_LIVE_NAV) docNavigationJson(); |
| 402 | 486 |
| 403 docIndex(); | 487 docIndex(); |
| 404 for (final library in _sortedLibraries) { | 488 for (final library in _sortedLibraries) { |
| (...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1274 if (type.isTypeVariable) { | 1358 if (type.isTypeVariable) { |
| 1275 // 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 |
| 1276 // just link back up to the class. | 1360 // just link back up to the class. |
| 1277 write(a(typeUrl(enclosingType), type.simpleName())); | 1361 write(a(typeUrl(enclosingType), type.simpleName())); |
| 1278 return; | 1362 return; |
| 1279 } | 1363 } |
| 1280 | 1364 |
| 1281 assert(type is InterfaceMirror); | 1365 assert(type is InterfaceMirror); |
| 1282 | 1366 |
| 1283 // Link to the type. | 1367 // Link to the type. |
| 1284 if (includeLibrary(type.library())) { | 1368 if (shouldLinkToPublicApi(type.library())) { |
| 1369 write('<a href="$API_LOCATION${typeUrl(type)}">${type.simpleName()}</a>'); |
| 1370 } else if (shouldIncludeLibrary(type.library())) { |
| 1285 write(a(typeUrl(type), type.simpleName())); | 1371 write(a(typeUrl(type), type.simpleName())); |
| 1286 } else { | 1372 } else { |
| 1287 write(type.simpleName()); | 1373 write(type.simpleName()); |
| 1288 } | 1374 } |
| 1289 | 1375 |
| 1290 if (type.isDeclaration) { | 1376 if (type.isDeclaration) { |
| 1291 // Avoid calling [:typeArguments():] on a declaration. | 1377 // Avoid calling [:typeArguments():] on a declaration. |
| 1292 return; | 1378 return; |
| 1293 } | 1379 } |
| 1294 | 1380 |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1498 } | 1584 } |
| 1499 | 1585 |
| 1500 /** | 1586 /** |
| 1501 * Returns [:true:] if [type] should be regarded as an exception. | 1587 * Returns [:true:] if [type] should be regarded as an exception. |
| 1502 */ | 1588 */ |
| 1503 bool isException(TypeMirror type) { | 1589 bool isException(TypeMirror type) { |
| 1504 return type.simpleName().endsWith('Exception'); | 1590 return type.simpleName().endsWith('Exception'); |
| 1505 } | 1591 } |
| 1506 } | 1592 } |
| 1507 | 1593 |
| OLD | NEW |