Chromium Code Reviews| Index: tools/html_json_doc/lib/html_to_json.dart |
| diff --git a/tools/html_json_doc/lib/html_to_json.dart b/tools/html_json_doc/lib/html_to_json.dart |
| index ddfb5eb2ef2a6fc7c7b6b10a63464e56ee489b5a..8b5465a9779221ac95ac2e092ea5136445ce8579 100644 |
| --- a/tools/html_json_doc/lib/html_to_json.dart |
| +++ b/tools/html_json_doc/lib/html_to_json.dart |
| @@ -48,18 +48,8 @@ Future<bool> convert(Path htmlPath, Path jsonPath) { |
| writeJson = _mergeJsonAndFile(convertedJson, jsonFile); |
| } |
| - var outputStream = jsonFile.openOutputStream(); |
| - outputStream.writeString(prettyPrintJson(writeJson)); |
| - |
| - outputStream.onNoPendingWrites = () { |
| - completer.complete(_anyErrors); |
| - }; |
| - |
| - outputStream.onClosed = () { |
| - completer.complete(_anyErrors); |
| - }; |
| - |
| - outputStream.onError = completer.completeException; |
| + jsonFile.writeAsStringSync(prettyPrintJson(writeJson)); |
| + completer.complete(_anyErrors); |
| }); |
| return completer.future; |
| @@ -72,15 +62,17 @@ Future<bool> convert(Path htmlPath, Path jsonPath) { |
| * Returns a future that completes to the converted JSON object. |
| */ |
| Future<Object> _convertFiles(Path htmlPath) { |
| - var completer = new Completer(); |
| - |
| - List<Future> fileFutures = []; |
| + //List<Future> fileFutures = []; |
|
Emily Fortuna
2012/11/28 17:17:30
probably just delete this line if it's going to be
|
| + var group = new FutureGroup(); |
| // Get a list of all HTML dart files. |
| // TODO(amouravski): discriminate .dart files. |
| final htmlDir = new Directory.fromPath(htmlPath); |
| final lister = htmlDir.list(recursive: false); |
| + var listCompleter = new Completer(); |
| + group.add(listCompleter.future); |
| + |
| lister.onFile = (String path) { |
| final name = new Path.fromNative(path).filename; |
| @@ -90,34 +82,37 @@ Future<Object> _convertFiles(Path htmlPath) { |
| // Ignore non-dart files. |
| if (!name.endsWith('.dart')) return; |
| - File file = new File(path); |
| + group.add(_convertFile(path)); |
| + //fileFutures.add(_convertFile(file)); |
|
Emily Fortuna
2012/11/28 17:17:30
ditto here.
|
| + }; |
| - // TODO(amouravski): Handle missing file. |
| - if (!file.existsSync()) { |
| - print('ERROR: cannot find file $path'); |
| - _anyErrors = true; |
| - return; |
| - } |
| - fileFutures.add(_convertFile(file)); |
| + // Combine all JSON objects |
| + lister.onDone = (done) { |
| + if (done) listCompleter.complete(null); |
| +// Futures.wait(fileFutures).then((jsonList) { |
|
Emily Fortuna
2012/11/28 17:17:30
and here
|
| +// var convertedJson = {}; |
| +// jsonList.forEach((json) { |
| +// final k = json.keys[0]; |
| +// convertedJson.putIfAbsent(k, () => json[k]); |
| +// }); |
| +// completer.complete(convertedJson); |
| +// }); |
| }; |
| + // TODO(amouravski): add more error handling. |
| - // Combine all JSON objects |
| - lister.onDone = (_) { |
| - Futures.wait(fileFutures).then((jsonList) { |
| + return group.future.transform((values) { |
| var convertedJson = {}; |
| - jsonList.forEach((json) { |
| + values.forEach((json) { |
| final k = json.keys[0]; |
| convertedJson.putIfAbsent(k, () => json[k]); |
| }); |
| - completer.complete(convertedJson); |
| - }); |
| - }; |
| - // TODO(amouravski): add more error handling. |
| + return convertedJson; |
| + }); |
| - return completer.future; |
| + //return completer.future; |
|
Emily Fortuna
2012/11/28 17:17:30
same
|
| } |
| @@ -127,29 +122,33 @@ Future<Object> _convertFiles(Path htmlPath) { |
| * Returns a map with one entry whose key is the file name and whose value is |
| * the list of comment lines. |
| */ |
| -Future<Map> _convertFile(File file) { |
| +Future<Map> _convertFile(String path) { |
| + File file = new File(path); |
| + |
| + // TODO(amouravski): Handle missing file. |
| + if (!file.existsSync()) { |
| + print('ERROR: cannot find file $path'); |
| + _anyErrors = true; |
| + return; |
| + } |
| + |
| var completer = new Completer(); |
| var comments = {}; |
| - // Find all /// @docsEditable annotations. |
| - InputStream file_stream = file.openInputStream(); |
| - StringInputStream inputLines = new StringInputStream(file_stream); |
| - |
| - // TODO(amouravski): Re-write as file.readAsLine().thin((lines) {...} |
| - inputLines.onLine = () { |
| + file.readAsLines().then((lines) { |
| var comment = <String>[]; |
| var docCommentFound = false; |
| String line; |
| - while ((line = inputLines.readLine()) != null) { |
| + while (!lines.isEmpty && (line = lines.removeAt(0)) != null) { |
| var trimmedLine = line.trim(); |
| // Sentinel found. Process the comment block. |
| if (trimmedLine.startsWith('///') && |
| trimmedLine.contains('@docsEditable')) { |
| if (docCommentFound == true) { |
| - var nextLine = inputLines.readLine(); |
| + var nextLine = lines.removeAt(0); |
| if (nextLine == null) return false; |
| @@ -182,13 +181,11 @@ Future<Map> _convertFile(File file) { |
| comment = <String>[]; |
| } |
| } |
| - }; |
| - inputLines.onClosed = () { |
| var jsonObject = {}; |
| jsonObject[new Path(file.fullPathSync()).filename] = comments; |
| completer.complete(jsonObject); |
| - }; |
| + }); |
| // TODO(amouravski): better error handling. |
| @@ -311,4 +308,38 @@ String prettyPrintJson(Object json, [String indentation = '']) { |
| output = '$indentation${JSON.stringify(json)}'; |
| } |
| return output; |
| -} |
| +} |
| +/** 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
|
| +class FutureGroup { |
| + const _FINISHED = -1; |
| + int _pending = 0; |
| + Completer<List> _completer = new Completer<List>(); |
| + final List<Future> futures = <Future>[]; |
| + final List output = []; |
| + |
| + /** |
| + * Wait for [task] to complete (assuming this barrier has not already been |
| + * marked as completed, otherwise you'll get an exception indicating |
| + * that a |
| + * future has already been completed). |
| + */ |
| + void add(Future task) { |
| + if (_pending == _FINISHED) { |
| + throw new FutureAlreadyCompleteException(); |
| + } |
| + _pending++; |
| + futures.add(task); |
| + task.handleException( |
| + (e) => _completer.completeException(e, task.stackTrace)); |
| + task.then((value) { |
| + if (value != null) output.add(value); |
| + _pending--; |
| + if (_pending == 0) { |
| + _pending = _FINISHED; |
| + _completer.complete(output); |
| + } |
| + }); |
| + } |
| + |
| + Future<List> get future => _completer.future; |
| +} |