OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 library barback.transform; | |
6 | |
7 import 'dart:async'; | |
8 import 'dart:convert'; | |
9 | |
10 import 'asset.dart'; | |
11 import 'asset_id.dart'; | |
12 import 'asset_set.dart'; | |
13 import 'base_transform.dart'; | |
14 import 'errors.dart'; | |
15 import 'transform_node.dart'; | |
16 import 'utils.dart'; | |
17 | |
18 /// While a [Transformer] represents a *kind* of transformation, this defines | |
19 /// one specific usage of it on a set of files. | |
20 /// | |
21 /// This ephemeral object exists only during an actual transform application to | |
22 /// facilitate communication between the [Transformer] and the code hosting | |
23 /// the transformation. It lets the [Transformer] access inputs and generate | |
24 /// outputs. | |
25 class Transform extends BaseTransform { | |
26 final TransformNode _node; | |
27 | |
28 final _outputs = new AssetSet(); | |
29 | |
30 /// Gets the primary input asset. | |
31 /// | |
32 /// While a transformation can use multiple input assets, one must be a | |
33 /// special "primary" asset. This will be the "entrypoint" or "main" input | |
34 /// file for a transformation. | |
35 /// | |
36 /// For example, with a dart2js transform, the primary input would be the | |
37 /// entrypoint Dart file. All of the other Dart files that that imports | |
38 /// would be secondary inputs. | |
39 /// | |
40 /// This method may fail at runtime with an [AssetNotFoundException] if called | |
41 /// asynchronously after the transform begins running. The primary input may | |
42 /// become unavailable while this transformer is running due to asset changes | |
43 /// earlier in the graph. You can ignore the error if this happens: the | |
44 /// transformer will be re-run automatically for you. | |
45 Asset get primaryInput { | |
46 if (!_node.primary.state.isAvailable) { | |
47 throw new AssetNotFoundException(_node.primary.id); | |
48 } | |
49 | |
50 return _node.primary.asset; | |
51 } | |
52 | |
53 Transform._(TransformNode node) | |
54 : _node = node, | |
55 super(node); | |
56 | |
57 /// Gets the asset for an input [id]. | |
58 /// | |
59 /// If an input with [id] cannot be found, throws an [AssetNotFoundException]. | |
60 Future<Asset> getInput(AssetId id) { | |
61 if (id == _node.primary.id) return syncFuture(() => primaryInput); | |
62 return _node.getInput(id); | |
63 } | |
64 | |
65 /// A convenience method to the contents of the input with [id] as a string. | |
66 /// | |
67 /// This is equivalent to calling [getInput] followed by [Asset.readAsString]. | |
68 /// | |
69 /// If the asset was created from a [String] the original string is always | |
70 /// returned and [encoding] is ignored. Otherwise, the binary data of the | |
71 /// asset is decoded using [encoding], which defaults to [UTF8]. | |
72 /// | |
73 /// If an input with [id] cannot be found, throws an [AssetNotFoundException]. | |
74 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { | |
75 if (encoding == null) encoding = UTF8; | |
76 return getInput(id).then((input) => input.readAsString(encoding: encoding)); | |
77 } | |
78 | |
79 /// A convenience method to the contents of the input with [id]. | |
80 /// | |
81 /// This is equivalent to calling [getInput] followed by [Asset.read]. | |
82 /// | |
83 /// If the asset was created from a [String], this returns its UTF-8 encoding. | |
84 /// | |
85 /// If an input with [id] cannot be found, throws an [AssetNotFoundException]. | |
86 Stream<List<int>> readInput(AssetId id) => | |
87 futureStream(getInput(id).then((input) => input.read())); | |
88 | |
89 /// A convenience method to return whether or not an asset exists. | |
90 /// | |
91 /// This is equivalent to calling [getInput] and catching an | |
92 /// [AssetNotFoundException]. | |
93 Future<bool> hasInput(AssetId id) { | |
94 return getInput(id).then((_) => true).catchError((error) { | |
95 if (error is AssetNotFoundException && error.id == id) return false; | |
96 throw error; | |
97 }); | |
98 } | |
99 | |
100 /// Stores [output] as the output created by this transformation. | |
101 /// | |
102 /// A transformation can output as many assets as it wants. | |
103 void addOutput(Asset output) { | |
104 // TODO(rnystrom): This should immediately throw if an output with that ID | |
105 // has already been created by this transformer. | |
106 _outputs.add(output); | |
107 } | |
108 } | |
109 | |
110 /// The controller for [Transform]. | |
111 class TransformController extends BaseTransformController { | |
112 Transform get transform => super.transform; | |
113 | |
114 /// The set of assets that the transformer has emitted. | |
115 AssetSet get outputs => transform._outputs; | |
116 | |
117 TransformController(TransformNode node) | |
118 : super(new Transform._(node)); | |
119 } | |
OLD | NEW |