Don't cache ResolvedLibraryResult(s) for partial / completion results.
Change-Id: I2212b8032d90f7959639f51f92eded3a3bd44003
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207381
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@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 e11ec7f..aa4627e 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -39,6 +39,7 @@
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:collection/collection.dart';
+import 'package:meta/meta.dart';
import 'package:yaml/yaml.dart';
const M = 1024 * 1024 /*1 MiB*/;
@@ -109,7 +110,8 @@
/// 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
/// are more than one error on a line.
- final Map<String, ResolvedLibraryResult> _cachedResults = {};
+ @visibleForTesting
+ final Map<String, ResolvedLibraryResult> cachedResults = {};
FileResolver(
PerformanceLog logger,
@@ -164,7 +166,7 @@
}
// Forget all results, anything is potentially affected.
- _cachedResults.clear();
+ cachedResults.clear();
// Remove this file and all files that transitively depend on it.
var removedFiles = <FileState>[];
@@ -445,24 +447,16 @@
}
}
- var libraryUnit = resolveLibrary(
+ var libraryResult = resolveLibrary(
completionLine: completionLine,
completionColumn: completionColumn,
path: libraryFile.path,
- completionPath: path,
+ completionPath: completionLine != null ? path : null,
performance: performance,
);
- var result =
- libraryUnit.units.firstWhereOrNull((element) => element.path == path);
- // TODO(scheglov) Fix and remove.
- if (result == null) {
- throw StateError('''
-libraryFile.path: ${libraryFile.path}
-path: $path
-units: ${libraryUnit.units.map((e) => '(${e.uri} = ${e.path})').toList()}
-''');
- }
- return result;
+ return libraryResult.units.firstWhere(
+ (unitResult) => unitResult.path == path,
+ );
});
}
@@ -478,7 +472,7 @@
performance ??= OperationPerformanceImpl('<default>');
- var cachedResult = _cachedResults[path];
+ var cachedResult = cachedResults[path];
if (cachedResult != null) {
return cachedResult;
}
@@ -570,7 +564,11 @@
var libraryUnit = resolvedUnits.first;
var result = ResolvedLibraryResultImpl(contextObjects!.analysisSession,
path, libraryUnit.uri, libraryUnit.libraryElement, resolvedUnits);
- _cachedResults[path] = result;
+
+ if (completionPath == null) {
+ cachedResults[path] = result;
+ }
+
return result;
});
}
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 c791be7..0944438 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
@@ -1059,17 +1059,21 @@
newFile(path, content: 'var a = 0;');
// No resolved files yet.
- expect(fileResolver.testView!.resolvedFiles, isEmpty);
+ var testView = fileResolver.testView!;
+ expect(testView.resolvedFiles, isEmpty);
await resolveFile2(path);
var result1 = result;
// The file was resolved.
- expect(fileResolver.testView!.resolvedFiles, [path]);
+ expect(testView.resolvedFiles, [path]);
+
+ // The result is cached.
+ expect(fileResolver.cachedResults, contains(path));
// Ask again, no changes, not resolved.
await resolveFile2(path);
- expect(fileResolver.testView!.resolvedFiles, [path]);
+ expect(testView.resolvedFiles, [path]);
// The same result was returned.
expect(result, same(result1));
@@ -1080,12 +1084,41 @@
// The was a change to a file, no matter which, resolve again.
await resolveFile2(path);
- expect(fileResolver.testView!.resolvedFiles, [path, path]);
+ expect(testView.resolvedFiles, [path, path]);
// Get should get a new result.
expect(result, isNot(same(result1)));
}
+ test_resolveFile_dontCache_whenForCompletion() async {
+ var a_path = convertPath('/workspace/dart/test/lib/a.dart');
+ newFile(a_path, content: r'''
+part 'b.dart';
+''');
+
+ var b_path = convertPath('/workspace/dart/test/lib/b.dart');
+ newFile(b_path, content: r'''
+part of 'a.dart';
+''');
+
+ // No resolved files yet.
+ var testView = fileResolver.testView!;
+ expect(testView.resolvedFiles, isEmpty);
+
+ fileResolver.resolve(
+ path: b_path,
+ completionLine: 0,
+ completionColumn: 0,
+ );
+
+ // The file was resolved.
+ expect(testView.resolvedFiles, [a_path]);
+
+ // The completion location was set, so not units are resolved.
+ // So, the result should not be cached.
+ expect(fileResolver.cachedResults, isEmpty);
+ }
+
test_resolveLibrary() async {
var aPath = convertPath('/workspace/dart/test/lib/a.dart');
newFile(aPath, content: r'''