OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 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.base_transform; | 5 library barback.base_transform; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:convert'; | |
9 | 8 |
10 import 'asset.dart'; | |
11 import 'asset_id.dart'; | |
12 import 'asset_node.dart'; | |
13 import 'errors.dart'; | |
14 import 'log.dart'; | 9 import 'log.dart'; |
15 import 'transform_logger.dart'; | 10 import 'transform_logger.dart'; |
16 import 'transform_node.dart'; | 11 import 'transform_node.dart'; |
17 import 'utils.dart'; | |
18 | 12 |
19 /// The base class for the ephemeral transform objects that are passed to | 13 /// The base class for the ephemeral transform objects that are passed to |
20 /// transformers. | 14 /// transformers. |
21 /// | 15 /// |
22 /// This class provides the transformers with inputs, but its up to the | 16 /// This class provides the transformers with inputs, but its up to the |
23 /// subclasses to provide a means of emitting outputs. | 17 /// subclasses to provide a means of emitting outputs. |
24 abstract class BaseTransform { | 18 abstract class BaseTransform { |
25 final TransformNode _node; | 19 final TransformNode _node; |
26 | 20 |
27 /// Whether the primary input should be consumed. | 21 /// Whether the primary input should be consumed. |
(...skipping 12 matching lines...) Expand all Loading... |
40 /// | 34 /// |
41 /// This is synchronous because error logs can cause the transform to fail, so | 35 /// This is synchronous because error logs can cause the transform to fail, so |
42 /// we need to ensure that their processing isn't delayed until after the | 36 /// we need to ensure that their processing isn't delayed until after the |
43 /// transform or build has finished. | 37 /// transform or build has finished. |
44 final _onLogController = new StreamController<LogEntry>.broadcast(sync: true); | 38 final _onLogController = new StreamController<LogEntry>.broadcast(sync: true); |
45 | 39 |
46 /// A logger so that the [Transformer] can report build details. | 40 /// A logger so that the [Transformer] can report build details. |
47 TransformLogger get logger => _logger; | 41 TransformLogger get logger => _logger; |
48 TransformLogger _logger; | 42 TransformLogger _logger; |
49 | 43 |
50 /// Gets the primary input asset. | |
51 /// | |
52 /// While a transformation can use multiple input assets, one must be a | |
53 /// special "primary" asset. This will be the "entrypoint" or "main" input | |
54 /// file for a transformation. | |
55 /// | |
56 /// For example, with a dart2js transform, the primary input would be the | |
57 /// entrypoint Dart file. All of the other Dart files that that imports | |
58 /// would be secondary inputs. | |
59 /// | |
60 /// This method may fail at runtime with an [AssetNotFoundException] if called | |
61 /// asynchronously after the transform begins running. The primary input may | |
62 /// become unavailable while this transformer is running due to asset changes | |
63 /// earlier in the graph. You can ignore the error if this happens: the | |
64 /// transformer will be re-run automatically for you. | |
65 Asset get primaryInput { | |
66 if (_node.primary.state != AssetState.AVAILABLE) { | |
67 throw new AssetNotFoundException(_node.primary.id); | |
68 } | |
69 | |
70 return _node.primary.asset; | |
71 } | |
72 | |
73 BaseTransform(this._node) { | 44 BaseTransform(this._node) { |
74 _logger = new TransformLogger((asset, level, message, span) { | 45 _logger = new TransformLogger((asset, level, message, span) { |
75 if (level == LogLevel.ERROR) _loggedError = true; | 46 if (level == LogLevel.ERROR) _loggedError = true; |
76 | 47 |
77 // If the log isn't already associated with an asset, use the primary. | 48 // If the log isn't already associated with an asset, use the primary. |
78 if (asset == null) asset = _node.primary.id; | 49 if (asset == null) asset = _node.primary.id; |
79 var entry = new LogEntry(_node.info, asset, level, message, span); | 50 var entry = new LogEntry(_node.info, asset, level, message, span); |
80 _onLogController.add(entry); | 51 _onLogController.add(entry); |
81 }); | 52 }); |
82 } | 53 } |
83 | 54 |
84 /// Gets the asset for an input [id]. | |
85 /// | |
86 /// If an input with [id] cannot be found, throws an [AssetNotFoundException]. | |
87 Future<Asset> getInput(AssetId id) => _node.getInput(id); | |
88 | |
89 /// A convenience method to the contents of the input with [id] as a string. | |
90 /// | |
91 /// This is equivalent to calling [getInput] followed by [Asset.readAsString]. | |
92 /// | |
93 /// If the asset was created from a [String] the original string is always | |
94 /// returned and [encoding] is ignored. Otherwise, the binary data of the | |
95 /// asset is decoded using [encoding], which defaults to [UTF8]. | |
96 /// | |
97 /// If an input with [id] cannot be found, throws an [AssetNotFoundException]. | |
98 Future<String> readInputAsString(AssetId id, {Encoding encoding}) { | |
99 if (encoding == null) encoding = UTF8; | |
100 return getInput(id).then((input) => input.readAsString(encoding: encoding)); | |
101 } | |
102 | |
103 /// A convenience method to the contents of the input with [id]. | |
104 /// | |
105 /// This is equivalent to calling [getInput] followed by [Asset.read]. | |
106 /// | |
107 /// If the asset was created from a [String], this returns its UTF-8 encoding. | |
108 /// | |
109 /// If an input with [id] cannot be found, throws an [AssetNotFoundException]. | |
110 Stream<List<int>> readInput(AssetId id) => | |
111 futureStream(getInput(id).then((input) => input.read())); | |
112 | |
113 /// A convenience method to return whether or not an asset exists. | |
114 /// | |
115 /// This is equivalent to calling [getInput] and catching an | |
116 /// [AssetNotFoundException]. | |
117 Future<bool> hasInput(AssetId id) { | |
118 return getInput(id).then((_) => true).catchError((error) { | |
119 if (error is AssetNotFoundException && error.id == id) return false; | |
120 throw error; | |
121 }); | |
122 } | |
123 | |
124 /// Consume the primary input so that it doesn't get processed by future | 55 /// Consume the primary input so that it doesn't get processed by future |
125 /// phases or emitted once processing has finished. | 56 /// phases or emitted once processing has finished. |
126 /// | 57 /// |
127 /// Normally the primary input will automatically be forwarded unless the | 58 /// Normally the primary input will automatically be forwarded unless the |
128 /// transformer overwrites it by emitting an input with the same id. This | 59 /// transformer overwrites it by emitting an input with the same id. This |
129 /// allows the transformer to tell barback not to forward the primary input | 60 /// allows the transformer to tell barback not to forward the primary input |
130 /// even if it's not overwritten. | 61 /// even if it's not overwritten. |
131 void consumePrimary() { | 62 void consumePrimary() { |
132 _consumePrimary = true; | 63 _consumePrimary = true; |
133 } | 64 } |
(...skipping 20 matching lines...) Expand all Loading... |
154 | 85 |
155 /// Notifies the [BaseTransform] that the transformation has finished being | 86 /// Notifies the [BaseTransform] that the transformation has finished being |
156 /// applied. | 87 /// applied. |
157 /// | 88 /// |
158 /// This will close any streams and release any resources that were allocated | 89 /// This will close any streams and release any resources that were allocated |
159 /// for the duration of the transformation. | 90 /// for the duration of the transformation. |
160 void close() { | 91 void close() { |
161 transform._onLogController.close(); | 92 transform._onLogController.close(); |
162 } | 93 } |
163 } | 94 } |
OLD | NEW |