Add workspace/didChangeWorkspaceFolders handler with graph-based project unloading#83090
Draft
Add workspace/didChangeWorkspaceFolders handler with graph-based project unloading#83090
Conversation
…ect unloading Agent-Logs-Url: https://github.com/dotnet/roslyn/sessions/b0d7a6c1-3998-4646-91f4-c1f637c574f5 Co-authored-by: JoeRobich <611219+JoeRobich@users.noreply.github.com>
…der disposal in tests Agent-Logs-Url: https://github.com/dotnet/roslyn/sessions/b0d7a6c1-3998-4646-91f4-c1f637c574f5 Co-authored-by: JoeRobich <611219+JoeRobich@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add support for unloading Roslyn LSP projects on workspace folder removal
Add workspace/didChangeWorkspaceFolders handler with graph-based project unloading
Apr 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Roslyn LSP had no handler for
workspace/didChangeWorkspaceFolders, so projects loaded from removed workspace roots were never unloaded. Critically, projects outside workspace folders that are still transitively referenced by in-scope projects must be retained.Core algorithm (
LanguageServerProjectLoader)New
UnloadProjectsNotReachableFromWorkspaceFoldersAsyncperforms a graph-based BFS from retained roots:PathUtilities.IsChildPath)Project.ProjectReferencesfrom each reachable project, retaining any transitively referenced tracked projectTryUnloadProject_NoLockAsyncNon-absolute paths are skipped (containment undefined). Empty workspace folder set → unload all.
Workspace folder state (
LanguageServerProjectSystem)_currentWorkspaceFolderPathstracks the active set (guarded by_folderPathsLock)SetInitialWorkspaceFolderPathsseeds state frominitializeParams.WorkspaceFoldersat startup (called fromAutoLoadProjectsInitializer)OnWorkspaceFoldersChangedAsync(added, removed, ct)applies deltas usingPathUtilities.Comparer, then calls the unload algorithmNew LSP handler (
DidChangeWorkspaceFoldersHandler)Handles
workspace/didChangeWorkspaceFolders, extractsfile:URI folder paths, and delegates toLanguageServerProjectSystem.OnWorkspaceFoldersChangedAsync. Non-file URIs are skipped with a warning.Capability advertisement (
DefaultCapabilitiesProvider)Sets
workspace.workspaceFolders = { supported: true, changeNotifications: true }so clients know to send folder-change notifications.Tests (
WorkspaceFolderChangeTests)Seven focused unit tests using a
TestAccessorto inject fakePrimordialproject state without running design-time builds:App → Core → Util, onlyAppin folder) → all retained/repofolder does not match/repo2/proj.csproj)Original prompt
Implement support in
dotnet/roslynfor unloading Roslyn LSP projects whenworkspace/didChangeWorkspaceFoldersremoves the workspace-folder roots that keep those projects in scope.Repository:
dotnet/roslynBase branch:
mainContext and current state:
src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/LanguageServerProjectLoader.cs.LanguageServerProjectLoaderalready supports explicit unloads viaTryUnloadProjectAsync(...)andUnloadAllProjectsAsync(), and it tracks loaded projects in_loadedProjectskeyed by project path.LanguageServerProjectSysteminsrc/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/LanguageServerProjectSystem.cshandles project loading throughOpenProjectsAsync(...)andOpenSolutionAsync(...).DidChangeWorkspaceFoldersParams,WorkspaceFoldersChangeEvent, andMethods.WorkspaceDidChangeWorkspaceFoldersName.workspace/didChangeWorkspaceFoldersto project unloading.Important additional requirement:
Implementation goals:
Add support for handling
workspace/didChangeWorkspaceFoldersin the Roslyn LSP server.LanguageServerProjectSystemor another appropriate abstraction.Track workspace folders in the project system.
LanguageServerProjectSystemfor setting/updating the active workspace folder paths.Extend
LanguageServerProjectLoaderwith a graph-based unload operation.UnloadProjectsNotReachableFromWorkspaceFoldersAsync(...)._gate.ProjectIdto tracked project path.Project.ProjectReferencesto compute the transitive closure from retained roots.ProjectIdfor a tracked path is reachable, retain that tracked path.TryUnloadProject_NoLockAsync,LoadedProject.Dispose(), primordial project removal) rather than inventing new removal mechanics.Keep race behavior safe.
ReloadProjectAsync(...)already checks_loadedProjectsbefore proceeding; preserve or extend this model so that folder-change-driven unloads do not leave inconsistent state._gateduring expensive work unless already part of the surrounding design.Add logging where useful for diagnosis.
Add or update tests in
src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer.UnitTests/.Please add focused tests covering at least:
Helpful files:
src/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/LanguageServerProjectLoader.cssrc/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/LanguageServerProjectSystem.cssrc/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/OpenProjectsHandler.cssrc/LanguageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/OpenSolutionHandler.csThis pull request was created from Copilot chat.