Skip to content
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

Revert "Query workspace for active document when we are not passed a project context in an LSP request" #54451

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 10 additions & 17 deletions src/Features/LanguageServer/Protocol/Extensions/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,30 +88,23 @@ private static ImmutableArray<Document> FilterDocumentsByClientName(ImmutableArr
return documents.FindDocumentInProjectContext(documentIdentifier);
}

public static Document FindDocumentInProjectContext(this ImmutableArray<Document> documents, TextDocumentIdentifier documentIdentifier)
public static T FindDocumentInProjectContext<T>(this ImmutableArray<T> documents, TextDocumentIdentifier documentIdentifier) where T : TextDocument
{
if (documents.Length > 1)
{
// We have more than one document; try to find the one that matches the right context
if (documentIdentifier is VSTextDocumentIdentifier vsDocumentIdentifier && vsDocumentIdentifier.ProjectContext != null)
if (documentIdentifier is VSTextDocumentIdentifier vsDocumentIdentifier)
{
var projectId = ProtocolConversions.ProjectContextToProjectId(vsDocumentIdentifier.ProjectContext);
var matchingDocument = documents.FirstOrDefault(d => d.Project.Id == projectId);

if (matchingDocument != null)
if (vsDocumentIdentifier.ProjectContext != null)
{
return matchingDocument;
}
}
else
{
// We were not passed a project context. This can happen when the LSP powered NavBar is not enabled.
// This branch should be removed when we're using the LSP based navbar in all scenarios.
var projectId = ProtocolConversions.ProjectContextToProjectId(vsDocumentIdentifier.ProjectContext);
var matchingDocument = documents.FirstOrDefault(d => d.Project.Id == projectId);

var solution = documents.First().Project.Solution;
// Lookup which of the linked documents is currently active in the workspace.
var documentIdInCurrentContext = solution.Workspace.GetDocumentIdInCurrentContext(documents.First().Id);
return solution.GetRequiredDocument(documentIdInCurrentContext);
if (matchingDocument != null)
{
return matchingDocument;
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Test;
using Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Experiments;
using Microsoft.CodeAnalysis.LanguageServer.Handler;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.SolutionCrawler;
using Microsoft.CodeAnalysis.Test.Utilities;
Expand All @@ -37,7 +35,7 @@ public async Task TestNoDocumentDiagnosticsForClosedFilesWithFSAOff()

var document = testLspServer.GetCurrentSolution().Projects.Single().Documents.Single();

var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document.GetURI());
var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document);

Assert.Empty(results);
}
Expand All @@ -57,7 +55,7 @@ public async Task TestDocumentDiagnosticsForOpenFilesWithFSAOff()
await OpenDocumentAsync(testLspServer, document);

var results = await RunGetDocumentPullDiagnosticsAsync(
testLspServer, document.GetURI());
testLspServer, testLspServer.GetCurrentSolution().Projects.Single().Documents.Single());

Assert.Equal("CS1513", results.Single().Diagnostics.Single().Code);
}
Expand All @@ -76,7 +74,7 @@ public async Task TestNoDocumentDiagnosticsForOpenFilesWithFSAOffIfInPushMode()

await OpenDocumentAsync(testLspServer, document);

var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document.GetURI());
var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document);

Assert.Empty(results.Single().Diagnostics);
}
Expand Down Expand Up @@ -141,7 +139,7 @@ public async Task TestDocumentDiagnosticsForRemovedDocument()
await WaitForDiagnosticsAsync(workspace);
var results = await testLspServer.ExecuteRequestAsync<DocumentDiagnosticsParams, DiagnosticReport[]>(
MSLSPMethods.DocumentPullDiagnosticName,
CreateDocumentDiagnosticParams(document.GetURI()),
CreateDocumentDiagnosticParams(document),
new LSP.ClientCapabilities(),
clientName: null,
CancellationToken.None);
Expand Down Expand Up @@ -179,13 +177,13 @@ public async Task TestNoChangeIfDocumentDiagnosticsCalledTwice()

await OpenDocumentAsync(testLspServer, document);

var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document.GetURI());
var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document);

Assert.Equal("CS1513", results.Single().Diagnostics.Single().Code);

var resultId = results.Single().ResultId;
results = await RunGetDocumentPullDiagnosticsAsync(
testLspServer, document.GetURI(), previousResultId: resultId);
testLspServer, testLspServer.GetCurrentSolution().Projects.Single().Documents.Single(), previousResultId: resultId);

Assert.Null(results.Single().Diagnostics);
Assert.Equal(resultId, results.Single().ResultId);
Expand All @@ -205,13 +203,13 @@ public async Task TestDocumentDiagnosticsRemovedAfterErrorIsFixed()

await OpenDocumentAsync(testLspServer, document);

var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document.GetURI());
var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document);

Assert.Equal("CS1513", results[0].Diagnostics.Single().Code);

await InsertTextAsync(testLspServer, document, buffer.CurrentSnapshot.Length, "}");

results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document.GetURI());
results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, testLspServer.GetCurrentSolution().Projects.Single().Documents.Single());

Assert.Empty(results[0].Diagnostics);
}
Expand All @@ -229,7 +227,7 @@ public async Task TestDocumentDiagnosticsRemainAfterErrorIsNotFixed()
var document = testLspServer.GetCurrentSolution().Projects.Single().Documents.Single();

await OpenDocumentAsync(testLspServer, document);
var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document.GetURI());
var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document);

Assert.Equal("CS1513", results[0].Diagnostics.Single().Code);
Assert.Equal(new Position { Line = 0, Character = 9 }, results[0].Diagnostics.Single().Range.Start);
Expand All @@ -238,7 +236,7 @@ public async Task TestDocumentDiagnosticsRemainAfterErrorIsNotFixed()
await InsertTextAsync(testLspServer, document, position: 0, text: " ");

results = await RunGetDocumentPullDiagnosticsAsync(
testLspServer, document.GetURI(),
testLspServer, testLspServer.GetCurrentSolution().Projects.Single().Documents.Single(),
previousResultId: results[0].ResultId);

Assert.Equal("CS1513", results[0].Diagnostics.Single().Code);
Expand Down Expand Up @@ -276,56 +274,12 @@ public async Task TestStreamingDocumentDiagnostics()
await OpenDocumentAsync(testLspServer, document);

var progress = BufferedProgress.Create<DiagnosticReport>(null);
var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, document.GetURI(), progress: progress);
var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, testLspServer.GetCurrentSolution().Projects.Single().Documents.Single(), progress: progress);

Assert.Null(results);
Assert.Equal("CS1513", progress.GetValues()!.Single().Diagnostics.Single().Code);
}

[Fact]
public async Task TestDocumentDiagnosticsForOpenFilesUsesActiveContext()
{
var documentText =
@"#if ONE
class A {
#endif
class B {";
var workspaceXml =
@$"<Workspace>
<Project Language=""C#"" CommonReferences=""true"" AssemblyName=""CSProj1"" PreprocessorSymbols=""ONE"">
<Document FilePath=""C:\C.cs"">{documentText}</Document>
</Project>
<Project Language=""C#"" CommonReferences=""true"" AssemblyName=""CSProj2"">
<Document IsLinkFile=""true"" LinkFilePath=""C:\C.cs"" LinkAssemblyName=""CSProj1"">{documentText}</Document>
</Project>
</Workspace>";

using var testLspServer = CreateTestWorkspaceFromXml(workspaceXml, BackgroundAnalysisScope.OpenFilesAndProjects);

var csproj1Document = testLspServer.GetCurrentSolution().Projects.Where(p => p.Name == "CSProj1").Single().Documents.First();
var csproj2Document = testLspServer.GetCurrentSolution().Projects.Where(p => p.Name == "CSProj2").Single().Documents.First();

// Open either of the documents via LSP, we're tracking the URI and text.
await OpenDocumentAsync(testLspServer, csproj1Document);

// This opens all documents in the workspace and ensures buffers are created.
testLspServer.TestWorkspace.GetTestDocument(csproj1Document.Id).GetTextBuffer();

// Set CSProj2 as the active context and get diagnostics.
testLspServer.TestWorkspace.SetDocumentContext(csproj2Document.Id);
var results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, csproj2Document.GetURI());
Assert.Equal("CS1513", results.Single().Diagnostics.Single().Code);
var vsDiagnostic = (LSP.VSDiagnostic)results.Single().Diagnostics.Single();
Assert.Equal("CSProj2", vsDiagnostic.Projects.Single().ProjectName);

// Set CSProj1 as the active context and get diagnostics.
testLspServer.TestWorkspace.SetDocumentContext(csproj1Document.Id);
results = await RunGetDocumentPullDiagnosticsAsync(testLspServer, csproj1Document.GetURI());
Assert.Equal(2, results.Single().Diagnostics!.Length);
Assert.All(results.Single().Diagnostics, d => Assert.Equal("CS1513", d.Code));
Assert.All(results.Single().Diagnostics, d => Assert.Equal("CSProj1", ((VSDiagnostic)d).Projects.Single().ProjectName));
}

#endregion

#region Workspace Diagnostics
Expand Down Expand Up @@ -526,15 +480,15 @@ public async Task TestStreamingWorkspaceDiagnostics()

private static async Task<DiagnosticReport[]> RunGetDocumentPullDiagnosticsAsync(
TestLspServer testLspServer,
Uri uri,
Document document,
string? previousResultId = null,
IProgress<DiagnosticReport[]>? progress = null)
{
await WaitForDiagnosticsAsync(testLspServer.TestWorkspace);

var result = await testLspServer.ExecuteRequestAsync<DocumentDiagnosticsParams, DiagnosticReport[]>(
MSLSPMethods.DocumentPullDiagnosticName,
CreateDocumentDiagnosticParams(uri, previousResultId, progress),
CreateDocumentDiagnosticParams(document, previousResultId, progress),
new LSP.ClientCapabilities(),
clientName: null,
CancellationToken.None);
Expand Down Expand Up @@ -569,13 +523,13 @@ private static async Task WaitForDiagnosticsAsync(TestWorkspace workspace)
}

private static DocumentDiagnosticsParams CreateDocumentDiagnosticParams(
Uri uri,
Document document,
string? previousResultId = null,
IProgress<DiagnosticReport[]>? progress = null)
{
return new DocumentDiagnosticsParams
{
TextDocument = new LSP.TextDocumentIdentifier { Uri = uri },
TextDocument = ProtocolConversions.DocumentToTextDocumentIdentifier(document),
PreviousResultId = previousResultId,
PartialResultToken = progress,
};
Expand All @@ -602,13 +556,6 @@ private TestLspServer CreateTestWorkspaceWithDiagnostics(string markup, Backgrou
return testLspServer;
}

private TestLspServer CreateTestWorkspaceFromXml(string xmlMarkup, BackgroundAnalysisScope scope, bool pullDiagnostics = true)
{
var testLspServer = CreateXmlTestLspServer(xmlMarkup, out _);
InitializeDiagnostics(scope, testLspServer.TestWorkspace, pullDiagnostics);
return testLspServer;
}

private TestLspServer CreateTestWorkspaceWithDiagnostics(string[] markups, BackgroundAnalysisScope scope, bool pullDiagnostics = true)
{
var testLspServer = CreateTestLspServer(markups, out _);
Expand Down