Return potentially affected files from applyPendingFileChanges()
Change-Id: I7a9410a5ba8a2cdbc2fd44fb5e25c311569696ab
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/237180
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/dart/analysis/analysis_context.dart b/pkg/analyzer/lib/dart/analysis/analysis_context.dart
index b30e1fc..68fb611 100644
--- a/pkg/analyzer/lib/dart/analysis/analysis_context.dart
+++ b/pkg/analyzer/lib/dart/analysis/analysis_context.dart
@@ -38,5 +38,12 @@
/// Return a [Future] that completes after pending file changes are applied,
/// so that [currentSession] can be used to compute results.
- Future<void> applyPendingFileChanges();
+ ///
+ /// The value is the set of all files that are potentially affected by
+ /// the pending changes. This set can be both wider than the set of analyzed
+ /// files (because it may include files imported from other packages, and
+ /// which are on the import path from a changed file to an analyze file),
+ /// and narrower than the set of analyzed files (because only files that
+ /// were previously accessed are considered to be known and affected).
+ Future<List<String>> applyPendingFileChanges();
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index bf8129f..562528c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -145,8 +145,12 @@
/// The file changes that should be applied before processing requests.
final List<_FileChange> _pendingFileChanges = [];
+ /// When [_applyFileChangesSynchronously] is `true`, affected files are
+ /// accumulated here.
+ Set<String> _accumulatedAffected = {};
+
/// The completers to complete after [_pendingFileChanges] are applied.
- final _pendingFileChangesCompleters = <Completer<void>>[];
+ final _pendingFileChangesCompleters = <Completer<List<String>>>[];
/// The mapping from the files for which analysis was requested using
/// [getResult] to the [Completer]s to report the result.
@@ -453,7 +457,7 @@
if (file_paths.isDart(resourceProvider.pathContext, path)) {
_priorityResults.clear();
if (_applyFileChangesSynchronously) {
- _removePotentiallyAffectedLibraries(path);
+ _removePotentiallyAffectedLibraries(_accumulatedAffected, path);
_fileTracker.addFile(path);
} else {
_pendingFileChanges.add(
@@ -466,13 +470,22 @@
/// Return a [Future] that completes after pending file changes are applied,
/// so that [currentSession] can be used to compute results.
- Future<void> applyPendingFileChanges() {
+ ///
+ /// The value is the set of all files that are potentially affected by
+ /// the pending changes. This set can be both wider than the set of analyzed
+ /// files (because it may include files imported from other packages, and
+ /// which are on the import path from a changed file to an analyze file),
+ /// and narrower than the set of analyzed files (because only files that
+ /// were previously accessed are considered to be known and affected).
+ Future<List<String>> applyPendingFileChanges() {
if (_pendingFileChanges.isNotEmpty) {
- var completer = Completer<void>();
+ var completer = Completer<List<String>>();
_pendingFileChangesCompleters.add(completer);
return completer.future;
} else {
- return Future.value();
+ var accumulatedAffected = _accumulatedAffected.toList();
+ _accumulatedAffected = {};
+ return Future.value(accumulatedAffected);
}
}
@@ -500,7 +513,7 @@
if (file_paths.isDart(resourceProvider.pathContext, path)) {
_priorityResults.clear();
if (_applyFileChangesSynchronously) {
- _removePotentiallyAffectedLibraries(path);
+ _removePotentiallyAffectedLibraries(_accumulatedAffected, path);
_fileTracker.changeFile(path);
} else {
_pendingFileChanges.add(
@@ -1386,7 +1399,7 @@
_lastProducedSignatures.remove(path);
_priorityResults.clear();
if (_applyFileChangesSynchronously) {
- _removePotentiallyAffectedLibraries(path);
+ _removePotentiallyAffectedLibraries(_accumulatedAffected, path);
_fileTracker.removeFile(path);
} else {
_pendingFileChanges.add(
@@ -1464,9 +1477,10 @@
}
void _applyPendingFileChanges() {
+ var accumulatedAffected = <String>{};
for (var fileChange in _pendingFileChanges) {
var path = fileChange.path;
- _removePotentiallyAffectedLibraries(path);
+ _removePotentiallyAffectedLibraries(accumulatedAffected, path);
switch (fileChange.kind) {
case _FileChangeKind.add:
_fileTracker.addFile(path);
@@ -1485,7 +1499,9 @@
var completers = _pendingFileChangesCompleters.toList();
_pendingFileChangesCompleters.clear();
for (var completer in completers) {
- completer.complete();
+ completer.complete(
+ accumulatedAffected.toList(),
+ );
}
}
}
@@ -1896,12 +1912,16 @@
'missing', errorsResult, AnalysisDriverUnitIndexBuilder());
}
- void _removePotentiallyAffectedLibraries(String path) {
+ void _removePotentiallyAffectedLibraries(
+ Set<String> accumulatedAffected,
+ String path,
+ ) {
var affected = <FileState>{};
_fsState.collectAffected(path, affected);
for (var file in affected) {
file.invalidateLibraryCycle();
+ accumulatedAffected.add(file.path);
}
_libraryContext?.elementFactory.removeLibraries(
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
index b00038a..79b54c0 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
@@ -55,7 +55,7 @@
}
@override
- Future<void> applyPendingFileChanges() {
+ Future<List<String>> applyPendingFileChanges() {
return driver.applyPendingFileChanges();
}
}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 5c33990..1bfe413 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -790,10 +790,10 @@
var b = newFile2('/test/lib/b.dart', '''
import 'a.dart';
''');
- newFile2('/test/lib/c.dart', '''
+ var c = newFile2('/test/lib/c.dart', '''
import 'b.dart';
''');
- newFile2('/test/lib/d.dart', '''
+ var d = newFile2('/test/lib/d.dart', '''
import 'c.dart';
''');
newFile2('/test/lib/e.dart', '');
@@ -832,7 +832,8 @@
// Change `b.dart`, also removes `c.dart` and `d.dart` that import it.
// But `a.dart` and `d.dart` is not affected.
driver.changeFile(b.path);
- await driver.applyPendingFileChanges();
+ var affectedPathList = await driver.applyPendingFileChanges();
+ expect(affectedPathList, unorderedEquals([b.path, c.path, d.path]));
// We have a new session.
var session2 = driver.currentSession;
@@ -863,10 +864,10 @@
var a = newFile2('/test/lib/a.dart', '''
part of 'b.dart';
''');
- newFile2('/test/lib/b.dart', '''
+ var b = newFile2('/test/lib/b.dart', '''
part 'a.dart';
''');
- newFile2('/test/lib/c.dart', '''
+ var c = newFile2('/test/lib/c.dart', '''
import 'b.dart';
''');
newFile2('/test/lib/d.dart', '');
@@ -900,7 +901,13 @@
// Removes `c.dart` that imports `b.dart`.
// But `d.dart` is not affected.
driver.changeFile(a.path);
- await driver.applyPendingFileChanges();
+ var affectedPathList = await driver.applyPendingFileChanges();
+ expect(affectedPathList, unorderedEquals([a.path, b.path, c.path]));
+
+ // We have a new session.
+ var session2 = driver.currentSession;
+ expect(session2, isNot(session1));
+
driver.assertLoadedLibraryUriSet(
excluded: [
'package:test/b.dart',
@@ -911,10 +918,6 @@
],
);
- // We have a new session.
- var session2 = driver.currentSession;
- expect(session2, isNot(session1));
-
// `d.dart` moved to the new session.
// Invalidated libraries stuck with the old session.
expect(b_element.session, session1);