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 * This generates the reference documentation for the core libraries that come | 6 * This generates the reference documentation for the core libraries that come |
7 * with dart. It is built on top of dartdoc, which is a general-purpose library | 7 * with dart. It is built on top of dartdoc, which is a general-purpose library |
8 * for generating docs from any Dart code. This library extends that to include | 8 * for generating docs from any Dart code. This library extends that to include |
9 * additional information and styling specific to our standard library. | 9 * additional information and styling specific to our standard library. |
10 * | 10 * |
11 * Usage: | 11 * Usage: |
12 * | 12 * |
13 * $ dart apidoc.dart [--out=<output directory>] | 13 * $ dart apidoc.dart [--out=<output directory>] |
14 */ | 14 */ |
15 | 15 |
16 #library('apidoc'); | 16 #library('apidoc'); |
17 | 17 |
18 #import('dart:io'); | 18 #import('dart:io'); |
19 #import('dart:json'); | 19 #import('dart:json'); |
20 #import('html_diff.dart'); | 20 #import('html_diff.dart'); |
21 #import('../../lib/dartdoc/mirrors/mirrors.dart'); | 21 #import('../../lib/dartdoc/mirrors/mirrors.dart'); |
22 #import('../../lib/dartdoc/mirrors/mirrors_util.dart'); | 22 #import('../../lib/dartdoc/mirrors/mirrors_util.dart'); |
23 #import('../../lib/dartdoc/dartdoc.dart', prefix: 'doc'); | 23 #import('../../lib/dartdoc/dartdoc.dart', prefix: 'doc'); |
| 24 #import('../../lib/compiler/implementation/library_map.dart'); |
24 | 25 |
25 HtmlDiff _diff; | 26 HtmlDiff _diff; |
26 | 27 |
27 void main() { | 28 void main() { |
28 final args = new Options().arguments; | 29 final args = new Options().arguments; |
29 | 30 |
30 int mode = doc.MODE_STATIC; | 31 int mode = doc.MODE_STATIC; |
31 Path outputDir = const Path('docs'); | 32 Path outputDir = const Path('docs'); |
32 bool generateAppCache = false; | 33 bool generateAppCache = false; |
33 | 34 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 htmldoc.documentLibraries( | 96 htmldoc.documentLibraries( |
96 <Path>[doc.scriptDir.append('../../lib/html/doc/html.dartdoc')], | 97 <Path>[doc.scriptDir.append('../../lib/html/doc/html.dartdoc')], |
97 doc.libPath); | 98 doc.libPath); |
98 print('Processing handwritten HTML documentation...'); | 99 print('Processing handwritten HTML documentation...'); |
99 | 100 |
100 // Process libraries. | 101 // Process libraries. |
101 | 102 |
102 // TODO(johnniwinther): Libraries for the compilation seem to be more like | 103 // TODO(johnniwinther): Libraries for the compilation seem to be more like |
103 // URIs. Perhaps Path should have a toURI() method. | 104 // URIs. Perhaps Path should have a toURI() method. |
104 // Add all of the core libraries. | 105 // Add all of the core libraries. |
105 var apidocLibraries = <Path>[ | 106 final apidocLibraries = <Path>[]; |
106 const Path('dart:core'), | 107 DART2JS_LIBRARY_MAP.forEach((String name, LibraryInfo info) { |
107 const Path('dart:coreimpl'), | 108 if (!info.isInternal) { |
108 const Path('dart:crypto'), | 109 apidocLibraries.add(new Path('dart:$name')); |
109 const Path('dart:html'), | 110 } |
110 const Path('dart:io'), | 111 }); |
111 const Path('dart:isolate'), | 112 apidocLibraries.add(doc.scriptDir.append('../../lib/unittest/unittest.dart')); |
112 const Path('dart:json'), | 113 apidocLibraries.add(doc.scriptDir.append('../../lib/i18n/intl.dart')); |
113 doc.scriptDir.append('../../lib/math/math.dart'), | 114 |
114 doc.scriptDir.append('../../lib/unittest/unittest.dart'), | |
115 doc.scriptDir.append('../../lib/i18n/intl.dart'), | |
116 const Path('dart:uri'), | |
117 const Path('dart:utf'), | |
118 const Path('dart:web'), | |
119 ]; | |
120 print('Generating docs...'); | 115 print('Generating docs...'); |
121 final apidoc = new Apidoc(mdn, htmldoc, outputDir, mode, generateAppCache); | 116 final apidoc = new Apidoc(mdn, htmldoc, outputDir, mode, generateAppCache); |
122 // Select the libraries to include in the produced documentation: | 117 // Select the libraries to include in the produced documentation: |
123 apidoc.libraries = <String>[ | 118 apidoc.includeApi = true; |
124 'core', | 119 apidoc.includedLibraries = <String>[ |
125 'coreimpl', | |
126 'crypto', | |
127 'html', | |
128 'io', | |
129 'dart:isolate', | |
130 'json', | |
131 'math', | |
132 'unittest', | 120 'unittest', |
133 'intl', | 121 'intl', |
134 'uri', | |
135 'utf', | |
136 'web', | |
137 ]; | 122 ]; |
138 | 123 |
139 Futures.wait([compiled, copiedStatic, copiedApiDocStatic]).then((_) { | 124 Futures.wait([compiled, copiedStatic, copiedApiDocStatic]).then((_) { |
140 apidoc.documentLibraries(apidocLibraries, doc.libPath); | 125 apidoc.documentLibraries(apidocLibraries, doc.libPath); |
141 }); | 126 }); |
142 } | 127 } |
143 | 128 |
144 /** | 129 /** |
145 * This class is purely here to scrape handwritten HTML documentation. | 130 * This class is purely here to scrape handwritten HTML documentation. |
146 * This scraped documentation will later be merged with the generated | 131 * This scraped documentation will later be merged with the generated |
(...skipping 18 matching lines...) Expand all Loading... |
165 } | 150 } |
166 | 151 |
167 // Suppress any actual writing to file. This is only for analysis. | 152 // Suppress any actual writing to file. This is only for analysis. |
168 void endFile() { | 153 void endFile() { |
169 } | 154 } |
170 | 155 |
171 void write(String s) { | 156 void write(String s) { |
172 } | 157 } |
173 | 158 |
174 String getRecordedLibraryComment(LibraryMirror library) { | 159 String getRecordedLibraryComment(LibraryMirror library) { |
175 if (library.simpleName() == 'html') { | 160 if (library.simpleName() == HTML_LIBRARY_NAME) { |
176 return libraryComment; | 161 return libraryComment; |
177 } | 162 } |
178 return null; | 163 return null; |
179 } | 164 } |
180 | 165 |
181 String getRecordedTypeComment(TypeMirror type) { | 166 String getRecordedTypeComment(TypeMirror type) { |
182 if (typeComments.containsKey(type.qualifiedName())) { | 167 if (typeComments.containsKey(type.qualifiedName())) { |
183 return typeComments[type.qualifiedName()]; | 168 return typeComments[type.qualifiedName()]; |
184 } | 169 } |
185 return null; | 170 return null; |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 super.docLibrary(library); | 342 super.docLibrary(library); |
358 } | 343 } |
359 | 344 |
360 /** Override definition from parent class to strip out annotation tags. */ | 345 /** Override definition from parent class to strip out annotation tags. */ |
361 String commentToHtml(String comment) { | 346 String commentToHtml(String comment) { |
362 return super.commentToHtml( | 347 return super.commentToHtml( |
363 comment.replaceAll(const RegExp("@([a-zA-Z]+) ([^;]+)(?:;|\$)"), '')); | 348 comment.replaceAll(const RegExp("@([a-zA-Z]+) ([^;]+)(?:;|\$)"), '')); |
364 } | 349 } |
365 | 350 |
366 String getLibraryComment(LibraryMirror library) { | 351 String getLibraryComment(LibraryMirror library) { |
367 if (library.simpleName() == 'html') { | 352 if (library.simpleName() == HTML_LIBRARY_NAME) { |
368 return htmldoc.libraryComment; | 353 return htmldoc.libraryComment; |
369 } | 354 } |
370 return super.getLibraryComment(library); | 355 return super.getLibraryComment(library); |
371 } | 356 } |
372 | 357 |
373 String getTypeComment(TypeMirror type) { | 358 String getTypeComment(TypeMirror type) { |
374 return _mergeDocs( | 359 return _mergeDocs( |
375 includeMdnTypeComment(type), super.getTypeComment(type), | 360 includeMdnTypeComment(type), super.getTypeComment(type), |
376 htmldoc.getRecordedTypeComment(type)); | 361 htmldoc.getRecordedTypeComment(type)); |
377 } | 362 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 </p> | 430 </p> |
446 '''); | 431 '''); |
447 } | 432 } |
448 } | 433 } |
449 | 434 |
450 /** | 435 /** |
451 * Gets the MDN-scraped docs for [type], or `null` if this type isn't | 436 * Gets the MDN-scraped docs for [type], or `null` if this type isn't |
452 * scraped from MDN. | 437 * scraped from MDN. |
453 */ | 438 */ |
454 includeMdnTypeComment(TypeMirror type) { | 439 includeMdnTypeComment(TypeMirror type) { |
455 if (type.library().simpleName() == 'html') { | 440 if (type.library().simpleName() == HTML_LIBRARY_NAME) { |
456 // If it's an HTML type, try to map it to a base DOM type so we can find | 441 // If it's an HTML type, try to map it to a base DOM type so we can find |
457 // the MDN docs. | 442 // the MDN docs. |
458 final domTypes = _diff.htmlTypesToDom[type.qualifiedName()]; | 443 final domTypes = _diff.htmlTypesToDom[type.qualifiedName()]; |
459 | 444 |
460 // Couldn't find a DOM type. | 445 // Couldn't find a DOM type. |
461 if ((domTypes == null) || (domTypes.length != 1)) return null; | 446 if ((domTypes == null) || (domTypes.length != 1)) return null; |
462 | 447 |
463 // Use the corresponding DOM type when searching MDN. | 448 // Use the corresponding DOM type when searching MDN. |
464 // TODO(rnystrom): Shame there isn't a simpler way to get the one item | 449 // TODO(rnystrom): Shame there isn't a simpler way to get the one item |
465 // out of a singleton Set. | 450 // out of a singleton Set. |
466 type = domTypes.iterator().next(); | 451 type = domTypes.iterator().next(); |
467 } else if (type.library().simpleName() != 'dom') { | 452 } else if (type.library().simpleName() != DOM_LIBRARY_NAME) { |
468 // Not a DOM type. | 453 // Not a DOM type. |
469 return null; | 454 return null; |
470 } | 455 } |
471 | 456 |
472 final mdnType = mdn[type.simpleName()]; | 457 final mdnType = mdn[type.simpleName()]; |
473 if (mdnType == null) return null; | 458 if (mdnType == null) return null; |
474 if (mdnType['skipped'] != null) return null; | 459 if (mdnType['skipped'] != null) return null; |
475 | 460 |
476 // Remember which MDN page we're using so we can attribute it. | 461 // Remember which MDN page we're using so we can attribute it. |
477 mdnUrl = mdnType['srcUrl']; | 462 mdnUrl = mdnType['srcUrl']; |
478 return mdnType['summary']; | 463 return mdnType['summary']; |
479 } | 464 } |
480 | 465 |
481 /** | 466 /** |
482 * Gets the MDN-scraped docs for [member], or `null` if this type isn't | 467 * Gets the MDN-scraped docs for [member], or `null` if this type isn't |
483 * scraped from MDN. | 468 * scraped from MDN. |
484 */ | 469 */ |
485 includeMdnMemberComment(MemberMirror member) { | 470 includeMdnMemberComment(MemberMirror member) { |
486 var library = findLibrary(member); | 471 var library = findLibrary(member); |
487 if (library.simpleName() == 'html') { | 472 if (library.simpleName() == HTML_LIBRARY_NAME) { |
488 // If it's an HTML type, try to map it to a base DOM type so we can find | 473 // If it's an HTML type, try to map it to a base DOM type so we can find |
489 // the MDN docs. | 474 // the MDN docs. |
490 final domMembers = _diff.htmlToDom[member.qualifiedName()]; | 475 final domMembers = _diff.htmlToDom[member.qualifiedName()]; |
491 | 476 |
492 // Couldn't find a DOM type. | 477 // Couldn't find a DOM type. |
493 if ((domMembers == null) || (domMembers.length != 1)) return null; | 478 if ((domMembers == null) || (domMembers.length != 1)) return null; |
494 | 479 |
495 // Use the corresponding DOM member when searching MDN. | 480 // Use the corresponding DOM member when searching MDN. |
496 // TODO(rnystrom): Shame there isn't a simpler way to get the one item | 481 // TODO(rnystrom): Shame there isn't a simpler way to get the one item |
497 // out of a singleton Set. | 482 // out of a singleton Set. |
498 member = domMembers.iterator().next(); | 483 member = domMembers.iterator().next(); |
499 } else if (library.simpleName() != 'dom') { | 484 } else if (library.simpleName() != DOM_LIBRARY_NAME) { |
500 // Not a DOM type. | 485 // Not a DOM type. |
501 return null; | 486 return null; |
502 } | 487 } |
503 | 488 |
504 // Ignore top-level functions. | 489 // Ignore top-level functions. |
505 if (member.isTopLevel) return null; | 490 if (member.isTopLevel) return null; |
506 | 491 |
507 final mdnType = mdn[member.surroundingDeclaration().simpleName()]; | 492 final mdnType = mdn[member.surroundingDeclaration().simpleName()]; |
508 if (mdnType == null) return null; | 493 if (mdnType == null) return null; |
509 var nameToFind = member.simpleName(); | 494 var nameToFind = member.simpleName(); |
(...skipping 20 matching lines...) Expand all Loading... |
530 final typeName = member.surroundingDeclaration().simpleName(); | 515 final typeName = member.surroundingDeclaration().simpleName(); |
531 var memberName = '$typeName.${member.simpleName()}'; | 516 var memberName = '$typeName.${member.simpleName()}'; |
532 if (member is MethodMirror && (member.isConstructor || member.isFactory)) { | 517 if (member is MethodMirror && (member.isConstructor || member.isFactory)) { |
533 final separator = member.constructorName == '' ? '' : '.'; | 518 final separator = member.constructorName == '' ? '' : '.'; |
534 memberName = 'new $typeName$separator${member.constructorName}'; | 519 memberName = 'new $typeName$separator${member.constructorName}'; |
535 } | 520 } |
536 | 521 |
537 return a(memberUrl(member), memberName); | 522 return a(memberUrl(member), memberName); |
538 } | 523 } |
539 } | 524 } |
OLD | NEW |