OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 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 | 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 analyzer.src.task.inputs; | 5 library analyzer.src.task.inputs; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/task/model.dart'; | 9 import 'package:analyzer/task/model.dart'; |
10 | 10 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 */ | 82 */ |
83 ListTaskInputImpl(AnalysisTarget target, ResultDescriptor<List<E>> result) | 83 ListTaskInputImpl(AnalysisTarget target, ResultDescriptor<List<E>> result) |
84 : super._unflushable(target, result); | 84 : super._unflushable(target, result); |
85 } | 85 } |
86 | 86 |
87 /** | 87 /** |
88 * A mixin-ready implementation of [ListTaskInput]. | 88 * A mixin-ready implementation of [ListTaskInput]. |
89 */ | 89 */ |
90 abstract class ListTaskInputMixin<E> implements ListTaskInput<E> { | 90 abstract class ListTaskInputMixin<E> implements ListTaskInput<E> { |
91 @override | 91 @override |
92 ListTaskInput/*<V>*/ toFlattenListOf/*<V>*/( | 92 ListTaskInput<V> toFlattenListOf<V>(ListResultDescriptor<V> subListResult) { |
93 ListResultDescriptor/*<V>*/ subListResult) { | 93 return new ListToFlattenListTaskInput<E, V>( |
94 return new ListToFlattenListTaskInput<E, dynamic/*=V*/ >( | |
95 this, | 94 this, |
96 (E element) => | 95 (E element) => |
97 subListResult.of(element as AnalysisTarget) as TaskInput/*<V>*/); | 96 subListResult.of(element as AnalysisTarget) as TaskInput<V>); |
98 } | 97 } |
99 | 98 |
100 ListTaskInput/*<V>*/ toList/*<V>*/(UnaryFunction<E, dynamic/*=V*/ > mapper) { | 99 ListTaskInput<V> toList<V>(UnaryFunction<E, V> mapper) { |
101 return new ListToListTaskInput<E, dynamic/*=V*/ >(this, mapper); | 100 return new ListToListTaskInput<E, V>(this, mapper); |
102 } | 101 } |
103 | 102 |
104 ListTaskInput/*<V>*/ toListOf/*<V>*/(ResultDescriptor/*<V>*/ valueResult) { | 103 ListTaskInput<V> toListOf<V>(ResultDescriptor<V> valueResult) { |
105 return (this as ListTaskInput<AnalysisTarget>).toList(valueResult.of); | 104 return (this as ListTaskInput<AnalysisTarget>).toList(valueResult.of); |
106 } | 105 } |
107 | 106 |
108 MapTaskInput<E, dynamic/*=V*/ > toMap/*<V>*/( | 107 MapTaskInput<E, V> toMap<V>(UnaryFunction<E, V> mapper) { |
109 UnaryFunction<E, dynamic/*=V*/ > mapper) { | 108 return new ListToMapTaskInput<E, V>(this, mapper); |
110 return new ListToMapTaskInput<E, dynamic/*=V*/ >(this, mapper); | |
111 } | 109 } |
112 | 110 |
113 MapTaskInput<AnalysisTarget, dynamic/*=V*/ > toMapOf/*<V>*/( | 111 MapTaskInput<AnalysisTarget, V> toMapOf<V>(ResultDescriptor<V> valueResult) { |
114 ResultDescriptor/*<V>*/ valueResult) { | |
115 return (this as ListTaskInputImpl<AnalysisTarget>).toMap(valueResult.of); | 112 return (this as ListTaskInputImpl<AnalysisTarget>).toMap(valueResult.of); |
116 } | 113 } |
117 } | 114 } |
118 | 115 |
119 /** | 116 /** |
120 * An input to an [AnalysisTask] that is computed by the following steps. First | 117 * An input to an [AnalysisTask] that is computed by the following steps. First |
121 * another (base) task input is used to compute a [List]-valued result. An input | 118 * another (base) task input is used to compute a [List]-valued result. An input |
122 * generator function is then used to map each element of that list to a task | 119 * generator function is then used to map each element of that list to a task |
123 * input. Finally, each of the task inputs are used to access analysis results, | 120 * input. Finally, each of the task inputs are used to access analysis results, |
124 * and the list of the analysis results is used as the input to the task. | 121 * and the list of the analysis results is used as the input to the task. |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 @override | 269 @override |
273 void _initResultValue() { | 270 void _initResultValue() { |
274 _resultValue = new HashMap<B, E>(); | 271 _resultValue = new HashMap<B, E>(); |
275 } | 272 } |
276 } | 273 } |
277 | 274 |
278 /** | 275 /** |
279 * A mixin-ready implementation of [MapTaskInput]. | 276 * A mixin-ready implementation of [MapTaskInput]. |
280 */ | 277 */ |
281 abstract class MapTaskInputMixin<K, V> implements MapTaskInput<K, V> { | 278 abstract class MapTaskInputMixin<K, V> implements MapTaskInput<K, V> { |
282 TaskInput<List/*<E>*/ > toFlattenList/*<E>*/( | 279 TaskInput<List<E>> toFlattenList<E>( |
283 BinaryFunction<K, dynamic /*element of V*/, dynamic/*=E*/ > mapper) { | 280 BinaryFunction<K, dynamic /*element of V*/, E> mapper) { |
284 return new MapToFlattenListTaskInput<K, dynamic /*element of V*/, | 281 return new MapToFlattenListTaskInput<K, dynamic /*element of V*/, E>( |
285 dynamic/*=E*/ >( | |
286 this as MapTaskInput<K, List /*element of V*/ >, mapper); | 282 this as MapTaskInput<K, List /*element of V*/ >, mapper); |
287 } | 283 } |
288 } | 284 } |
289 | 285 |
290 /** | 286 /** |
291 * A [TaskInput] that is computed by the following steps. | 287 * A [TaskInput] that is computed by the following steps. |
292 * | 288 * |
293 * First the [base] task input is used to compute a [Map]-valued result. | 289 * First the [base] task input is used to compute a [Map]-valued result. |
294 * The values of the [Map] must be [List]s. | 290 * The values of the [Map] must be [List]s. |
295 * | 291 * |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 currentBuilder.currentValueNotAvailable(); | 362 currentBuilder.currentValueNotAvailable(); |
367 } | 363 } |
368 | 364 |
369 @override | 365 @override |
370 bool moveNext() { | 366 bool moveNext() { |
371 // Prepare base Map. | 367 // Prepare base Map. |
372 if (baseMap == null) { | 368 if (baseMap == null) { |
373 if (currentBuilder.moveNext()) { | 369 if (currentBuilder.moveNext()) { |
374 return true; | 370 return true; |
375 } | 371 } |
376 baseMap = currentBuilder.inputValue as dynamic/*=Map<K, List<V>>*/; | 372 baseMap = currentBuilder.inputValue as Map<K, List<V>>; |
377 if (baseMap == null) { | 373 if (baseMap == null) { |
378 // No base map could be computed due to a circular dependency. Use an | 374 // No base map could be computed due to a circular dependency. Use an |
379 // empty map so that no further results will be computed. | 375 // empty map so that no further results will be computed. |
380 baseMap = {}; | 376 baseMap = {}; |
381 } | 377 } |
382 keyIterator = baseMap.keys.iterator; | 378 keyIterator = baseMap.keys.iterator; |
383 // Done with this builder. | 379 // Done with this builder. |
384 currentBuilder = null; | 380 currentBuilder = null; |
385 } | 381 } |
386 // Prepare the next result value. | 382 // Prepare the next result value. |
387 if (currentBuilder != null) { | 383 if (currentBuilder != null) { |
388 if (currentBuilder.moveNext()) { | 384 if (currentBuilder.moveNext()) { |
389 return true; | 385 return true; |
390 } | 386 } |
391 // Add the result value for the current Map key/value. | 387 // Add the result value for the current Map key/value. |
392 E resultValue = currentBuilder.inputValue as dynamic/*=E*/; | 388 E resultValue = currentBuilder.inputValue as E; |
393 if (resultValue != null) { | 389 if (resultValue != null) { |
394 inputValue.add(resultValue); | 390 inputValue.add(resultValue); |
395 } | 391 } |
396 // Done with this builder. | 392 // Done with this builder. |
397 currentBuilder = null; | 393 currentBuilder = null; |
398 } | 394 } |
399 // Move to the next Map value. | 395 // Move to the next Map value. |
400 if (valueIterator != null && valueIterator.moveNext()) { | 396 if (valueIterator != null && valueIterator.moveNext()) { |
401 K key = keyIterator.current; | 397 K key = keyIterator.current; |
402 V value = valueIterator.current; | 398 V value = valueIterator.current; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 * Initialize a newly created task input that computes the input by accessing | 433 * Initialize a newly created task input that computes the input by accessing |
438 * the given [baseInput] associated with the given [mapper]. | 434 * the given [baseInput] associated with the given [mapper]. |
439 */ | 435 */ |
440 ObjectToListTaskInput(this.baseInput, this.mapper); | 436 ObjectToListTaskInput(this.baseInput, this.mapper); |
441 | 437 |
442 @override | 438 @override |
443 TaskInputBuilder<List<E>> createBuilder() => | 439 TaskInputBuilder<List<E>> createBuilder() => |
444 new ObjectToListTaskInputBuilder<E>(this); | 440 new ObjectToListTaskInputBuilder<E>(this); |
445 | 441 |
446 @override | 442 @override |
447 ListTaskInput/*<V>*/ toFlattenListOf/*<V>*/( | 443 ListTaskInput<V> toFlattenListOf<V>(ListResultDescriptor<V> subListResult) { |
448 ListResultDescriptor/*<V>*/ subListResult) { | 444 return new ListToFlattenListTaskInput<E, V>( |
449 return new ListToFlattenListTaskInput<E, dynamic/*=V*/ >( | |
450 this, | 445 this, |
451 (E element) => | 446 (E element) => |
452 subListResult.of(element as AnalysisTarget) as TaskInput/*<V>*/); | 447 subListResult.of(element as AnalysisTarget) as TaskInput<V>); |
453 } | 448 } |
454 | 449 |
455 @override | 450 @override |
456 ListTaskInput/*<V>*/ toListOf/*<V>*/(ResultDescriptor/*<V>*/ valueResult) { | 451 ListTaskInput<V> toListOf<V>(ResultDescriptor<V> valueResult) { |
457 return new ListToListTaskInput<E, dynamic/*=V*/ >( | 452 return new ListToListTaskInput<E, V>( |
458 this, (E element) => valueResult.of(element as AnalysisTarget)); | 453 this, (E element) => valueResult.of(element as AnalysisTarget)); |
459 } | 454 } |
460 | 455 |
461 @override | 456 @override |
462 MapTaskInput<AnalysisTarget, dynamic/*=V*/ > toMapOf/*<V>*/( | 457 MapTaskInput<AnalysisTarget, V> toMapOf<V>(ResultDescriptor<V> valueResult) { |
463 ResultDescriptor/*<V>*/ valueResult) { | 458 return new ListToMapTaskInput<AnalysisTarget, V>( |
464 return new ListToMapTaskInput<AnalysisTarget, dynamic/*=V*/ >( | 459 this as TaskInput<List<AnalysisTarget>>, valueResult.of); |
465 this as dynamic/*=TaskInput<List<AnalysisTarget>>*/, valueResult.of); | |
466 } | 460 } |
467 } | 461 } |
468 | 462 |
469 /** | 463 /** |
470 * A [TaskInputBuilder] used to build an input based on a [SimpleTaskInput]. | 464 * A [TaskInputBuilder] used to build an input based on a [SimpleTaskInput]. |
471 */ | 465 */ |
472 class ObjectToListTaskInputBuilder<E> implements TaskInputBuilder<List<E>> { | 466 class ObjectToListTaskInputBuilder<E> implements TaskInputBuilder<List<E>> { |
473 /** | 467 /** |
474 * The input being built. | 468 * The input being built. |
475 */ | 469 */ |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 'The value of the current result must be set before moving to the ne
xt result.'); | 687 'The value of the current result must be set before moving to the ne
xt result.'); |
694 } | 688 } |
695 _state = _AFTER; | 689 _state = _AFTER; |
696 return false; | 690 return false; |
697 } | 691 } |
698 } | 692 } |
699 } | 693 } |
700 | 694 |
701 abstract class TaskInputImpl<V> implements TaskInput<V> { | 695 abstract class TaskInputImpl<V> implements TaskInput<V> { |
702 @override | 696 @override |
703 ListTaskInput/*<E>*/ mappedToList/*<E>*/(List/*<E>*/ mapper(V value)) { | 697 ListTaskInput<E> mappedToList<E>(List<E> mapper(V value)) { |
704 return new ObjectToListTaskInput( | 698 return new ObjectToListTaskInput( |
705 this, (Object element) => mapper(element as V)); | 699 this, (Object element) => mapper(element as V)); |
706 } | 700 } |
707 } | 701 } |
708 | 702 |
709 /** | 703 /** |
710 * A [TaskInputBuilder] used to build an input based on one or more other task | 704 * A [TaskInputBuilder] used to build an input based on one or more other task |
711 * inputs. The task inputs to be built are specified by a table mapping the name | 705 * inputs. The task inputs to be built are specified by a table mapping the name |
712 * of the input to the task used to access the input's value. | 706 * of the input to the task used to access the input's value. |
713 */ | 707 */ |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 // We have already computed all of the results, so just return false. | 960 // We have already computed all of the results, so just return false. |
967 return false; | 961 return false; |
968 } | 962 } |
969 } | 963 } |
970 if (currentBuilder.moveNext()) { | 964 if (currentBuilder.moveNext()) { |
971 return true; | 965 return true; |
972 } | 966 } |
973 if (_resultValue == null) { | 967 if (_resultValue == null) { |
974 // We have finished computing the list of values from which the results | 968 // We have finished computing the list of values from which the results |
975 // will be derived. | 969 // will be derived. |
976 _baseList = currentBuilder.inputValue as dynamic/*=List<B>*/; | 970 _baseList = currentBuilder.inputValue as List<B>; |
977 if (_baseList == null) { | 971 if (_baseList == null) { |
978 // No base list could be computed due to a circular dependency. Use an | 972 // No base list could be computed due to a circular dependency. Use an |
979 // empty list so that no further results will be computed. | 973 // empty list so that no further results will be computed. |
980 _baseList = []; | 974 _baseList = []; |
981 } | 975 } |
982 _baseListIndex = 0; | 976 _baseListIndex = 0; |
983 _initResultValue(); | 977 _initResultValue(); |
984 } else { | 978 } else { |
985 // We have finished computing one of the elements in the result list. | 979 // We have finished computing one of the elements in the result list. |
986 if (currentBuilder.inputValue != null) { | 980 if (currentBuilder.inputValue != null) { |
987 _addResultElement( | 981 _addResultElement(_baseListElement, currentBuilder.inputValue as E); |
988 _baseListElement, currentBuilder.inputValue as dynamic/*=E*/); | |
989 } | 982 } |
990 _baseListIndex++; | 983 _baseListIndex++; |
991 } | 984 } |
992 if (_baseListIndex >= _baseList.length) { | 985 if (_baseListIndex >= _baseList.length) { |
993 currentBuilder = null; | 986 currentBuilder = null; |
994 return false; | 987 return false; |
995 } | 988 } |
996 _baseListElement = _baseList[_baseListIndex]; | 989 _baseListElement = _baseList[_baseListIndex]; |
997 currentBuilder = input.generateTaskInputs(_baseListElement).createBuilder(); | 990 currentBuilder = input.generateTaskInputs(_baseListElement).createBuilder(); |
998 return currentBuilder.moveNext(); | 991 return currentBuilder.moveNext(); |
999 } | 992 } |
1000 | 993 |
1001 void _addResultElement(B baseElement, E resultElement); | 994 void _addResultElement(B baseElement, E resultElement); |
1002 void _initResultValue(); | 995 void _initResultValue(); |
1003 } | 996 } |
OLD | NEW |