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

Side by Side Diff: tools/html_json_doc/lib/html_to_json.dart

Issue 11413197: Updated json_to_html to be sync. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: A shot. Created 8 years 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) 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 * Library for extracting the documentation comments from files generated by 6 * Library for extracting the documentation comments from files generated by
7 * the HTML library. The comments are stored in a JSON file. 7 * the HTML library. The comments are stored in a JSON file.
8 * 8 *
9 * Comments must be in either the block style with leading *s: 9 * Comments must be in either the block style with leading *s:
10 * 10 *
(...skipping 30 matching lines...) Expand all
41 // TODO(amouravski): make this transform once I know what I want this file to 41 // TODO(amouravski): make this transform once I know what I want this file to
42 // return. 42 // return.
43 _convertFiles(htmlPath).then((convertedJson) { 43 _convertFiles(htmlPath).then((convertedJson) {
44 final jsonFile = new File.fromPath(jsonPath); 44 final jsonFile = new File.fromPath(jsonPath);
45 var writeJson = convertedJson; 45 var writeJson = convertedJson;
46 46
47 if (jsonFile.existsSync()) { 47 if (jsonFile.existsSync()) {
48 writeJson = _mergeJsonAndFile(convertedJson, jsonFile); 48 writeJson = _mergeJsonAndFile(convertedJson, jsonFile);
49 } 49 }
50 50
51 var outputStream = jsonFile.openOutputStream(); 51 jsonFile.writeAsStringSync(prettyPrintJson(writeJson));
52 outputStream.writeString(prettyPrintJson(writeJson)); 52 completer.complete(_anyErrors);
53
54 outputStream.onNoPendingWrites = () {
55 completer.complete(_anyErrors);
56 };
57
58 outputStream.onClosed = () {
59 completer.complete(_anyErrors);
60 };
61
62 outputStream.onError = completer.completeException;
63 }); 53 });
64 54
65 return completer.future; 55 return completer.future;
66 } 56 }
67 57
68 58
69 /** 59 /**
70 * Convert all files on [htmlPath]. 60 * Convert all files on [htmlPath].
71 * 61 *
72 * Returns a future that completes to the converted JSON object. 62 * Returns a future that completes to the converted JSON object.
73 */ 63 */
74 Future<Object> _convertFiles(Path htmlPath) { 64 Future<Object> _convertFiles(Path htmlPath) {
75 var completer = new Completer(); 65 //List<Future> fileFutures = [];
Emily Fortuna 2012/11/28 17:17:30 probably just delete this line if it's going to be
76 66 var group = new FutureGroup();
77 List<Future> fileFutures = [];
78 67
79 // Get a list of all HTML dart files. 68 // Get a list of all HTML dart files.
80 // TODO(amouravski): discriminate .dart files. 69 // TODO(amouravski): discriminate .dart files.
81 final htmlDir = new Directory.fromPath(htmlPath); 70 final htmlDir = new Directory.fromPath(htmlPath);
82 final lister = htmlDir.list(recursive: false); 71 final lister = htmlDir.list(recursive: false);
83 72
73 var listCompleter = new Completer();
74 group.add(listCompleter.future);
75
84 lister.onFile = (String path) { 76 lister.onFile = (String path) {
85 final name = new Path.fromNative(path).filename; 77 final name = new Path.fromNative(path).filename;
86 78
87 // Ignore private classes. 79 // Ignore private classes.
88 if (name.startsWith('_')) return; 80 if (name.startsWith('_')) return;
89 81
90 // Ignore non-dart files. 82 // Ignore non-dart files.
91 if (!name.endsWith('.dart')) return; 83 if (!name.endsWith('.dart')) return;
92 84
93 File file = new File(path); 85 group.add(_convertFile(path));
94 86 //fileFutures.add(_convertFile(file));
Emily Fortuna 2012/11/28 17:17:30 ditto here.
95 // TODO(amouravski): Handle missing file.
96 if (!file.existsSync()) {
97 print('ERROR: cannot find file $path');
98 _anyErrors = true;
99 return;
100 }
101
102 fileFutures.add(_convertFile(file));
103 }; 87 };
104 88
105 89
106 // Combine all JSON objects 90 // Combine all JSON objects
107 lister.onDone = (_) { 91 lister.onDone = (done) {
108 Futures.wait(fileFutures).then((jsonList) { 92 if (done) listCompleter.complete(null);
109 var convertedJson = {}; 93 // Futures.wait(fileFutures).then((jsonList) {
Emily Fortuna 2012/11/28 17:17:30 and here
110 jsonList.forEach((json) { 94 // var convertedJson = {};
111 final k = json.keys[0]; 95 // jsonList.forEach((json) {
112 convertedJson.putIfAbsent(k, () => json[k]); 96 // final k = json.keys[0];
113 }); 97 // convertedJson.putIfAbsent(k, () => json[k]);
114 completer.complete(convertedJson); 98 // });
115 }); 99 // completer.complete(convertedJson);
100 // });
116 }; 101 };
117 102
118 // TODO(amouravski): add more error handling. 103 // TODO(amouravski): add more error handling.
119 104
120 return completer.future; 105 return group.future.transform((values) {
106 var convertedJson = {};
107 values.forEach((json) {
108 final k = json.keys[0];
109 convertedJson.putIfAbsent(k, () => json[k]);
110 });
111
112 return convertedJson;
113 });
114
115 //return completer.future;
Emily Fortuna 2012/11/28 17:17:30 same
121 } 116 }
122 117
123 118
124 /** 119 /**
125 * Convert a single file to JSON docs. 120 * Convert a single file to JSON docs.
126 * 121 *
127 * Returns a map with one entry whose key is the file name and whose value is 122 * Returns a map with one entry whose key is the file name and whose value is
128 * the list of comment lines. 123 * the list of comment lines.
129 */ 124 */
130 Future<Map> _convertFile(File file) { 125 Future<Map> _convertFile(String path) {
126 File file = new File(path);
127
128 // TODO(amouravski): Handle missing file.
129 if (!file.existsSync()) {
130 print('ERROR: cannot find file $path');
131 _anyErrors = true;
132 return;
133 }
134
131 var completer = new Completer(); 135 var completer = new Completer();
132 136
133 var comments = {}; 137 var comments = {};
134 138
135 // Find all /// @docsEditable annotations. 139 file.readAsLines().then((lines) {
136 InputStream file_stream = file.openInputStream();
137 StringInputStream inputLines = new StringInputStream(file_stream);
138
139 // TODO(amouravski): Re-write as file.readAsLine().thin((lines) {...}
140 inputLines.onLine = () {
141 var comment = <String>[]; 140 var comment = <String>[];
142 141
143 var docCommentFound = false; 142 var docCommentFound = false;
144 String line; 143 String line;
145 while ((line = inputLines.readLine()) != null) { 144 while (!lines.isEmpty && (line = lines.removeAt(0)) != null) {
146 var trimmedLine = line.trim(); 145 var trimmedLine = line.trim();
147 146
148 // Sentinel found. Process the comment block. 147 // Sentinel found. Process the comment block.
149 if (trimmedLine.startsWith('///') && 148 if (trimmedLine.startsWith('///') &&
150 trimmedLine.contains('@docsEditable')) { 149 trimmedLine.contains('@docsEditable')) {
151 if (docCommentFound == true) { 150 if (docCommentFound == true) {
152 var nextLine = inputLines.readLine(); 151 var nextLine = lines.removeAt(0);
153 152
154 if (nextLine == null) return false; 153 if (nextLine == null) return false;
155 154
156 var lineObject = {}; 155 var lineObject = {};
157 156
158 if (comments[nextLine] != null) { 157 if (comments[nextLine] != null) {
159 print('WARNING: duplicate line ${nextLine} found in' 158 print('WARNING: duplicate line ${nextLine} found in'
160 '${new Path(file.fullPathSync()).filename}'); 159 '${new Path(file.fullPathSync()).filename}');
161 } 160 }
162 comments.putIfAbsent(nextLine, () => comment); 161 comments.putIfAbsent(nextLine, () => comment);
(...skipping 12 matching lines...) Expand all
175 // /// blah 174 // /// blah
176 // * 175 // *
177 (trimmedLine.startsWith('*') || trimmedLine.startsWith('///'))) { 176 (trimmedLine.startsWith('*') || trimmedLine.startsWith('///'))) {
178 comment.add(line); 177 comment.add(line);
179 } else { 178 } else {
180 // Reset if we're not in a comment. 179 // Reset if we're not in a comment.
181 docCommentFound = false; 180 docCommentFound = false;
182 comment = <String>[]; 181 comment = <String>[];
183 } 182 }
184 } 183 }
185 };
186 184
187 inputLines.onClosed = () {
188 var jsonObject = {}; 185 var jsonObject = {};
189 jsonObject[new Path(file.fullPathSync()).filename] = comments; 186 jsonObject[new Path(file.fullPathSync()).filename] = comments;
190 completer.complete(jsonObject); 187 completer.complete(jsonObject);
191 }; 188 });
192 189
193 // TODO(amouravski): better error handling. 190 // TODO(amouravski): better error handling.
194 191
195 return completer.future; 192 return completer.future;
196 } 193 }
197 194
198 195
199 /** 196 /**
200 * Merge the new JSON object and the existing file. 197 * Merge the new JSON object and the existing file.
201 */ 198 */
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 '$indentation${JSON.stringify(key)}:\n' 301 '$indentation${JSON.stringify(key)}:\n'
305 '${prettyPrintJson(json[key], '$indentation ')}'); 302 '${prettyPrintJson(json[key], '$indentation ')}');
306 var recursiveOutput = Strings.join(mapList, ',\n'); 303 var recursiveOutput = Strings.join(mapList, ',\n');
307 output = '$indentation{\n' 304 output = '$indentation{\n'
308 '$recursiveOutput' 305 '$recursiveOutput'
309 '\n$indentation}'; 306 '\n$indentation}';
310 } else { 307 } else {
311 output = '$indentation${JSON.stringify(json)}'; 308 output = '$indentation${JSON.stringify(json)}';
312 } 309 }
313 return output; 310 return output;
314 } 311 }
312 /** A completer that waits until all added [Future]s complete. */
Emily Fortuna 2012/11/28 17:17:30 add a blank newline before this line
313 class FutureGroup {
314 const _FINISHED = -1;
315 int _pending = 0;
316 Completer<List> _completer = new Completer<List>();
317 final List<Future> futures = <Future>[];
318 final List output = [];
319
320 /**
321 * Wait for [task] to complete (assuming this barrier has not already been
322 * marked as completed, otherwise you'll get an exception indicating
323 * that a
324 * future has already been completed).
325 */
326 void add(Future task) {
327 if (_pending == _FINISHED) {
328 throw new FutureAlreadyCompleteException();
329 }
330 _pending++;
331 futures.add(task);
332 task.handleException(
333 (e) => _completer.completeException(e, task.stackTrace));
334 task.then((value) {
335 if (value != null) output.add(value);
336 _pending--;
337 if (_pending == 0) {
338 _pending = _FINISHED;
339 _completer.complete(output);
340 }
341 });
342 }
343
344 Future<List> get future => _completer.future;
345 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698