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

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

Issue 997383002: Add MapBasedTaskInput. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/inputs_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 arbitrary object into a [TaskInput]. This is 12 * A function that converts an arbitrary object into a [TaskInput]. This is
13 * used, for example, by a [ListBasedTaskInput] to create task inputs for each 13 * used, for example, by a [ListBasedTaskInput] to create task inputs for each
14 * value in a list of values. 14 * value in a list of values.
15 */ 15 */
16 typedef TaskInput<E> GenerateTaskInputs<E>(Object object); 16 typedef TaskInput<E> GenerateTaskInputs<E>(Object object);
17 17
18 /** 18 /**
19 * An input to an [AnalysisTask] that is computed by the following steps. First 19 * An input to an [AnalysisTask] that is computed by the following steps. First
20 * another (base) task input is used to compute a [List]-valued result. An input 20 * another (base) task input is used to compute a [List]-valued result. An input
21 * generator function is then used to map each element of that list to a task 21 * generator function is then used to map each element of that list to a task
22 * input. Finally, each of the task inputs are used to access analysis results, 22 * input. Finally, each of the task inputs are used to access analysis results,
23 * and the list of the analysis results is used as the input to the task. 23 * and the list of the analysis results is used as the input to the task.
24 */ 24 */
25 class ListBasedTaskInput<B, E> implements TaskInput<List<E>> { 25 class ListBasedTaskInput<B, E>
26 /** 26 extends _CollectionBasedTaskInput<B, E, List<E>> {
27 * The accessor used to access the list of elements being mapped.
28 */
29 final TaskInput<B> baseAccessor;
30
31 /**
32 * The function used to convert an element in the list returned by the
33 * [baseAccessor] to a task input.
34 */
35 GenerateTaskInputs<E> generateTaskInputs;
36
37 /** 27 /**
38 * Initialize a result accessor to use the given [baseAccessor] to access a 28 * Initialize a result accessor to use the given [baseAccessor] to access a
39 * list of values that can be passed to the given [generateTaskInputs] to gene rate 29 * list of values that can be passed to the given [generateTaskInputs] to
40 * a list of task inputs that can be used to access the elements of the input 30 * generate a list of task inputs that can be used to access the elements of
41 * being accessed. 31 * the input being accessed.
42 */ 32 */
43 ListBasedTaskInput(this.baseAccessor, this.generateTaskInputs); 33 ListBasedTaskInput(
34 TaskInput<B> baseAccessor, GenerateTaskInputs<E> generateTaskInputs)
35 : super(baseAccessor, generateTaskInputs);
44 36
45 @override 37 @override
46 TaskInputBuilder<List<E>> createBuilder() => 38 TaskInputBuilder<List<E>> createBuilder() =>
47 new ListBasedTaskInputBuilder<B, E>(this); 39 new ListBasedTaskInputBuilder<B, E>(this);
48 } 40 }
49 41
50 /** 42 /**
51 * A [TaskInputBuilder] used to build an input based on a [ListBasedTaskInput]. 43 * A [TaskInputBuilder] used to build an input based on a [ListBasedTaskInput].
52 */ 44 */
53 class ListBasedTaskInputBuilder<B, E> implements TaskInputBuilder<List<E>> { 45 class ListBasedTaskInputBuilder<B, E>
54 /** 46 extends _CollectionBasedTaskInputBuilder<B, E, List<E>> {
55 * The input being built.
56 */
57 final ListBasedTaskInput<B, E> input;
58
59 /**
60 * The builder used to build the current result.
61 */
62 TaskInputBuilder currentBuilder;
63
64 /**
65 * The list of values computed by the [input]'s base accessor.
66 */
67 List _baseList = null;
68
69 /**
70 * The index in the [_baseList] of the value for which a value is currently
71 * being built.
72 */
73 int _baseListIndex = -1;
74
75 /** 47 /**
76 * The list of values being built. 48 * The list of values being built.
77 */ 49 */
78 List<E> _resultValue = null; 50 List<E> _resultValue;
79 51
80 /** 52 /**
81 * Initialize a newly created task input builder that computes the result 53 * Initialize a newly created task input builder that computes the result
82 * specified by the given [input]. 54 * specified by the given [input].
83 */ 55 */
84 ListBasedTaskInputBuilder(this.input); 56 ListBasedTaskInputBuilder(ListBasedTaskInput<B, E> input) : super(input);
85 57
86 @override 58 @override
87 ResultDescriptor get currentResult { 59 void _addResultElement(B baseElement, E resultElement) {
88 if (currentBuilder == null) { 60 _resultValue.add(resultElement);
89 return null;
90 }
91 return currentBuilder.currentResult;
92 } 61 }
93 62
94 @override 63 @override
95 AnalysisTarget get currentTarget { 64 void _initResultValue() {
96 if (currentBuilder == null) { 65 _resultValue = <E>[];
97 return null; 66 }
98 } 67 }
99 return currentBuilder.currentTarget; 68
69 /**
70 * An input to an [AnalysisTask] that is computed by the following steps. First
71 * another (base) task input is used to compute a [List]-valued result. An input
72 * generator function is then used to map each element of that list to a task
73 * input. Finally, each of the task inputs are used to access analysis results,
74 * and the map of the base elements to the analysis results is used as the
75 * input to the task.
76 */
77 class MapBasedTaskInput<B, E>
78 extends _CollectionBasedTaskInput<B, E, Map<B, E>> {
79 /**
80 * Initialize a result accessor to use the given [baseAccessor] to access a
81 * list of values that can be passed to the given [generateTaskInputs] to
82 * generate a list of task inputs that can be used to access the elements of
83 * the input being accessed.
84 */
85 MapBasedTaskInput(
86 TaskInput<B> baseAccessor, GenerateTaskInputs<E> generateTaskInputs)
87 : super(baseAccessor, generateTaskInputs);
88
89 @override
90 TaskInputBuilder<Map<B, E>> createBuilder() =>
91 new MapBasedTaskInputBuilder<B, E>(this);
92 }
93
94 /**
95 * A [TaskInputBuilder] used to build an input based on a [MapBasedTaskInput].
96 */
97 class MapBasedTaskInputBuilder<B, E>
98 extends _CollectionBasedTaskInputBuilder<B, E, Map<B, E>> {
99 /**
100 * The map being built.
101 */
102 Map<B, E> _resultValue;
103
104 /**
105 * Initialize a newly created task input builder that computes the result
106 * specified by the given [input].
107 */
108 MapBasedTaskInputBuilder(MapBasedTaskInput<B, E> input) : super(input);
109
110 @override
111 void _addResultElement(B baseElement, E resultElement) {
112 _resultValue[baseElement] = resultElement;
100 } 113 }
101 114
102 @override 115 @override
103 void set currentValue(Object value) { 116 void _initResultValue() {
104 if (currentBuilder == null) { 117 _resultValue = new HashMap<B, E>();
105 throw new StateError(
106 'Cannot set the result value when there is no current result');
107 }
108 currentBuilder.currentValue = value;
109 }
110
111 @override
112 List<E> get inputValue {
113 if (currentBuilder != null || _resultValue == null) {
114 throw new StateError('Result value has not been created');
115 }
116 return _resultValue;
117 }
118
119 @override
120 bool moveNext() {
121 if (currentBuilder == null) {
122 if (_resultValue == null) {
123 // This is the first time moveNext has been invoked, so start by
124 // computing the list of values from which the results will be derived.
125 currentBuilder = input.baseAccessor.createBuilder();
126 return currentBuilder.moveNext();
127 } else {
128 // We have already computed all of the results, so just return false.
129 return false;
130 }
131 }
132 if (currentBuilder.moveNext()) {
133 return true;
134 }
135 if (_resultValue == null) {
136 // We have finished computing the list of values from which the results
137 // will be derived.
138 _baseList = currentBuilder.inputValue;
139 _baseListIndex = 0;
140 _resultValue = <E>[];
141 } else {
142 // We have finished computing one of the elements in the result list.
143 _resultValue.add(currentBuilder.inputValue);
144 _baseListIndex++;
145 }
146 if (_baseListIndex >= _baseList.length) {
147 currentBuilder = null;
148 return false;
149 }
150 currentBuilder =
151 input.generateTaskInputs(_baseList[_baseListIndex]).createBuilder();
152 return currentBuilder.moveNext();
153 } 118 }
154 } 119 }
155 120
156 /** 121 /**
157 * An input to an [AnalysisTask] that is computed by accessing a single result 122 * An input to an [AnalysisTask] that is computed by accessing a single result
158 * defined on a single target. 123 * defined on a single target.
159 */ 124 */
160 class SimpleTaskInput<V> implements TaskInput<V> { 125 class SimpleTaskInput<V> implements TaskInput<V> {
161 /** 126 /**
162 * The target on which the result is defined. 127 * The target on which the result is defined.
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 return false; 335 return false;
371 } 336 }
372 currentBuilder = inputDescriptors[_currentName].createBuilder(); 337 currentBuilder = inputDescriptors[_currentName].createBuilder();
373 // NOTE: This assumes that every builder will require at least one result 338 // NOTE: This assumes that every builder will require at least one result
374 // value to be created. If that assumption is every broken, this method will 339 // value to be created. If that assumption is every broken, this method will
375 // need to be changed to advance until we find a builder that does require 340 // need to be changed to advance until we find a builder that does require
376 // a result to be computed (or run out of builders). 341 // a result to be computed (or run out of builders).
377 return currentBuilder.moveNext(); 342 return currentBuilder.moveNext();
378 } 343 }
379 } 344 }
345
346 /**
347 * An input to an [AnalysisTask] that is computed by the following steps. First
348 * another (base) task input is used to compute a [List]-valued result. An input
Brian Wilkerson 2015/03/12 13:59:47 The comment needs to be updated.
scheglov 2015/03/12 15:10:36 Actually baseAccessor still provides a List. But
349 * generator function is then used to map each element of that list to a task
350 * input. Finally, each of the task inputs are used to access analysis results,
351 * and the collection of the analysis results is used as the input to the task.
352 */
353 abstract class _CollectionBasedTaskInput<B, E, C> implements TaskInput<C> {
Brian Wilkerson 2015/03/12 13:59:47 Is there a reason to make this class private? (It'
scheglov 2015/03/12 15:10:36 I don't think there is lot of different data stru
354 /**
355 * The accessor used to access the list of elements being mapped.
356 */
357 final TaskInput<B> baseAccessor;
358
359 /**
360 * The function used to convert an element in the list returned by the
361 * [baseAccessor] to a task input.
362 */
363 GenerateTaskInputs<E> generateTaskInputs;
Brian Wilkerson 2015/03/12 13:59:47 Should this be final?
scheglov 2015/03/12 15:10:36 Done.
364
365 /**
366 * Initialize a result accessor to use the given [baseAccessor] to access a
367 * list of values that can be passed to the given [generateTaskInputs] to gene rate
368 * a list of task inputs that can be used to access the elements of the input
369 * being accessed.
370 */
371 _CollectionBasedTaskInput(this.baseAccessor, this.generateTaskInputs);
372 }
373
374 /**
375 * A [TaskInputBuilder] used to build an input based on a [ListBasedTaskInput].
Brian Wilkerson 2015/03/12 13:59:47 The comment needs to be updated.
scheglov 2015/03/12 15:10:36 Done.
376 */
377 abstract class _CollectionBasedTaskInputBuilder<B, E, C>
378 implements TaskInputBuilder<C> {
379 /**
380 * The input being built.
381 */
382 final _CollectionBasedTaskInput<B, E, C> input;
383
384 /**
385 * The builder used to build the current result.
386 */
387 TaskInputBuilder currentBuilder;
388
389 /**
390 * The list of values computed by the [input]'s base accessor.
391 */
392 List _baseList = null;
393
394 /**
395 * The index in the [_baseList] of the value for which a value is currently
396 * being built.
397 */
398 int _baseListIndex = -1;
399
400 /**
401 * Initialize a newly created task input builder that computes the result
402 * specified by the given [input].
403 */
404 _CollectionBasedTaskInputBuilder(this.input);
405
406 @override
407 ResultDescriptor get currentResult {
408 if (currentBuilder == null) {
409 return null;
410 }
411 return currentBuilder.currentResult;
412 }
413
414 @override
415 AnalysisTarget get currentTarget {
416 if (currentBuilder == null) {
417 return null;
418 }
419 return currentBuilder.currentTarget;
420 }
421
422 @override
423 void set currentValue(Object value) {
424 if (currentBuilder == null) {
425 throw new StateError(
426 'Cannot set the result value when there is no current result');
427 }
428 currentBuilder.currentValue = value;
429 }
430
431 @override
432 C get inputValue {
433 if (currentBuilder != null || _resultValue == null) {
434 throw new StateError('Result value has not been created');
435 }
436 return _resultValue;
437 }
438
439 /**
440 * The list of values being built.
441 */
442 C get _resultValue;
443
444 @override
445 bool moveNext() {
446 if (currentBuilder == null) {
447 if (_resultValue == null) {
448 // This is the first time moveNext has been invoked, so start by
449 // computing the list of values from which the results will be derived.
450 currentBuilder = input.baseAccessor.createBuilder();
451 return currentBuilder.moveNext();
452 } else {
453 // We have already computed all of the results, so just return false.
454 return false;
455 }
456 }
457 if (currentBuilder.moveNext()) {
458 return true;
459 }
460 if (_resultValue == null) {
461 // We have finished computing the list of values from which the results
462 // will be derived.
463 _baseList = currentBuilder.inputValue;
464 _baseListIndex = 0;
465 _initResultValue();
466 } else {
467 // We have finished computing one of the elements in the result list.
468 _addResultElement(_baseList[_baseListIndex], currentBuilder.inputValue);
469 _baseListIndex++;
470 }
471 if (_baseListIndex >= _baseList.length) {
472 currentBuilder = null;
473 return false;
474 }
475 currentBuilder =
476 input.generateTaskInputs(_baseList[_baseListIndex]).createBuilder();
477 return currentBuilder.moveNext();
478 }
479
480 void _addResultElement(B baseElement, E resultElement);
481 void _initResultValue();
482 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/inputs_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698