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

Unified Diff: pkg/analyzer/lib/src/dart/analysis/driver.dart

Issue 2450053003: Replace Stream with monitor. (Closed)
Patch Set: Created 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 d96e63daa15ccad290dd73e509a663c6854690ff..01c66563862b88f6803bdd3c718ccc09c8cee0c5 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -158,9 +158,9 @@ class AnalysisDriver {
final _dependencySignatureMap = <Uri, String>{};
/**
- * TODO(scheglov) document and improve
+ * The monitor that is signalled when there is work to do.
*/
- final _hasWorkStreamController = new StreamController<String>();
+ final _Monitor _hasWork = new _Monitor();
AnalysisDriver(this._logger, this._resourceProvider, this._byteStore,
this._contentCache, this._sourceFactory, this._analysisOptions) {
@@ -203,31 +203,36 @@ class AnalysisDriver {
*/
Stream<AnalysisResult> get results async* {
try {
+ PerformanceLogSection analysisSection = null;
while (true) {
// TODO(scheglov) implement state transitioning
- await for (String why in _hasWorkStreamController.stream) {
- _verifyUnlinkedSignatureOfChangedFiles();
-
- // Analyze the first file in the general queue.
- if (_filesToAnalyze.isNotEmpty) {
- PerformanceLogSection analysisSection =
- _logger.enter('Analyze ${_filesToAnalyze.length} files');
- try {
- // TODO(scheglov) The loop is strange for now.
- while (_filesToAnalyze.isNotEmpty) {
- String path = _filesToAnalyze.first;
- _filesToAnalyze.remove(path);
- _File file = _fileForPath(path);
- AnalysisResult result = _computeAnalysisResult(file);
- yield result;
- }
- } finally {
- analysisSection.exit();
- }
- }
+ await _hasWork.signal;
+
+ if (analysisSection == null) {
+ analysisSection = _logger.enter('Analyzing');
+ }
+
+ // TODO(scheglov) verify one file at a time
+ _verifyUnlinkedSignatureOfChangedFiles();
+
+ // Analyze the first file in the general queue.
+ if (_filesToAnalyze.isNotEmpty) {
+ String path = _filesToAnalyze.first;
+ _filesToAnalyze.remove(path);
+ _File file = _fileForPath(path);
+ AnalysisResult result = _computeAnalysisResult(file);
+ yield result;
+ }
+
+ // If there is work to do, notify the monitor.
+ if (_filesToAnalyze.isNotEmpty) {
+ _hasWork.notify();
+ } else {
+ analysisSection.exit();
+ analysisSection = null;
}
- // TODO(scheglov) implement
}
+ // TODO(scheglov) implement
} finally {
print('The stream was cancelled.');
}
@@ -243,7 +248,7 @@ class AnalysisDriver {
void addFile(String path) {
_explicitFiles.add(path);
_filesToAnalyze.add(path);
- _hasWorkStreamController.add('do it!');
+ _hasWork.notify();
}
/**
@@ -267,7 +272,7 @@ class AnalysisDriver {
void changeFile(String path) {
_filesToVerifyUnlinkedSignature.add(path);
_filesToAnalyze.add(path);
- _hasWorkStreamController.add('do it!');
+ _hasWork.notify();
}
/**
@@ -289,7 +294,7 @@ class AnalysisDriver {
_requestedFiles
.putIfAbsent(path, () => <Completer<AnalysisResult>>[])
.add(completer);
- _hasWorkStreamController.add(path);
+ _hasWork.notify();
return completer.future;
}
@@ -942,6 +947,35 @@ class _LibraryNode {
}
/**
+ * [_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(true);
+ }
+ }
+}
+
+/**
* TODO(scheglov) document
*/
class _ReferencedUris {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698