| OLD | NEW | 
|    1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file |    1 // Copyright (c) 2013, 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 library barback.graph.package_graph; |    5 library barback.graph.package_graph; | 
|    6  |    6  | 
|    7 import 'dart:async'; |    7 import 'dart:async'; | 
|    8 import 'dart:collection'; |    8 import 'dart:collection'; | 
|    9  |    9  | 
|   10 import '../asset/asset_id.dart'; |   10 import '../asset/asset_id.dart'; | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   50   /// This will not emit programming errors from barback itself. Those will be |   50   /// This will not emit programming errors from barback itself. Those will be | 
|   51   /// emitted through the [results] stream's error channel. |   51   /// emitted through the [results] stream's error channel. | 
|   52   Stream<BarbackException> get errors => _errors; |   52   Stream<BarbackException> get errors => _errors; | 
|   53   Stream<BarbackException> _errors; |   53   Stream<BarbackException> _errors; | 
|   54  |   54  | 
|   55   /// The stream of [LogEntry] objects used to report transformer log entries. |   55   /// The stream of [LogEntry] objects used to report transformer log entries. | 
|   56   Stream<LogEntry> get log => _logController.stream; |   56   Stream<LogEntry> get log => _logController.stream; | 
|   57   final _logController = new StreamController<LogEntry>.broadcast(sync: true); |   57   final _logController = new StreamController<LogEntry>.broadcast(sync: true); | 
|   58  |   58  | 
|   59   /// How far along [this] is in processing its assets. |   59   /// How far along [this] is in processing its assets. | 
|   60   NodeStatus get _status => NodeStatus.dirtiest( |   60   NodeStatus get _status => | 
|   61       _cascades.values.map((cascade) => cascade.status)); |   61       NodeStatus.dirtiest(_cascades.values.map((cascade) => cascade.status)); | 
|   62  |   62  | 
|   63   /// Whether a [BuildResult] is scheduled to be emitted on [results] (see |   63   /// Whether a [BuildResult] is scheduled to be emitted on [results] (see | 
|   64   /// [_tryScheduleResult]). |   64   /// [_tryScheduleResult]). | 
|   65   bool _resultScheduled = false; |   65   bool _resultScheduled = false; | 
|   66  |   66  | 
|   67   /// The most recent [BuildResult] emitted on [results]. |   67   /// The most recent [BuildResult] emitted on [results]. | 
|   68   BuildResult _lastResult; |   68   BuildResult _lastResult; | 
|   69  |   69  | 
|   70   // TODO(nweiz): This can have bogus errors if an error is created and resolved |   70   // TODO(nweiz): This can have bogus errors if an error is created and resolved | 
|   71   // in the space of one build. |   71   // in the space of one build. | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  120   } |  120   } | 
|  121  |  121  | 
|  122   /// Gets the asset node identified by [id]. |  122   /// Gets the asset node identified by [id]. | 
|  123   /// |  123   /// | 
|  124   /// If [id] is for a generated or transformed asset, this will wait until it |  124   /// If [id] is for a generated or transformed asset, this will wait until it | 
|  125   /// has been created and return it. This means that the returned asset will |  125   /// has been created and return it. This means that the returned asset will | 
|  126   /// always be [AssetState.AVAILABLE]. |  126   /// always be [AssetState.AVAILABLE]. | 
|  127   /// |  127   /// | 
|  128   /// If the asset cannot be found, returns null. |  128   /// If the asset cannot be found, returns null. | 
|  129   Future<AssetNode> getAssetNode(AssetId id) { |  129   Future<AssetNode> getAssetNode(AssetId id) { | 
|  130     return _inErrorZone/*<Future<AssetNode>>*/(() { |  130     return _inErrorZone<Future<AssetNode>>(() { | 
|  131       var cascade = _cascades[id.package]; |  131       var cascade = _cascades[id.package]; | 
|  132       if (cascade != null) return cascade.getAssetNode(id); |  132       if (cascade != null) return cascade.getAssetNode(id); | 
|  133       return new Future.value(null); |  133       return new Future.value(null); | 
|  134     }); |  134     }); | 
|  135   } |  135   } | 
|  136  |  136  | 
|  137   /// Returns the stream of newly-emitted assets for the given package's |  137   /// Returns the stream of newly-emitted assets for the given package's | 
|  138   /// cascade. |  138   /// cascade. | 
|  139   /// |  139   /// | 
|  140   /// If there's no cascade for [package], returns `null`. |  140   /// If there's no cascade for [package], returns `null`. | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  151   /// |  151   /// | 
|  152   /// Any transforms using [LazyTransformer]s will be forced to generate |  152   /// Any transforms using [LazyTransformer]s will be forced to generate | 
|  153   /// concrete outputs, and those outputs will be returned. |  153   /// concrete outputs, and those outputs will be returned. | 
|  154   Future<AssetSet> getAllAssets() { |  154   Future<AssetSet> getAllAssets() { | 
|  155     for (var cascade in _cascades.values) { |  155     for (var cascade in _cascades.values) { | 
|  156       _inErrorZone(() => cascade.forceAllTransforms()); |  156       _inErrorZone(() => cascade.forceAllTransforms()); | 
|  157     } |  157     } | 
|  158  |  158  | 
|  159     if (_status != NodeStatus.IDLE) { |  159     if (_status != NodeStatus.IDLE) { | 
|  160       // A build is still ongoing, so wait for it to complete and try again. |  160       // A build is still ongoing, so wait for it to complete and try again. | 
|  161       return results.first.then/*<Future<AssetSet>>*/((_) => getAllAssets()); |  161       return results.first.then<Future<AssetSet>>((_) => getAllAssets()); | 
|  162     } |  162     } | 
|  163  |  163  | 
|  164     // If an unexpected error occurred, complete with that. |  164     // If an unexpected error occurred, complete with that. | 
|  165     if (_lastUnexpectedError != null) { |  165     if (_lastUnexpectedError != null) { | 
|  166       var error = _lastUnexpectedError; |  166       var error = _lastUnexpectedError; | 
|  167       _lastUnexpectedError = null; |  167       _lastUnexpectedError = null; | 
|  168       return new Future.error(error, _lastUnexpectedErrorTrace); |  168       return new Future.error(error, _lastUnexpectedErrorTrace); | 
|  169     } |  169     } | 
|  170  |  170  | 
|  171     // If the last build completed with an error, complete the future with it. |  171     // If the last build completed with an error, complete the future with it. | 
|  172     if (!_lastResult.succeeded) { |  172     if (!_lastResult.succeeded) { | 
|  173       return new Future.error(BarbackException.aggregate(_lastResult.errors)); |  173       return new Future.error(BarbackException.aggregate(_lastResult.errors)); | 
|  174     } |  174     } | 
|  175  |  175  | 
|  176     // Otherwise, return all of the final output assets. |  176     // Otherwise, return all of the final output assets. | 
|  177     return Future.wait(_cascades.values.map( |  177     return Future | 
|  178             (cascade) => cascade.availableOutputs)) |  178         .wait(_cascades.values.map((cascade) => cascade.availableOutputs)) | 
|  179           .then((assetSets) { |  179         .then((assetSets) { | 
|  180       var assets = unionAll(assetSets.map((assetSet) => assetSet.toSet())); |  180       var assets = unionAll(assetSets.map((assetSet) => assetSet.toSet())); | 
|  181       return new AssetSet.from(assets); |  181       return new AssetSet.from(assets); | 
|  182     }); |  182     }); | 
|  183   } |  183   } | 
|  184  |  184  | 
|  185   /// Adds [sources] to the graph's known set of source assets. |  185   /// Adds [sources] to the graph's known set of source assets. | 
|  186   /// |  186   /// | 
|  187   /// Begins applying any transforms that can consume any of the sources. If a |  187   /// Begins applying any transforms that can consume any of the sources. If a | 
|  188   /// given source is already known, it is considered modified and all |  188   /// given source is already known, it is considered modified and all | 
|  189   /// transforms that use it will be re-applied. |  189   /// transforms that use it will be re-applied. | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
|  218     // It's possible for updating transformers not to cause any processing. The |  218     // It's possible for updating transformers not to cause any processing. The | 
|  219     // user still expects there to be a build, though, so we emit one |  219     // user still expects there to be a build, though, so we emit one | 
|  220     // immediately. |  220     // immediately. | 
|  221     _tryScheduleResult(); |  221     _tryScheduleResult(); | 
|  222   } |  222   } | 
|  223  |  223  | 
|  224   /// A handler for a log entry from an [AssetCascade]. |  224   /// A handler for a log entry from an [AssetCascade]. | 
|  225   void _onLog(LogEntry entry) { |  225   void _onLog(LogEntry entry) { | 
|  226     if (entry.level == LogLevel.ERROR) { |  226     if (entry.level == LogLevel.ERROR) { | 
|  227       // TODO(nweiz): keep track of stack chain. |  227       // TODO(nweiz): keep track of stack chain. | 
|  228       _accumulatedErrors.add( |  228       _accumulatedErrors | 
|  229           new TransformerException(entry.transform, entry.message, null)); |  229           .add(new TransformerException(entry.transform, entry.message, null)); | 
|  230     } |  230     } | 
|  231  |  231  | 
|  232     if (_logController.hasListener) { |  232     if (_logController.hasListener) { | 
|  233       _logController.add(entry); |  233       _logController.add(entry); | 
|  234     } else if (entry.level != LogLevel.FINE) { |  234     } else if (entry.level != LogLevel.FINE) { | 
|  235       // No listeners, so just print entry. |  235       // No listeners, so just print entry. | 
|  236       var buffer = new StringBuffer(); |  236       var buffer = new StringBuffer(); | 
|  237       buffer.write("[${entry.level} ${entry.transform}] "); |  237       buffer.write("[${entry.level} ${entry.transform}] "); | 
|  238  |  238  | 
|  239       if (entry.span != null) { |  239       if (entry.span != null) { | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
|  267     }); |  267     }); | 
|  268   } |  268   } | 
|  269  |  269  | 
|  270   /// Run [body] in an error-handling [Zone] and pipe any unexpected errors to |  270   /// Run [body] in an error-handling [Zone] and pipe any unexpected errors to | 
|  271   /// the error channel of [results]. |  271   /// the error channel of [results]. | 
|  272   /// |  272   /// | 
|  273   /// [body] can return a value or a [Future] that will be piped to the returned |  273   /// [body] can return a value or a [Future] that will be piped to the returned | 
|  274   /// [Future]. If it throws a [BarbackException], that exception will be piped |  274   /// [Future]. If it throws a [BarbackException], that exception will be piped | 
|  275   /// to the returned [Future] as well. Any other exceptions will be piped to |  275   /// to the returned [Future] as well. Any other exceptions will be piped to | 
|  276   /// [results]. |  276   /// [results]. | 
|  277   Future/*<T>*/ _inErrorZone/*<T>*/(/*=T*/ body()) { |  277   Future<T> _inErrorZone<T>(T body()) { | 
|  278     var completer = new Completer/*<T>*/.sync(); |  278     var completer = new Completer<T>.sync(); | 
|  279     runZoned(() { |  279     runZoned(() { | 
|  280       new Future.sync(body).then(completer.complete) |  280       new Future.sync(body) | 
 |  281           .then(completer.complete) | 
|  281           .catchError((error, stackTrace) { |  282           .catchError((error, stackTrace) { | 
|  282         if (error is! BarbackException) throw error; |  283         if (error is! BarbackException) throw error; | 
|  283         completer.completeError(error, stackTrace); |  284         completer.completeError(error, stackTrace); | 
|  284       }); |  285       }); | 
|  285     }, onError: (error, stackTrace) { |  286     }, onError: (error, stackTrace) { | 
|  286       _lastUnexpectedError = error; |  287       _lastUnexpectedError = error; | 
|  287       _lastUnexpectedErrorTrace = stackTrace; |  288       _lastUnexpectedErrorTrace = stackTrace; | 
|  288       _resultsController.addError(error, stackTrace); |  289       _resultsController.addError(error, stackTrace); | 
|  289     }); |  290     }); | 
|  290     return completer.future; |  291     return completer.future; | 
|  291   } |  292   } | 
|  292 } |  293 } | 
| OLD | NEW |