Do nothing if [changeFile] reported, but the file content is the same.

R=brianwilkerson@google.com, paulberry@google.com
BUG=

Review URL: https://codereview.chromium.org/2458853003 .
This commit is contained in:
Konstantin Shcheglov 2016-10-28 14:08:50 -07:00
parent 89560c68a0
commit 1ffda5601b
2 changed files with 42 additions and 8 deletions

View file

@ -208,12 +208,6 @@ class AnalysisDriver {
* "analyzing" and an analysis result is produced for every added file prior
* to the next time the analysis state transitions to "idle".
*
* At least one analysis result is produced for every file passed to
* [addFile] or [changeFile] prior to the next time the analysis state
* transitions to "idle", unless the file is later removed from analysis
* using [removeFile]. Analysis results for other files are produced only if
* the changes affect analysis results of other files.
*
* More than one result might be produced for the same file, even if the
* client does not change the state of the files.
*
@ -305,6 +299,11 @@ class AnalysisDriver {
* The [path] must be absolute and normalized.
*
* The results of analysis are eventually produced by the [results] stream.
*
* Causes the analysis state to transition to "analyzing" (if it is not in
* that state already). At least one analysis result will be produced the
* file prior to the next time the analysis state transitions to "idle",
* unless the file is later removed from analysis using [removeFile].
*/
void addFile(String path) {
_explicitFiles.add(path);
@ -326,6 +325,11 @@ class AnalysisDriver {
* into the current file state prior to the next time the analysis state
* transitions to "idle".
*
* If the file content is the same, no new results will be produced because
* of this notification, including no result for the file itself. Otherwise,
* one or more results will be produced - for the file itself and other
* files that that change in the file might affect.
*
* Invocation of this method will not prevent a [Future] returned from
* [getResult] from completing with a result, but the result is not
* guaranteed to be consistent with the new current file state after this
@ -681,16 +685,22 @@ class AnalysisDriver {
*/
void _verifyApiSignatureOfChangedFile(String path) {
_logger.run('Verify API signature of $path', () {
String oldContentHash = _fileContentHashMap[path];
String oldSignature = _fileApiSignatureMap[path];
// Compute the new API signature.
// _File.forResolution() also updates the content hash in the cache.
Source source = _sourceForPath(path);
_File newFile = new _File.forResolution(this, source);
String newSignature = newFile.unlinked.apiSignature;
// If the file content hash is the same, we don't need analyzing it.
if (newFile.contentHash == oldContentHash) {
_filesToAnalyze.remove(path);
return;
}
// 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.
String newSignature = newFile.unlinked.apiSignature;
if (oldSignature != null && oldSignature != newSignature) {
_logger.writeln('API signatures mismatch found for $newFile');
_dependencySignatureMap.clear();

View file

@ -77,7 +77,7 @@ class DriverTest {
})
], null, provider),
new AnalysisOptionsImpl()..strongMode = true);
driver.status.lastWhere((status) {
driver.status.listen((status) {
allStatuses.add(status);
if (status.isIdle) {
idleStatusMonitor.notify();
@ -141,6 +141,30 @@ var A = B;
}
}
test_changeFile_noContentChange_noNewResult() async {
_addTestFile('main() {}', priority: true);
// Initial analysis.
await _waitForIdle();
expect(allResults, hasLength(1));
// Update the file, but don't notify the driver.
// Don't update the file in the file system.
// But tell the driver the the file was changed.
// The driver should eventually check the file and ignore.
allStatuses.clear();
allResults.clear();
driver.changeFile(testFile);
// The driver switched to analysis and back to idle.
await _waitForIdle();
expect(allStatuses, hasLength(2));
expect(allStatuses.map((status) => status.isAnalyzing), [true, false]);
// No new results.
expect(allResults, isEmpty);
}
test_changeFile_selfConsistent() async {
var a = _p('/test/lib/a.dart');
var b = _p('/test/lib/b.dart');