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

Side by Side Diff: packages/analyzer/lib/task/model.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
« no previous file with comments | « packages/analyzer/lib/task/html.dart ('k') | packages/analyzer/pubspec.yaml » ('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.task.model; 5 library analyzer.task.model;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:developer';
8 9
9 import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask; 10 import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
11 import 'package:analyzer/src/generated/error.dart' show AnalysisError;
10 import 'package:analyzer/src/generated/java_engine.dart'; 12 import 'package:analyzer/src/generated/java_engine.dart';
11 import 'package:analyzer/src/generated/source.dart'; 13 import 'package:analyzer/src/generated/source.dart';
14 import 'package:analyzer/src/generated/utilities_general.dart';
12 import 'package:analyzer/src/task/driver.dart'; 15 import 'package:analyzer/src/task/driver.dart';
13 import 'package:analyzer/src/task/model.dart'; 16 import 'package:analyzer/src/task/model.dart';
14 17
15 /** 18 /**
16 * A function that converts the given [key] and [value] into a [TaskInput]. 19 * A function that converts the given [key] and [value] into a [TaskInput].
17 */ 20 */
18 typedef TaskInput<E> BinaryFunction<K, V, E>(K key, V value); 21 typedef TaskInput<E> BinaryFunction<K, V, E>(K key, V value);
19 22
20 /** 23 /**
21 * A function that takes an analysis [context] and an analysis [target] and 24 * A function that takes an analysis [context] and an analysis [target] and
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 * Clients are expected to extend this class when creating new tasks. 78 * Clients are expected to extend this class when creating new tasks.
76 */ 79 */
77 abstract class AnalysisTask { 80 abstract class AnalysisTask {
78 /** 81 /**
79 * A table mapping the types of analysis tasks to the number of times each 82 * A table mapping the types of analysis tasks to the number of times each
80 * kind of task has been performed. 83 * kind of task has been performed.
81 */ 84 */
82 static final Map<Type, int> countMap = new HashMap<Type, int>(); 85 static final Map<Type, int> countMap = new HashMap<Type, int>();
83 86
84 /** 87 /**
88 * A table mapping the types of analysis tasks to user tags used to collect
89 * timing data for the Observatory.
90 */
91 static Map<Type, UserTag> tagMap = new HashMap<Type, UserTag>();
92
93 /**
85 * A table mapping the types of analysis tasks to stopwatches used to compute 94 * A table mapping the types of analysis tasks to stopwatches used to compute
86 * how much time was spent executing each kind of task. 95 * how much time was spent executing each kind of task.
87 */ 96 */
88 static final Map<Type, Stopwatch> stopwatchMap = 97 static final Map<Type, Stopwatch> stopwatchMap =
89 new HashMap<Type, Stopwatch>(); 98 new HashMap<Type, Stopwatch>();
90 99
91 /** 100 /**
92 * The context in which the task is to be performed. 101 * The context in which the task is to be performed.
93 */ 102 */
94 final AnalysisContext context; 103 final AnalysisContext context;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 * map should be fully populated (have a key/value pair for each result that 198 * map should be fully populated (have a key/value pair for each result that
190 * this task is expected to produce) or the [caughtException] should be set. 199 * this task is expected to produce) or the [caughtException] should be set.
191 * 200 *
192 * Clients should not override this method. 201 * Clients should not override this method.
193 */ 202 */
194 void perform() { 203 void perform() {
195 try { 204 try {
196 _safelyPerform(); 205 _safelyPerform();
197 } on AnalysisException catch (exception, stackTrace) { 206 } on AnalysisException catch (exception, stackTrace) {
198 caughtException = new CaughtException(exception, stackTrace); 207 caughtException = new CaughtException(exception, stackTrace);
199 AnalysisEngine.instance.logger.logInformation( 208 AnalysisEngine.instance.logger
200 "Task failed: ${description}", caughtException); 209 .logInformation("Task failed: ${description}", caughtException);
201 } 210 }
202 } 211 }
203 212
204 @override 213 @override
205 String toString() => description; 214 String toString() => description;
206 215
207 /** 216 /**
208 * Perform this analysis task, ensuring that all exceptions are wrapped in an 217 * Perform this analysis task, ensuring that all exceptions are wrapped in an
209 * [AnalysisException]. 218 * [AnalysisException].
210 * 219 *
211 * Clients should not override this method. 220 * Clients should not override this method.
212 */ 221 */
213 void _safelyPerform() { 222 void _safelyPerform() {
214 try { 223 try {
215 // 224 //
216 // Report that this task is being performed. 225 // Report that this task is being performed.
217 // 226 //
218 String contextName = context.name; 227 String contextName = context.name;
219 if (contextName == null) { 228 if (contextName == null) {
220 contextName = 'unnamed'; 229 contextName = 'unnamed';
221 } 230 }
222 AnalysisEngine.instance.instrumentationService.logAnalysisTask( 231 AnalysisEngine.instance.instrumentationService
223 contextName, this); 232 .logAnalysisTask(contextName, this);
224 // 233 //
225 // Gather statistics on the performance of the task. 234 // Gather statistics on the performance of the task.
226 // 235 //
227 int count = countMap[runtimeType]; 236 int count = countMap[runtimeType];
228 countMap[runtimeType] = count == null ? 1 : count + 1; 237 countMap[runtimeType] = count == null ? 1 : count + 1;
238 // UserTag tag = tagMap.putIfAbsent(
239 // runtimeType, () => new UserTag(runtimeType.toString()));
229 Stopwatch stopwatch = stopwatchMap[runtimeType]; 240 Stopwatch stopwatch = stopwatchMap[runtimeType];
230 if (stopwatch == null) { 241 if (stopwatch == null) {
231 stopwatch = new Stopwatch(); 242 stopwatch = new Stopwatch();
232 stopwatchMap[runtimeType] = stopwatch; 243 stopwatchMap[runtimeType] = stopwatch;
233 } 244 }
245 // UserTag previousTag = tag.makeCurrent();
246 // try {
234 stopwatch.start(); 247 stopwatch.start();
235 // 248 //
236 // Actually perform the task. 249 // Actually perform the task.
237 // 250 //
238 try { 251 try {
239 if (dependencyCycle != null && !handlesDependencyCycles) { 252 if (dependencyCycle != null && !handlesDependencyCycles) {
240 throw new InfiniteTaskLoopException(this, dependencyCycle); 253 throw new InfiniteTaskLoopException(this, dependencyCycle);
241 } 254 }
242 internalPerform(); 255 internalPerform();
243 } finally { 256 } finally {
244 stopwatch.stop(); 257 stopwatch.stop();
245 } 258 }
259 // } finally {
260 // previousTag.makeCurrent();
261 // }
246 } on AnalysisException { 262 } on AnalysisException {
247 rethrow; 263 rethrow;
248 } catch (exception, stackTrace) { 264 } catch (exception, stackTrace) {
249 throw new AnalysisException( 265 throw new AnalysisException(
250 'Unexpected exception while performing $description', 266 'Unexpected exception while performing $description',
251 new CaughtException(exception, stackTrace)); 267 new CaughtException(exception, stackTrace));
252 } 268 }
253 } 269 }
254 } 270 }
255 271
256 /** 272 /**
257 * A description of a [List]-based analysis result that can be computed by an 273 * A description of a [List]-based analysis result that can be computed by an
258 * [AnalysisTask]. 274 * [AnalysisTask].
259 * 275 *
260 * Clients are not expected to subtype this class. 276 * Clients are not expected to subtype this class.
261 */ 277 */
262 abstract class ListResultDescriptor<E> implements ResultDescriptor<List<E>> { 278 abstract class ListResultDescriptor<E> implements ResultDescriptor<List<E>> {
263 /** 279 /**
264 * Initialize a newly created analysis result to have the given [name] and 280 * Initialize a newly created analysis result to have the given [name] and
265 * [defaultValue]. If a [cachingPolicy] is provided, it will control how long 281 * [defaultValue]. If a [cachingPolicy] is provided, it will control how long
266 * values associated with this result will remain in the cache. 282 * values associated with this result will remain in the cache.
267 */ 283 */
268 factory ListResultDescriptor(String name, List<E> defaultValue, 284 factory ListResultDescriptor(String name, List<E> defaultValue,
269 {ResultCachingPolicy<List<E>> cachingPolicy}) = ListResultDescriptorImpl<E >; 285 {ResultCachingPolicy<List<E>> cachingPolicy}) = ListResultDescriptorImpl<
286 E>;
270 287
271 @override 288 @override
272 ListTaskInput<E> of(AnalysisTarget target); 289 ListTaskInput<E> of(AnalysisTarget target, {bool flushOnAccess: false});
273 } 290 }
274 291
275 /** 292 /**
276 * A description of an input to an [AnalysisTask] that can be used to compute 293 * A description of an input to an [AnalysisTask] that can be used to compute
277 * that input. 294 * that input.
278 * 295 *
279 * Clients are not expected to subtype this class. 296 * Clients are not expected to subtype this class.
280 */ 297 */
281 abstract class ListTaskInput<E> extends TaskInput<List<E>> { 298 abstract class ListTaskInput<E> extends TaskInput<List<E>> {
282 /** 299 /**
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 */ 394 */
378 V get defaultValue; 395 V get defaultValue;
379 396
380 /** 397 /**
381 * Return the name of this descriptor. 398 * Return the name of this descriptor.
382 */ 399 */
383 String get name; 400 String get name;
384 401
385 /** 402 /**
386 * Return a task input that can be used to compute this result for the given 403 * Return a task input that can be used to compute this result for the given
387 * [target]. 404 * [target]. If [flushOnAccess] is `true` then the value of this result that
405 * is associated with the [target] will be flushed when it is accessed.
388 */ 406 */
389 TaskInput<V> of(AnalysisTarget target); 407 TaskInput<V> of(AnalysisTarget target, {bool flushOnAccess: false});
390 } 408 }
391 409
392 /** 410 /**
411 * A specification of the given [result] for the given [target].
412 *
413 * Clients are not expected to subtype this class.
414 */
415 class TargetedResult {
416 /**
417 * An empty list of results.
418 */
419 static final List<TargetedResult> EMPTY_LIST = const <TargetedResult>[];
420
421 /**
422 * The target with which the result is associated.
423 */
424 final AnalysisTarget target;
425
426 /**
427 * The result associated with the target.
428 */
429 final ResultDescriptor result;
430
431 /**
432 * Initialize a new targeted result.
433 */
434 TargetedResult(this.target, this.result);
435
436 @override
437 int get hashCode {
438 return JenkinsSmiHash.combine(target.hashCode, result.hashCode);
439 }
440
441 @override
442 bool operator ==(other) {
443 return other is TargetedResult &&
444 other.target == target &&
445 other.result == result;
446 }
447
448 @override
449 String toString() => '$result for $target';
450 }
451
452 /**
393 * A description of an [AnalysisTask]. 453 * A description of an [AnalysisTask].
394 */ 454 */
395 abstract class TaskDescriptor { 455 abstract class TaskDescriptor {
396 /** 456 /**
397 * Initialize a newly created task descriptor to have the given [name] and to 457 * Initialize a newly created task descriptor to have the given [name] and to
398 * describe a task that takes the inputs built using the given [inputBuilder], 458 * describe a task that takes the inputs built using the given [inputBuilder],
399 * and produces the given [results]. The [buildTask] will be used to create 459 * and produces the given [results]. The [buildTask] will be used to create
400 * the instance of [AnalysisTask] thusly described. 460 * the instance of [AnalysisTask] thusly described.
401 */ 461 */
402 factory TaskDescriptor(String name, BuildTask buildTask, 462 factory TaskDescriptor(
463 String name,
464 BuildTask buildTask,
403 CreateTaskInputs inputBuilder, 465 CreateTaskInputs inputBuilder,
404 List<ResultDescriptor> results) = TaskDescriptorImpl; 466 List<ResultDescriptor> results) = TaskDescriptorImpl;
405 467
406 /** 468 /**
407 * Return the builder used to build the inputs to the task. 469 * Return the builder used to build the inputs to the task.
408 */ 470 */
409 CreateTaskInputs get createTaskInputs; 471 CreateTaskInputs get createTaskInputs;
410 472
411 /** 473 /**
412 * Return the name of the task being described. 474 * Return the name of the task being described.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 538
477 /** 539 /**
478 * Set the [value] that was computed for the current result. 540 * Set the [value] that was computed for the current result.
479 * 541 *
480 * Throws a [StateError] if [moveNext] has not been invoked or if the last 542 * Throws a [StateError] if [moveNext] has not been invoked or if the last
481 * invocation of [moveNext] returned `false`. 543 * invocation of [moveNext] returned `false`.
482 */ 544 */
483 void set currentValue(Object value); 545 void set currentValue(Object value);
484 546
485 /** 547 /**
548 * Return `true` if the value accessed by this input builder should be flushed
549 * from the cache at the time it is retrieved.
550 */
551 bool get flushOnAccess;
552
553 /**
486 * Return the [value] that was computed by this builder. 554 * Return the [value] that was computed by this builder.
487 * 555 *
488 * Throws a [StateError] if [moveNext] has not been invoked or if the last 556 * Throws a [StateError] if [moveNext] has not been invoked or if the last
489 * invocation of [moveNext] returned `true`. 557 * invocation of [moveNext] returned `true`.
490 * 558 *
491 * Returns `null` if no value could be computed due to a circular dependency. 559 * Returns `null` if no value could be computed due to a circular dependency.
492 */ 560 */
493 V get inputValue; 561 V get inputValue;
494 562
495 /** 563 /**
(...skipping 11 matching lines...) Expand all
507 * be computed, or `false` if the inputs have been computed. 575 * be computed, or `false` if the inputs have been computed.
508 * 576 *
509 * It is safe to invoke [moveNext] after it has returned `false`. In this case 577 * It is safe to invoke [moveNext] after it has returned `false`. In this case
510 * [moveNext] has no effect and will again return `false`. 578 * [moveNext] has no effect and will again return `false`.
511 * 579 *
512 * Throws a [StateError] if the value of the current result has not been 580 * Throws a [StateError] if the value of the current result has not been
513 * provided using [currentValue]. 581 * provided using [currentValue].
514 */ 582 */
515 bool moveNext(); 583 bool moveNext();
516 } 584 }
585
586 /**
587 * [WorkManager]s are used to drive analysis.
588 *
589 * They know specific of the targets and results they care about,
590 * so they can request analysis results in optimal order.
591 */
592 abstract class WorkManager {
593 /**
594 * Notifies the manager about changes in the explicit source list.
595 */
596 void applyChange(List<Source> addedSources, List<Source> changedSources,
597 List<Source> removedSources);
598
599 /**
600 * Notifies the managers that the given set of priority [targets] was set.
601 */
602 void applyPriorityTargets(List<AnalysisTarget> targets);
603
604 /**
605 * Return a list of all of the errors associated with the given [source].
606 * The list of errors will be empty if the source is not known to the context
607 * or if there are no errors in the source. The errors contained in the list
608 * can be incomplete.
609 */
610 List<AnalysisError> getErrors(Source source);
611
612 /**
613 * Return the next [TargetedResult] that this work manager wants to be
614 * computed, or `null` if this manager doesn't need any new results.
615 *
616 * Note, that it is not guaranteed that this result will be computed, it is
617 * up to the work manager to check whether the result is already computed
618 * (for example during the next [getNextResult] invocation) or computation
619 * of the same result should be requested again.
620 */
621 TargetedResult getNextResult();
622
623 /**
624 * Return the priority if the next work order this work manager want to be
625 * computed. The [AnalysisDriver] will perform the work order with
626 * the highest priority.
627 *
628 * Even if the returned value is [WorkOrderPriority.NONE], it still does not
629 * guarantee that [getNextResult] will return not `null`.
630 */
631 WorkOrderPriority getNextResultPriority();
632
633 /**
634 * Notifies the manager about analysis options changes.
635 */
636 void onAnalysisOptionsChanged();
637
638 /**
639 * Notifies the manager about [SourceFactory] changes.
640 */
641 void onSourceFactoryChanged();
642
643 /**
644 * Notifies the manager that the given [outputs] were produced for
645 * the given [target].
646 */
647 void resultsComputed(
648 AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs);
649 }
650
651 /**
652 * The priorities of work orders returned by [WorkManager]s.
653 *
654 * New priorities may be added with time, clients need to tolerate this.
655 */
656 enum WorkOrderPriority {
657 /**
658 * Responding to an user's action.
659 */
660 INTERACTIVE,
661
662 /**
663 * Computing information for priority sources.
664 */
665 PRIORITY,
666
667 /**
668 * A work should be done, but without any special urgency.
669 */
670 NORMAL,
671
672 /**
673 * Nothing to do.
674 */
675 NONE
676 }
OLDNEW
« no previous file with comments | « packages/analyzer/lib/task/html.dart ('k') | packages/analyzer/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698