| 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 |
| 11 /** | 11 /** |
| 12 * A function that converts an object of the type [B] into a [TaskInput]. | 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 | 13 * This is used, for example, by a [ListToListTaskInput] to create task inputs |
| 14 * for each value in a list of values. | 14 * for each value in a list of values. |
| 15 */ | 15 */ |
| 16 typedef TaskInput<E> GenerateTaskInputs<B, E>(B object); | 16 typedef TaskInput<E> GenerateTaskInputs<B, E>(B object); |
| 17 | 17 |
| 18 /** | 18 /** |
| 19 * A function that maps one [value] to another value. |
| 20 */ |
| 21 typedef R Mapper<P, R>(P value); |
| 22 |
| 23 /** |
| 19 * An input to an [AnalysisTask] that is computed by accessing a single result | 24 * An input to an [AnalysisTask] that is computed by accessing a single result |
| 20 * defined on a single target. | 25 * defined on a single target. |
| 21 */ | 26 */ |
| 22 class ListTaskInputImpl<E> extends SimpleTaskInput<List<E>> | 27 class ListTaskInputImpl<E> extends SimpleTaskInput<List<E>> |
| 23 with ListTaskInputMixin<E> implements ListTaskInput<E> { | 28 with ListTaskInputMixin<E> implements ListTaskInput<E> { |
| 24 /** | 29 /** |
| 25 * Initialize a newly created task input that computes the input by accessing | 30 * Initialize a newly created task input that computes the input by accessing |
| 26 * the given [result] associated with the given [target]. | 31 * the given [result] associated with the given [target]. |
| 27 */ | 32 */ |
| 28 ListTaskInputImpl(AnalysisTarget target, ResultDescriptor<List<E>> result) | 33 ListTaskInputImpl(AnalysisTarget target, ResultDescriptor<List<E>> result) |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 * | 178 * |
| 174 * First the [base] task input is used to compute a [Map]-valued result. | 179 * First the [base] task input is used to compute a [Map]-valued result. |
| 175 * The values of the [Map] must be [List]s. | 180 * The values of the [Map] must be [List]s. |
| 176 * | 181 * |
| 177 * The given [mapper] is used to transform each key / value pair of the [Map] | 182 * The given [mapper] is used to transform each key / value pair of the [Map] |
| 178 * into task inputs. | 183 * into task inputs. |
| 179 * | 184 * |
| 180 * Finally, each of the task inputs are used to access analysis results, | 185 * Finally, each of the task inputs are used to access analysis results, |
| 181 * and the list of the results is used as the input. | 186 * and the list of the results is used as the input. |
| 182 */ | 187 */ |
| 183 class MapToFlattenListTaskInput<K, V, E> implements TaskInput<List<E>> { | 188 class MapToFlattenListTaskInput<K, V, E> extends TaskInputImpl<List<E>> { |
| 184 final MapTaskInput<K, List<V>> base; | 189 final MapTaskInput<K, List<V>> base; |
| 185 final BinaryFunction<K, V, E> mapper; | 190 final BinaryFunction<K, V, E> mapper; |
| 186 | 191 |
| 187 MapToFlattenListTaskInput(this.base, this.mapper); | 192 MapToFlattenListTaskInput(this.base, this.mapper); |
| 188 | 193 |
| 189 @override | 194 @override |
| 190 TaskInputBuilder<List<E>> createBuilder() { | 195 TaskInputBuilder<List<E>> createBuilder() { |
| 191 return new MapToFlattenListTaskInputBuilder<K, V, E>(base, mapper); | 196 return new MapToFlattenListTaskInputBuilder<K, V, E>(base, mapper); |
| 192 } | 197 } |
| 193 } | 198 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 K key = keyIterator.current; | 291 K key = keyIterator.current; |
| 287 valueIterator = baseMap[key].iterator; | 292 valueIterator = baseMap[key].iterator; |
| 288 return moveNext(); | 293 return moveNext(); |
| 289 } | 294 } |
| 290 // No more Map values/keys to transform. | 295 // No more Map values/keys to transform. |
| 291 return false; | 296 return false; |
| 292 } | 297 } |
| 293 } | 298 } |
| 294 | 299 |
| 295 /** | 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 with ListTaskInputMixin<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, 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 /** |
| 296 * An input to an [AnalysisTask] that is computed by accessing a single result | 430 * An input to an [AnalysisTask] that is computed by accessing a single result |
| 297 * defined on a single target. | 431 * defined on a single target. |
| 298 */ | 432 */ |
| 299 class SimpleTaskInput<V> implements TaskInput<V> { | 433 class SimpleTaskInput<V> extends TaskInputImpl<V> { |
| 300 /** | 434 /** |
| 301 * The target on which the result is defined. | 435 * The target on which the result is defined. |
| 302 */ | 436 */ |
| 303 final AnalysisTarget target; | 437 final AnalysisTarget target; |
| 304 | 438 |
| 305 /** | 439 /** |
| 306 * The result to be accessed. | 440 * The result to be accessed. |
| 307 */ | 441 */ |
| 308 final ResultDescriptor<V> result; | 442 final ResultDescriptor<V> result; |
| 309 | 443 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 if (!_resultSet) { | 543 if (!_resultSet) { |
| 410 throw new StateError( | 544 throw new StateError( |
| 411 'The value of the current result must be set before moving to the ne
xt result.'); | 545 'The value of the current result must be set before moving to the ne
xt result.'); |
| 412 } | 546 } |
| 413 _state = _AFTER; | 547 _state = _AFTER; |
| 414 return false; | 548 return false; |
| 415 } | 549 } |
| 416 } | 550 } |
| 417 } | 551 } |
| 418 | 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 |
| 419 /** | 560 /** |
| 420 * A [TaskInputBuilder] used to build an input based on one or more other task | 561 * A [TaskInputBuilder] used to build an input based on one or more other task |
| 421 * inputs. The task inputs to be built are specified by a table mapping the name | 562 * inputs. The task inputs to be built are specified by a table mapping the name |
| 422 * of the input to the task used to access the input's value. | 563 * of the input to the task used to access the input's value. |
| 423 */ | 564 */ |
| 424 class TopLevelTaskInputBuilder | 565 class TopLevelTaskInputBuilder |
| 425 implements TaskInputBuilder<Map<String, Object>> { | 566 implements TaskInputBuilder<Map<String, Object>> { |
| 426 /** | 567 /** |
| 427 * The descriptors describing the inputs to be built. | 568 * The descriptors describing the inputs to be built. |
| 428 */ | 569 */ |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 } | 680 } |
| 540 } | 681 } |
| 541 | 682 |
| 542 /** | 683 /** |
| 543 * An input to an [AnalysisTask] that is computed by the following steps. First | 684 * An input to an [AnalysisTask] that is computed by the following steps. First |
| 544 * another (base) task input is used to compute a [List]-valued result. An input | 685 * another (base) task input is used to compute a [List]-valued result. An input |
| 545 * generator function is then used to map each element of that list to a task | 686 * generator function is then used to map each element of that list to a task |
| 546 * input. Finally, each of the task inputs are used to access analysis results, | 687 * input. Finally, each of the task inputs are used to access analysis results, |
| 547 * and a collection of the analysis results is used as the input to the task. | 688 * and a collection of the analysis results is used as the input to the task. |
| 548 */ | 689 */ |
| 549 abstract class _ListToCollectionTaskInput<B, E, C> implements TaskInput<C> { | 690 abstract class _ListToCollectionTaskInput<B, E, C> extends TaskInputImpl<C> { |
| 550 /** | 691 /** |
| 551 * The accessor used to access the list of elements being mapped. | 692 * The accessor used to access the list of elements being mapped. |
| 552 */ | 693 */ |
| 553 final TaskInput<List<B>> baseAccessor; | 694 final TaskInput<List<B>> baseAccessor; |
| 554 | 695 |
| 555 /** | 696 /** |
| 556 * The function used to convert an element in the list returned by the | 697 * The function used to convert an element in the list returned by the |
| 557 * [baseAccessor] to a task input. | 698 * [baseAccessor] to a task input. |
| 558 */ | 699 */ |
| 559 final GenerateTaskInputs<B, E> generateTaskInputs; | 700 final GenerateTaskInputs<B, E> generateTaskInputs; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 return false; | 831 return false; |
| 691 } | 832 } |
| 692 _baseListElement = _baseList[_baseListIndex]; | 833 _baseListElement = _baseList[_baseListIndex]; |
| 693 currentBuilder = input.generateTaskInputs(_baseListElement).createBuilder(); | 834 currentBuilder = input.generateTaskInputs(_baseListElement).createBuilder(); |
| 694 return currentBuilder.moveNext(); | 835 return currentBuilder.moveNext(); |
| 695 } | 836 } |
| 696 | 837 |
| 697 void _addResultElement(B baseElement, E resultElement); | 838 void _addResultElement(B baseElement, E resultElement); |
| 698 void _initResultValue(); | 839 void _initResultValue(); |
| 699 } | 840 } |
| OLD | NEW |