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

Side by Side Diff: analyzer/lib/src/task/inputs.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 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
OLDNEW
(Empty)
1 // Copyright (c) 2015, 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 analyzer.src.task.inputs;
6
7 import 'dart:collection';
8
9 import 'package:analyzer/task/model.dart';
10
11 /**
12 * A function that converts an object of the type [B] into a [TaskInput].
13 * This is used, for example, by a [ListToListTaskInput] to create task inputs
14 * for each value in a list of values.
15 */
16 typedef TaskInput<E> GenerateTaskInputs<B, E>(B object);
17
18 /**
19 * A function that maps one [value] to another value.
20 */
21 typedef R Mapper<P, R>(P value);
22
23 /**
24 * An input to an [AnalysisTask] that is computed by accessing a single result
25 * defined on a single target.
26 */
27 class ListTaskInputImpl<E> extends SimpleTaskInput<List<E>>
28 with ListTaskInputMixin<E> implements ListTaskInput<E> {
29 /**
30 * Initialize a newly created task input that computes the input by accessing
31 * the given [result] associated with the given [target].
32 */
33 ListTaskInputImpl(AnalysisTarget target, ResultDescriptor<List<E>> result)
34 : super(target, result);
35 }
36
37 /**
38 * A mixin-ready implementation of [ListTaskInput].
39 */
40 abstract class ListTaskInputMixin<E> implements ListTaskInput<E> {
41 ListTaskInput /*<V>*/ toList(UnaryFunction<E, dynamic /*<V>*/ > mapper) {
42 return new ListToListTaskInput<E, dynamic /*V*/ >(this, mapper);
43 }
44
45 ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult) {
46 return (this as ListTaskInputImpl<AnalysisTarget>).toList(valueResult.of);
47 }
48
49 MapTaskInput<E, dynamic /*V*/ > toMap(
50 UnaryFunction<E, dynamic /*<V>*/ > mapper) {
51 return new ListToMapTaskInput<E, dynamic /*V*/ >(this, mapper);
52 }
53
54 MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf(
55 ResultDescriptor /*<V>*/ valueResult) {
56 return (this as ListTaskInputImpl<AnalysisTarget>).toMap(valueResult.of);
57 }
58 }
59
60 /**
61 * An input to an [AnalysisTask] that is computed by the following steps. First
62 * another (base) task input is used to compute a [List]-valued result. An input
63 * generator function is then used to map each element of that list to a task
64 * input. Finally, each of the task inputs are used to access analysis results,
65 * and the list of the analysis results is used as the input to the task.
66 */
67 class ListToListTaskInput<B, E>
68 extends _ListToCollectionTaskInput<B, E, List<E>>
69 with ListTaskInputMixin<E> {
70 /**
71 * Initialize a result accessor to use the given [baseAccessor] to access a
72 * list of values that can be passed to the given [generateTaskInputs] to
73 * generate a list of task inputs that can be used to access the elements of
74 * the input being accessed.
75 */
76 ListToListTaskInput(TaskInput<List<B>> baseAccessor,
77 GenerateTaskInputs<B, E> generateTaskInputs)
78 : super(baseAccessor, generateTaskInputs);
79
80 @override
81 TaskInputBuilder<List<E>> createBuilder() =>
82 new ListToListTaskInputBuilder<B, E>(this);
83 }
84
85 /**
86 * A [TaskInputBuilder] used to build an input based on a [ListToListTaskInput].
87 */
88 class ListToListTaskInputBuilder<B, E>
89 extends _ListToCollectionTaskInputBuilder<B, E, List<E>> {
90 /**
91 * The list of values being built.
92 */
93 List<E> _resultValue;
94
95 /**
96 * Initialize a newly created task input builder that computes the result
97 * specified by the given [input].
98 */
99 ListToListTaskInputBuilder(ListToListTaskInput<B, E> input) : super(input);
100
101 @override
102 void _addResultElement(B baseElement, E resultElement) {
103 _resultValue.add(resultElement);
104 }
105
106 @override
107 void _initResultValue() {
108 _resultValue = <E>[];
109 }
110 }
111
112 /**
113 * An input to an [AnalysisTask] that is computed by the following steps. First
114 * another (base) task input is used to compute a [List]-valued result. An input
115 * generator function is then used to map each element of that list to a task
116 * input. Finally, each of the task inputs are used to access analysis results,
117 * and the map of the base elements to the analysis results is used as the
118 * input to the task.
119 */
120 class ListToMapTaskInput<B, E>
121 extends _ListToCollectionTaskInput<B, E, Map<B, E>>
122 with MapTaskInputMixin<B, E> {
123 /**
124 * Initialize a result accessor to use the given [baseAccessor] to access a
125 * list of values that can be passed to the given [generateTaskInputs] to
126 * generate a list of task inputs that can be used to access the elements of
127 * the input being accessed.
128 */
129 ListToMapTaskInput(TaskInput<List<B>> baseAccessor,
130 GenerateTaskInputs<B, E> generateTaskInputs)
131 : super(baseAccessor, generateTaskInputs);
132
133 @override
134 TaskInputBuilder<Map<B, E>> createBuilder() =>
135 new ListToMapTaskInputBuilder<B, E>(this);
136 }
137
138 /**
139 * A [TaskInputBuilder] used to build an input based on a [ListToMapTaskInput].
140 */
141 class ListToMapTaskInputBuilder<B, E>
142 extends _ListToCollectionTaskInputBuilder<B, E, Map<B, E>> {
143 /**
144 * The map being built.
145 */
146 Map<B, E> _resultValue;
147
148 /**
149 * Initialize a newly created task input builder that computes the result
150 * specified by the given [input].
151 */
152 ListToMapTaskInputBuilder(ListToMapTaskInput<B, E> input) : super(input);
153
154 @override
155 void _addResultElement(B baseElement, E resultElement) {
156 _resultValue[baseElement] = resultElement;
157 }
158
159 @override
160 void _initResultValue() {
161 _resultValue = new HashMap<B, E>();
162 }
163 }
164
165 /**
166 * A mixin-ready implementation of [MapTaskInput].
167 */
168 abstract class MapTaskInputMixin<K, V> implements MapTaskInput<K, V> {
169 TaskInput<List /*<E>*/ > toFlattenList(
170 BinaryFunction<K, dynamic /*element of V*/, dynamic /*<E>*/ > mapper) {
171 return new MapToFlattenListTaskInput<K, dynamic /*element of V*/, dynamic /* E*/ >(
172 this as MapTaskInput<K, List /*<element of V>*/ >, mapper);
173 }
174 }
175
176 /**
177 * A [TaskInput] that is computed by the following steps.
178 *
179 * First the [base] task input is used to compute a [Map]-valued result.
180 * The values of the [Map] must be [List]s.
181 *
182 * The given [mapper] is used to transform each key / value pair of the [Map]
183 * into task inputs.
184 *
185 * Finally, each of the task inputs are used to access analysis results,
186 * and the list of the results is used as the input.
187 */
188 class MapToFlattenListTaskInput<K, V, E> extends TaskInputImpl<List<E>> {
189 final MapTaskInput<K, List<V>> base;
190 final BinaryFunction<K, V, E> mapper;
191
192 MapToFlattenListTaskInput(this.base, this.mapper);
193
194 @override
195 TaskInputBuilder<List<E>> createBuilder() {
196 return new MapToFlattenListTaskInputBuilder<K, V, E>(base, mapper);
197 }
198 }
199
200 /**
201 * The [TaskInputBuilder] for [MapToFlattenListTaskInput].
202 */
203 class MapToFlattenListTaskInputBuilder<K, V, E>
204 implements TaskInputBuilder<List<E>> {
205 final MapTaskInput<K, List<V>> base;
206 final BinaryFunction<K, V, E> mapper;
207
208 TaskInputBuilder currentBuilder;
209 Map<K, List<V>> baseMap;
210 Iterator<K> keyIterator;
211 Iterator<V> valueIterator;
212
213 final List<E> inputValue = <E>[];
214
215 MapToFlattenListTaskInputBuilder(this.base, this.mapper) {
216 currentBuilder = base.createBuilder();
217 }
218
219 @override
220 ResultDescriptor get currentResult {
221 if (currentBuilder == null) {
222 return null;
223 }
224 return currentBuilder.currentResult;
225 }
226
227 AnalysisTarget get currentTarget {
228 if (currentBuilder == null) {
229 return null;
230 }
231 return currentBuilder.currentTarget;
232 }
233
234 @override
235 void set currentValue(Object value) {
236 if (currentBuilder == null) {
237 throw new StateError(
238 'Cannot set the result value when there is no current result');
239 }
240 currentBuilder.currentValue = value;
241 }
242
243 @override
244 void currentValueNotAvailable() {
245 if (currentBuilder == null) {
246 throw new StateError(
247 'Cannot set the result value when there is no current result');
248 }
249 currentBuilder.currentValueNotAvailable();
250 }
251
252 @override
253 bool moveNext() {
254 // Prepare base Map.
255 if (baseMap == null) {
256 if (currentBuilder.moveNext()) {
257 return true;
258 }
259 baseMap = currentBuilder.inputValue;
260 if (baseMap == null) {
261 // No base map could be computed due to a circular dependency. Use an
262 // empty map so that no further results will be computed.
263 baseMap = {};
264 }
265 keyIterator = baseMap.keys.iterator;
266 // Done with this builder.
267 currentBuilder = null;
268 }
269 // Prepare the next result value.
270 if (currentBuilder != null) {
271 if (currentBuilder.moveNext()) {
272 return true;
273 }
274 // Add the result value for the current Map key/value.
275 E resultValue = currentBuilder.inputValue;
276 if (resultValue != null) {
277 inputValue.add(resultValue);
278 }
279 // Done with this builder.
280 currentBuilder = null;
281 }
282 // Move to the next Map value.
283 if (valueIterator != null && valueIterator.moveNext()) {
284 K key = keyIterator.current;
285 V value = valueIterator.current;
286 currentBuilder = mapper(key, value).createBuilder();
287 return moveNext();
288 }
289 // Move to the next Map key.
290 if (keyIterator.moveNext()) {
291 K key = keyIterator.current;
292 valueIterator = baseMap[key].iterator;
293 return moveNext();
294 }
295 // No more Map values/keys to transform.
296 return false;
297 }
298 }
299
300 /**
301 * An input to an [AnalysisTask] that is computed by mapping the value of
302 * another task input to a list of values.
303 */
304 class ObjectToListTaskInput<E> extends TaskInputImpl<List<E>> with ListTaskInput Mixin<E>
305 implements ListTaskInput<E> {
306 /**
307 * The input used to compute the value to be mapped.
308 */
309 final TaskInput baseInput;
310
311 /**
312 * The function used to map the value of the base input to the list of values.
313 */
314 final Mapper<Object, List<E>> mapper;
315
316 /**
317 * Initialize a newly created task input that computes the input by accessing
318 * the given [result] associated with the given [target].
319 */
320 ObjectToListTaskInput(this.baseInput, this.mapper);
321
322 @override
323 TaskInputBuilder<List<E>> createBuilder() =>
324 new ObjectToListTaskInputBuilder<E>(this);
325
326 @override
327 ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult) {
328 return new ListToListTaskInput<E, dynamic /*V*/ >(
329 this, valueResult.of as dynamic);
330 }
331
332 @override
333 MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf(
334 ResultDescriptor /*<V>*/ valueResult) {
335 return new ListToMapTaskInput<AnalysisTarget, dynamic /*V*/ >(
336 this as dynamic, valueResult.of);
337 }
338 }
339
340 /**
341 * A [TaskInputBuilder] used to build an input based on a [SimpleTaskInput].
342 */
343 class ObjectToListTaskInputBuilder<E> implements TaskInputBuilder<List<E>> {
344 /**
345 * The input being built.
346 */
347 final ObjectToListTaskInput<E> input;
348
349 /**
350 * The builder created by the input.
351 */
352 TaskInputBuilder builder;
353
354 /**
355 * The value of the input being built, or `null` if the value hasn't been set
356 * yet or if no result is available ([currentValueNotAvailable] was called).
357 */
358 List<E> _inputValue = null;
359
360 /**
361 * Initialize a newly created task input builder that computes the result
362 * specified by the given [input].
363 */
364 ObjectToListTaskInputBuilder(this.input) {
365 builder = input.baseInput.createBuilder();
366 }
367
368 @override
369 ResultDescriptor get currentResult {
370 if (builder == null) {
371 return null;
372 }
373 return builder.currentResult;
374 }
375
376 @override
377 AnalysisTarget get currentTarget {
378 if (builder == null) {
379 return null;
380 }
381 return builder.currentTarget;
382 }
383
384 @override
385 void set currentValue(Object value) {
386 if (builder == null) {
387 throw new StateError(
388 'Cannot set the result value when there is no current result');
389 }
390 builder.currentValue = value;
391 }
392
393 @override
394 List<E> get inputValue {
395 if (builder != null) {
396 throw new StateError('Result value has not been created');
397 }
398 return _inputValue;
399 }
400
401 @override
402 void currentValueNotAvailable() {
403 if (builder == null) {
404 throw new StateError(
405 'Cannot set the result value when there is no current result');
406 }
407 builder.currentValueNotAvailable();
408 }
409
410 @override
411 bool moveNext() {
412 if (builder == null) {
413 return false;
414 } else if (builder.moveNext()) {
415 return true;
416 } else {
417 // This might not be the right semantics. If the value could not be
418 // computed then we pass the resulting `null` in to the mapper function.
419 // Unfortunately, we cannot tell the difference between a `null` that's
420 // there because no value could be computed and a `null` that's there
421 // because that's what *was* computed.
422 _inputValue = input.mapper(builder.inputValue);
423 builder = null;
424 return false;
425 }
426 }
427 }
428
429 /**
430 * An input to an [AnalysisTask] that is computed by accessing a single result
431 * defined on a single target.
432 */
433 class SimpleTaskInput<V> extends TaskInputImpl<V> {
434 /**
435 * The target on which the result is defined.
436 */
437 final AnalysisTarget target;
438
439 /**
440 * The result to be accessed.
441 */
442 final ResultDescriptor<V> result;
443
444 /**
445 * Initialize a newly created task input that computes the input by accessing
446 * the given [result] associated with the given [target].
447 */
448 SimpleTaskInput(this.target, this.result);
449
450 @override
451 TaskInputBuilder<V> createBuilder() => new SimpleTaskInputBuilder<V>(this);
452 }
453
454 /**
455 * A [TaskInputBuilder] used to build an input based on a [SimpleTaskInput].
456 */
457 class SimpleTaskInputBuilder<V> implements TaskInputBuilder<V> {
458 /**
459 * The state value indicating that the builder is positioned before the single
460 * result.
461 */
462 static const _BEFORE = -1;
463
464 /**
465 * The state value indicating that the builder is positioned at the single
466 * result.
467 */
468 static const _AT = 0;
469
470 /**
471 * The state value indicating that the builder is positioned after the single
472 * result.
473 */
474 static const _AFTER = 1;
475
476 /**
477 * The input being built.
478 */
479 final SimpleTaskInput<V> input;
480
481 /**
482 * The value of the input being built. `null` if the value hasn't been set
483 * yet, or if no result is available ([currentValueNotAvailable] was called).
484 */
485 V _resultValue = null;
486
487 /**
488 * The state of the builder.
489 */
490 int _state = _BEFORE;
491
492 /**
493 * A flag indicating whether the result value was explicitly set.
494 */
495 bool _resultSet = false;
496
497 /**
498 * Initialize a newly created task input builder that computes the result
499 * specified by the given [input].
500 */
501 SimpleTaskInputBuilder(this.input);
502
503 @override
504 ResultDescriptor get currentResult => _state == _AT ? input.result : null;
505
506 @override
507 AnalysisTarget get currentTarget => _state == _AT ? input.target : null;
508
509 @override
510 void set currentValue(Object value) {
511 if (_state != _AT) {
512 throw new StateError(
513 'Cannot set the result value when there is no current result');
514 }
515 _resultValue = value as V;
516 _resultSet = true;
517 }
518
519 @override
520 V get inputValue {
521 if (_state != _AFTER) {
522 throw new StateError('Result value has not been created');
523 }
524 return _resultValue;
525 }
526
527 @override
528 void currentValueNotAvailable() {
529 if (_state != _AT) {
530 throw new StateError(
531 'Cannot set the result value when there is no current result');
532 }
533 _resultValue = null;
534 _resultSet = true;
535 }
536
537 @override
538 bool moveNext() {
539 if (_state == _BEFORE) {
540 _state = _AT;
541 return true;
542 } else {
543 if (!_resultSet) {
544 throw new StateError(
545 'The value of the current result must be set before moving to the ne xt result.');
546 }
547 _state = _AFTER;
548 return false;
549 }
550 }
551 }
552
553 abstract class TaskInputImpl<V> implements TaskInput<V> {
554 @override
555 ListTaskInput /*<E>*/ mappedToList(List /*<E>*/ mapper(V value)) {
556 return new ObjectToListTaskInput(this, mapper);
557 }
558 }
559
560 /**
561 * A [TaskInputBuilder] used to build an input based on one or more other task
562 * inputs. The task inputs to be built are specified by a table mapping the name
563 * of the input to the task used to access the input's value.
564 */
565 class TopLevelTaskInputBuilder
566 implements TaskInputBuilder<Map<String, Object>> {
567 /**
568 * The descriptors describing the inputs to be built.
569 */
570 final Map<String, TaskInput> inputDescriptors;
571
572 /**
573 * The names of the inputs. There are the keys from the [inputDescriptors] in
574 * an indexable form.
575 */
576 List<String> inputNames;
577
578 /**
579 * The index of the input name associated with the current result and target.
580 */
581 int nameIndex = -1;
582
583 /**
584 * The builder used to build the current result.
585 */
586 TaskInputBuilder currentBuilder;
587
588 /**
589 * The inputs that are being or have been built. The map will be incomplete
590 * unless the method [moveNext] returns `false`.
591 */
592 final Map<String, Object> inputs = new HashMap<String, Object>();
593
594 /**
595 * Initialize a newly created task input builder to build the inputs described
596 * by the given [inputDescriptors].
597 */
598 TopLevelTaskInputBuilder(this.inputDescriptors) {
599 inputNames = inputDescriptors.keys.toList();
600 }
601
602 @override
603 ResultDescriptor get currentResult {
604 if (currentBuilder == null) {
605 return null;
606 }
607 return currentBuilder.currentResult;
608 }
609
610 @override
611 AnalysisTarget get currentTarget {
612 if (currentBuilder == null) {
613 return null;
614 }
615 return currentBuilder.currentTarget;
616 }
617
618 @override
619 void set currentValue(Object value) {
620 if (currentBuilder == null) {
621 throw new StateError(
622 'Cannot set the result value when there is no current result');
623 }
624 currentBuilder.currentValue = value;
625 }
626
627 @override
628 Map<String, Object> get inputValue {
629 if (nameIndex < inputNames.length) {
630 throw new StateError('Result value has not been created');
631 }
632 return inputs;
633 }
634
635 /**
636 * Assuming that there is a current input, return its name.
637 */
638 String get _currentName => inputNames[nameIndex];
639
640 @override
641 void currentValueNotAvailable() {
642 if (currentBuilder == null) {
643 throw new StateError(
644 'Cannot set the result value when there is no current result');
645 }
646 currentBuilder.currentValueNotAvailable();
647 }
648
649 @override
650 bool moveNext() {
651 if (nameIndex >= inputNames.length) {
652 // We have already computed all of the results, so just return false.
653 return false;
654 }
655 if (nameIndex < 0) {
656 // This is the first time moveNext has been invoked, so we just determine
657 // whether there are any results to be computed.
658 nameIndex = 0;
659 } else {
660 if (currentBuilder.moveNext()) {
661 // We are still working on building the value associated with the
662 // current name.
663 return true;
664 }
665 if (currentBuilder.inputValue != null) {
666 inputs[_currentName] = currentBuilder.inputValue;
667 }
668 nameIndex++;
669 }
670 if (nameIndex >= inputNames.length) {
671 // There is no next value, so we're done.
672 return false;
673 }
674 currentBuilder = inputDescriptors[_currentName].createBuilder();
675 // NOTE: This assumes that every builder will require at least one result
676 // value to be created. If that assumption is every broken, this method will
677 // need to be changed to advance until we find a builder that does require
678 // a result to be computed (or run out of builders).
679 return currentBuilder.moveNext();
680 }
681 }
682
683 /**
684 * An input to an [AnalysisTask] that is computed by the following steps. First
685 * another (base) task input is used to compute a [List]-valued result. An input
686 * generator function is then used to map each element of that list to a task
687 * input. Finally, each of the task inputs are used to access analysis results,
688 * and a collection of the analysis results is used as the input to the task.
689 */
690 abstract class _ListToCollectionTaskInput<B, E, C> extends TaskInputImpl<C> {
691 /**
692 * The accessor used to access the list of elements being mapped.
693 */
694 final TaskInput<List<B>> baseAccessor;
695
696 /**
697 * The function used to convert an element in the list returned by the
698 * [baseAccessor] to a task input.
699 */
700 final GenerateTaskInputs<B, E> generateTaskInputs;
701
702 /**
703 * Initialize a result accessor to use the given [baseAccessor] to access a
704 * list of values that can be passed to the given [generateTaskInputs] to
705 * generate a list of task inputs that can be used to access the elements of
706 * the input being accessed.
707 */
708 _ListToCollectionTaskInput(this.baseAccessor, this.generateTaskInputs);
709 }
710
711 /**
712 * A [TaskInputBuilder] used to build an [_ListToCollectionTaskInput].
713 */
714 abstract class _ListToCollectionTaskInputBuilder<B, E, C>
715 implements TaskInputBuilder<C> {
716 /**
717 * The input being built.
718 */
719 final _ListToCollectionTaskInput<B, E, C> input;
720
721 /**
722 * The builder used to build the current result.
723 */
724 TaskInputBuilder currentBuilder;
725
726 /**
727 * The list of values computed by the [input]'s base accessor.
728 */
729 List<B> _baseList = null;
730
731 /**
732 * The index in the [_baseList] of the value for which a value is currently
733 * being built.
734 */
735 int _baseListIndex = -1;
736
737 /**
738 * The element of the [_baseList] for which a value is currently being built.
739 */
740 B _baseListElement;
741
742 /**
743 * Initialize a newly created task input builder that computes the result
744 * specified by the given [input].
745 */
746 _ListToCollectionTaskInputBuilder(this.input);
747
748 @override
749 ResultDescriptor get currentResult {
750 if (currentBuilder == null) {
751 return null;
752 }
753 return currentBuilder.currentResult;
754 }
755
756 @override
757 AnalysisTarget get currentTarget {
758 if (currentBuilder == null) {
759 return null;
760 }
761 return currentBuilder.currentTarget;
762 }
763
764 @override
765 void set currentValue(Object value) {
766 if (currentBuilder == null) {
767 throw new StateError(
768 'Cannot set the result value when there is no current result');
769 }
770 currentBuilder.currentValue = value;
771 }
772
773 @override
774 C get inputValue {
775 if (currentBuilder != null || _resultValue == null) {
776 throw new StateError('Result value has not been created');
777 }
778 return _resultValue;
779 }
780
781 /**
782 * The list of values being built.
783 */
784 C get _resultValue;
785
786 @override
787 void currentValueNotAvailable() {
788 if (currentBuilder == null) {
789 throw new StateError(
790 'Cannot set the result value when there is no current result');
791 }
792 currentBuilder.currentValueNotAvailable();
793 }
794
795 @override
796 bool moveNext() {
797 if (currentBuilder == null) {
798 if (_resultValue == null) {
799 // This is the first time moveNext has been invoked, so start by
800 // computing the list of values from which the results will be derived.
801 currentBuilder = input.baseAccessor.createBuilder();
802 return currentBuilder.moveNext();
803 } else {
804 // We have already computed all of the results, so just return false.
805 return false;
806 }
807 }
808 if (currentBuilder.moveNext()) {
809 return true;
810 }
811 if (_resultValue == null) {
812 // We have finished computing the list of values from which the results
813 // will be derived.
814 _baseList = currentBuilder.inputValue;
815 if (_baseList == null) {
816 // No base list could be computed due to a circular dependency. Use an
817 // empty list so that no further results will be computed.
818 _baseList = [];
819 }
820 _baseListIndex = 0;
821 _initResultValue();
822 } else {
823 // We have finished computing one of the elements in the result list.
824 if (currentBuilder.inputValue != null) {
825 _addResultElement(_baseListElement, currentBuilder.inputValue);
826 }
827 _baseListIndex++;
828 }
829 if (_baseListIndex >= _baseList.length) {
830 currentBuilder = null;
831 return false;
832 }
833 _baseListElement = _baseList[_baseListIndex];
834 currentBuilder = input.generateTaskInputs(_baseListElement).createBuilder();
835 return currentBuilder.moveNext();
836 }
837
838 void _addResultElement(B baseElement, E resultElement);
839 void _initResultValue();
840 }
OLDNEW
« no previous file with comments | « analyzer/lib/src/task/incremental_element_builder.dart ('k') | analyzer/lib/src/task/manager.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698