From b185cd6efd5f477b28c69166d4c1f9609cabc244 Mon Sep 17 00:00:00 2001 From: Joey Robichaud Date: Fri, 4 Oct 2024 01:12:41 -0700 Subject: [PATCH 1/3] Add a WorkspaceKind property to ProjectContext. --- .../Extensions/ProtocolConversions.cs | 10 +++++++++ .../Protocol/Extensions/VSProjectContext.cs | 10 +++++++++ .../Protocol/Extensions/VSWorkspaceKind.cs | 22 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/LanguageServer/Protocol/Protocol/Extensions/VSWorkspaceKind.cs diff --git a/src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs b/src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs index 573990221e8f4..6193c455743c1 100644 --- a/src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs +++ b/src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs @@ -827,6 +827,16 @@ public static LSP.VSProjectContext ProjectToProjectContext(Project project) projectContext.Kind = LSP.VSProjectKind.VisualBasic; } + var solution = project.Solution; + if (solution.WorkspaceKind == WorkspaceKind.Host) + { + projectContext.WorkspaceKind = LSP.VSWorkspaceKind.Host; + } + else if (solution.WorkspaceKind == WorkspaceKind.MiscellaneousFiles) + { + projectContext.WorkspaceKind = LSP.VSWorkspaceKind.MiscellaneousFiles; + } + return projectContext; } diff --git a/src/LanguageServer/Protocol/Protocol/Extensions/VSProjectContext.cs b/src/LanguageServer/Protocol/Protocol/Extensions/VSProjectContext.cs index 528a49257dea7..69842943e239f 100644 --- a/src/LanguageServer/Protocol/Protocol/Extensions/VSProjectContext.cs +++ b/src/LanguageServer/Protocol/Protocol/Extensions/VSProjectContext.cs @@ -44,6 +44,16 @@ public VSProjectKind Kind set; } + /// + /// Gets or sets the kind of the workspace the project context is associated. + /// + [JsonPropertyName("_vs_workspace_kind")] + public VSWorkspaceKind WorkspaceKind + { + get; + set; + } + public static bool operator ==(VSProjectContext? value1, VSProjectContext? value2) { if (ReferenceEquals(value1, value2)) diff --git a/src/LanguageServer/Protocol/Protocol/Extensions/VSWorkspaceKind.cs b/src/LanguageServer/Protocol/Protocol/Extensions/VSWorkspaceKind.cs new file mode 100644 index 0000000000000..fdac7416d0d5d --- /dev/null +++ b/src/LanguageServer/Protocol/Protocol/Extensions/VSWorkspaceKind.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Roslyn.LanguageServer.Protocol +{ + /// + /// represents the various kinds of known workspaces. + /// + internal enum VSWorkspaceKind + { + /// + /// Host Workspace + /// + Host = 1, + + /// + /// Miscellaneous Files Workspace + /// + MiscellaneousFiles = 2, + } +} From a0fa31e9d5f64f28173804b1a7b0eb6f66669704 Mon Sep 17 00:00:00 2001 From: Joey Robichaud Date: Tue, 8 Oct 2024 00:23:02 -0700 Subject: [PATCH 2/3] Switch to an IsMiscellaneous property on ProjectContext --- .../Extensions/ProtocolConversions.cs | 13 ++--------- .../Protocol/Extensions/VSProjectContext.cs | 6 ++--- .../Protocol/Extensions/VSWorkspaceKind.cs | 22 ------------------- 3 files changed, 5 insertions(+), 36 deletions(-) delete mode 100644 src/LanguageServer/Protocol/Protocol/Extensions/VSWorkspaceKind.cs diff --git a/src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs b/src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs index 6193c455743c1..a86a0e660cca9 100644 --- a/src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs +++ b/src/LanguageServer/Protocol/Extensions/ProtocolConversions.cs @@ -815,7 +815,8 @@ public static LSP.VSProjectContext ProjectToProjectContext(Project project) var projectContext = new LSP.VSProjectContext { Id = ProjectIdToProjectContextId(project.Id), - Label = project.Name + Label = project.Name, + IsMiscellaneous = project.Solution.WorkspaceKind == WorkspaceKind.MiscellaneousFiles, }; if (project.Language == LanguageNames.CSharp) @@ -827,16 +828,6 @@ public static LSP.VSProjectContext ProjectToProjectContext(Project project) projectContext.Kind = LSP.VSProjectKind.VisualBasic; } - var solution = project.Solution; - if (solution.WorkspaceKind == WorkspaceKind.Host) - { - projectContext.WorkspaceKind = LSP.VSWorkspaceKind.Host; - } - else if (solution.WorkspaceKind == WorkspaceKind.MiscellaneousFiles) - { - projectContext.WorkspaceKind = LSP.VSWorkspaceKind.MiscellaneousFiles; - } - return projectContext; } diff --git a/src/LanguageServer/Protocol/Protocol/Extensions/VSProjectContext.cs b/src/LanguageServer/Protocol/Protocol/Extensions/VSProjectContext.cs index 69842943e239f..bd0742518cdc3 100644 --- a/src/LanguageServer/Protocol/Protocol/Extensions/VSProjectContext.cs +++ b/src/LanguageServer/Protocol/Protocol/Extensions/VSProjectContext.cs @@ -45,10 +45,10 @@ public VSProjectKind Kind } /// - /// Gets or sets the kind of the workspace the project context is associated. + /// Gets or sets this project context represents miscellaneous files. /// - [JsonPropertyName("_vs_workspace_kind")] - public VSWorkspaceKind WorkspaceKind + [JsonPropertyName("_vs_is_miscellaneous")] + public bool IsMiscellaneous { get; set; diff --git a/src/LanguageServer/Protocol/Protocol/Extensions/VSWorkspaceKind.cs b/src/LanguageServer/Protocol/Protocol/Extensions/VSWorkspaceKind.cs deleted file mode 100644 index fdac7416d0d5d..0000000000000 --- a/src/LanguageServer/Protocol/Protocol/Extensions/VSWorkspaceKind.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Roslyn.LanguageServer.Protocol -{ - /// - /// represents the various kinds of known workspaces. - /// - internal enum VSWorkspaceKind - { - /// - /// Host Workspace - /// - Host = 1, - - /// - /// Miscellaneous Files Workspace - /// - MiscellaneousFiles = 2, - } -} From 32d3c409a4777b4bb9e2371ed845e8cafa7e9c36 Mon Sep 17 00:00:00 2001 From: Joey Robichaud Date: Tue, 8 Oct 2024 00:23:18 -0700 Subject: [PATCH 3/3] Add conversion tests for ProejctContext --- .../ProtocolConversionsTests.cs | 66 ++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/LanguageServer/ProtocolUnitTests/ProtocolConversionsTests.cs b/src/LanguageServer/ProtocolUnitTests/ProtocolConversionsTests.cs index d093833d00971..c7f83533e1ade 100644 --- a/src/LanguageServer/ProtocolUnitTests/ProtocolConversionsTests.cs +++ b/src/LanguageServer/ProtocolUnitTests/ProtocolConversionsTests.cs @@ -5,17 +5,24 @@ using System; using System.IO; using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis.Text; using Roslyn.LanguageServer.Protocol; using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; +using Xunit.Abstractions; using Range = Roslyn.LanguageServer.Protocol.Range; namespace Microsoft.CodeAnalysis.LanguageServer.UnitTests { - public class ProtocolConversionsTests + public class ProtocolConversionsTests : AbstractLanguageServerProtocolTests { + public ProtocolConversionsTests(ITestOutputHelper testOutputHelper) : base(testOutputHelper) + { + } + [Fact] public void CreateAbsoluteUri_LocalPaths_AllAscii() { @@ -276,5 +283,62 @@ private static string GetTestMarkup() }"; return markup; } + + [Theory, CombinatorialData] + public async Task ProjectToProjectContext_HostWorkspace(bool mutatingLspWorkspace) + { + var source = """ + class {|caret:A|} + { + void M() + { + } + } + """; + + // Create a server with an existing file. + await using var testLspServer = await CreateTestLspServerAsync(source, mutatingLspWorkspace, new InitializationOptions { ServerKind = WellKnownLspServerKinds.CSharpVisualBasicLspServer }); + var caret = testLspServer.GetLocations("caret").Single(); + + var document = await GetTextDocumentAsync(testLspServer, caret.Uri); + Assert.NotNull(document); + + var projectContext = ProtocolConversions.ProjectToProjectContext(document.Project); + + Assert.False(projectContext.IsMiscellaneous); + } + + [Theory, CombinatorialData] + public async Task ProjectToProjectContext_MiscellaneousFilesWorkspace(bool mutatingLspWorkspace) + { + var source = """ + class A + { + void M() + { + } + } + """; + + // Create a server that supports LSP misc files. + await using var testLspServer = await CreateTestLspServerAsync(string.Empty, mutatingLspWorkspace, new InitializationOptions { ServerKind = WellKnownLspServerKinds.CSharpVisualBasicLspServer }); + + // Open an empty loose file. + var looseFileUri = ProtocolConversions.CreateAbsoluteUri(@"C:\SomeFile.cs"); + await testLspServer.OpenDocumentAsync(looseFileUri, source).ConfigureAwait(false); + + var document = await GetTextDocumentAsync(testLspServer, looseFileUri); + Assert.NotNull(document); + + var projectContext = ProtocolConversions.ProjectToProjectContext(document.Project); + + Assert.True(projectContext.IsMiscellaneous); + } + + internal static async Task GetTextDocumentAsync(TestLspServer testLspServer, Uri uri) + { + var (_, _, textDocument) = await testLspServer.GetManager().GetLspDocumentInfoAsync(new TextDocumentIdentifier { Uri = uri }, CancellationToken.None); + return textDocument; + } } }