Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 use it, from this directory, run: | 6 * To use it, from this directory, run: |
| 7 * | 7 * |
| 8 * $ dartdoc <path to .dart file> | 8 * $ dartdoc <path to .dart file> |
| 9 * | 9 * |
| 10 * This will create a "docs" directory with the docs for your libraries. To | 10 * This will create a "docs" directory with the docs for your libraries. To |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 | 47 |
| 48 /** | 48 /** |
| 49 * The cached lookup-table to associate doc comments with spans. The outer map | 49 * The cached lookup-table to associate doc comments with spans. The outer map |
| 50 * is from filenames to doc comments in that file. The inner map maps from the | 50 * is from filenames to doc comments in that file. The inner map maps from the |
| 51 * token positions to doc comments. Each position is the starting offset of the | 51 * token positions to doc comments. Each position is the starting offset of the |
| 52 * next non-comment token *following* the doc comment. For example, the position | 52 * next non-comment token *following* the doc comment. For example, the position |
| 53 * for this comment would be the position of the "Map" token below. | 53 * for this comment would be the position of the "Map" token below. |
| 54 */ | 54 */ |
| 55 Map<String, Map<int, String>> _comments; | 55 Map<String, Map<int, String>> _comments; |
| 56 | 56 |
| 57 /** A callback that returns additional Markdown documentation for a type. */ | |
| 58 typedef String DocTypeFunction(Type type); | |
| 59 | |
| 60 /** A list of callbacks registered for documenting types. */ | |
| 61 List<DocTypeFunction> _docTypeFns; | |
|
Bob Nystrom
2011/12/06 23:11:23
How about "Documenter" instead of "Function" and "
nweiz
2011/12/07 19:26:56
Done.
| |
| 62 | |
| 63 /** A callback that returns additional Markdown documentation for a method. */ | |
| 64 typedef String DocMethodFunction(MethodMember method); | |
| 65 | |
| 66 /** A list of callbacks registered for documenting methods. */ | |
| 67 List<DocMethodFunction> _docMethodFns; | |
| 68 | |
| 69 /** A callback that returns additional Markdown documentation for a field. */ | |
| 70 typedef String DocFieldFunction(FieldMember field); | |
| 71 | |
| 72 /** A list of callbacks registered for documenting fields. */ | |
| 73 List<DocFieldFunction> _docFieldFns; | |
| 74 | |
| 57 int _totalLibraries = 0; | 75 int _totalLibraries = 0; |
| 58 int _totalTypes = 0; | 76 int _totalTypes = 0; |
| 59 int _totalMembers = 0; | 77 int _totalMembers = 0; |
| 60 | 78 |
| 61 /** | 79 /** |
| 62 * Run this from the `utils/dartdoc` directory. | 80 * Run this from the `utils/dartdoc` directory. |
| 63 */ | 81 */ |
| 64 void main() { | 82 void main() { |
| 65 // The entrypoint of the library to generate docs for. | 83 // The entrypoint of the library to generate docs for. |
| 66 final entrypoint = process.argv[2]; | 84 final entrypoint = process.argv[2]; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 for (final library in world.libraries.getValues()) { | 147 for (final library in world.libraries.getValues()) { |
| 130 docLibrary(library); | 148 docLibrary(library); |
| 131 } | 149 } |
| 132 }); | 150 }); |
| 133 | 151 |
| 134 print('Documented $_totalLibraries libraries, $_totalTypes types, and ' + | 152 print('Documented $_totalLibraries libraries, $_totalTypes types, and ' + |
| 135 '$_totalMembers members in ${elapsed}msec.'); | 153 '$_totalMembers members in ${elapsed}msec.'); |
| 136 } | 154 } |
| 137 | 155 |
| 138 void initializeDartDoc() { | 156 void initializeDartDoc() { |
| 157 if (_comments != null) return; | |
| 139 _comments = <String, Map<int, String>>{}; | 158 _comments = <String, Map<int, String>>{}; |
| 159 _docTypeFns = <DocTypeFunction>[]; | |
| 160 _docMethodFns = <DocMethodFunction>[]; | |
| 161 _docFieldFns = <DocFieldFunction>[]; | |
| 140 } | 162 } |
| 141 | 163 |
| 142 writeHeader(String title) { | 164 writeHeader(String title) { |
| 143 writeln( | 165 writeln( |
| 144 ''' | 166 ''' |
| 145 <!DOCTYPE html> | 167 <!DOCTYPE html> |
| 146 <html> | 168 <html> |
| 147 <head> | 169 <head> |
| 148 <meta charset="utf-8"> | 170 <meta charset="utf-8"> |
| 149 <title>$title</title> | 171 <title>$title</title> |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 write('<strong>${typeName(type)}</strong>'); | 249 write('<strong>${typeName(type)}</strong>'); |
| 228 } else { | 250 } else { |
| 229 write('${a(typeUrl(type), typeName(type))}'); | 251 write('${a(typeUrl(type), typeName(type))}'); |
| 230 } | 252 } |
| 231 | 253 |
| 232 writeln('</li>'); | 254 writeln('</li>'); |
| 233 } | 255 } |
| 234 writeln('</ul>'); | 256 writeln('</ul>'); |
| 235 } | 257 } |
| 236 | 258 |
| 259 String _callbacks(var item, List<Function> callbacks) => | |
|
Bob Nystrom
2011/12/06 23:11:23
Just because you *can* use a functional style does
nweiz
2011/12/07 19:26:56
I'll concede that Member#hashCode and #== were a b
| |
| 260 Strings.join(map(callbacks, (cb) => cb(item)), '\n\n'); | |
| 261 | |
| 237 docLibrary(Library library) { | 262 docLibrary(Library library) { |
| 238 _totalLibraries++; | 263 _totalLibraries++; |
| 239 _currentLibrary = library; | 264 _currentLibrary = library; |
| 240 _currentType = null; | 265 _currentType = null; |
| 241 | 266 |
| 242 startFile(libraryUrl(library)); | 267 startFile(libraryUrl(library)); |
| 243 writeHeader(library.name); | 268 writeHeader(library.name); |
| 244 writeln('<h1>Library <strong>${library.name}</strong></h1>'); | 269 writeln('<h1>Library <strong>${library.name}</strong></h1>'); |
| 245 | 270 |
| 246 // Look for a comment for the entire library. | 271 // Look for a comment for the entire library. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 writeHeader('Library ${type.library.name} / $typeTitle'); | 312 writeHeader('Library ${type.library.name} / $typeTitle'); |
| 288 writeln( | 313 writeln( |
| 289 ''' | 314 ''' |
| 290 <h1>${a(libraryUrl(type.library), | 315 <h1>${a(libraryUrl(type.library), |
| 291 "Library <strong>${type.library.name}</strong>")}</h1> | 316 "Library <strong>${type.library.name}</strong>")}</h1> |
| 292 <h2>${type.isClass ? "Class" : "Interface"} | 317 <h2>${type.isClass ? "Class" : "Interface"} |
| 293 <strong>${typeName(type)}</strong></h2> | 318 <strong>${typeName(type)}</strong></h2> |
| 294 '''); | 319 '''); |
| 295 | 320 |
| 296 docInheritance(type); | 321 docInheritance(type); |
| 297 docCode(type.span); | 322 docCode(type.span, _callbacks(type, _docTypeFns)); |
| 298 docConstructors(type); | 323 docConstructors(type); |
| 299 docMembers(type); | 324 docMembers(type); |
| 300 | 325 |
| 301 writeFooter(); | 326 writeFooter(); |
| 302 endFile(); | 327 endFile(); |
| 303 } | 328 } |
| 304 | 329 |
| 305 void docMembers(Type type) { | 330 void docMembers(Type type) { |
| 306 // Collect the different kinds of members. | 331 // Collect the different kinds of members. |
| 307 final methods = []; | 332 final methods = []; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 write('('); | 479 write('('); |
| 455 final parameters = map(method.parameters, | 480 final parameters = map(method.parameters, |
| 456 (p) => '${annotation(type, p.type)}${p.name}'); | 481 (p) => '${annotation(type, p.type)}${p.name}'); |
| 457 write(Strings.join(parameters, ', ')); | 482 write(Strings.join(parameters, ', ')); |
| 458 write(')'); | 483 write(')'); |
| 459 | 484 |
| 460 write(''' <a class="anchor-link" href="#${memberAnchor(method)}" | 485 write(''' <a class="anchor-link" href="#${memberAnchor(method)}" |
| 461 title="Permalink to ${typeName(type)}.$name">#</a>'''); | 486 title="Permalink to ${typeName(type)}.$name">#</a>'''); |
| 462 writeln('</h4>'); | 487 writeln('</h4>'); |
| 463 | 488 |
| 464 docCode(method.span, showCode: true); | 489 docCode(method.span, _callbacks(method, _docMethodFns), showCode: true); |
| 465 | 490 |
| 466 writeln('</div>'); | 491 writeln('</div>'); |
| 467 } | 492 } |
| 468 | 493 |
| 469 /** Documents the field [field] of type [type]. */ | 494 /** Documents the field [field] of type [type]. */ |
| 470 docField(Type type, FieldMember field) { | 495 docField(Type type, FieldMember field) { |
| 471 _totalMembers++; | 496 _totalMembers++; |
| 472 _currentMember = field; | 497 _currentMember = field; |
| 473 | 498 |
| 474 writeln('<div class="field"><h4 id="${memberAnchor(field)}">'); | 499 writeln('<div class="field"><h4 id="${memberAnchor(field)}">'); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 489 | 514 |
| 490 write(annotation(type, field.type)); | 515 write(annotation(type, field.type)); |
| 491 write( | 516 write( |
| 492 ''' | 517 ''' |
| 493 <strong>${field.name}</strong> <a class="anchor-link" | 518 <strong>${field.name}</strong> <a class="anchor-link" |
| 494 href="#${memberAnchor(field)}" | 519 href="#${memberAnchor(field)}" |
| 495 title="Permalink to ${typeName(type)}.${field.name}">#</a> | 520 title="Permalink to ${typeName(type)}.${field.name}">#</a> |
| 496 </h4> | 521 </h4> |
| 497 '''); | 522 '''); |
| 498 | 523 |
| 499 docCode(field.span, showCode: true); | 524 docCode(field.span, _callbacks(field, _docFieldFns), showCode: true); |
| 500 writeln('</div>'); | 525 writeln('</div>'); |
| 501 } | 526 } |
| 502 | 527 |
| 503 /** | 528 /** |
| 504 * Creates a hyperlink. Handles turning the [href] into an appropriate relative | 529 * Creates a hyperlink. Handles turning the [href] into an appropriate relative |
| 505 * path from the current file. | 530 * path from the current file. |
| 506 */ | 531 */ |
| 507 String a(String href, String contents, [String class]) { | 532 String a(String href, String contents, [String class]) { |
| 508 final css = class == null ? '' : ' class="$class"'; | 533 final css = class == null ? '' : ' class="$class"'; |
| 509 return '<a href="${relativePath(href)}"$css>$contents</a>'; | 534 return '<a href="${relativePath(href)}"$css>$contents</a>'; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 618 // * Type parameters of the enclosing type. | 643 // * Type parameters of the enclosing type. |
| 619 | 644 |
| 620 return new md.Element.text('code', name); | 645 return new md.Element.text('code', name); |
| 621 } | 646 } |
| 622 | 647 |
| 623 /** | 648 /** |
| 624 * Documents the code contained within [span]. Will include the previous | 649 * Documents the code contained within [span]. Will include the previous |
| 625 * Dartdoc associated with that span if found, and will include the syntax | 650 * Dartdoc associated with that span if found, and will include the syntax |
| 626 * highlighted code itself if desired. | 651 * highlighted code itself if desired. |
| 627 */ | 652 */ |
| 628 docCode(SourceSpan span, [bool showCode = false]) { | 653 docCode(SourceSpan span, String extraDocs, [bool showCode = false]) { |
|
Bob Nystrom
2011/12/06 23:11:23
"extraMarkdown"
We need to make it clear that thi
nweiz
2011/12/07 19:26:56
Done.
| |
| 629 if (span == null) return; | 654 if (span == null) return; |
| 630 | 655 |
| 631 writeln('<div class="doc">'); | 656 writeln('<div class="doc">'); |
| 632 final comment = findComment(span); | 657 final comment = findComment(span); |
| 633 if (comment != null) { | 658 if (comment != null) { |
| 634 writeln(md.markdownToHtml(comment)); | 659 writeln(md.markdownToHtml('${comment}\n\n${extraDocs}')); |
| 660 } else { | |
| 661 writeln(md.markdownToHtml(extraDocs)); | |
| 635 } | 662 } |
| 636 | 663 |
| 637 if (includeSource && showCode) { | 664 if (includeSource && showCode) { |
| 638 writeln('<pre class="source">'); | 665 writeln('<pre class="source">'); |
| 639 write(formatCode(span)); | 666 write(formatCode(span)); |
| 640 writeln('</pre>'); | 667 writeln('</pre>'); |
| 641 } | 668 } |
| 642 | 669 |
| 643 writeln('</div>'); | 670 writeln('</div>'); |
| 644 } | 671 } |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 742 line = line.substring(2, line.length); | 769 line = line.substring(2, line.length); |
| 743 } else if (line.startsWith('*')) { | 770 } else if (line.startsWith('*')) { |
| 744 line = line.substring(1, line.length); | 771 line = line.substring(1, line.length); |
| 745 } | 772 } |
| 746 | 773 |
| 747 buf.add(line); | 774 buf.add(line); |
| 748 buf.add('\n'); | 775 buf.add('\n'); |
| 749 } | 776 } |
| 750 | 777 |
| 751 return buf.toString(); | 778 return buf.toString(); |
| 752 } | 779 } |
| 780 | |
| 781 /** Register a callback to add additional documentation to a type. */ | |
| 782 registerTypeCallback(DocTypeFunction fn) => _docTypeFns.add(fn); | |
|
Bob Nystrom
2011/12/06 23:11:23
I'd name this "add" instead of "register" to make
nweiz
2011/12/07 19:26:56
Done.
| |
| 783 | |
| 784 /** Register a callback to add additional documentation to a method. */ | |
| 785 registerMethodCallback(DocMethodFunction fn) => _docMethodFns.add(fn); | |
| 786 | |
| 787 /** Register a callback to add additional documentation to a field. */ | |
| 788 registerFieldCallback(DocFieldFunction fn) => _docFieldFns.add(fn); | |
| OLD | NEW |