Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: utils/dartdoc/dartdoc.dart

Issue 8515029: Move doc generator out of frog samples. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 // TODO(rnystrom): This is moving from a sample to being a real project. Right 5 /** An awesome documentation generator. */
6 // now, to try this out: 6 #library('dartdoc');
7 // 1. Compile interact.dart to JS:
8 // $ ./frogsh --out=docs/interact.js --compile-only docs/interact.dart
9 // 2. Run the doc generator:
10 // $ ./frogsh samples/doc.dart
11 // 3. Look at the results in frog/docs/
12 7
13 /** An awesome documentation generator. */ 8 #import('../../frog/lang.dart');
14 #library('doc'); 9 #import('../../frog/file_system_node.dart');
15 10
16 #import('../lang.dart'); 11 #source('classify.dart');
17 #import('../file_system_node.dart');
18 #import('classify.dart');
19
20 /** Path to starting library or application. */
21 // TODO(rnystrom): Make this a command-line arg.
22 final libPath = 'samples/doc.dart';
23 12
24 /** Path to corePath library. */ 13 /** Path to corePath library. */
25 final corePath = 'lib'; 14 final corePath = 'lib';
26 15
27 /** Path to generate html files into. */ 16 /** Path to generate html files into. */
28 final outdir = './docs'; 17 final outdir = 'docs';
29 18
30 /** Special comment position used to store the library-level doc comment. */ 19 /** Special comment position used to store the library-level doc comment. */
31 final _libraryDoc = -1; 20 final _libraryDoc = -1;
32 21
33 /** The file currently being written to. */ 22 /** The file currently being written to. */
34 StringBuffer _file; 23 StringBuffer _file;
35 24
36 /** 25 /**
37 * The cached lookup-table to associate doc comments with spans. The outer map 26 * The cached lookup-table to associate doc comments with spans. The outer map
38 * is from filenames to doc comments in that file. The inner map maps from the 27 * is from filenames to doc comments in that file. The inner map maps from the
39 * token positions to doc comments. Each position is the starting offset of the 28 * token positions to doc comments. Each position is the starting offset of the
40 * next non-comment token *following* the doc comment. For example, the position 29 * next non-comment token *following* the doc comment. For example, the position
41 * for this comment would be the position of the "Map" token below. 30 * for this comment would be the position of the "Map" token below.
42 */ 31 */
43 Map<String, Map<int, String>> _comments; 32 Map<String, Map<int, String>> _comments;
44 33
45 // TODO(jimhug): This generates really ugly output with lots of holes. 34 int _totalLibraries = 0;
Jennifer Messerly 2011/11/11 02:29:58 haha. yes, that TODO is very obsolete :)
jimhug 2011/11/11 18:02:31 Whoo hoo!
Bob Nystrom 2011/11/11 18:21:28 :D Still need private members, but almost everyth
35 int _totalTypes = 0;
36 int _totalMembers = 0;
46 37
47 /** 38 /**
48 * Run this from the frog/samples directory. Before running, you need 39 * Run this from the frog/samples directory. Before running, you need
49 * to create a docs dir with 'mkdir docs' - since Dart currently doesn't 40 * to create a docs dir with 'mkdir docs' - since Dart currently doesn't
50 * support creating new directories. 41 * support creating new directories.
51 */ 42 */
52 void main() { 43 void main() {
44 // The entrypoint of the library to generate docs for.
45 final libPath = process.argv[2];
46
53 // TODO(rnystrom): Get options and homedir like frog.dart does. 47 // TODO(rnystrom): Get options and homedir like frog.dart does.
54 final files = new NodeFileSystem(); 48 final files = new NodeFileSystem();
55 parseOptions('.', [] /* args */, files); 49 parseOptions('../../frog', [] /* args */, files);
56 50
57 initializeWorld(files); 51 final elapsed = time(() {
52 initializeWorld(files);
58 53
59 world.withTiming('parsed', () {
60 world.processScript(libPath); 54 world.processScript(libPath);
61 }); 55 world.resolveAll();
62 56
63 world.withTiming('resolved', () {
64 world.resolveAll();
65 });
66
67 world.withTiming('generated docs', () {
68 _comments = <String, Map<int, String>>{}; 57 _comments = <String, Map<int, String>>{};
69 58
70 for (var library in world.libraries.getValues()) { 59 for (var library in world.libraries.getValues()) {
71 docLibrary(library); 60 docLibrary(library);
72 } 61 }
73 62
74 docIndex(world.libraries.getValues()); 63 docIndex(world.libraries.getValues());
75 }); 64 });
65
66 print('Documented $_totalLibraries libraries, $_totalTypes types, and ' +
67 '$_totalMembers members in ${elapsed}msec.');
jimhug 2011/11/11 18:02:31 Nice reporting code.
Bob Nystrom 2011/11/11 18:21:28 Thanks! I was using withTiming() before but that d
68 }
69
70 num time(callback()) {
71 // Unlike world.withTiming, returns the elapsed time.
72 final watch = new StopWatch();
73 watch.start();
74 callback();
75 watch.stop();
76 return watch.elapsedInMs();
76 } 77 }
77 78
78 startFile() { 79 startFile() {
79 _file = new StringBuffer(); 80 _file = new StringBuffer();
80 } 81 }
81 82
82 write(String s) { 83 write(String s) {
83 _file.add(s); 84 _file.add(s);
84 } 85 }
85 86
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 ''' 127 '''
127 </ul> 128 </ul>
128 </div> 129 </div>
129 </body></html> 130 </body></html>
130 '''); 131 ''');
131 132
132 endFile('$outdir/index.html'); 133 endFile('$outdir/index.html');
133 } 134 }
134 135
135 docLibrary(Library library) { 136 docLibrary(Library library) {
137 _totalLibraries++;
138
136 startFile(); 139 startFile();
137 writeln( 140 writeln(
138 ''' 141 '''
139 <html> 142 <html>
140 <head> 143 <head>
141 <title>${library.name}</title> 144 <title>${library.name}</title>
142 <link rel="stylesheet" type="text/css" href="styles.css" /> 145 <link rel="stylesheet" type="text/css" href="styles.css" />
143 <link href="http://fonts.googleapis.com/css?family=Open+Sans:400,600,700,8 00" rel="stylesheet" type="text/css"> 146 <link href="http://fonts.googleapis.com/css?family=Open+Sans:400,600,700,8 00" rel="stylesheet" type="text/css">
144 <script src="interact.js"></script> 147 <script src="interact.js"></script>
145 </head> 148 </head>
146 <body> 149 <body>
147 <div class="content"> 150 <div class="content">
148 <h1>Library <strong>${library.name}</strong></h1> 151 <h1>Library <strong>${library.name}</strong></h1>
149 '''); 152 ''');
150 153
151 bool needsSeparator = false; 154 bool needsSeparator = false;
152 155
153 // Look for a comment for the entire library. 156 // Look for a comment for the entire library.
154 final comment = findCommentInFile(library.baseSource, _libraryDoc); 157 final comment = findCommentInFile(library.baseSource, _libraryDoc);
155 if (comment != null) { 158 if (comment != null) {
156 writeln('<div class="doc"><p>$comment</p></div>'); 159 writeln('<div class="doc"><p>$comment</p></div>');
157 needsSeparator = true; 160 needsSeparator = true;
158 } 161 }
159 162
160 for (var type in library.types.getValues()) { 163 for (var type in library.types.getValues()) {
161 if (needsSeparator) writeln('<hr/>'); 164 if (needsSeparator) writeln('<hr/>');
162 if (docType(type)) needsSeparator = false; 165 if (docType(type)) needsSeparator = true;
163 } 166 }
164 167
165 writeln( 168 writeln(
166 ''' 169 '''
167 </div> 170 </div>
168 </body></html> 171 </body></html>
169 '''); 172 ''');
170 173
171 endFile('$outdir/${sanitize(library.name)}.html'); 174 endFile('$outdir/${sanitize(library.name)}.html');
172 } 175 }
173 176
174 /** 177 /**
175 * Documents [Type]. Handles top-level members if given an unnamed Type. 178 * Documents [Type]. Handles top-level members if given an unnamed Type.
176 * Returns [:true:] if it wrote anything. 179 * Returns [:true:] if it wrote anything.
177 */ 180 */
178 bool docType(Type type) { 181 bool docType(Type type) {
182 _totalTypes++;
183
179 bool wroteSomething = false; 184 bool wroteSomething = false;
180 185
181 if (type.name != null) { 186 if (type.name != null) {
182 write( 187 write(
183 ''' 188 '''
184 <h2 id="${type.name}"> 189 <h2 id="${type.name}">
185 ${type.isClass ? "Class" : "Interface"} <strong>${type.name}</strong> 190 ${type.isClass ? "Class" : "Interface"} <strong>${type.name}</strong>
186 <a class="anchor-link" href="#${type.name}" 191 <a class="anchor-link" href="#${type.name}"
187 title="Permalink to ${type.name}">#</a> 192 title="Permalink to ${type.name}">#</a>
188 </h2> 193 </h2>
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 284 }
280 } 285 }
281 } 286 }
282 287
283 /** 288 /**
284 * Documents the [method] in a type named [typeName]. Handles all kinds of 289 * Documents the [method] in a type named [typeName]. Handles all kinds of
285 * methods including getters, setters, and constructors. 290 * methods including getters, setters, and constructors.
286 */ 291 */
287 docMethod(String typeName, MethodMember method, 292 docMethod(String typeName, MethodMember method,
288 [String namedConstructor = null]) { 293 [String namedConstructor = null]) {
294 _totalMembers++;
295
289 writeln( 296 writeln(
290 ''' 297 '''
291 <div class="method"><h4 id="$typeName.${method.name}"> 298 <div class="method"><h4 id="$typeName.${method.name}">
292 <span class="show-code">Code</span> 299 <span class="show-code">Code</span>
293 '''); 300 ''');
294 301
295 // A null typeName means it's a top-level definition which is implicitly 302 // A null typeName means it's a top-level definition which is implicitly
296 // static so doesn't need to annotate it. 303 // static so doesn't need to annotate it.
297 if (method.isStatic && (typeName != null)) { 304 if (method.isStatic && (typeName != null)) {
298 write('static '); 305 write('static ');
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 title="Permalink to $typeName.$name">#</a>'''); 352 title="Permalink to $typeName.$name">#</a>''');
346 writeln('</h4>'); 353 writeln('</h4>');
347 354
348 docCode(method.span, showCode: true); 355 docCode(method.span, showCode: true);
349 356
350 writeln('</div>'); 357 writeln('</div>');
351 } 358 }
352 359
353 /** Documents the field [field] in a type named [typeName]. */ 360 /** Documents the field [field] in a type named [typeName]. */
354 docField(String typeName, FieldMember field) { 361 docField(String typeName, FieldMember field) {
362 _totalMembers++;
363
355 writeln( 364 writeln(
356 ''' 365 '''
357 <div class="field"><h4 id="$typeName.${field.name}"> 366 <div class="field"><h4 id="$typeName.${field.name}">
358 <span class="show-code">Code</span> 367 <span class="show-code">Code</span>
359 '''); 368 ''');
360 369
361 // A null typeName means it's a top-level definition which is implicitly 370 // A null typeName means it's a top-level definition which is implicitly
362 // static so doesn't need to annotate it. 371 // static so doesn't need to annotate it.
363 if (field.isStatic && (typeName != null)) { 372 if (field.isStatic && (typeName != null)) {
364 write('static '); 373 write('static ');
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 if (line.endsWith('*/')) line = line.substring(0, line.length-2); 542 if (line.endsWith('*/')) line = line.substring(0, line.length-2);
534 line = line.trim(); 543 line = line.trim();
535 while (line.startsWith('*')) line = line.substring(1, line.length); 544 while (line.startsWith('*')) line = line.substring(1, line.length);
536 line = line.trim(); 545 line = line.trim();
537 buf.add(line); 546 buf.add(line);
538 buf.add(' '); 547 buf.add(' ');
539 } 548 }
540 549
541 return buf.toString(); 550 return buf.toString();
542 } 551 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698