Add changeFiles(), use instead of changeFile().
I would like to remove releaseAndClearRemovedIds(), so that methods
of FileResolver call it when necessary, as linkLibraries2(),
dispose() do it.
Change-Id: I494abaffa7a5b8a8360c2750efb5b88b4b5535e9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247926
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Keerti Parthasarathy <keertip@google.com>
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 1f0ecb0..6e30935 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -116,11 +116,11 @@
LibraryContext? libraryContext;
/// List of keys for cache elements that are invalidated. Track elements that
- /// are invalidated during [changeFile]. Used in [releaseAndClearRemovedIds]
+ /// are invalidated during [changeFiles]. Used in [releaseAndClearRemovedIds]
/// to release the cache items and is then cleared.
final Set<String> removedCacheKeys = {};
- /// The cache of file results, cleared on [changeFile].
+ /// The cache of file results, cleared on [changeFiles].
///
/// It is used to allow assists and fixes without resolving the same file
/// multiple times, as we compute more than one assist, or fixes when there
@@ -160,7 +160,17 @@
/// that directly or indirectly referenced it, is resolved, we used the new
/// state of the file. Updates [removedCacheKeys] with the ids of the invalidated
/// items, used in [releaseAndClearRemovedIds] to release the cache items.
+ /// TODO(scheglov) Remove [releaseKeys] when removing [changeFile].
+ @Deprecated('Use changeFiles() instead')
void changeFile(String path) {
+ changeFiles([path], releaseKeys: false);
+ }
+
+ /// Update the resolver to reflect the fact that the files with the given
+ /// [paths] were changed. For each specified file we need to make sure that
+ /// when the file, of any file that directly or indirectly referenced it,
+ /// is resolved, we use the new state of the file.
+ void changeFiles(List<String> paths, {bool releaseKeys = true}) {
if (fsState == null) {
return;
}
@@ -168,19 +178,23 @@
// Forget all results, anything is potentially affected.
cachedResults.clear();
- // Remove this file and all files that transitively depend on it.
- var removedFiles = <FileState>[];
- fsState!.changeFile(path, removedFiles);
+ // Remove the specified files and files that transitively depend on it.
+ final removedFiles = <FileState>[];
+ for (final path in paths) {
+ fsState!.changeFile(path, removedFiles);
+ }
// Schedule disposing references to cached unlinked data.
- for (var removedFile in removedFiles) {
+ for (final removedFile in removedFiles) {
removedCacheKeys.add(removedFile.unlinkedKey);
}
// Remove libraries represented by removed files.
// If we need these libraries later, we will relink and reattach them.
- if (libraryContext != null) {
- libraryContext!.remove(removedFiles, removedCacheKeys);
+ libraryContext?.remove(removedFiles, removedCacheKeys);
+
+ if (releaseKeys) {
+ releaseAndClearRemovedIds();
}
}
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 775ac45..1ad2d13 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -18,13 +18,13 @@
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(FileResolver_changeFile_Test);
+ defineReflectiveTests(FileResolver_changeFiles_Test);
defineReflectiveTests(FileResolverTest);
});
}
@reflectiveTest
-class FileResolver_changeFile_Test extends FileResolutionTest {
+class FileResolver_changeFiles_Test extends FileResolutionTest {
test_changeFile_refreshedFiles() async {
final a = newFile('$testPackageLibPath/a.dart', r'''
class A {}
@@ -128,8 +128,7 @@
assertStateString(state_1);
// Change a.dart, discard data for a.dart and c.dart, but not b.dart
- fileResolver.changeFile(a.path);
- fileResolver.releaseAndClearRemovedIds();
+ fileResolver.changeFiles([a.path]);
assertStateString(r'''
files
/sdk/lib/_internal/internal.dart
@@ -294,7 +293,7 @@
class A {}
class B {}
''');
- fileResolver.changeFile(a.path);
+ fileResolver.changeFiles([a.path]);
result = await resolveFile(b.path);
assertErrorsInResolvedUnit(result, []);
@@ -325,7 +324,7 @@
int foo = 0;
}
''');
- fileResolver.changeFile(a.path);
+ fileResolver.changeFiles([a.path]);
result = await resolveFile(b.path);
assertErrorsInResolvedUnit(result, []);
@@ -351,7 +350,7 @@
var b = B(1);
''');
- fileResolver.changeFile(a.path);
+ fileResolver.changeFiles([a.path]);
// Update b.dart, but do not notify the resolver.
// If we try to read it now, it will throw.
@@ -368,7 +367,7 @@
}, throwsStateError);
// Notify the resolver about b.dart, it is OK now.
- fileResolver.changeFile(b.path);
+ fileResolver.changeFiles([b.path]);
result = await resolveFile(a.path);
assertErrorsInResolvedUnit(result, []);
}
@@ -448,8 +447,7 @@
''');
// Change b.dart, discard both b.dart and a.dart
- fileResolver.changeFile(b.path);
- fileResolver.releaseAndClearRemovedIds();
+ fileResolver.changeFiles([b.path]);
assertStateString(r'''
files
/sdk/lib/_internal/internal.dart
@@ -653,8 +651,7 @@
''');
// Should invalidate a.dart, b.dart, c.dart
- fileResolver.changeFile(b.path);
- fileResolver.releaseAndClearRemovedIds();
+ fileResolver.changeFiles([b.path]);
assertStateString(r'''
files
/sdk/lib/_internal/internal.dart
@@ -1007,7 +1004,7 @@
var dartCorePath = a_result.session.uriConverter.uriToPath(
Uri.parse('dart:core'),
)!;
- fileResolver.changeFile(dartCorePath);
+ fileResolver.changeFiles([dartCorePath]);
// Analyze, this will read the element model for `dart:core`.
// There was a bug that `root::dart:core::dynamic` had no element set.
@@ -1360,7 +1357,7 @@
// Change the file, will be resolved again.
newFile(testFilePath, 'var a = c;');
- fileResolver.changeFile(testFile.path);
+ fileResolver.changeFiles([testFile.path]);
expect((await getTestErrors()).errors, hasLength(1));
_assertResolvedFiles([testFile]);
}
@@ -1392,7 +1389,7 @@
newFile(a.path, r'''
var a = 4.2;
''');
- fileResolver.changeFile(a.path);
+ fileResolver.changeFiles([a.path]);
expect((await getTestErrors()).errors, hasLength(1));
_assertResolvedFiles([testFile]);
}
@@ -2554,7 +2551,7 @@
// Change a file.
var a_path = convertPath('/workspace/dart/test/lib/a.dart');
- fileResolver.changeFile(a_path);
+ fileResolver.changeFiles([a_path]);
// The was a change to a file, no matter which, resolve again.
await resolveFile2(testFile.path);