[Analyzer] Don't create new analysis roots for files opened outside an existing root

Change-Id: I55a0bf44551ba1e7abe810fc3fa5654c6cd4ea8c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/162508
Commit-Queue: Danny Tuppeny <danny@tuppeny.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
index 6e6309a..152ba37 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
@@ -126,7 +126,7 @@
       );
       server.onOverlayCreated(path, doc.text);
 
-      final driver = server.contextManager.getDriverFor(path);
+      final driver = server.getAnalysisDriver(path);
       // If the file did not exist, and is "overlay only", it still should be
       // analyzed. Add it to driver to which it should have been added.
 
diff --git a/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart b/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart
index 3b42924..95e11f4 100644
--- a/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart
+++ b/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart
@@ -192,6 +192,43 @@
     );
   }
 
+  Future<void> test_changeWorkspaceFolders_openFileOutsideRoot() async {
+    // When a file is opened that is outside of the analysis roots, the first
+    // analysis driver will be used (see [AbstractAnalysisServer.getAnalysisDriver]).
+    // This means as long as there is already an analysis root, the implicit root
+    // will be the original root and not the path of the opened file.
+    // For example, Go-to-Definition into a file in PubCache must *not* result in
+    // the pub cache folder being added as an analysis root, it should be analyzed
+    // by the existing project's driver.
+    final workspace1FilePath = join(workspaceFolder1Path, 'test.dart');
+    await newFile(workspace1FilePath);
+    final workspace2FilePath = join(workspaceFolder2Path, 'test.dart');
+    final workspace2FileUri = Uri.file(workspace2FilePath);
+    await newFile(workspace2FilePath);
+
+    await initialize(workspaceFolders: [workspaceFolder1Uri]);
+
+    // Expect explicit root for the workspace folder.
+    expect(
+      server.contextManager.includedPaths,
+      unorderedEquals([workspaceFolder1Path]),
+    );
+
+    // Open a file in workspaceFolder2 (which is not in the analysis roots).
+    await openFile(workspace2FileUri, '');
+    expect(
+      server.contextManager.includedPaths,
+      unorderedEquals([workspaceFolder1Path]),
+    );
+
+    // Closing the file should not result in the project being removed.
+    await closeFile(workspace2FileUri);
+    expect(
+      server.contextManager.includedPaths,
+      unorderedEquals([workspaceFolder1Path]),
+    );
+  }
+
   Future<void> test_changeWorkspaceFolders_remove() async {
     await initialize(
       workspaceFolders: [workspaceFolder1Uri, workspaceFolder2Uri],