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

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

Issue 10453097: Frog now called directly in dartdoc (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 6 months 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
« no previous file with comments | « frog/minfrogc.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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:json'); 20 #import('dart:json');
21 #import('../../frog/lang.dart'); 21 #import('../../frog/lang.dart');
22 #import('../../frog/file_system.dart'); 22 #import('../../frog/file_system.dart');
23 #import('../../frog/file_system_vm.dart'); 23 #import('../../frog/file_system_vm.dart');
24 #import('classify.dart'); 24 #import('classify.dart');
25 #import('markdown.dart', prefix: 'md'); 25 #import('markdown.dart', prefix: 'md');
26 #import('../../frog/minfrogc.dart', prefix: 'frog');
26 27
27 #source('comment_map.dart'); 28 #source('comment_map.dart');
28 #source('utils.dart'); 29 #source('utils.dart');
29 30
30 /** 31 /**
31 * Generates completely static HTML containing everything you need to browse 32 * Generates completely static HTML containing everything you need to browse
32 * the docs. The only client side behavior is trivial stuff like syntax 33 * the docs. The only client side behavior is trivial stuff like syntax
33 * highlighting code. 34 * highlighting code.
34 */ 35 */
35 final MODE_STATIC = 0; 36 final MODE_STATIC = 0;
36 37
37 /** 38 /**
38 * Generated docs do not include baked HTML navigation. Instead, a single 39 * Generated docs do not include baked HTML navigation. Instead, a single
39 * `nav.json` file is created and the appropriate navigation is generated 40 * `nav.json` file is created and the appropriate navigation is generated
40 * client-side by parsing that and building HTML. 41 * client-side by parsing that and building HTML.
41 * 42 *
42 * This dramatically reduces the generated size of the HTML since a large 43 * This dramatically reduces the generated size of the HTML since a large
43 * fraction of each static page is just redundant navigation links. 44 * fraction of each static page is just redundant navigation links.
44 * 45 *
45 * In this mode, the browser will do a XHR for nav.json which means that to 46 * In this mode, the browser will do a XHR for nav.json which means that to
46 * preview docs locally, you will need to enable requesting file:// links in 47 * preview docs locally, you will need to enable requesting file:// links in
47 * your browser or run a little local server like `python -m SimpleHTTPServer`. 48 * your browser or run a little local server like `python -m SimpleHTTPServer`.
48 */ 49 */
49 final MODE_LIVE_NAV = 1; 50 final MODE_LIVE_NAV = 1;
50 51
52 void printUsage() {
kasperl 2012/05/31 13:30:23 I would consider moving printUsage down below main
53 print('''
54 Usage dartdoc [options] <entrypoint>
55 [options] include
56 --no-code Do not include source code in the documentation.
57
58 --mode=static Generates completely static HTML containing
59 everything you need to browse the docs. The only
60 client side behavior is trivial stuff like syntax
61 highlighting code.
62
63 --mode=live-nav (default) Generated docs do not include baked HTML
64 navigation. Instead, a single `nav.json` file is
65 created and the appropriate navigation is generated
66 client-side by parsing that and building HTML.
67 This dramatically reduces the generated size of
68 the HTML since a large fraction of each static page
69 is just redundant navigation links.
70 In this mode, the browser will do a XHR for
71 nav.json which means that to preview docs locally,
72 you will need to enable requesting file:// links in
73 your browser or run a little local server like
74 `python -m SimpleHTTPServer`.
75
76 --generate-app-cache Generates the App Cache manifest file, enabling
77 offline doc viewing.
78 --generate-app-cache=true --''--
79
80 --out=<dir> Generates files into directory <dir>. If omitted
81 the files are generated into ./docs/
82 ''');
83 }
84
51 /** 85 /**
52 * Run this from the `lib/dartdoc` directory. 86 * Run this from the `lib/dartdoc` directory.
53 */ 87 */
54 void main() { 88 void main() {
55 final args = new Options().arguments; 89 final args = new Options().arguments;
56 90
57 // Parse the dartdoc options. 91 // Parse the dartdoc options.
58 bool includeSource; 92 bool includeSource;
59 int mode; 93 int mode;
60 String outputDir; 94 String outputDir;
61 bool generateAppCache; 95 bool generateAppCache;
96
97 if (args.length == 0) {
kasperl 2012/05/31 13:30:23 args.isEmpty()?
98 print('No arguments provided.');
99 printUsage();
100 return;
101 }
62 102
63 for (int i = 0; i < args.length - 1; i++) { 103 for (int i = 0; i < args.length - 1; i++) {
64 final arg = args[i]; 104 final arg = args[i];
65 105
66 switch (arg) { 106 switch (arg) {
67 case '--no-code': 107 case '--no-code':
68 includeSource = false; 108 includeSource = false;
69 break; 109 break;
70 110
71 case '--mode=static': 111 case '--mode=static':
72 mode = MODE_STATIC; 112 mode = MODE_STATIC;
73 break; 113 break;
74 114
75 case '--mode=live-nav': 115 case '--mode=live-nav':
76 mode = MODE_LIVE_NAV; 116 mode = MODE_LIVE_NAV;
77 break; 117 break;
78 118
79 case '--generate-app-cache': 119 case '--generate-app-cache':
80 case '--generate-app-cache=true': 120 case '--generate-app-cache=true':
81 generateAppCache = true; 121 generateAppCache = true;
82 break; 122 break;
83 123
84 default: 124 default:
85 if (arg.startsWith('--out=')) { 125 if (arg.startsWith('--out=')) {
86 outputDir = arg.substring('--out='.length); 126 outputDir = arg.substring('--out='.length);
87 } else { 127 } else {
88 print('Unknown option: $arg'); 128 print('Unknown option: $arg');
129 printUsage();
89 return; 130 return;
90 } 131 }
91 break; 132 break;
92 } 133 }
93 } 134 }
94 135
95 // The entrypoint of the library to generate docs for. 136 // The entrypoint of the library to generate docs for.
96 final entrypoint = args[args.length - 1]; 137 final entrypoint = args[args.length - 1];
97 138
98 final files = new VMFileSystem(); 139 final files = new VMFileSystem();
99 140
100 // TODO(rnystrom): Note that the following lines get munged by create-sdk to 141 // TODO(rnystrom): Note that the following lines get munged by create-sdk to
101 // work with the SDK's different file layout. If you change, be sure to test 142 // work with the SDK's different file layout. If you change, be sure to test
102 // that dartdoc still works when run from the built SDK directory. 143 // that dartdoc still works when run from the built SDK directory.
103 final frogPath = joinPaths(scriptDir, '../../frog/'); 144 final frogPath = joinPaths(scriptDir, '../../frog/');
104 final libDir = joinPaths(frogPath, 'lib'); 145 final libDir = joinPaths(frogPath, 'lib');
105 final compilerPath = joinPaths(frogPath, 'minfrog');
106 146
107 parseOptions(frogPath, ['', '', '--libdir=$libDir'], files); 147 parseOptions(frogPath, ['', '', '--libdir=$libDir'], files);
108 initializeWorld(files); 148 initializeWorld(files);
109 149
110 final dartdoc = new Dartdoc(); 150 final dartdoc = new Dartdoc();
111 151
112 if (includeSource != null) dartdoc.includeSource = includeSource; 152 if (includeSource != null) dartdoc.includeSource = includeSource;
113 if (mode != null) dartdoc.mode = mode; 153 if (mode != null) dartdoc.mode = mode;
114 if (outputDir != null) dartdoc.outputDir = outputDir; 154 if (outputDir != null) dartdoc.outputDir = outputDir;
115 if (generateAppCache != null) dartdoc.generateAppCache = generateAppCache; 155 if (generateAppCache != null) dartdoc.generateAppCache = generateAppCache;
116 156
117 cleanOutputDirectory(dartdoc.outputDir); 157 cleanOutputDirectory(dartdoc.outputDir);
118 158
119 // Compile the client-side code to JS. 159 // Compile the client-side code to JS.
120 final clientScript = (dartdoc.mode == MODE_STATIC) ? 'static' : 'live-nav'; 160 final clientScript = (dartdoc.mode == MODE_STATIC) ? 'static' : 'live-nav';
121 final Future scriptCompiled = compileScript(compilerPath, libDir, 161 final Future scriptCompiled = compileScript(libDir,
122 '$scriptDir/client-$clientScript.dart', 162 '$scriptDir/client-$clientScript.dart',
kasperl 2012/05/31 13:30:23 The indentation here seems off (not your fault). I
123 '${dartdoc.outputDir}/client-$clientScript.js'); 163 '${dartdoc.outputDir}/client-$clientScript.js');
124 164
125 final Future filesCopied = copyFiles('$scriptDir/static', dartdoc.outputDir); 165 final Future filesCopied = copyFiles('$scriptDir/static', dartdoc.outputDir);
126 166
127 Futures.wait([scriptCompiled, filesCopied]).then((_) { 167 Futures.wait([scriptCompiled, filesCopied]).then((_) {
128 dartdoc.document(entrypoint); 168 dartdoc.document(entrypoint);
169
170 print('Documented ${dartdoc._totalLibraries} libraries, ' +
ngeoffray 2012/05/31 13:22:56 You can remove the '+'s here, they're not needed,
kasperl 2012/05/31 13:30:23 We're deprecating using + for string concatenation
171 '${dartdoc._totalTypes} types, and ' +
172 '${dartdoc._totalMembers} members.');
129 }); 173 });
130 174
131 print('Documented ${dartdoc._totalLibraries} libraries, ' +
132 '${dartdoc._totalTypes} types, and ' +
133 '${dartdoc._totalMembers} members.');
134 } 175 }
135 176
136 /** 177 /**
137 * Gets the full path to the directory containing the entrypoint of the current 178 * Gets the full path to the directory containing the entrypoint of the current
138 * script. In other words, if you invoked dartdoc, directly, it will be the 179 * script. In other words, if you invoked dartdoc, directly, it will be the
139 * path to the directory containing `dartdoc.dart`. If you're running a script 180 * path to the directory containing `dartdoc.dart`. If you're running a script
140 * that imports dartdoc, it will be the path to that script. 181 * that imports dartdoc, it will be the path to that script.
141 */ 182 */
142 String get scriptDir() { 183 String get scriptDir() {
143 return dirname(new File(new Options().script).fullPathSync()); 184 return dirname(new File(new Options().script).fullPathSync());
144 } 185 }
145 186
146 /** 187 /**
147 * Deletes and recreates the output directory at [path] if it exists. 188 * Deletes and recreates the output directory at [path] if it exists.
148 */ 189 */
149 void cleanOutputDirectory(String path) { 190 void cleanOutputDirectory(String path) {
150 final outputDir = new Directory(path); 191 final outputDir = new Directory(path);
151 if (outputDir.existsSync()) { 192 if (outputDir.existsSync()) {
152 outputDir.deleteRecursivelySync(); 193 outputDir.deleteRecursivelySync();
153 } 194 }
154 195
155 outputDir.createSync(); 196 try {
197 //TODO(johnniwinther) hack to avoid 'file already exists' exception thrown
ngeoffray 2012/05/31 13:22:56 missing space before TODO
kasperl 2012/05/31 13:30:23 Add a space before TODO and terminate the comment
198 // due to invalid result from dir.existsSync() (probably due to race
199 // conditions)
200 outputDir.createSync();
201 } catch (DirectoryIOException e) {
202 // ignore
kasperl 2012/05/31 13:30:23 Start comments with uppercase and terminate with .
203 // print('$e: $path');
ngeoffray 2012/05/31 13:22:56 Leftover debugging?
kasperl 2012/05/31 13:30:23 We try to avoid code in comments.
204 }
156 } 205 }
157 206
158 /** 207 /**
159 * Copies all of the files in the directory [from] to [to]. Does *not* 208 * Copies all of the files in the directory [from] to [to]. Does *not*
160 * recursively copy subdirectories. 209 * recursively copy subdirectories.
161 * 210 *
162 * Note: runs asynchronously, so you won't see any files copied until after the 211 * Note: runs asynchronously, so you won't see any files copied until after the
163 * event loop has had a chance to pump (i.e. after `main()` has returned). 212 * event loop has had a chance to pump (i.e. after `main()` has returned).
164 */ 213 */
165 Future copyFiles(String from, String to) { 214 Future copyFiles(String from, String to) {
(...skipping 12 matching lines...) Expand all
178 stream.write(bytes, copyBuffer: false); 227 stream.write(bytes, copyBuffer: false);
179 stream.close(); 228 stream.close();
180 }); 229 });
181 }; 230 };
182 lister.onDone = (done) => completer.complete(true); 231 lister.onDone = (done) => completer.complete(true);
183 return completer.future; 232 return completer.future;
184 } 233 }
185 234
186 /** 235 /**
187 * Compiles the given Dart script to a JavaScript file at [jsPath] using the 236 * Compiles the given Dart script to a JavaScript file at [jsPath] using the
188 * Dart-to-JS compiler located at [compilerPath]. 237 * Frog compiler located.
ngeoffray 2012/05/31 13:22:56 Remove located.
189 */ 238 */
190 Future compileScript(String compilerPath, String libDir, 239 Future compileScript(String libDir,
191 String dartPath, String jsPath) { 240 String dartPath, String jsPath) {
kasperl 2012/05/31 13:30:23 Would all the parameters fit on one line now?
192 final completer = new Completer(); 241 final completer = new Completer();
193 onExit(ProcessResult result) { 242 print('Compiling $dartPath to $jsPath');
194 if (result.exitCode != 0) { 243
195 final message = 'Non-zero exit code from $compilerPath'; 244 var result = true;
245 try {
246 result = frog.internalMain([
247 '--libdir=$libDir', '--out=$jsPath',
kasperl 2012/05/31 13:30:23 4 space indent.
248 '--compile-only', '--enable-type-checks', '--warnings-as-errors',
249 dartPath]);
250 } catch (Object error) {
ngeoffray 2012/05/31 13:22:56 strange indentation
kasperl 2012/05/31 13:30:23 Indentation seems off.
251 final message = 'Error trying to execute the compiler. Error: $error';
196 print('$message.'); 252 print('$message.');
ngeoffray 2012/05/31 13:22:56 Note that you can just write: print(message) The
197 print(result.stdout);
198 print(result.stderr);
199 throw message; 253 throw message;
kasperl 2012/05/31 13:30:23 This should probably be completer.completeExceptio
200 } 254 }
201 completer.complete(true); 255 if (!result) {
202 } 256 final message = 'Non-zero exit code from the compiler';
203
204 onError(error) {
205 final message = 'Error trying to execute $compilerPath. Error: $error';
206 print('$message.'); 257 print('$message.');
207 throw message; 258 throw message;
kasperl 2012/05/31 13:30:23 This should probably be completer.completeExceptio
kasperl 2012/05/31 13:30:23 This should probably be completer.completeExceptio
208 } 259 }
209 260 completer.complete(result);
210 print('Compiling $dartPath to $jsPath');
211 var processFuture = Process.run(compilerPath, [
212 '--libdir=$libDir', '--out=$jsPath',
213 '--compile-only', '--enable-type-checks', '--warnings-as-errors',
214 dartPath]);
215
216 processFuture.handleException(onError);
217 processFuture.then(onExit);
218 261
219 return completer.future; 262 return completer.future;
220 } 263 }
221 264
222 class Dartdoc { 265 class Dartdoc {
223 266
224 /** Set to `false` to not include the source code in the generated docs. */ 267 /** Set to `false` to not include the source code in the generated docs. */
225 bool includeSource = true; 268 bool includeSource = true;
226 269
227 /** 270 /**
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 387
345 void startFile(String path) { 388 void startFile(String path) {
346 _filePath = path; 389 _filePath = path;
347 _file = new StringBuffer(); 390 _file = new StringBuffer();
348 } 391 }
349 392
350 void endFile() { 393 void endFile() {
351 final outPath = '$outputDir/$_filePath'; 394 final outPath = '$outputDir/$_filePath';
352 final dir = new Directory(dirname(outPath)); 395 final dir = new Directory(dirname(outPath));
353 if (!dir.existsSync()) { 396 if (!dir.existsSync()) {
354 dir.createSync(); 397 //TODO(johnniwinther) hack to avoid 'file already exists' exception thrown
ngeoffray 2012/05/31 13:22:56 Space before TODO
kasperl 2012/05/31 13:30:23 Space before TODO. Terminate comment with . Consid
398 // due to invalid result from dir.existsSync() (probably due to race
399 // conditions)
400 try {
401 dir.createSync();
402 } catch (DirectoryIOException e) {
403 // ignore
kasperl 2012/05/31 13:30:23 // Ignore.
404 }
355 } 405 }
356 406
357 world.files.writeString(outPath, _file.toString()); 407 world.files.writeString(outPath, _file.toString());
358 _filePath = null; 408 _filePath = null;
359 _file = null; 409 _file = null;
360 } 410 }
361 411
362 void write(String s) { 412 void write(String s) {
363 _file.add(s); 413 _file.add(s);
364 } 414 }
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 toCache.onFile = (filename) { 1398 toCache.onFile = (filename) {
1349 if (filename.endsWith('appcache.manifest')) { 1399 if (filename.endsWith('appcache.manifest')) {
1350 return; 1400 return;
1351 } 1401 }
1352 var relativePath = filename.substring(pathPrefixLength + 1); 1402 var relativePath = filename.substring(pathPrefixLength + 1);
1353 write("$relativePath\n"); 1403 write("$relativePath\n");
1354 }; 1404 };
1355 toCache.onDone = (done) => endFile(); 1405 toCache.onDone = (done) => endFile();
1356 toCache.list(recursive: true); 1406 toCache.list(recursive: true);
1357 } 1407 }
1358 } 1408 }
OLDNEW
« no previous file with comments | « frog/minfrogc.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698