| 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.transform_node; | 5 library barback.graph.transform_node; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import '../asset/asset.dart'; | 9 import '../asset/asset.dart'; |
| 10 import '../asset/asset_id.dart'; | 10 import '../asset/asset_id.dart'; |
| 11 import '../asset/asset_node.dart'; | 11 import '../asset/asset_node.dart'; |
| 12 import '../errors.dart'; | 12 import '../errors.dart'; |
| 13 import '../log.dart'; | 13 import '../log.dart'; |
| 14 import '../transformer/aggregate_transform.dart'; |
| 15 import '../transformer/declaring_aggregate_transform.dart'; |
| 14 import '../transformer/declaring_transform.dart'; | 16 import '../transformer/declaring_transform.dart'; |
| 15 import '../transformer/declaring_transformer.dart'; | 17 import '../transformer/declaring_transformer.dart'; |
| 16 import '../transformer/lazy_transformer.dart'; | 18 import '../transformer/lazy_transformer.dart'; |
| 17 import '../transformer/transform.dart'; | 19 import '../transformer/transform.dart'; |
| 18 import '../transformer/transformer.dart'; | 20 import '../transformer/transformer.dart'; |
| 19 import '../utils.dart'; | |
| 20 import 'node_status.dart'; | 21 import 'node_status.dart'; |
| 21 import 'node_streams.dart'; | 22 import 'node_streams.dart'; |
| 22 import 'phase.dart'; | 23 import 'phase.dart'; |
| 23 | 24 |
| 24 /// Describes a transform on a set of assets and its relationship to the build | 25 /// Describes a transform on a set of assets and its relationship to the build |
| 25 /// dependency graph. | 26 /// dependency graph. |
| 26 /// | 27 /// |
| 27 /// Keeps track of whether it's dirty and needs to be run and which assets it | 28 /// Keeps track of whether it's dirty and needs to be run and which assets it |
| 28 /// depends on. | 29 /// depends on. |
| 29 class TransformNode { | 30 class TransformNode { |
| 31 /// The aggregate key for this node. |
| 32 final String key; |
| 33 |
| 30 /// The [Phase] that this transform runs in. | 34 /// The [Phase] that this transform runs in. |
| 31 final Phase phase; | 35 final Phase phase; |
| 32 | 36 |
| 33 /// The [Transformer] to apply to this node's inputs. | 37 /// The [Transformer] to apply to this node's inputs. |
| 34 final Transformer transformer; | 38 final Transformer transformer; |
| 35 | 39 |
| 36 /// The node for the primary asset this transform depends on. | 40 /// The node for the primary asset this transform depends on. |
| 37 final AssetNode primary; | 41 final AssetNode primary; |
| 38 | 42 |
| 39 /// A string describing the location of [this] in the transformer graph. | 43 /// A string describing the location of [this] in the transformer graph. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 bool _consumePrimary = false; | 123 bool _consumePrimary = false; |
| 120 | 124 |
| 121 /// The set of output ids that [transformer] declared it would emit. | 125 /// The set of output ids that [transformer] declared it would emit. |
| 122 /// | 126 /// |
| 123 /// This is only non-null if [transformer] is a [DeclaringTransformer] and its | 127 /// This is only non-null if [transformer] is a [DeclaringTransformer] and its |
| 124 /// [declareOutputs] has been run successfully. | 128 /// [declareOutputs] has been run successfully. |
| 125 Set<AssetId> _declaredOutputs; | 129 Set<AssetId> _declaredOutputs; |
| 126 | 130 |
| 127 TransformNode(this.phase, Transformer transformer, AssetNode primary, | 131 TransformNode(this.phase, Transformer transformer, AssetNode primary, |
| 128 this._location) | 132 this._location) |
| 129 : transformer = transformer, | 133 : key = primary.id.path, |
| 134 transformer = transformer, |
| 130 primary = primary { | 135 primary = primary { |
| 131 _forced = transformer is! DeclaringTransformer; | 136 _forced = transformer is! DeclaringTransformer; |
| 132 if (_forced) primary.force(); | 137 if (_forced) primary.force(); |
| 133 | 138 |
| 134 _primarySubscription = primary.onStateChange.listen((state) { | 139 _primarySubscription = primary.onStateChange.listen((state) { |
| 135 if (state.isRemoved) { | 140 if (state.isRemoved) { |
| 136 remove(); | 141 remove(); |
| 137 } else { | 142 } else { |
| 138 if (_forced) primary.force(); | 143 if (_forced) primary.force(); |
| 139 _dirty(); | 144 _dirty(); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 } else { | 231 } else { |
| 227 _state = _State.NEEDS_APPLY; | 232 _state = _State.NEEDS_APPLY; |
| 228 } | 233 } |
| 229 } | 234 } |
| 230 | 235 |
| 231 /// Runs [transform.declareOutputs] and emits the resulting assets as dirty | 236 /// Runs [transform.declareOutputs] and emits the resulting assets as dirty |
| 232 /// assets. | 237 /// assets. |
| 233 Future _declareOutputs() { | 238 Future _declareOutputs() { |
| 234 if (transformer is! DeclaringTransformer) return new Future.value(); | 239 if (transformer is! DeclaringTransformer) return new Future.value(); |
| 235 | 240 |
| 236 var controller = new DeclaringTransformController(this); | 241 var controller = new DeclaringAggregateTransformController(this); |
| 237 return syncFuture(() { | 242 _streams.onLogPool.add(controller.onLog); |
| 238 return (transformer as DeclaringTransformer) | 243 controller.idController.add(primary.id); |
| 239 .declareOutputs(controller.transform); | 244 return newDeclaringTransform(controller.transform).then((transform) { |
| 245 return (transformer as DeclaringTransformer).declareOutputs(transform); |
| 240 }).then((_) { | 246 }).then((_) { |
| 241 if (_isRemoved) return; | 247 if (_isRemoved) return; |
| 242 if (controller.loggedError) return; | 248 if (controller.loggedError) return; |
| 243 | 249 |
| 244 _consumePrimary = controller.consumePrimary; | 250 _consumePrimary = controller.consumedPrimaries.contains(primary.id); |
| 245 _declaredOutputs = controller.outputIds; | 251 _declaredOutputs = controller.outputIds; |
| 246 var invalidIds = _declaredOutputs | 252 var invalidIds = _declaredOutputs |
| 247 .where((id) => id.package != phase.cascade.package).toSet(); | 253 .where((id) => id.package != phase.cascade.package).toSet(); |
| 248 for (var id in invalidIds) { | 254 for (var id in invalidIds) { |
| 249 _declaredOutputs.remove(id); | 255 _declaredOutputs.remove(id); |
| 250 // TODO(nweiz): report this as a warning rather than a failing error. | 256 // TODO(nweiz): report this as a warning rather than a failing error. |
| 251 phase.cascade.reportError(new InvalidOutputException(info, id)); | 257 phase.cascade.reportError(new InvalidOutputException(info, id)); |
| 252 } | 258 } |
| 253 | 259 |
| 254 if (!_declaredOutputs.contains(primary.id)) _emitPassThrough(); | 260 if (!_declaredOutputs.contains(primary.id)) _emitPassThrough(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 }); | 343 }); |
| 338 | 344 |
| 339 return node.asset; | 345 return node.asset; |
| 340 }); | 346 }); |
| 341 } | 347 } |
| 342 | 348 |
| 343 /// Run [Transformer.apply] as soon as [primary] is available. | 349 /// Run [Transformer.apply] as soon as [primary] is available. |
| 344 /// | 350 /// |
| 345 /// Returns whether or not an error occurred while running the transformer. | 351 /// Returns whether or not an error occurred while running the transformer. |
| 346 Future<bool> _runApply() { | 352 Future<bool> _runApply() { |
| 347 var transformController = new TransformController(this); | 353 var controller = new AggregateTransformController(this); |
| 348 _streams.onLogPool.add(transformController.onLog); | 354 _streams.onLogPool.add(controller.onLog); |
| 349 | 355 |
| 350 return primary.whenAvailable((_) { | 356 return primary.whenAvailable((_) { |
| 351 if (_isRemoved) return null; | 357 if (_isRemoved) return null; |
| 352 _state = _State.APPLYING; | 358 _state = _State.APPLYING; |
| 353 return syncFuture(() => transformer.apply(transformController.transform)); | 359 controller.inputController.add(primary.asset); |
| 360 return newTransform(controller.transform).then((transform) { |
| 361 return transformer.apply(transform); |
| 362 }); |
| 354 }).then((_) { | 363 }).then((_) { |
| 355 if (!_forced && !primary.state.isAvailable) { | 364 if (!_forced && !primary.state.isAvailable) { |
| 356 _state = _State.DECLARED; | 365 _state = _State.DECLARED; |
| 357 _streams.changeStatus(NodeStatus.IDLE); | 366 _streams.changeStatus(NodeStatus.IDLE); |
| 358 return false; | 367 return false; |
| 359 } | 368 } |
| 360 | 369 |
| 361 if (_isRemoved) return false; | 370 if (_isRemoved) return false; |
| 362 if (_state == _State.NEEDS_APPLY) return false; | 371 if (_state == _State.NEEDS_APPLY) return false; |
| 363 if (_state == _State.DECLARING) return false; | 372 if (_state == _State.DECLARING) return false; |
| 364 if (transformController.loggedError) return true; | 373 if (controller.loggedError) return true; |
| 365 _handleApplyResults(transformController); | 374 _handleApplyResults(controller); |
| 366 return false; | 375 return false; |
| 367 }).catchError((error, stackTrace) { | 376 }).catchError((error, stackTrace) { |
| 368 // If the transform became dirty while processing, ignore any errors from | 377 // If the transform became dirty while processing, ignore any errors from |
| 369 // it. | 378 // it. |
| 370 if (_state == _State.NEEDS_APPLY || _isRemoved) return false; | 379 if (_state == _State.NEEDS_APPLY || _isRemoved) return false; |
| 371 | 380 |
| 372 // Catch all transformer errors and pipe them to the results stream. This | 381 // Catch all transformer errors and pipe them to the results stream. This |
| 373 // is so a broken transformer doesn't take down the whole graph. | 382 // is so a broken transformer doesn't take down the whole graph. |
| 374 phase.cascade.reportError(_wrapException(error, stackTrace)); | 383 phase.cascade.reportError(_wrapException(error, stackTrace)); |
| 375 return true; | 384 return true; |
| 376 }); | 385 }); |
| 377 } | 386 } |
| 378 | 387 |
| 379 /// Handle the results of running [Transformer.apply]. | 388 /// Handle the results of running [Transformer.apply]. |
| 380 /// | 389 /// |
| 381 /// [transformController] should be the controller for the [Transform] passed | 390 /// [controller] should be the controller for the [AggegateTransform] passed |
| 382 /// to [Transformer.apply]. | 391 /// to [AggregateTransformer.apply]. |
| 383 void _handleApplyResults(TransformController transformController) { | 392 void _handleApplyResults(AggregateTransformController controller) { |
| 384 _consumePrimary = transformController.consumePrimary; | 393 _consumePrimary = controller.consumedPrimaries.contains(primary.id); |
| 385 | 394 |
| 386 var newOutputs = transformController.outputs; | 395 var newOutputs = controller.outputs; |
| 387 // Any ids that are for a different package are invalid. | 396 // Any ids that are for a different package are invalid. |
| 388 var invalidIds = newOutputs | 397 var invalidIds = newOutputs |
| 389 .map((asset) => asset.id) | 398 .map((asset) => asset.id) |
| 390 .where((id) => id.package != phase.cascade.package) | 399 .where((id) => id.package != phase.cascade.package) |
| 391 .toSet(); | 400 .toSet(); |
| 392 for (var id in invalidIds) { | 401 for (var id in invalidIds) { |
| 393 newOutputs.removeId(id); | 402 newOutputs.removeId(id); |
| 394 // TODO(nweiz): report this as a warning rather than a failing error. | 403 // TODO(nweiz): report this as a warning rather than a failing error. |
| 395 phase.cascade.reportError(new InvalidOutputException(info, id)); | 404 phase.cascade.reportError(new InvalidOutputException(info, id)); |
| 396 } | 405 } |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 /// If an input changes, this will transition to [DECLARED] if the transform | 535 /// If an input changes, this will transition to [DECLARED] if the transform |
| 527 /// is deferred and [APPLYING] otherwise. | 536 /// is deferred and [APPLYING] otherwise. |
| 528 static final APPLIED = const _State._("applied"); | 537 static final APPLIED = const _State._("applied"); |
| 529 | 538 |
| 530 final String name; | 539 final String name; |
| 531 | 540 |
| 532 const _State._(this.name); | 541 const _State._(this.name); |
| 533 | 542 |
| 534 String toString() => name; | 543 String toString() => name; |
| 535 } | 544 } |
| OLD | NEW |