Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Side by Side Diff: pkg/barback/lib/src/transform_node.dart

Issue 224933002: Only run [Transformer.isPrimary] once for each asset/transformer pair. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: code review Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/barback/lib/src/transform.dart ('k') | pkg/barback/lib/src/transformer.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 26 matching lines...) Expand all
37 /// A string describing the location of [this] in the transformer graph. 37 /// A string describing the location of [this] in the transformer graph.
38 final String _location; 38 final String _location;
39 39
40 /// The subscription to [primary]'s [AssetNode.onStateChange] stream. 40 /// The subscription to [primary]'s [AssetNode.onStateChange] stream.
41 StreamSubscription _primarySubscription; 41 StreamSubscription _primarySubscription;
42 42
43 /// The subscription to [phase]'s [Phase.onAsset] stream. 43 /// The subscription to [phase]'s [Phase.onAsset] stream.
44 StreamSubscription<AssetNode> _phaseSubscription; 44 StreamSubscription<AssetNode> _phaseSubscription;
45 45
46 /// Whether [this] is dirty and still has more processing to do. 46 /// Whether [this] is dirty and still has more processing to do.
47 bool get isDirty => !_state.isDone; 47 bool get isDirty => _state != _State.NOT_PRIMARY && _state != _State.APPLIED;
48 48
49 /// Whether [transformer] is lazy and this transform has yet to be forced. 49 /// Whether [transformer] is lazy and this transform has yet to be forced.
50 bool _isLazy; 50 bool _isLazy;
51 51
52 /// The subscriptions to each input's [AssetNode.onStateChange] stream. 52 /// The subscriptions to each input's [AssetNode.onStateChange] stream.
53 final _inputSubscriptions = new Map<AssetId, StreamSubscription>(); 53 final _inputSubscriptions = new Map<AssetId, StreamSubscription>();
54 54
55 /// The controllers for the asset nodes emitted by this node. 55 /// The controllers for the asset nodes emitted by this node.
56 final _outputControllers = new Map<AssetId, AssetNodeController>(); 56 final _outputControllers = new Map<AssetId, AssetNodeController>();
57 57
(...skipping 25 matching lines...) Expand all
83 83
84 /// A stream that emits an event whenever this transform logs an entry. 84 /// A stream that emits an event whenever this transform logs an entry.
85 /// 85 ///
86 /// This is synchronous because error logs can cause the transform to fail, so 86 /// This is synchronous because error logs can cause the transform to fail, so
87 /// we need to ensure that their processing isn't delayed until after the 87 /// we need to ensure that their processing isn't delayed until after the
88 /// transform or build has finished. 88 /// transform or build has finished.
89 Stream<LogEntry> get onLog => _onLogPool.stream; 89 Stream<LogEntry> get onLog => _onLogPool.stream;
90 final _onLogPool = new StreamPool<LogEntry>.broadcast(); 90 final _onLogPool = new StreamPool<LogEntry>.broadcast();
91 91
92 /// The current state of [this]. 92 /// The current state of [this].
93 var _state = _TransformNodeState.PROCESSING; 93 var _state = _State.COMPUTING_IS_PRIMARY;
94 94
95 /// Whether [this] has been marked as removed. 95 /// Whether [this] has been marked as removed.
96 bool get _isRemoved => _onAssetController.isClosed; 96 bool get _isRemoved => _onAssetController.isClosed;
97 97
98 /// Whether the most recent run of this transform has declared that it 98 /// Whether the most recent run of this transform has declared that it
99 /// consumes the primary input. 99 /// consumes the primary input.
100 /// 100 ///
101 /// Defaults to `false`. This is not meaningful unless [_state] is 101 /// Defaults to `false`. This is not meaningful unless [_state] is
102 /// [_TransformNodeState.APPLIED]. 102 /// [_State.APPLIED].
103 bool _consumePrimary = false; 103 bool _consumePrimary = false;
104 104
105 TransformNode(this.phase, Transformer transformer, this.primary, 105 TransformNode(this.phase, Transformer transformer, this.primary,
106 this._location) 106 this._location)
107 : transformer = transformer, 107 : transformer = transformer,
108 _isLazy = transformer is LazyTransformer { 108 _isLazy = transformer is LazyTransformer {
109 _primarySubscription = primary.onStateChange.listen((state) { 109 _primarySubscription = primary.onStateChange.listen((state) {
110 if (state.isRemoved) { 110 if (state.isRemoved) {
111 remove(); 111 remove();
112 } else { 112 } else {
113 _dirty(primaryChanged: true); 113 _dirty();
114 } 114 }
115 }); 115 });
116 116
117 _phaseSubscription = phase.previous.onAsset.listen((node) { 117 _phaseSubscription = phase.previous.onAsset.listen((node) {
118 if (_missingInputs.contains(node.id)) _dirty(primaryChanged: false); 118 if (_missingInputs.contains(node.id)) _dirty();
119 }); 119 });
120 120
121 _process(); 121 syncFuture(() => transformer.isPrimary(primary.id))
122 .catchError((error, stackTrace) {
123 if (_isRemoved) return false;
124
125 // Catch all transformer errors and pipe them to the results stream. This
126 // is so a broken transformer doesn't take down the whole graph.
127 phase.cascade.reportError(_wrapException(error, stackTrace));
128
129 return false;
130 }).then((isPrimary) {
131 if (_isRemoved) return;
132 if (isPrimary) {
133 _apply();
134 return;
135 }
136
137 _emitPassThrough();
138 _state = _State.NOT_PRIMARY;
139 _onDoneController.add(null);
140 });
122 } 141 }
123 142
124 /// The [TransformInfo] describing this node. 143 /// The [TransformInfo] describing this node.
125 /// 144 ///
126 /// [TransformInfo] is the publicly-visible representation of a transform 145 /// [TransformInfo] is the publicly-visible representation of a transform
127 /// node. 146 /// node.
128 TransformInfo get info => new TransformInfo(transformer, primary.id); 147 TransformInfo get info => new TransformInfo(transformer, primary.id);
129 148
130 /// Marks this transform as removed. 149 /// Marks this transform as removed.
131 /// 150 ///
(...skipping 14 matching lines...) Expand all
146 } 165 }
147 } 166 }
148 167
149 /// If [transformer] is lazy, ensures that its concrete outputs will be 168 /// If [transformer] is lazy, ensures that its concrete outputs will be
150 /// generated. 169 /// generated.
151 void force() { 170 void force() {
152 // TODO(nweiz): we might want to have a timeout after which, if the 171 // TODO(nweiz): we might want to have a timeout after which, if the
153 // transform's outputs have gone unused, we switch it back to lazy mode. 172 // transform's outputs have gone unused, we switch it back to lazy mode.
154 if (!_isLazy) return; 173 if (!_isLazy) return;
155 _isLazy = false; 174 _isLazy = false;
156 _dirty(primaryChanged: false); 175 _dirty();
157 } 176 }
158 177
159 /// Marks this transform as dirty. 178 /// Marks this transform as dirty.
160 /// 179 ///
161 /// This causes all of the transform's outputs to be marked as dirty as well. 180 /// This causes all of the transform's outputs to be marked as dirty as well.
162 /// [primaryChanged] should be true if and only if [this] was set dirty 181 void _dirty() {
163 /// because [primary] changed. 182 if (_state == _State.COMPUTING_IS_PRIMARY) return;
164 void _dirty({bool primaryChanged: false}) { 183 if (_state == _State.NOT_PRIMARY) {
165 if (!primaryChanged && _state.isNotPrimary) return; 184 _emitPassThrough();
185 return;
186 }
166 187
167 if (_passThroughController != null) _passThroughController.setDirty(); 188 if (_passThroughController != null) _passThroughController.setDirty();
168 for (var controller in _outputControllers.values) { 189 for (var controller in _outputControllers.values) {
169 controller.setDirty(); 190 controller.setDirty();
170 } 191 }
171 192
172 if (_state.isDone) { 193 if (_state == _State.APPLIED) {
173 if (primaryChanged) { 194 _apply();
174 _process(); 195 } else {
175 } else { 196 _state = _State.NEEDS_APPLY;
176 _apply();
177 }
178 } else if (primaryChanged) {
179 _state = _TransformNodeState.NEEDS_IS_PRIMARY;
180 } else if (!_state.needsIsPrimary) {
181 _state = _TransformNodeState.NEEDS_APPLY;
182 } 197 }
183 } 198 }
184 199
185 /// Determines whether [primary] is primary for [transformer], and if so runs
186 /// [transformer.apply].
187 void _process() {
188 // Clear all the old input subscriptions. If an input is re-used, we'll
189 // re-subscribe.
190 _clearInputSubscriptions();
191 _state = _TransformNodeState.PROCESSING;
192 primary.whenAvailable((_) {
193 _state = _TransformNodeState.PROCESSING;
194 return transformer.isPrimary(primary.asset);
195 }).catchError((error, stackTrace) {
196 // If the transform became dirty while processing, ignore any errors from
197 // it.
198 if (_state.needsIsPrimary || _isRemoved) return false;
199
200 // Catch all transformer errors and pipe them to the results stream. This
201 // is so a broken transformer doesn't take down the whole graph.
202 phase.cascade.reportError(_wrapException(error, stackTrace));
203
204 return false;
205 }).then((isPrimary) {
206 if (_isRemoved) return;
207 if (_state.needsIsPrimary) {
208 _process();
209 } else if (isPrimary) {
210 _apply();
211 } else {
212 _clearOutputs();
213 _emitPassThrough();
214 _state = _TransformNodeState.NOT_PRIMARY;
215 _onDoneController.add(null);
216 }
217 });
218 }
219
220 /// Applies this transform. 200 /// Applies this transform.
221 void _apply() { 201 void _apply() {
222 assert(!_onAssetController.isClosed); 202 assert(!_isRemoved);
223 203
224 // Clear input subscriptions here as well as in [_process] because [_apply] 204 // Clear input subscriptions here as well as in [_process] because [_apply]
225 // may be restarted independently if only a secondary input changes. 205 // may be restarted independently if only a secondary input changes.
226 _clearInputSubscriptions(); 206 _clearInputSubscriptions();
227 _state = _TransformNodeState.PROCESSING; 207 _state = _State.APPLYING;
228 primary.whenAvailable((_) { 208 primary.whenAvailable((_) {
229 if (_state.needsIsPrimary) return null; 209 if (_isRemoved) return null;
230 _state = _TransformNodeState.PROCESSING; 210 _state = _State.APPLYING;
231 // TODO(nweiz): If [transformer] is a [DeclaringTransformer] but not a 211 // TODO(nweiz): If [transformer] is a [DeclaringTransformer] but not a
232 // [LazyTransformer], we can get some mileage out of doing a declarative 212 // [LazyTransformer], we can get some mileage out of doing a declaration
233 // first so we know how to hook up the assets. 213 // first so we know how to hook up the assets.
234 if (_isLazy) return _declareLazy(); 214 if (_isLazy) return _declareLazy();
235 return _applyImmediate(); 215 return _applyImmediate();
236 }).catchError((error, stackTrace) { 216 }).catchError((error, stackTrace) {
237 // If the transform became dirty while processing, ignore any errors from 217 // If the transform became dirty while processing, ignore any errors from
238 // it. 218 // it.
239 if (!_state.isProcessing || _isRemoved) return false; 219 if (_state == _State.NEEDS_APPLY || _isRemoved) return false;
240 220
241 // Catch all transformer errors and pipe them to the results stream. This 221 // Catch all transformer errors and pipe them to the results stream. This
242 // is so a broken transformer doesn't take down the whole graph. 222 // is so a broken transformer doesn't take down the whole graph.
243 phase.cascade.reportError(_wrapException(error, stackTrace)); 223 phase.cascade.reportError(_wrapException(error, stackTrace));
244 return true; 224 return true;
245 }).then((hadError) { 225 }).then((hadError) {
246 if (_isRemoved) return; 226 if (_isRemoved) return;
247 227
248 if (_state.needsIsPrimary) { 228 if (_state == _State.NEEDS_APPLY) {
249 _process();
250 } else if (_state.needsApply) {
251 _apply(); 229 _apply();
252 } else { 230 return;
253 assert(_state.isProcessing); 231 }
254 if (hadError) {
255 _clearOutputs();
256 _dontEmitPassThrough();
257 }
258 232
259 _state = _TransformNodeState.APPLIED; 233 assert(_state == _State.APPLYING);
260 _onDoneController.add(null); 234 if (hadError) {
235 _clearOutputs();
236 _dontEmitPassThrough();
261 } 237 }
238
239 _state = _State.APPLIED;
240 _onDoneController.add(null);
262 }); 241 });
263 } 242 }
264 243
265 /// Gets the asset for an input [id]. 244 /// Gets the asset for an input [id].
266 /// 245 ///
267 /// If an input with [id] cannot be found, throws an [AssetNotFoundException]. 246 /// If an input with [id] cannot be found, throws an [AssetNotFoundException].
268 Future<Asset> getInput(AssetId id) { 247 Future<Asset> getInput(AssetId id) {
269 return phase.previous.getOutput(id).then((node) { 248 return phase.previous.getOutput(id).then((node) {
270 // Throw if the input isn't found. This ensures the transformer's apply 249 // Throw if the input isn't found. This ensures the transformer's apply
271 // is exited. We'll then catch this and report it through the proper 250 // is exited. We'll then catch this and report it through the proper
272 // results stream. 251 // results stream.
273 if (node == null) { 252 if (node == null) {
274 _missingInputs.add(id); 253 _missingInputs.add(id);
275 throw new AssetNotFoundException(id); 254 throw new AssetNotFoundException(id);
276 } 255 }
277 256
278 _inputSubscriptions.putIfAbsent(node.id, () { 257 _inputSubscriptions.putIfAbsent(node.id, () {
279 return node.onStateChange.listen((_) => _dirty(primaryChanged: false)); 258 return node.onStateChange.listen((_) => _dirty());
280 }); 259 });
281 260
282 return node.asset; 261 return node.asset;
283 }); 262 });
284 } 263 }
285 264
286 /// Applies the transform so that it produces concrete (as opposed to lazy) 265 /// Applies the transform so that it produces concrete (as opposed to lazy)
287 /// outputs. 266 /// outputs.
288 /// 267 ///
289 /// Returns whether or not the transformer logged an error. 268 /// Returns whether or not the transformer logged an error.
290 Future<bool> _applyImmediate() { 269 Future<bool> _applyImmediate() {
291 var transformController = new TransformController(this); 270 var transformController = new TransformController(this);
292 _onLogPool.add(transformController.onLog); 271 _onLogPool.add(transformController.onLog);
293 272
294 return syncFuture(() { 273 return syncFuture(() {
295 return transformer.apply(transformController.transform); 274 return transformer.apply(transformController.transform);
296 }).then((_) { 275 }).then((_) {
297 if (!_state.isProcessing || _onAssetController.isClosed) return false; 276 if (_state == _State.NEEDS_APPLY || _isRemoved) return false;
298 if (transformController.loggedError) return true; 277 if (transformController.loggedError) return true;
299 278
300 _consumePrimary = transformController.consumePrimary; 279 _consumePrimary = transformController.consumePrimary;
301 280
302 var newOutputs = transformController.outputs; 281 var newOutputs = transformController.outputs;
303 // Any ids that are for a different package are invalid. 282 // Any ids that are for a different package are invalid.
304 var invalidIds = newOutputs 283 var invalidIds = newOutputs
305 .map((asset) => asset.id) 284 .map((asset) => asset.id)
306 .where((id) => id.package != phase.cascade.package) 285 .where((id) => id.package != phase.cascade.package)
307 .toSet(); 286 .toSet();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 /// outputs. 324 /// outputs.
346 /// 325 ///
347 /// Returns whether or not the transformer logged an error. 326 /// Returns whether or not the transformer logged an error.
348 Future<bool> _declareLazy() { 327 Future<bool> _declareLazy() {
349 var transformController = new DeclaringTransformController(this); 328 var transformController = new DeclaringTransformController(this);
350 329
351 return syncFuture(() { 330 return syncFuture(() {
352 return (transformer as LazyTransformer) 331 return (transformer as LazyTransformer)
353 .declareOutputs(transformController.transform); 332 .declareOutputs(transformController.transform);
354 }).then((_) { 333 }).then((_) {
355 if (!_state.isProcessing || _onAssetController.isClosed) return false; 334 if (_state == _State.NEEDS_APPLY || _isRemoved) return false;
356 if (transformController.loggedError) return true; 335 if (transformController.loggedError) return true;
357 336
358 _consumePrimary = transformController.consumePrimary; 337 _consumePrimary = transformController.consumePrimary;
359 338
360 var newIds = transformController.outputIds; 339 var newIds = transformController.outputIds;
361 var invalidIds = 340 var invalidIds =
362 newIds.where((id) => id.package != phase.cascade.package).toSet(); 341 newIds.where((id) => id.package != phase.cascade.package).toSet();
363 for (var id in invalidIds) { 342 for (var id in invalidIds) {
364 newIds.remove(id); 343 newIds.remove(id);
365 // TODO(nweiz): report this as a warning rather than a failing error. 344 // TODO(nweiz): report this as a warning rather than a failing error.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 } 393 }
415 394
416 /// Emit the pass-through asset if it's not being emitted already. 395 /// Emit the pass-through asset if it's not being emitted already.
417 void _emitPassThrough() { 396 void _emitPassThrough() {
418 assert(!_outputControllers.containsKey(primary.id)); 397 assert(!_outputControllers.containsKey(primary.id));
419 398
420 if (_consumePrimary) return; 399 if (_consumePrimary) return;
421 if (_passThroughController == null) { 400 if (_passThroughController == null) {
422 _passThroughController = new AssetNodeController.from(primary); 401 _passThroughController = new AssetNodeController.from(primary);
423 _onAssetController.add(_passThroughController.node); 402 _onAssetController.add(_passThroughController.node);
424 } else { 403 } else if (primary.state.isDirty) {
404 _passThroughController.setDirty();
405 } else if (!_passThroughController.node.state.isAvailable) {
425 _passThroughController.setAvailable(primary.asset); 406 _passThroughController.setAvailable(primary.asset);
426 } 407 }
427 } 408 }
428 409
429 /// Stop emitting the pass-through asset if it's being emitted already. 410 /// Stop emitting the pass-through asset if it's being emitted already.
430 void _dontEmitPassThrough() { 411 void _dontEmitPassThrough() {
431 if (_passThroughController == null) return; 412 if (_passThroughController == null) return;
432 _passThroughController.setRemoved(); 413 _passThroughController.setRemoved();
433 _passThroughController = null; 414 _passThroughController = null;
434 } 415 }
435 416
436 BarbackException _wrapException(error, StackTrace stackTrace) { 417 BarbackException _wrapException(error, StackTrace stackTrace) {
437 if (error is! AssetNotFoundException) { 418 if (error is! AssetNotFoundException) {
438 return new TransformerException(info, error, stackTrace); 419 return new TransformerException(info, error, stackTrace);
439 } else { 420 } else {
440 return new MissingInputException(info, error.id); 421 return new MissingInputException(info, error.id);
441 } 422 }
442 } 423 }
443 424
444 String toString() => 425 String toString() =>
445 "transform node in $_location for $transformer on $primary"; 426 "transform node in $_location for $transformer on $primary";
446 } 427 }
447 428
448 /// The enum of states that [TransformNode] can be in. 429 /// The enum of states that [TransformNode] can be in.
449 class _TransformNodeState { 430 class _State {
450 /// The transform node is running [Transformer.isPrimary] or 431 /// The transform is running [Transformer.isPrimary].
451 /// [Transformer.apply] and doesn't need to re-run them.
452 /// 432 ///
453 /// If there are no external changes by the time the processing finishes, this 433 /// This is the initial state of the transformer. Once [Transformer.isPrimary]
454 /// will transition to [APPLIED] or [NOT_PRIMARY] depending on the result of 434 /// finishes running, this will transition to [APPLYING] if the input is
455 /// [Transformer.isPrimary]. If the primary input changes, this will 435 /// primary, or [NOT_PRIMARY] if it's not.
456 /// transition to [NEEDS_IS_PRIMARY]. If a secondary input changes, this will 436 static final COMPUTING_IS_PRIMARY = const _State._("computing isPrimary");
457 /// transition to [NEEDS_APPLY].
458 static final PROCESSING = const _TransformNodeState._("processing");
459 437
460 /// The transform is running [Transformer.isPrimary] or [Transformer.apply], 438 /// The transform is running [Transformer.apply].
461 /// but since it started the primary input changed, so it will need to re-run
462 /// [Transformer.isPrimary].
463 /// 439 ///
464 /// This will always transition to [Transformer.PROCESSING]. 440 /// If an input changes while in this state, it will transition to
465 static final NEEDS_IS_PRIMARY = 441 /// [NEEDS_APPLY]. If the [TransformNode] is still in this state when
466 const _TransformNodeState._("needs isPrimary"); 442 /// [Transformer.apply] finishes running, it will transition to [APPLIED].
443 static final APPLYING = const _State._("applying");
467 444
468 /// The transform is running [Transformer.apply], but since it started a 445 /// The transform is running [Transformer.apply], but an input changed after
469 /// secondary input changed, so it will need to re-run [Transformer.apply]. 446 /// it started, so it will need to re-run [Transformer.apply].
470 /// 447 ///
471 /// If there are no external changes by the time [Transformer.apply] finishes, 448 /// This will transition to [APPLYING] once [Transformer.apply] finishes
472 /// this will transition to [PROCESSING]. If the primary input changes, this 449 /// running.
473 /// will transition to [NEEDS_IS_PRIMARY]. 450 static final NEEDS_APPLY = const _State._("needs apply");
474 static final NEEDS_APPLY = const _TransformNodeState._("needs apply");
475 451
476 /// The transform has finished running [Transformer.apply], whether or not it 452 /// The transform has finished running [Transformer.apply], whether or not it
477 /// emitted an error. 453 /// emitted an error.
478 /// 454 ///
479 /// If the primary input or a secondary input changes, this will transition to 455 /// If an input changes, this will transition to [APPLYING].
480 /// [PROCESSING]. 456 static final APPLIED = const _State._("applied");
481 static final APPLIED = const _TransformNodeState._("applied");
482 457
483 /// The transform has finished running [Transformer.isPrimary], which returned 458 /// The transform has finished running [Transformer.isPrimary], which returned
484 /// `false`. 459 /// `false`.
485 /// 460 ///
486 /// If the primary input changes, this will transition to [PROCESSING]. 461 /// This will never transition to another state.
487 static final NOT_PRIMARY = const _TransformNodeState._("not primary"); 462 static final NOT_PRIMARY = const _State._("not primary");
488
489 /// Whether [this] is [PROCESSING].
490 bool get isProcessing => this == _TransformNodeState.PROCESSING;
491
492 /// Whether [this] is [NEEDS_IS_PRIMARY].
493 bool get needsIsPrimary => this == _TransformNodeState.NEEDS_IS_PRIMARY;
494
495 /// Whether [this] is [NEEDS_APPLY].
496 bool get needsApply => this == _TransformNodeState.NEEDS_APPLY;
497
498 /// Whether [this] is [APPLIED].
499 bool get isApplied => this == _TransformNodeState.APPLIED;
500
501 /// Whether [this] is [NOT_PRIMARY].
502 bool get isNotPrimary => this == _TransformNodeState.NOT_PRIMARY;
503
504 /// Whether the transform has finished running [Transformer.isPrimary] and
505 /// [Transformer.apply].
506 ///
507 /// Specifically, whether [this] is [APPLIED] or [NOT_PRIMARY].
508 bool get isDone => isApplied || isNotPrimary;
509 463
510 final String name; 464 final String name;
511 465
512 const _TransformNodeState._(this.name); 466 const _State._(this.name);
513 467
514 String toString() => name; 468 String toString() => name;
515 } 469 }
OLDNEW
« no previous file with comments | « pkg/barback/lib/src/transform.dart ('k') | pkg/barback/lib/src/transformer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698