| 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 21 matching lines...) Expand all Loading... |
| 32 @override | 32 @override |
| 33 TaskInputBuilder<V> createBuilder() { | 33 TaskInputBuilder<V> createBuilder() { |
| 34 return new ConstantTaskInputBuilder<V>(this); | 34 return new ConstantTaskInputBuilder<V>(this); |
| 35 } | 35 } |
| 36 } | 36 } |
| 37 | 37 |
| 38 /** | 38 /** |
| 39 * A [TaskInputBuilder] used to build an input based on a [ConstantTaskInput]. | 39 * A [TaskInputBuilder] used to build an input based on a [ConstantTaskInput]. |
| 40 */ | 40 */ |
| 41 class ConstantTaskInputBuilder<V> implements TaskInputBuilder<V> { | 41 class ConstantTaskInputBuilder<V> implements TaskInputBuilder<V> { |
| 42 final ConstantTaskInput input; | 42 final ConstantTaskInput<V> input; |
| 43 | 43 |
| 44 ConstantTaskInputBuilder(this.input); | 44 ConstantTaskInputBuilder(this.input); |
| 45 | 45 |
| 46 @override | 46 @override |
| 47 ResultDescriptor get currentResult => null; | 47 ResultDescriptor get currentResult => null; |
| 48 | 48 |
| 49 @override | 49 @override |
| 50 AnalysisTarget get currentTarget => null; | 50 AnalysisTarget get currentTarget => null; |
| 51 | 51 |
| 52 @override | 52 @override |
| (...skipping 28 matching lines...) Expand all Loading... |
| 81 * the given [result] associated with the given [target]. | 81 * the given [result] associated with the given [target]. |
| 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 ListTaskInput /*<V>*/ toList(UnaryFunction<E, dynamic /*<V>*/ > mapper) { | 91 @override |
| 92 return new ListToListTaskInput<E, dynamic /*V*/ >(this, mapper); | 92 ListTaskInput/*<V>*/ toFlattenListOf/*<V>*/( |
| 93 ListResultDescriptor/*<V>*/ subListResult) { |
| 94 return new ListToFlattenListTaskInput<E, dynamic/*=V*/ >( |
| 95 this, |
| 96 (E element) => |
| 97 subListResult.of(element as AnalysisTarget) as TaskInput/*<V>*/); |
| 93 } | 98 } |
| 94 | 99 |
| 95 ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult) { | 100 ListTaskInput/*<V>*/ toList/*<V>*/(UnaryFunction<E, dynamic/*=V*/ > mapper) { |
| 96 return (this as ListTaskInputImpl<AnalysisTarget>).toList(valueResult.of); | 101 return new ListToListTaskInput<E, dynamic/*=V*/ >(this, mapper); |
| 97 } | 102 } |
| 98 | 103 |
| 99 MapTaskInput<E, dynamic /*V*/ > toMap( | 104 ListTaskInput/*<V>*/ toListOf/*<V>*/(ResultDescriptor/*<V>*/ valueResult) { |
| 100 UnaryFunction<E, dynamic /*<V>*/ > mapper) { | 105 return (this as ListTaskInput<AnalysisTarget>).toList(valueResult.of); |
| 101 return new ListToMapTaskInput<E, dynamic /*V*/ >(this, mapper); | |
| 102 } | 106 } |
| 103 | 107 |
| 104 MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf( | 108 MapTaskInput<E, dynamic/*=V*/ > toMap/*<V>*/( |
| 105 ResultDescriptor /*<V>*/ valueResult) { | 109 UnaryFunction<E, dynamic/*=V*/ > mapper) { |
| 110 return new ListToMapTaskInput<E, dynamic/*=V*/ >(this, mapper); |
| 111 } |
| 112 |
| 113 MapTaskInput<AnalysisTarget, dynamic/*=V*/ > toMapOf/*<V>*/( |
| 114 ResultDescriptor/*<V>*/ valueResult) { |
| 106 return (this as ListTaskInputImpl<AnalysisTarget>).toMap(valueResult.of); | 115 return (this as ListTaskInputImpl<AnalysisTarget>).toMap(valueResult.of); |
| 107 } | 116 } |
| 108 } | 117 } |
| 109 | 118 |
| 110 /** | 119 /** |
| 111 * An input to an [AnalysisTask] that is computed by the following steps. First | 120 * An input to an [AnalysisTask] that is computed by the following steps. First |
| 112 * another (base) task input is used to compute a [List]-valued result. An input | 121 * 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 |
| 123 * 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. |
| 125 */ |
| 126 class ListToFlattenListTaskInput<B, E> |
| 127 extends _ListToCollectionTaskInput<B, E, List<E>> |
| 128 with ListTaskInputMixin<E> |
| 129 implements ListTaskInput<E> { |
| 130 /** |
| 131 * Initialize a result accessor to use the given [baseAccessor] to access a |
| 132 * list of values that can be passed to the given [generateTaskInputs] to |
| 133 * generate a list of task inputs that can be used to access the elements of |
| 134 * the input being accessed. |
| 135 */ |
| 136 ListToFlattenListTaskInput(TaskInput<List<B>> baseAccessor, |
| 137 GenerateTaskInputs<B, E> generateTaskInputs) |
| 138 : super(baseAccessor, generateTaskInputs); |
| 139 |
| 140 @override |
| 141 TaskInputBuilder<List<E>> createBuilder() => |
| 142 new ListToFlattenListTaskInputBuilder<B, E>(this); |
| 143 } |
| 144 |
| 145 /** |
| 146 * A [TaskInputBuilder] used to build an input based on a [ListToFlattenListTask
Input]. |
| 147 */ |
| 148 class ListToFlattenListTaskInputBuilder<B, E> |
| 149 extends _ListToCollectionTaskInputBuilder<B, E, List<E>> { |
| 150 /** |
| 151 * The list of values being built. |
| 152 */ |
| 153 List<E> _resultValue; |
| 154 |
| 155 /** |
| 156 * Initialize a newly created task input builder that computes the result |
| 157 * specified by the given [input]. |
| 158 */ |
| 159 ListToFlattenListTaskInputBuilder(ListToFlattenListTaskInput<B, E> input) |
| 160 : super(input); |
| 161 |
| 162 @override |
| 163 void _addResultElement(B baseElement, E resultElement) { |
| 164 _resultValue.addAll(resultElement as Iterable<E>); |
| 165 } |
| 166 |
| 167 @override |
| 168 void _initResultValue() { |
| 169 _resultValue = <E>[]; |
| 170 } |
| 171 } |
| 172 |
| 173 /** |
| 174 * An input to an [AnalysisTask] that is computed by the following steps. First |
| 175 * another (base) task input is used to compute a [List]-valued result. An input |
| 113 * generator function is then used to map each element of that list to a task | 176 * generator function is then used to map each element of that list to a task |
| 114 * input. Finally, each of the task inputs are used to access analysis results, | 177 * input. Finally, each of the task inputs are used to access analysis results, |
| 115 * and the list of the analysis results is used as the input to the task. | 178 * and the list of the analysis results is used as the input to the task. |
| 116 */ | 179 */ |
| 117 class ListToListTaskInput<B, E> | 180 class ListToListTaskInput<B, E> |
| 118 extends _ListToCollectionTaskInput<B, E, List<E>> | 181 extends _ListToCollectionTaskInput<B, E, List<E>> |
| 119 with ListTaskInputMixin<E> { | 182 with ListTaskInputMixin<E> { |
| 120 /** | 183 /** |
| 121 * Initialize a result accessor to use the given [baseAccessor] to access a | 184 * Initialize a result accessor to use the given [baseAccessor] to access a |
| 122 * list of values that can be passed to the given [generateTaskInputs] to | 185 * list of values that can be passed to the given [generateTaskInputs] to |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 @override | 272 @override |
| 210 void _initResultValue() { | 273 void _initResultValue() { |
| 211 _resultValue = new HashMap<B, E>(); | 274 _resultValue = new HashMap<B, E>(); |
| 212 } | 275 } |
| 213 } | 276 } |
| 214 | 277 |
| 215 /** | 278 /** |
| 216 * A mixin-ready implementation of [MapTaskInput]. | 279 * A mixin-ready implementation of [MapTaskInput]. |
| 217 */ | 280 */ |
| 218 abstract class MapTaskInputMixin<K, V> implements MapTaskInput<K, V> { | 281 abstract class MapTaskInputMixin<K, V> implements MapTaskInput<K, V> { |
| 219 TaskInput<List /*<E>*/ > toFlattenList( | 282 TaskInput<List/*<E>*/ > toFlattenList/*<E>*/( |
| 220 BinaryFunction<K, dynamic /*element of V*/, dynamic /*<E>*/ > mapper) { | 283 BinaryFunction<K, dynamic /*element of V*/, dynamic/*=E*/ > mapper) { |
| 221 return new MapToFlattenListTaskInput<K, dynamic /*element of V*/, | 284 return new MapToFlattenListTaskInput<K, dynamic /*element of V*/, |
| 222 dynamic /*E*/ >( | 285 dynamic/*=E*/ >(this as MapTaskInput<K, List /*element of V*/ >, mapper)
; |
| 223 this as MapTaskInput<K, List /*<element of V>*/ >, mapper); | |
| 224 } | 286 } |
| 225 } | 287 } |
| 226 | 288 |
| 227 /** | 289 /** |
| 228 * A [TaskInput] that is computed by the following steps. | 290 * A [TaskInput] that is computed by the following steps. |
| 229 * | 291 * |
| 230 * First the [base] task input is used to compute a [Map]-valued result. | 292 * First the [base] task input is used to compute a [Map]-valued result. |
| 231 * The values of the [Map] must be [List]s. | 293 * The values of the [Map] must be [List]s. |
| 232 * | 294 * |
| 233 * The given [mapper] is used to transform each key / value pair of the [Map] | 295 * The given [mapper] is used to transform each key / value pair of the [Map] |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 currentBuilder.currentValueNotAvailable(); | 365 currentBuilder.currentValueNotAvailable(); |
| 304 } | 366 } |
| 305 | 367 |
| 306 @override | 368 @override |
| 307 bool moveNext() { | 369 bool moveNext() { |
| 308 // Prepare base Map. | 370 // Prepare base Map. |
| 309 if (baseMap == null) { | 371 if (baseMap == null) { |
| 310 if (currentBuilder.moveNext()) { | 372 if (currentBuilder.moveNext()) { |
| 311 return true; | 373 return true; |
| 312 } | 374 } |
| 313 baseMap = currentBuilder.inputValue; | 375 baseMap = currentBuilder.inputValue as dynamic/*=Map<K, List<V>>*/; |
| 314 if (baseMap == null) { | 376 if (baseMap == null) { |
| 315 // No base map could be computed due to a circular dependency. Use an | 377 // No base map could be computed due to a circular dependency. Use an |
| 316 // empty map so that no further results will be computed. | 378 // empty map so that no further results will be computed. |
| 317 baseMap = {}; | 379 baseMap = {}; |
| 318 } | 380 } |
| 319 keyIterator = baseMap.keys.iterator; | 381 keyIterator = baseMap.keys.iterator; |
| 320 // Done with this builder. | 382 // Done with this builder. |
| 321 currentBuilder = null; | 383 currentBuilder = null; |
| 322 } | 384 } |
| 323 // Prepare the next result value. | 385 // Prepare the next result value. |
| 324 if (currentBuilder != null) { | 386 if (currentBuilder != null) { |
| 325 if (currentBuilder.moveNext()) { | 387 if (currentBuilder.moveNext()) { |
| 326 return true; | 388 return true; |
| 327 } | 389 } |
| 328 // Add the result value for the current Map key/value. | 390 // Add the result value for the current Map key/value. |
| 329 E resultValue = currentBuilder.inputValue; | 391 E resultValue = currentBuilder.inputValue as dynamic/*=E*/; |
| 330 if (resultValue != null) { | 392 if (resultValue != null) { |
| 331 inputValue.add(resultValue); | 393 inputValue.add(resultValue); |
| 332 } | 394 } |
| 333 // Done with this builder. | 395 // Done with this builder. |
| 334 currentBuilder = null; | 396 currentBuilder = null; |
| 335 } | 397 } |
| 336 // Move to the next Map value. | 398 // Move to the next Map value. |
| 337 if (valueIterator != null && valueIterator.moveNext()) { | 399 if (valueIterator != null && valueIterator.moveNext()) { |
| 338 K key = keyIterator.current; | 400 K key = keyIterator.current; |
| 339 V value = valueIterator.current; | 401 V value = valueIterator.current; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 351 } | 413 } |
| 352 } | 414 } |
| 353 | 415 |
| 354 /** | 416 /** |
| 355 * An input to an [AnalysisTask] that is computed by mapping the value of | 417 * An input to an [AnalysisTask] that is computed by mapping the value of |
| 356 * another task input to a list of values. | 418 * another task input to a list of values. |
| 357 */ | 419 */ |
| 358 class ObjectToListTaskInput<E> extends TaskInputImpl<List<E>> | 420 class ObjectToListTaskInput<E> extends TaskInputImpl<List<E>> |
| 359 with ListTaskInputMixin<E> | 421 with ListTaskInputMixin<E> |
| 360 implements ListTaskInput<E> { | 422 implements ListTaskInput<E> { |
| 423 // TODO(brianwilkerson) Add another type parameter to this class that can be |
| 424 // used as the type of the keys of [mapper]. |
| 361 /** | 425 /** |
| 362 * The input used to compute the value to be mapped. | 426 * The input used to compute the value to be mapped. |
| 363 */ | 427 */ |
| 364 final TaskInput baseInput; | 428 final TaskInput baseInput; |
| 365 | 429 |
| 366 /** | 430 /** |
| 367 * The function used to map the value of the base input to the list of values. | 431 * The function used to map the value of the base input to the list of values. |
| 368 */ | 432 */ |
| 369 final Mapper<Object, List<E>> mapper; | 433 final Mapper<Object, List<E>> mapper; |
| 370 | 434 |
| 371 /** | 435 /** |
| 372 * Initialize a newly created task input that computes the input by accessing | 436 * Initialize a newly created task input that computes the input by accessing |
| 373 * the given [result] associated with the given [target]. | 437 * the given [baseInput] associated with the given [mapper]. |
| 374 */ | 438 */ |
| 375 ObjectToListTaskInput(this.baseInput, this.mapper); | 439 ObjectToListTaskInput(this.baseInput, this.mapper); |
| 376 | 440 |
| 377 @override | 441 @override |
| 378 TaskInputBuilder<List<E>> createBuilder() => | 442 TaskInputBuilder<List<E>> createBuilder() => |
| 379 new ObjectToListTaskInputBuilder<E>(this); | 443 new ObjectToListTaskInputBuilder<E>(this); |
| 380 | 444 |
| 381 @override | 445 @override |
| 382 ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult) { | 446 ListTaskInput/*<V>*/ toFlattenListOf/*<V>*/( |
| 383 return new ListToListTaskInput<E, dynamic /*V*/ >( | 447 ListResultDescriptor/*<V>*/ subListResult) { |
| 384 this, valueResult.of as dynamic); | 448 return new ListToFlattenListTaskInput<E, dynamic/*=V*/ >( |
| 449 this, |
| 450 (E element) => |
| 451 subListResult.of(element as AnalysisTarget) as TaskInput/*<V>*/); |
| 385 } | 452 } |
| 386 | 453 |
| 387 @override | 454 @override |
| 388 MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf( | 455 ListTaskInput/*<V>*/ toListOf/*<V>*/(ResultDescriptor/*<V>*/ valueResult) { |
| 389 ResultDescriptor /*<V>*/ valueResult) { | 456 return new ListToListTaskInput<E, dynamic/*=V*/ >( |
| 390 return new ListToMapTaskInput<AnalysisTarget, dynamic /*V*/ >( | 457 this, (E element) => valueResult.of(element as AnalysisTarget)); |
| 391 this as dynamic, valueResult.of); | 458 } |
| 459 |
| 460 @override |
| 461 MapTaskInput<AnalysisTarget, dynamic/*=V*/ > toMapOf/*<V>*/( |
| 462 ResultDescriptor/*<V>*/ valueResult) { |
| 463 return new ListToMapTaskInput<AnalysisTarget, dynamic/*=V*/ >( |
| 464 this as dynamic/*=TaskInput<List<AnalysisTarget>>*/, valueResult.of); |
| 392 } | 465 } |
| 393 } | 466 } |
| 394 | 467 |
| 395 /** | 468 /** |
| 396 * A [TaskInputBuilder] used to build an input based on a [SimpleTaskInput]. | 469 * A [TaskInputBuilder] used to build an input based on a [SimpleTaskInput]. |
| 397 */ | 470 */ |
| 398 class ObjectToListTaskInputBuilder<E> implements TaskInputBuilder<List<E>> { | 471 class ObjectToListTaskInputBuilder<E> implements TaskInputBuilder<List<E>> { |
| 399 /** | 472 /** |
| 400 * The input being built. | 473 * The input being built. |
| 401 */ | 474 */ |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 'The value of the current result must be set before moving to the ne
xt result.'); | 692 'The value of the current result must be set before moving to the ne
xt result.'); |
| 620 } | 693 } |
| 621 _state = _AFTER; | 694 _state = _AFTER; |
| 622 return false; | 695 return false; |
| 623 } | 696 } |
| 624 } | 697 } |
| 625 } | 698 } |
| 626 | 699 |
| 627 abstract class TaskInputImpl<V> implements TaskInput<V> { | 700 abstract class TaskInputImpl<V> implements TaskInput<V> { |
| 628 @override | 701 @override |
| 629 ListTaskInput /*<E>*/ mappedToList(List /*<E>*/ mapper(V value)) { | 702 ListTaskInput/*<E>*/ mappedToList/*<E>*/(List/*<E>*/ mapper(V value)) { |
| 630 return new ObjectToListTaskInput(this, mapper); | 703 return new ObjectToListTaskInput( |
| 704 this, (Object element) => mapper(element as V)); |
| 631 } | 705 } |
| 632 } | 706 } |
| 633 | 707 |
| 634 /** | 708 /** |
| 635 * A [TaskInputBuilder] used to build an input based on one or more other task | 709 * A [TaskInputBuilder] used to build an input based on one or more other task |
| 636 * inputs. The task inputs to be built are specified by a table mapping the name | 710 * inputs. The task inputs to be built are specified by a table mapping the name |
| 637 * of the input to the task used to access the input's value. | 711 * of the input to the task used to access the input's value. |
| 638 */ | 712 */ |
| 639 class TopLevelTaskInputBuilder | 713 class TopLevelTaskInputBuilder |
| 640 implements TaskInputBuilder<Map<String, Object>> { | 714 implements TaskInputBuilder<Map<String, Object>> { |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 891 // We have already computed all of the results, so just return false. | 965 // We have already computed all of the results, so just return false. |
| 892 return false; | 966 return false; |
| 893 } | 967 } |
| 894 } | 968 } |
| 895 if (currentBuilder.moveNext()) { | 969 if (currentBuilder.moveNext()) { |
| 896 return true; | 970 return true; |
| 897 } | 971 } |
| 898 if (_resultValue == null) { | 972 if (_resultValue == null) { |
| 899 // We have finished computing the list of values from which the results | 973 // We have finished computing the list of values from which the results |
| 900 // will be derived. | 974 // will be derived. |
| 901 _baseList = currentBuilder.inputValue; | 975 _baseList = currentBuilder.inputValue as dynamic/*=List<B>*/; |
| 902 if (_baseList == null) { | 976 if (_baseList == null) { |
| 903 // No base list could be computed due to a circular dependency. Use an | 977 // No base list could be computed due to a circular dependency. Use an |
| 904 // empty list so that no further results will be computed. | 978 // empty list so that no further results will be computed. |
| 905 _baseList = []; | 979 _baseList = []; |
| 906 } | 980 } |
| 907 _baseListIndex = 0; | 981 _baseListIndex = 0; |
| 908 _initResultValue(); | 982 _initResultValue(); |
| 909 } else { | 983 } else { |
| 910 // We have finished computing one of the elements in the result list. | 984 // We have finished computing one of the elements in the result list. |
| 911 if (currentBuilder.inputValue != null) { | 985 if (currentBuilder.inputValue != null) { |
| 912 _addResultElement(_baseListElement, currentBuilder.inputValue); | 986 _addResultElement( |
| 987 _baseListElement, currentBuilder.inputValue as dynamic/*=E*/); |
| 913 } | 988 } |
| 914 _baseListIndex++; | 989 _baseListIndex++; |
| 915 } | 990 } |
| 916 if (_baseListIndex >= _baseList.length) { | 991 if (_baseListIndex >= _baseList.length) { |
| 917 currentBuilder = null; | 992 currentBuilder = null; |
| 918 return false; | 993 return false; |
| 919 } | 994 } |
| 920 _baseListElement = _baseList[_baseListIndex]; | 995 _baseListElement = _baseList[_baseListIndex]; |
| 921 currentBuilder = input.generateTaskInputs(_baseListElement).createBuilder(); | 996 currentBuilder = input.generateTaskInputs(_baseListElement).createBuilder(); |
| 922 return currentBuilder.moveNext(); | 997 return currentBuilder.moveNext(); |
| 923 } | 998 } |
| 924 | 999 |
| 925 void _addResultElement(B baseElement, E resultElement); | 1000 void _addResultElement(B baseElement, E resultElement); |
| 926 void _initResultValue(); | 1001 void _initResultValue(); |
| 927 } | 1002 } |
| OLD | NEW |