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 01c66563862b88f6803bdd3c718ccc09c8cee0c5..b01894771a07a1420283a7a2b322160cf8afaffe 100644 |
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart |
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart |
@@ -119,11 +119,10 @@ class AnalysisDriver { |
final _explicitFiles = new LinkedHashSet<String>(); |
/** |
- * The set of files were reported as changed through [changeFile] and for |
- * which API signatures should be recomputed and compared before performing |
- * any other analysis. |
+ * The set of files were reported as changed through [changeFile] and not |
+ * checked for actual changes yet. |
*/ |
- final _filesToVerifyUnlinkedSignature = new Set<String>(); |
+ final _changedFiles = new LinkedHashSet<String>(); |
/** |
* The set of files that are currently scheduled for analysis. |
@@ -205,32 +204,36 @@ class AnalysisDriver { |
try { |
PerformanceLogSection analysisSection = null; |
while (true) { |
- // TODO(scheglov) implement state transitioning |
await _hasWork.signal; |
+ // TODO(scheglov) implement state transitioning |
if (analysisSection == null) { |
analysisSection = _logger.enter('Analyzing'); |
} |
- // TODO(scheglov) verify one file at a time |
- _verifyUnlinkedSignatureOfChangedFiles(); |
+ // Verify all changed files one at a time. |
+ if (_changedFiles.isNotEmpty) { |
+ String path = _removeFirst(_changedFiles); |
+ _verifyApiSignatureOfChangedFile(path); |
+ // Repeat the processing loop. |
+ _hasWork.notify(); |
+ continue; |
+ } |
// Analyze the first file in the general queue. |
if (_filesToAnalyze.isNotEmpty) { |
- String path = _filesToAnalyze.first; |
- _filesToAnalyze.remove(path); |
+ String path = _removeFirst(_filesToAnalyze); |
_File file = _fileForPath(path); |
AnalysisResult result = _computeAnalysisResult(file); |
yield result; |
- } |
- |
- // If there is work to do, notify the monitor. |
- if (_filesToAnalyze.isNotEmpty) { |
+ // Repeat the processing loop. |
_hasWork.notify(); |
- } else { |
- analysisSection.exit(); |
- analysisSection = null; |
+ continue; |
} |
+ |
+ // There is nothing to do. |
+ analysisSection.exit(); |
+ analysisSection = null; |
} |
// TODO(scheglov) implement |
} finally { |
@@ -270,7 +273,7 @@ class AnalysisDriver { |
* [changeFile] invocation. |
*/ |
void changeFile(String path) { |
- _filesToVerifyUnlinkedSignature.add(path); |
+ _changedFiles.add(path); |
_filesToAnalyze.add(path); |
_hasWork.notify(); |
} |
@@ -517,42 +520,38 @@ class AnalysisDriver { |
} |
/** |
- * Verify the API signatures for the changed files, and decide which linked |
- * libraries should be invalidated, and files reanalyzed. |
+ * Verify the API signature for the file with the given [path], and decide |
+ * which linked libraries should be invalidated, and files reanalyzed. |
* |
* TODO(scheglov) I see that adding a local var changes (full) API signature. |
*/ |
- void _verifyUnlinkedSignatureOfChangedFiles() { |
- if (_filesToVerifyUnlinkedSignature.isEmpty) { |
- return; |
- } |
- int numOfFiles = _filesToVerifyUnlinkedSignature.length; |
- _logger.run('Verify API signatures of $numOfFiles files', () { |
- bool hasMismatch = false; |
- for (String path in _filesToVerifyUnlinkedSignature) { |
- String oldSignature = _fileApiSignatureMap[path]; |
- // Compute the new API signature. |
- // _File.forResolution() also updates the content hash in the cache. |
- _File newFile = _fileForPath(path); |
- String newSignature = newFile.unlinked.apiSignature; |
- // If the old API signature is not null, then the file was used to |
- // compute at least one dependency signature. If the new API signature |
- // is different, then potentially all dependency signatures and |
- // resolution results are invalid. |
- if (oldSignature != null && oldSignature != newSignature) { |
- _logger.writeln('API signature mismatch found for $newFile.'); |
- hasMismatch = true; |
- } |
- } |
- if (hasMismatch) { |
+ void _verifyApiSignatureOfChangedFile(String path) { |
+ _logger.run('Verify API signature of $path', () { |
+ String oldSignature = _fileApiSignatureMap[path]; |
+ // Compute the new API signature. |
+ // _File.forResolution() also updates the content hash in the cache. |
+ _File newFile = _fileForPath(path); |
+ String newSignature = newFile.unlinked.apiSignature; |
+ // If the old API signature is not null, then the file was used to |
+ // compute at least one dependency signature. If the new API signature |
+ // is different, then potentially all dependency signatures and |
+ // resolution results are invalid. |
+ if (oldSignature != null && oldSignature != newSignature) { |
+ _logger.writeln('API signatures mismatch found for $newFile'); |
_dependencySignatureMap.clear(); |
_filesToAnalyze.addAll(_explicitFiles); |
- } else { |
- _logger.writeln('All API signatures match.'); |
} |
- _filesToVerifyUnlinkedSignature.clear(); |
}); |
} |
+ |
+ /** |
+ * Remove and return the first item in the given [set]. |
+ */ |
+ static Object/*=T*/ _removeFirst/*<T>*/(LinkedHashSet<Object/*=T*/ > set) { |
+ Object/*=T*/ element = set.first; |
+ set.remove(element); |
+ return element; |
+ } |
} |
/** |