diff --git a/src/LanguageServer/Protocol/Handler/ProjectContext/ProjectContextRefreshQueue.cs b/src/LanguageServer/Protocol/Handler/ProjectContext/ProjectContextRefreshQueue.cs new file mode 100644 index 0000000000000..ebed53b3d8ecd --- /dev/null +++ b/src/LanguageServer/Protocol/Handler/ProjectContext/ProjectContextRefreshQueue.cs @@ -0,0 +1,29 @@ +// 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. + +using Microsoft.CodeAnalysis.Shared.TestHooks; +using Roslyn.LanguageServer.Protocol; + +namespace Microsoft.CodeAnalysis.LanguageServer.Handler.ProjectContext; + +internal sealed class ProjectContextRefreshQueue : AbstractRefreshQueue +{ + internal ProjectContextRefreshQueue( + IAsynchronousOperationListenerProvider asynchronousOperationListenerProvider, + LspWorkspaceRegistrationService lspWorkspaceRegistrationService, + LspWorkspaceManager lspWorkspaceManager, + IClientLanguageServerManager notificationManager) + : base(asynchronousOperationListenerProvider, lspWorkspaceRegistrationService, lspWorkspaceManager, notificationManager) + { + } + + protected override string GetFeatureAttribute() + => FeatureAttribute.LanguageServer; + + protected override bool? GetRefreshSupport(ClientCapabilities clientCapabilities) + => (clientCapabilities.Workspace as VSInternalWorkspaceClientCapabilities)?.ProjectContext?.RefreshSupport; + + protected override string GetWorkspaceRefreshName() + => VSInternalMethods.WorkspaceProjectContextRefreshName; +} diff --git a/src/LanguageServer/Protocol/Handler/ProjectContext/ProjectContextRefreshQueueFactory.cs b/src/LanguageServer/Protocol/Handler/ProjectContext/ProjectContextRefreshQueueFactory.cs new file mode 100644 index 0000000000000..9a7f6e3090f8e --- /dev/null +++ b/src/LanguageServer/Protocol/Handler/ProjectContext/ProjectContextRefreshQueueFactory.cs @@ -0,0 +1,29 @@ +// 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. + +using System; +using System.Composition; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Shared.TestHooks; + +namespace Microsoft.CodeAnalysis.LanguageServer.Handler.ProjectContext; + +[ExportCSharpVisualBasicLspServiceFactory(typeof(ProjectContextRefreshQueue)), Shared] +[method: ImportingConstructor] +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed class ProjectContextRefreshQueueFactory( + IAsynchronousOperationListenerProvider asynchronousOperationListenerProvider, + LspWorkspaceRegistrationService lspWorkspaceRegistrationService) : ILspServiceFactory +{ + private readonly IAsynchronousOperationListenerProvider _asynchronousOperationListenerProvider = asynchronousOperationListenerProvider; + private readonly LspWorkspaceRegistrationService _lspWorkspaceRegistrationService = lspWorkspaceRegistrationService; + + public ILspService CreateILspService(LspServices lspServices, WellKnownLspServerKinds serverKind) + { + var notificationManager = lspServices.GetRequiredService(); + var lspWorkspaceManager = lspServices.GetRequiredService(); + + return new ProjectContextRefreshQueue(_asynchronousOperationListenerProvider, _lspWorkspaceRegistrationService, lspWorkspaceManager, notificationManager); + } +} diff --git a/src/LanguageServer/Protocol/Protocol/Internal/Converters/VSInternalExtensionUtilities.cs b/src/LanguageServer/Protocol/Protocol/Internal/Converters/VSInternalExtensionUtilities.cs index 53cb0ffb79119..ac3108a2ee25d 100644 --- a/src/LanguageServer/Protocol/Protocol/Internal/Converters/VSInternalExtensionUtilities.cs +++ b/src/LanguageServer/Protocol/Protocol/Internal/Converters/VSInternalExtensionUtilities.cs @@ -52,6 +52,7 @@ private static void AddConverters(IList converters) AddOrReplaceConverter(); AddOrReplaceConverter(); AddOrReplaceConverter(); + AddOrReplaceConverter(); void AddOrReplaceConverter() where TExtension : TBase diff --git a/src/LanguageServer/Protocol/Protocol/Internal/VSInternalMethods.cs b/src/LanguageServer/Protocol/Protocol/Internal/VSInternalMethods.cs index 05c4a21bca6a4..1fafa61431856 100644 --- a/src/LanguageServer/Protocol/Protocol/Internal/VSInternalMethods.cs +++ b/src/LanguageServer/Protocol/Protocol/Internal/VSInternalMethods.cs @@ -22,6 +22,7 @@ internal static class VSInternalMethods public const string TextDocumentUriPresentationName = "textDocument/_vs_uriPresentation"; public const string TextDocumentValidateBreakableRangeName = "textDocument/_vs_validateBreakableRange"; public const string WorkspaceMapCodeName = "workspace/_vs_mapCode"; + public const string WorkspaceProjectContextRefreshName = "workspace/projectContext/_vs_refresh"; public const string WorkspacePullDiagnosticName = "workspace/_vs_diagnostic"; public const string WorkspaceSpellCheckableRangesName = "workspace/_vs_spellCheckableRanges"; diff --git a/src/LanguageServer/Protocol/Protocol/Internal/VSInternalProjectContextWorkspaceSetting.cs b/src/LanguageServer/Protocol/Protocol/Internal/VSInternalProjectContextWorkspaceSetting.cs new file mode 100644 index 0000000000000..4e5b53e94e156 --- /dev/null +++ b/src/LanguageServer/Protocol/Protocol/Internal/VSInternalProjectContextWorkspaceSetting.cs @@ -0,0 +1,26 @@ +// 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; + +using System.Text.Json.Serialization; + +/// +/// Class representing the workspace project context client capabilities. +/// +internal sealed class VSInternalProjectContextWorkspaceSetting +{ + /// + /// Whether the client supports a refresh request sent from the server to the client. + /// + /// Note that this event is global and will force the client to refresh all + /// project contexts currently shown. It should be used with absolute care + /// and is useful for situation where a server for example detects a project + /// wide change that requires such a calculation. + /// + /// + [JsonPropertyName("refreshSupport")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public bool RefreshSupport { get; set; } +} diff --git a/src/LanguageServer/Protocol/Protocol/Internal/VSInternalWorkspaceClientCapabilities.cs b/src/LanguageServer/Protocol/Protocol/Internal/VSInternalWorkspaceClientCapabilities.cs new file mode 100644 index 0000000000000..9370f2487cb0d --- /dev/null +++ b/src/LanguageServer/Protocol/Protocol/Internal/VSInternalWorkspaceClientCapabilities.cs @@ -0,0 +1,21 @@ +// 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; + +using System.Text.Json.Serialization; + +/// +/// Extension class for WorkspaceClientCapabilities with fields specific to Visual Studio. +/// +internal sealed class VSInternalWorkspaceClientCapabilities : WorkspaceClientCapabilities +{ + /// + /// Gets or sets capabilities indicating what support the client has for workspace project contexts. + /// + /// Since LSP 3.17 + [JsonPropertyName("_vs_projectContext")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public DiagnosticWorkspaceSetting? ProjectContext { get; set; } +} diff --git a/src/LanguageServer/Protocol/Protocol/WorkspaceClientCapabilities.cs b/src/LanguageServer/Protocol/Protocol/WorkspaceClientCapabilities.cs index b305cb72b70ed..680879015d46b 100644 --- a/src/LanguageServer/Protocol/Protocol/WorkspaceClientCapabilities.cs +++ b/src/LanguageServer/Protocol/Protocol/WorkspaceClientCapabilities.cs @@ -12,7 +12,7 @@ namespace Roslyn.LanguageServer.Protocol; /// See the Language Server Protocol specification for additional information. /// /// -internal sealed class WorkspaceClientCapabilities +internal class WorkspaceClientCapabilities { // NOTE: these are kept in the same order as the spec to make them easier to update