| 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.transform_node; | 5 library barback.transform_node; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'asset.dart'; | 9 import 'asset.dart'; |
| 10 import 'asset_id.dart'; | 10 import 'asset_id.dart'; |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 if (_state.needsIsPrimary) return null; | 222 if (_state.needsIsPrimary) return null; |
| 223 _state = _TransformNodeState.PROCESSING; | 223 _state = _TransformNodeState.PROCESSING; |
| 224 // TODO(nweiz): If [transformer] is a [DeclaringTransformer] but not a | 224 // TODO(nweiz): If [transformer] is a [DeclaringTransformer] but not a |
| 225 // [LazyTransformer], we can get some mileage out of doing a declarative | 225 // [LazyTransformer], we can get some mileage out of doing a declarative |
| 226 // first so we know how to hook up the assets. | 226 // first so we know how to hook up the assets. |
| 227 if (_isLazy) return _declareLazy(); | 227 if (_isLazy) return _declareLazy(); |
| 228 return _applyImmediate(); | 228 return _applyImmediate(); |
| 229 }).catchError((error, stackTrace) { | 229 }).catchError((error, stackTrace) { |
| 230 // If the transform became dirty while processing, ignore any errors from | 230 // If the transform became dirty while processing, ignore any errors from |
| 231 // it. | 231 // it. |
| 232 if (!_state.isProcessing || _isRemoved) return; | 232 if (!_state.isProcessing || _isRemoved) return false; |
| 233 | 233 |
| 234 if (error is! MissingInputException) { | 234 if (error is! MissingInputException) { |
| 235 error = new TransformerException(info, error, stackTrace); | 235 error = new TransformerException(info, error, stackTrace); |
| 236 } | 236 } |
| 237 | 237 |
| 238 // Catch all transformer errors and pipe them to the results stream. This | 238 // Catch all transformer errors and pipe them to the results stream. This |
| 239 // is so a broken transformer doesn't take down the whole graph. | 239 // is so a broken transformer doesn't take down the whole graph. |
| 240 phase.cascade.reportError(error); | 240 phase.cascade.reportError(error); |
| 241 | 241 return true; |
| 242 _clearOutputs(); | 242 }).then((hadError) { |
| 243 _dontEmitPassThrough(); | |
| 244 }).then((_) { | |
| 245 if (_isRemoved) return; | 243 if (_isRemoved) return; |
| 246 | 244 |
| 247 if (_state.needsIsPrimary) { | 245 if (_state.needsIsPrimary) { |
| 248 _process(); | 246 _process(); |
| 249 } else if (_state.needsApply) { | 247 } else if (_state.needsApply) { |
| 250 _apply(); | 248 _apply(); |
| 251 } else { | 249 } else { |
| 252 assert(_state.isProcessing); | 250 assert(_state.isProcessing); |
| 251 if (hadError) { |
| 252 _clearOutputs(); |
| 253 _dontEmitPassThrough(); |
| 254 } |
| 255 |
| 253 _state = _TransformNodeState.APPLIED; | 256 _state = _TransformNodeState.APPLIED; |
| 254 _onDoneController.add(null); | 257 _onDoneController.add(null); |
| 255 } | 258 } |
| 256 }); | 259 }); |
| 257 } | 260 } |
| 258 | 261 |
| 259 /// Gets the asset for an input [id]. | 262 /// Gets the asset for an input [id]. |
| 260 /// | 263 /// |
| 261 /// If an input with that ID cannot be found, throws an | 264 /// If an input with that ID cannot be found, throws an |
| 262 /// [AssetNotFoundException]. | 265 /// [AssetNotFoundException]. |
| 263 Future<Asset> getInput(AssetId id) { | 266 Future<Asset> getInput(AssetId id) { |
| 264 return phase.getInput(id).then((node) { | 267 return phase.getInput(id).then((node) { |
| 265 // Throw if the input isn't found. This ensures the transformer's apply | 268 // Throw if the input isn't found. This ensures the transformer's apply |
| 266 // is exited. We'll then catch this and report it through the proper | 269 // is exited. We'll then catch this and report it through the proper |
| 267 // results stream. | 270 // results stream. |
| 268 if (node == null) throw new MissingInputException(info, id); | 271 if (node == null) throw new MissingInputException(info, id); |
| 269 | 272 |
| 270 _inputSubscriptions.putIfAbsent(node.id, () { | 273 _inputSubscriptions.putIfAbsent(node.id, () { |
| 271 return node.onStateChange.listen((_) => _dirty(primaryChanged: false)); | 274 return node.onStateChange.listen((_) => _dirty(primaryChanged: false)); |
| 272 }); | 275 }); |
| 273 | 276 |
| 274 return node.asset; | 277 return node.asset; |
| 275 }); | 278 }); |
| 276 } | 279 } |
| 277 | 280 |
| 278 /// Applies the transform so that it produces concrete (as opposed to lazy) | 281 /// Applies the transform so that it produces concrete (as opposed to lazy) |
| 279 /// outputs. | 282 /// outputs. |
| 280 Future _applyImmediate() { | 283 /// |
| 284 /// Returns whether or not the transformer logged an error. |
| 285 Future<bool> _applyImmediate() { |
| 281 var transformController = new TransformController(this); | 286 var transformController = new TransformController(this); |
| 282 _onLogPool.add(transformController.onLog); | 287 _onLogPool.add(transformController.onLog); |
| 283 | 288 |
| 284 return syncFuture(() { | 289 return syncFuture(() { |
| 285 return transformer.apply(transformController.transform); | 290 return transformer.apply(transformController.transform); |
| 286 }).then((_) { | 291 }).then((_) { |
| 287 if (!_state.isProcessing || _onAssetController.isClosed) return; | 292 if (!_state.isProcessing || _onAssetController.isClosed) return false; |
| 293 if (transformController.loggedError) return true; |
| 288 | 294 |
| 289 _consumePrimary = transformController.consumePrimary; | 295 _consumePrimary = transformController.consumePrimary; |
| 290 | 296 |
| 291 var newOutputs = transformController.outputs; | 297 var newOutputs = transformController.outputs; |
| 292 // Any ids that are for a different package are invalid. | 298 // Any ids that are for a different package are invalid. |
| 293 var invalidIds = newOutputs | 299 var invalidIds = newOutputs |
| 294 .map((asset) => asset.id) | 300 .map((asset) => asset.id) |
| 295 .where((id) => id.package != phase.cascade.package) | 301 .where((id) => id.package != phase.cascade.package) |
| 296 .toSet(); | 302 .toSet(); |
| 297 for (var id in invalidIds) { | 303 for (var id in invalidIds) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 318 for (var asset in newOutputs) { | 324 for (var asset in newOutputs) { |
| 319 var controller = _outputControllers[asset.id]; | 325 var controller = _outputControllers[asset.id]; |
| 320 if (controller != null) { | 326 if (controller != null) { |
| 321 controller.setAvailable(asset); | 327 controller.setAvailable(asset); |
| 322 } else { | 328 } else { |
| 323 var controller = new AssetNodeController.available(asset, this); | 329 var controller = new AssetNodeController.available(asset, this); |
| 324 _outputControllers[asset.id] = controller; | 330 _outputControllers[asset.id] = controller; |
| 325 _onAssetController.add(controller.node); | 331 _onAssetController.add(controller.node); |
| 326 } | 332 } |
| 327 } | 333 } |
| 334 |
| 335 return false; |
| 328 }); | 336 }); |
| 329 } | 337 } |
| 330 | 338 |
| 331 /// Applies the transform in declarative mode so that it produces lazy | 339 /// Applies the transform in declarative mode so that it produces lazy |
| 332 /// outputs. | 340 /// outputs. |
| 333 Future _declareLazy() { | 341 /// |
| 342 /// Returns whether or not the transformer logged an error. |
| 343 Future<bool> _declareLazy() { |
| 334 var transformController = new DeclaringTransformController(this); | 344 var transformController = new DeclaringTransformController(this); |
| 335 | 345 |
| 336 return syncFuture(() { | 346 return syncFuture(() { |
| 337 return (transformer as LazyTransformer) | 347 return (transformer as LazyTransformer) |
| 338 .declareOutputs(transformController.transform); | 348 .declareOutputs(transformController.transform); |
| 339 }).then((_) { | 349 }).then((_) { |
| 340 if (!_state.isProcessing || _onAssetController.isClosed) return; | 350 if (!_state.isProcessing || _onAssetController.isClosed) return false; |
| 351 if (transformController.loggedError) return true; |
| 341 | 352 |
| 342 _consumePrimary = transformController.consumePrimary; | 353 _consumePrimary = transformController.consumePrimary; |
| 343 | 354 |
| 344 var newIds = transformController.outputIds; | 355 var newIds = transformController.outputIds; |
| 345 var invalidIds = | 356 var invalidIds = |
| 346 newIds.where((id) => id.package != phase.cascade.package).toSet(); | 357 newIds.where((id) => id.package != phase.cascade.package).toSet(); |
| 347 for (var id in invalidIds) { | 358 for (var id in invalidIds) { |
| 348 newIds.remove(id); | 359 newIds.remove(id); |
| 349 // TODO(nweiz): report this as a warning rather than a failing error. | 360 // TODO(nweiz): report this as a warning rather than a failing error. |
| 350 phase.cascade.reportError(new InvalidOutputException(info, id)); | 361 phase.cascade.reportError(new InvalidOutputException(info, id)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 367 for (var id in newIds) { | 378 for (var id in newIds) { |
| 368 var controller = _outputControllers[id]; | 379 var controller = _outputControllers[id]; |
| 369 if (controller != null) { | 380 if (controller != null) { |
| 370 controller.setLazy(force); | 381 controller.setLazy(force); |
| 371 } else { | 382 } else { |
| 372 var controller = new AssetNodeController.lazy(id, force, this); | 383 var controller = new AssetNodeController.lazy(id, force, this); |
| 373 _outputControllers[id] = controller; | 384 _outputControllers[id] = controller; |
| 374 _onAssetController.add(controller.node); | 385 _onAssetController.add(controller.node); |
| 375 } | 386 } |
| 376 } | 387 } |
| 388 |
| 389 return false; |
| 377 }); | 390 }); |
| 378 } | 391 } |
| 379 | 392 |
| 380 /// Cancels all subscriptions to secondary input nodes. | 393 /// Cancels all subscriptions to secondary input nodes. |
| 381 void _clearInputSubscriptions() { | 394 void _clearInputSubscriptions() { |
| 382 for (var subscription in _inputSubscriptions.values) { | 395 for (var subscription in _inputSubscriptions.values) { |
| 383 subscription.cancel(); | 396 subscription.cancel(); |
| 384 } | 397 } |
| 385 _inputSubscriptions.clear(); | 398 _inputSubscriptions.clear(); |
| 386 } | 399 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 /// | 492 /// |
| 480 /// Specifically, whether [this] is [APPLIED] or [NOT_PRIMARY]. | 493 /// Specifically, whether [this] is [APPLIED] or [NOT_PRIMARY]. |
| 481 bool get isDone => isApplied || isNotPrimary; | 494 bool get isDone => isApplied || isNotPrimary; |
| 482 | 495 |
| 483 final String name; | 496 final String name; |
| 484 | 497 |
| 485 const _TransformNodeState._(this.name); | 498 const _TransformNodeState._(this.name); |
| 486 | 499 |
| 487 String toString() => name; | 500 String toString() => name; |
| 488 } | 501 } |
| OLD | NEW |