-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Ensure LspWorkspaceManager returns solutions without misc document when file moved
#80535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
GetTextDocumentAsync returning different document from request context
...ageServer/Microsoft.CodeAnalysis.LanguageServer.UnitTests/FileBasedProgramsWorkspaceTests.cs
Outdated
Show resolved
Hide resolved
...ageServer/Microsoft.CodeAnalysis.LanguageServer.UnitTests/FileBasedProgramsWorkspaceTests.cs
Outdated
Show resolved
Hide resolved
...ageServer/Microsoft.CodeAnalysis.LanguageServer.UnitTests/FileBasedProgramsWorkspaceTests.cs
Outdated
Show resolved
Hide resolved
...ageServer/Microsoft.CodeAnalysis.LanguageServer.UnitTests/FileBasedProgramsWorkspaceTests.cs
Outdated
Show resolved
Hide resolved
GetTextDocumentAsync returning different document from request contextLspWorkspaceManager returns solutions without misc document when file moved
| // The first call should return a document in the misc files workspace. | ||
| var (_, miscDocument) = await GetLspWorkspaceAndDocumentAsync(newDocumentUri, testLspServer).ConfigureAwait(false); | ||
| Assert.NotNull(miscDocument); | ||
| Assert.True(await testLspServer.GetManagerAccessor().IsMiscellaneousFilesDocumentAsync(miscDocument)); | ||
| Assert.Equal(WorkspaceKind.MiscellaneousFiles, miscDocument.Project.Solution.Workspace.Kind); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this technically a race if the project system were to load it first? It seems terribly unlikely, but still.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not currently, no. This is what happens
- Nothing happens when the document is opened, the text is just saved.
GetLspWorkspaceAndDocumentAsyncsearches the workspaces, doesn't find the doc and then calls into the misc providerAddMiscellaneousDocumentAsync.- FBP misc provider creates the 'primordial' document in the misc workspace and triggers the load of the FBP program (adds to the batch).
- FBP misc provider always returns the primordial document.
So even if the FBP project load completed instantly, the FBP misc provider still just returns the primordial document from AddMiscellaneousDocumentAsync.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right! Makes sense...does that deserve a comment?
jasonmalinowski
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code change is great; not sure if the test can be unified with another one in the base or moved down to the base, but that's not critical.
| } | ||
|
|
||
| [Theory, CombinatorialData] | ||
| public async Task TestLspTransfersFromFileBasedProgramToHostWorkspaceDocumentOrderingAsync(bool mutatingLspWorkspace) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not entirely clear to me how this test is much different than TestLspTransfersFromMiscellaneousFilesToHostWorkspaceAsync test already in the base. I'd expect we should be able to push it to the base class anyways.
src/LanguageServer/Protocol/Workspaces/ILspMiscellaneousFilesWorkspaceProvider.cs
Show resolved
Hide resolved
...ageServer/Microsoft.CodeAnalysis.LanguageServer/HostWorkspace/LanguageServerProjectLoader.cs
Outdated
Show resolved
Hide resolved
| // The first call should return a document in the misc files workspace. | ||
| var (_, miscDocument) = await GetLspWorkspaceAndDocumentAsync(newDocumentUri, testLspServer).ConfigureAwait(false); | ||
| Assert.NotNull(miscDocument); | ||
| Assert.True(await testLspServer.GetManagerAccessor().IsMiscellaneousFilesDocumentAsync(miscDocument)); | ||
| Assert.Equal(WorkspaceKind.MiscellaneousFiles, miscDocument.Project.Solution.Workspace.Kind); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right! Makes sense...does that deserve a comment?
Resolves https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2576168
When the diagnostics handler was looking up documentIds to compare the previous results, it uses
GetTextDocumentAsyncon the LSP text doc identifier. However, in document pull, the diagnostics originally get computed against therequestContext.Document, as determined by the LspWorkspaceManager.Generally this is not an issue, the lookup from document URI -> document is intended to be stable, regardless of if a project context is provided or not.
However this was broken with file based programs. Consider the following sequence:
DocumentIdfromrequestContext.DocumentandrequestContext.Solution.GetTextDocumentAsync. Because of 4), these are now different and the handler attempts to report diagnostics for the document and the document as being removed in the same call.The fix I made here is to remove the document from the misc provider, and re-lookup the document. This ensures the misc document is not part of the solution that is given to the handler. The queue was already blocked on removing the file from misc anyway, so we might as well read that result.