Index: packages/analyzer/lib/src/task/inputs.dart |
diff --git a/analyzer/lib/src/task/inputs.dart b/packages/analyzer/lib/src/task/inputs.dart |
similarity index 90% |
rename from analyzer/lib/src/task/inputs.dart |
rename to packages/analyzer/lib/src/task/inputs.dart |
index 308b06a5f2082c92ecee97b28f55f93ebe1810ea..468f3139f7eabba5232cca35971220a9e9ec4e20 100644 |
--- a/analyzer/lib/src/task/inputs.dart |
+++ b/packages/analyzer/lib/src/task/inputs.dart |
@@ -24,14 +24,64 @@ typedef R Mapper<P, R>(P value); |
* An input to an [AnalysisTask] that is computed by accessing a single result |
* defined on a single target. |
*/ |
+class ConstantTaskInput<V> extends TaskInputImpl<V> { |
+ final V value; |
+ |
+ ConstantTaskInput(this.value); |
+ |
+ @override |
+ TaskInputBuilder<V> createBuilder() { |
+ return new ConstantTaskInputBuilder<V>(this); |
+ } |
+} |
+ |
+/** |
+ * A [TaskInputBuilder] used to build an input based on a [ConstantTaskInput]. |
+ */ |
+class ConstantTaskInputBuilder<V> implements TaskInputBuilder<V> { |
+ final ConstantTaskInput input; |
+ |
+ ConstantTaskInputBuilder(this.input); |
+ |
+ @override |
+ ResultDescriptor get currentResult => null; |
+ |
+ @override |
+ AnalysisTarget get currentTarget => null; |
+ |
+ @override |
+ void set currentValue(Object value) { |
+ throw new StateError('Only supported after moveNext() returns true'); |
+ } |
+ |
+ @override |
+ bool get flushOnAccess => false; |
+ |
+ @override |
+ V get inputValue => input.value; |
+ |
+ @override |
+ void currentValueNotAvailable() { |
+ throw new StateError('Only supported after moveNext() returns true'); |
+ } |
+ |
+ @override |
+ bool moveNext() => false; |
+} |
+ |
+/** |
+ * An input to an [AnalysisTask] that is computed by accessing a single result |
+ * defined on a single target. |
+ */ |
class ListTaskInputImpl<E> extends SimpleTaskInput<List<E>> |
- with ListTaskInputMixin<E> implements ListTaskInput<E> { |
+ with ListTaskInputMixin<E> |
+ implements ListTaskInput<E> { |
/** |
* Initialize a newly created task input that computes the input by accessing |
* the given [result] associated with the given [target]. |
*/ |
ListTaskInputImpl(AnalysisTarget target, ResultDescriptor<List<E>> result) |
- : super(target, result); |
+ : super._unflushable(target, result); |
} |
/** |
@@ -168,7 +218,8 @@ class ListToMapTaskInputBuilder<B, E> |
abstract class MapTaskInputMixin<K, V> implements MapTaskInput<K, V> { |
TaskInput<List /*<E>*/ > toFlattenList( |
BinaryFunction<K, dynamic /*element of V*/, dynamic /*<E>*/ > mapper) { |
- return new MapToFlattenListTaskInput<K, dynamic /*element of V*/, dynamic /*E*/ >( |
+ return new MapToFlattenListTaskInput<K, dynamic /*element of V*/, |
+ dynamic /*E*/ >( |
this as MapTaskInput<K, List /*<element of V>*/ >, mapper); |
} |
} |
@@ -241,6 +292,9 @@ class MapToFlattenListTaskInputBuilder<K, V, E> |
} |
@override |
+ bool get flushOnAccess => currentBuilder.flushOnAccess; |
+ |
+ @override |
void currentValueNotAvailable() { |
if (currentBuilder == null) { |
throw new StateError( |
@@ -301,7 +355,8 @@ class MapToFlattenListTaskInputBuilder<K, V, E> |
* An input to an [AnalysisTask] that is computed by mapping the value of |
* another task input to a list of values. |
*/ |
-class ObjectToListTaskInput<E> extends TaskInputImpl<List<E>> with ListTaskInputMixin<E> |
+class ObjectToListTaskInput<E> extends TaskInputImpl<List<E>> |
+ with ListTaskInputMixin<E> |
implements ListTaskInput<E> { |
/** |
* The input used to compute the value to be mapped. |
@@ -391,6 +446,9 @@ class ObjectToListTaskInputBuilder<E> implements TaskInputBuilder<List<E>> { |
} |
@override |
+ bool get flushOnAccess => builder.flushOnAccess; |
+ |
+ @override |
List<E> get inputValue { |
if (builder != null) { |
throw new StateError('Result value has not been created'); |
@@ -442,10 +500,23 @@ class SimpleTaskInput<V> extends TaskInputImpl<V> { |
final ResultDescriptor<V> result; |
/** |
+ * Return `true` if the value accessed by this input builder should be flushed |
+ * from the cache at the time it is retrieved. |
+ */ |
+ final bool flushOnAccess; |
+ |
+ /** |
+ * Initialize a newly created task input that computes the input by accessing |
+ * the given [result] associated with the given [target]. |
+ */ |
+ SimpleTaskInput(this.target, this.result, {this.flushOnAccess: false}); |
+ |
+ /** |
* Initialize a newly created task input that computes the input by accessing |
* the given [result] associated with the given [target]. |
*/ |
- SimpleTaskInput(this.target, this.result); |
+ SimpleTaskInput._unflushable(this.target, this.result) |
+ : flushOnAccess = false; |
@override |
TaskInputBuilder<V> createBuilder() => new SimpleTaskInputBuilder<V>(this); |
@@ -517,6 +588,9 @@ class SimpleTaskInputBuilder<V> implements TaskInputBuilder<V> { |
} |
@override |
+ bool get flushOnAccess => input.flushOnAccess; |
+ |
+ @override |
V get inputValue { |
if (_state != _AFTER) { |
throw new StateError('Result value has not been created'); |
@@ -625,6 +699,9 @@ class TopLevelTaskInputBuilder |
} |
@override |
+ bool get flushOnAccess => currentBuilder.flushOnAccess; |
+ |
+ @override |
Map<String, Object> get inputValue { |
if (nameIndex < inputNames.length) { |
throw new StateError('Result value has not been created'); |
@@ -672,11 +749,18 @@ class TopLevelTaskInputBuilder |
return false; |
} |
currentBuilder = inputDescriptors[_currentName].createBuilder(); |
- // NOTE: This assumes that every builder will require at least one result |
- // value to be created. If that assumption is every broken, this method will |
- // need to be changed to advance until we find a builder that does require |
- // a result to be computed (or run out of builders). |
- return currentBuilder.moveNext(); |
+ while (!currentBuilder.moveNext()) { |
+ if (currentBuilder.inputValue != null) { |
+ inputs[_currentName] = currentBuilder.inputValue; |
+ } |
+ nameIndex++; |
+ if (nameIndex >= inputNames.length) { |
+ // There is no next value, so we're done. |
+ return false; |
+ } |
+ currentBuilder = inputDescriptors[_currentName].createBuilder(); |
+ } |
+ return true; |
} |
} |
@@ -771,6 +855,9 @@ abstract class _ListToCollectionTaskInputBuilder<B, E, C> |
} |
@override |
+ bool get flushOnAccess => currentBuilder.flushOnAccess; |
+ |
+ @override |
C get inputValue { |
if (currentBuilder != null || _resultValue == null) { |
throw new StateError('Result value has not been created'); |