| Index: pkg/analyzer/lib/src/dart/analysis/driver.dart
|
| diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
|
| index 5b901f1a675e159c1d0629426c5ca52493e69796..de4b10d88424d474566d6db9364bfcadc05b4887 100644
|
| --- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
|
| +++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
|
| @@ -13,6 +13,7 @@ import 'package:analyzer/file_system/file_system.dart';
|
| import 'package:analyzer/src/context/context.dart';
|
| import 'package:analyzer/src/dart/analysis/byte_store.dart';
|
| import 'package:analyzer/src/dart/analysis/file_state.dart';
|
| +import 'package:analyzer/src/dart/analysis/status.dart';
|
| import 'package:analyzer/src/generated/engine.dart'
|
| show AnalysisContext, AnalysisEngine, AnalysisOptions, ChangeSet;
|
| import 'package:analyzer/src/generated/source.dart';
|
| @@ -180,14 +181,9 @@ class AnalysisDriver {
|
| final _dependencySignatureMap = <Uri, String>{};
|
|
|
| /**
|
| - * The controller for the [status] stream.
|
| + * The instance of the status helper.
|
| */
|
| - final _statusController = new StreamController<AnalysisStatus>();
|
| -
|
| - /**
|
| - * The last status sent to the [status] stream.
|
| - */
|
| - AnalysisStatus _currentStatus = AnalysisStatus.IDLE;
|
| + final StatusSupport _statusSupport = new StatusSupport();
|
|
|
| /**
|
| * Create a new instance of [AnalysisDriver].
|
| @@ -223,7 +219,7 @@ class AnalysisDriver {
|
| void set priorityFiles(List<String> priorityPaths) {
|
| _priorityFiles.clear();
|
| _priorityFiles.addAll(priorityPaths);
|
| - _transitionToAnalyzing();
|
| + _statusSupport.transitionToAnalyzing();
|
| _scheduler._notify(this);
|
| }
|
|
|
| @@ -254,7 +250,7 @@ class AnalysisDriver {
|
| /**
|
| * Return the stream that produces [AnalysisStatus] events.
|
| */
|
| - Stream<AnalysisStatus> get status => _statusController.stream;
|
| + Stream<AnalysisStatus> get status => _statusSupport.stream;
|
|
|
| /**
|
| * Return the priority of work that the driver needs to perform.
|
| @@ -279,7 +275,7 @@ class AnalysisDriver {
|
| if (_requestedParts.isNotEmpty || _partsToAnalyze.isNotEmpty) {
|
| return AnalysisDriverPriority.general;
|
| }
|
| - _transitionToIdle();
|
| + _statusSupport.transitionToIdle();
|
| return AnalysisDriverPriority.nothing;
|
| }
|
|
|
| @@ -295,7 +291,7 @@ class AnalysisDriver {
|
| _explicitFiles.add(path);
|
| _filesToAnalyze.add(path);
|
| }
|
| - _transitionToAnalyzing();
|
| + _statusSupport.transitionToAnalyzing();
|
| _scheduler._notify(this);
|
| }
|
|
|
| @@ -324,7 +320,7 @@ class AnalysisDriver {
|
| _filesToAnalyze.add(path);
|
| }
|
| }
|
| - _transitionToAnalyzing();
|
| + _statusSupport.transitionToAnalyzing();
|
| _scheduler._notify(this);
|
| }
|
|
|
| @@ -354,7 +350,7 @@ class AnalysisDriver {
|
| _requestedFiles
|
| .putIfAbsent(path, () => <Completer<AnalysisResult>>[])
|
| .add(completer);
|
| - _transitionToAnalyzing();
|
| + _statusSupport.transitionToAnalyzing();
|
| _scheduler._notify(this);
|
| return completer.future;
|
| }
|
| @@ -781,27 +777,6 @@ class AnalysisDriver {
|
| }
|
|
|
| /**
|
| - * Send a notifications to the [status] stream that the driver started
|
| - * analyzing.
|
| - */
|
| - void _transitionToAnalyzing() {
|
| - if (_currentStatus != AnalysisStatus.ANALYZING) {
|
| - _currentStatus = AnalysisStatus.ANALYZING;
|
| - _statusController.add(AnalysisStatus.ANALYZING);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Send a notifications to the [status] stream that the driver is idle.
|
| - */
|
| - void _transitionToIdle() {
|
| - if (_currentStatus != AnalysisStatus.IDLE) {
|
| - _currentStatus = AnalysisStatus.IDLE;
|
| - _statusController.add(AnalysisStatus.IDLE);
|
| - }
|
| - }
|
| -
|
| - /**
|
| * Verify the API signature for the file with the given [path], and decide
|
| * which linked libraries should be invalidated, and files reanalyzed.
|
| */
|
| @@ -848,13 +823,19 @@ enum AnalysisDriverPriority { nothing, general, priority, interactive }
|
| class AnalysisDriverScheduler {
|
| final PerformanceLog _logger;
|
| final List<AnalysisDriver> _drivers = [];
|
| - final _Monitor _hasWork = new _Monitor();
|
| + final Monitor _hasWork = new Monitor();
|
| + final StatusSupport _statusSupport = new StatusSupport();
|
|
|
| bool _started = false;
|
|
|
| AnalysisDriverScheduler(this._logger);
|
|
|
| /**
|
| + * Return the stream that produces [AnalysisStatus] events.
|
| + */
|
| + Stream<AnalysisStatus> get status => _statusSupport.stream;
|
| +
|
| + /**
|
| * Start the scheduler, so that any [AnalysisDriver] created before or
|
| * after will be asked to perform work.
|
| */
|
| @@ -871,6 +852,7 @@ class AnalysisDriverScheduler {
|
| */
|
| void _add(AnalysisDriver driver) {
|
| _drivers.add(driver);
|
| + _statusSupport.transitionToAnalyzing();
|
| _hasWork.notify();
|
| }
|
|
|
| @@ -879,6 +861,7 @@ class AnalysisDriverScheduler {
|
| * perform some work.
|
| */
|
| void _notify(AnalysisDriver driver) {
|
| + _statusSupport.transitionToAnalyzing();
|
| _hasWork.notify();
|
| }
|
|
|
| @@ -888,6 +871,7 @@ class AnalysisDriverScheduler {
|
| */
|
| void _remove(AnalysisDriver driver) {
|
| _drivers.remove(driver);
|
| + _statusSupport.transitionToAnalyzing();
|
| _hasWork.notify();
|
| }
|
|
|
| @@ -930,6 +914,7 @@ class AnalysisDriverScheduler {
|
| if (bestPriority == AnalysisDriverPriority.nothing) {
|
| analysisSection.exit();
|
| analysisSection = null;
|
| + _statusSupport.transitionToIdle();
|
| continue;
|
| }
|
|
|
| @@ -1007,28 +992,6 @@ class AnalysisResult {
|
| }
|
|
|
| /**
|
| - * The status of [AnalysisDriver]
|
| - */
|
| -class AnalysisStatus {
|
| - static const IDLE = const AnalysisStatus._(false);
|
| - static const ANALYZING = const AnalysisStatus._(true);
|
| -
|
| - final bool _analyzing;
|
| -
|
| - const AnalysisStatus._(this._analyzing);
|
| -
|
| - /**
|
| - * Return `true` is the driver is analyzing.
|
| - */
|
| - bool get isAnalyzing => _analyzing;
|
| -
|
| - /**
|
| - * Return `true` is the driver is idle.
|
| - */
|
| - bool get isIdle => !_analyzing;
|
| -}
|
| -
|
| -/**
|
| * The result of parsing of a single file.
|
| *
|
| * These results are self-consistent, i.e. [content], [contentHash], the
|
| @@ -1212,32 +1175,3 @@ class _LibraryNode {
|
| @override
|
| String toString() => uri.toString();
|
| }
|
| -
|
| -/**
|
| - * [_Monitor] can be used to wait for a signal.
|
| - *
|
| - * Signals are not queued, the client will receive exactly one signal
|
| - * regardless of the number of [notify] invocations. The [signal] is reset
|
| - * after completion and will not complete until [notify] is called next time.
|
| - */
|
| -class _Monitor {
|
| - Completer<Null> _completer = new Completer<Null>();
|
| -
|
| - /**
|
| - * Return a [Future] that completes when [notify] is called at least once.
|
| - */
|
| - Future<Null> get signal async {
|
| - await _completer.future;
|
| - _completer = new Completer<Null>();
|
| - }
|
| -
|
| - /**
|
| - * Complete the [signal] future if it is not completed yet. It is safe to
|
| - * call this method multiple times, but the [signal] will complete only once.
|
| - */
|
| - void notify() {
|
| - if (!_completer.isCompleted) {
|
| - _completer.complete(null);
|
| - }
|
| - }
|
| -}
|
|
|