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'''