diff --git a/sample/SampleServer/Program.cs b/sample/SampleServer/Program.cs index 317881999..d9839c1d9 100644 --- a/sample/SampleServer/Program.cs +++ b/sample/SampleServer/Program.cs @@ -3,12 +3,6 @@ using System.Threading.Tasks; using Microsoft.Extensions.Logging; using OmniSharp.Extensions.LanguageServer; -using OmniSharp.Extensions.LanguageServer.Abstractions; -using OmniSharp.Extensions.LanguageServer.Capabilities.Client; -using OmniSharp.Extensions.LanguageServer.Capabilities.Server; -using OmniSharp.Extensions.LanguageServer.Models; -using OmniSharp.Extensions.LanguageServer.Protocol; -using OmniSharp.Extensions.LanguageServer.Protocol.Document; namespace SampleServer { @@ -34,100 +28,4 @@ static async Task MainAsync(string[] args) await server.WasShutDown; } } - - class TextDocumentHandler : ITextDocumentSyncHandler - { - private readonly ILanguageServer _router; - - private readonly DocumentSelector _documentSelector = new DocumentSelector( - new DocumentFilter() - { - Pattern = "**/*.csproj", - Language = "xml" - } - ); - - private SynchronizationCapability _capability; - - public TextDocumentHandler(ILanguageServer router) - { - _router = router; - } - - public TextDocumentSyncOptions Options { get; } = new TextDocumentSyncOptions() - { - WillSaveWaitUntil = false, - WillSave = true, - Change = TextDocumentSyncKind.Full, - Save = new SaveOptions() - { - IncludeText = true - }, - OpenClose = true - }; - - public Task Handle(DidChangeTextDocumentParams notification) - { - _router.LogMessage(new LogMessageParams() - { - Type = MessageType.Log, - Message = "Hello World!!!!" - }); - return Task.CompletedTask; - } - - TextDocumentChangeRegistrationOptions IRegistration.GetRegistrationOptions() - { - return new TextDocumentChangeRegistrationOptions() - { - DocumentSelector = _documentSelector, - SyncKind = Options.Change - }; - } - - public void SetCapability(SynchronizationCapability capability) - { - _capability = capability; - } - - public async Task Handle(DidOpenTextDocumentParams notification) - { - _router.LogMessage(new LogMessageParams() - { - Type = MessageType.Log, - Message = "Hello World!!!!" - }); - } - - TextDocumentRegistrationOptions IRegistration.GetRegistrationOptions() - { - return new TextDocumentRegistrationOptions() - { - DocumentSelector = _documentSelector, - }; - } - - public Task Handle(DidCloseTextDocumentParams notification) - { - return Task.CompletedTask; - } - - public Task Handle(DidSaveTextDocumentParams notification) - { - return Task.CompletedTask; - } - - TextDocumentSaveRegistrationOptions IRegistration.GetRegistrationOptions() - { - return new TextDocumentSaveRegistrationOptions() - { - DocumentSelector = _documentSelector, - IncludeText = Options.Save.IncludeText - }; - } - public TextDocumentAttributes GetTextDocumentAttributes(Uri uri) - { - return new TextDocumentAttributes(uri, "csharp"); - } - } } diff --git a/sample/SampleServer/TextDocumentHandler.cs b/sample/SampleServer/TextDocumentHandler.cs new file mode 100644 index 000000000..b85a7d9fc --- /dev/null +++ b/sample/SampleServer/TextDocumentHandler.cs @@ -0,0 +1,108 @@ +using System; +using System.Threading.Tasks; +using OmniSharp.Extensions.LanguageServer; +using OmniSharp.Extensions.LanguageServer.Abstractions; +using OmniSharp.Extensions.LanguageServer.Capabilities.Client; +using OmniSharp.Extensions.LanguageServer.Capabilities.Server; +using OmniSharp.Extensions.LanguageServer.Models; +using OmniSharp.Extensions.LanguageServer.Protocol; +using OmniSharp.Extensions.LanguageServer.Protocol.Document; + +namespace SampleServer +{ + class TextDocumentHandler : ITextDocumentSyncHandler + { + private readonly ILanguageServer _router; + + private readonly DocumentSelector _documentSelector = new DocumentSelector( + new DocumentFilter() + { + Pattern = "**/*.csproj", + Language = "xml" + } + ); + + private SynchronizationCapability _capability; + + public TextDocumentHandler(ILanguageServer router) + { + _router = router; + } + + public TextDocumentSyncOptions Options { get; } = new TextDocumentSyncOptions() + { + WillSaveWaitUntil = false, + WillSave = true, + Change = TextDocumentSyncKind.Full, + Save = new SaveOptions() + { + IncludeText = true + }, + OpenClose = true + }; + + public Task Handle(DidChangeTextDocumentParams notification) + { + _router.LogMessage(new LogMessageParams() + { + Type = MessageType.Log, + Message = "Hello World!!!!" + }); + return Task.CompletedTask; + } + + TextDocumentChangeRegistrationOptions IRegistration.GetRegistrationOptions() + { + return new TextDocumentChangeRegistrationOptions() + { + DocumentSelector = _documentSelector, + SyncKind = Options.Change + }; + } + + public void SetCapability(SynchronizationCapability capability) + { + _capability = capability; + } + + public async Task Handle(DidOpenTextDocumentParams notification) + { + _router.LogMessage(new LogMessageParams() + { + Type = MessageType.Log, + Message = "Hello World!!!!" + }); + } + + TextDocumentRegistrationOptions IRegistration.GetRegistrationOptions() + { + return new TextDocumentRegistrationOptions() + { + DocumentSelector = _documentSelector, + }; + } + + public Task Handle(DidCloseTextDocumentParams notification) + { + return Task.CompletedTask; + } + + public Task Handle(DidSaveTextDocumentParams notification) + { + return Task.CompletedTask; + } + + TextDocumentSaveRegistrationOptions IRegistration.GetRegistrationOptions() + { + return new TextDocumentSaveRegistrationOptions() + { + DocumentSelector = _documentSelector, + IncludeText = Options.Save.IncludeText + }; + } + public TextDocumentAttributes GetTextDocumentAttributes(Uri uri) + { + return new TextDocumentAttributes(uri, "csharp"); + } + } +} \ No newline at end of file diff --git a/src/JsonRpc/Events.cs b/src/JsonRpc/Events.cs new file mode 100644 index 000000000..0321cf7ac --- /dev/null +++ b/src/JsonRpc/Events.cs @@ -0,0 +1,11 @@ +using Microsoft.Extensions.Logging; + +namespace OmniSharp.Extensions.JsonRpc +{ + public static class Events + { + public static EventId UnhandledException = new EventId(1337_100); + public static EventId UnhandledRequest = new EventId(1337_101); + public static EventId UnhandledNotification = new EventId(1337_102); + } +} \ No newline at end of file diff --git a/src/JsonRpc/HandlerCollection.cs b/src/JsonRpc/HandlerCollection.cs index 54d68e21c..dd4e68993 100644 --- a/src/JsonRpc/HandlerCollection.cs +++ b/src/JsonRpc/HandlerCollection.cs @@ -6,11 +6,11 @@ namespace OmniSharp.Extensions.JsonRpc { - class HandlerCollection : IEnumerable + class HandlerCollection : IEnumerable { internal readonly List _handlers = new List(); - internal class HandlerInstance : IHandlerInstance, IDisposable + internal class HandlerInstance : IHandlerDescriptor, IDisposable { private readonly Action _disposeAction; @@ -34,7 +34,7 @@ public void Dispose() } } - public IEnumerator GetEnumerator() + public IEnumerator GetEnumerator() { return _handlers.GetEnumerator(); } diff --git a/src/JsonRpc/IHandlerInstance.cs b/src/JsonRpc/IHandlerDescriptor.cs similarity index 82% rename from src/JsonRpc/IHandlerInstance.cs rename to src/JsonRpc/IHandlerDescriptor.cs index 905280d4b..fdd930ae0 100644 --- a/src/JsonRpc/IHandlerInstance.cs +++ b/src/JsonRpc/IHandlerDescriptor.cs @@ -2,11 +2,11 @@ namespace OmniSharp.Extensions.JsonRpc { - public interface IHandlerInstance + public interface IHandlerDescriptor { string Method { get; } IJsonRpcHandler Handler { get; } Type HandlerType { get; } Type Params { get; } } -} \ No newline at end of file +} diff --git a/src/JsonRpc/IRequestProcessIdentifier.cs b/src/JsonRpc/IRequestProcessIdentifier.cs index 5450ecce8..eeea9d281 100644 --- a/src/JsonRpc/IRequestProcessIdentifier.cs +++ b/src/JsonRpc/IRequestProcessIdentifier.cs @@ -4,6 +4,6 @@ namespace OmniSharp.Extensions.JsonRpc { public interface IRequestProcessIdentifier { - RequestProcessType Identify(Renor renor); + RequestProcessType Identify(IHandlerDescriptor descriptor); } -} \ No newline at end of file +} diff --git a/src/JsonRpc/IRequestRouter.cs b/src/JsonRpc/IRequestRouter.cs index 99bc56896..9f9035d40 100644 --- a/src/JsonRpc/IRequestRouter.cs +++ b/src/JsonRpc/IRequestRouter.cs @@ -6,7 +6,12 @@ namespace OmniSharp.Extensions.JsonRpc { public interface IRequestRouter { + IHandlerDescriptor GetDescriptor(Notification notification); + IHandlerDescriptor GetDescriptor(Request request); + Task RouteNotification(Notification notification); + Task RouteNotification(IHandlerDescriptor descriptor, Notification notification); Task RouteRequest(Request request); + Task RouteRequest(IHandlerDescriptor descriptor, Request request); } } diff --git a/src/JsonRpc/InputHandler.cs b/src/JsonRpc/InputHandler.cs index f599a983b..9bd875275 100644 --- a/src/JsonRpc/InputHandler.cs +++ b/src/JsonRpc/InputHandler.cs @@ -162,17 +162,20 @@ private void HandleRequest(string request) return; } - foreach (var (type, item) in requests.Select(x => (type: _requestProcessIdentifier.Identify(x), item: x))) + foreach (var item in requests) { if (item.IsRequest) { + var descriptor = _requestRouter.GetDescriptor(item.Request); + if (descriptor is null) continue; + var type = _requestProcessIdentifier.Identify(descriptor); _scheduler.Add( type, item.Request.Method, async () => { try { - var result = await _requestRouter.RouteRequest(item.Request); + var result = await _requestRouter.RouteRequest(descriptor, item.Request); _outputHandler.Send(result.Value); } catch (Exception e) @@ -187,13 +190,16 @@ private void HandleRequest(string request) } else if (item.IsNotification) { + var descriptor = _requestRouter.GetDescriptor(item.Notification); + if (descriptor is null) continue; + var type = _requestProcessIdentifier.Identify(descriptor); _scheduler.Add( type, item.Notification.Method, async () => { try { - await _requestRouter.RouteNotification(item.Notification); + await _requestRouter.RouteNotification(descriptor, item.Notification); } catch (Exception e) { diff --git a/src/JsonRpc/MethodAttribute.cs b/src/JsonRpc/MethodAttribute.cs index 56b66c65c..6b693f72b 100644 --- a/src/JsonRpc/MethodAttribute.cs +++ b/src/JsonRpc/MethodAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace OmniSharp.Extensions.JsonRpc { @@ -12,4 +12,4 @@ public MethodAttribute(string method) Method = method; } } -} \ No newline at end of file +} diff --git a/src/JsonRpc/ParallelAttrbute.cs b/src/JsonRpc/ParallelAttrbute.cs new file mode 100644 index 000000000..de968b1ec --- /dev/null +++ b/src/JsonRpc/ParallelAttrbute.cs @@ -0,0 +1,7 @@ +namespace OmniSharp.Extensions.JsonRpc +{ + public sealed class ParallelAttribute : ProcessAttribute + { + public ParallelAttribute() : base(RequestProcessType.Parallel) { } + } +} diff --git a/src/JsonRpc/ParallelRequestProcessIdentifier.cs b/src/JsonRpc/ParallelRequestProcessIdentifier.cs index 1c5066fa4..8e864b0c6 100644 --- a/src/JsonRpc/ParallelRequestProcessIdentifier.cs +++ b/src/JsonRpc/ParallelRequestProcessIdentifier.cs @@ -4,9 +4,9 @@ namespace OmniSharp.Extensions.JsonRpc { public class ParallelRequestProcessIdentifier : IRequestProcessIdentifier { - public RequestProcessType Identify(Renor renor) + public RequestProcessType Identify(IHandlerDescriptor descriptor) { return RequestProcessType.Parallel; } } -} \ No newline at end of file +} diff --git a/src/JsonRpc/ProcessAttribute.cs b/src/JsonRpc/ProcessAttribute.cs new file mode 100644 index 000000000..9dc8121b3 --- /dev/null +++ b/src/JsonRpc/ProcessAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace OmniSharp.Extensions.JsonRpc +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] + public class ProcessAttribute : Attribute + { + public ProcessAttribute(RequestProcessType type) + { + Type = type; + } + + public RequestProcessType Type { get; } + } +} \ No newline at end of file diff --git a/src/JsonRpc/ProcessScheduler.cs b/src/JsonRpc/ProcessScheduler.cs index 2ddddb2e4..fa4f199f2 100644 --- a/src/JsonRpc/ProcessScheduler.cs +++ b/src/JsonRpc/ProcessScheduler.cs @@ -127,11 +127,4 @@ public void Dispose() _cancel.Dispose(); } } - - public static class Events - { - public static EventId UnhandledException = new EventId(1337_100); - public static EventId UnhandledRequest = new EventId(1337_101); - public static EventId UnhandledNotification = new EventId(1337_102); - } } diff --git a/src/JsonRpc/ReflectionRequestHandlers.cs b/src/JsonRpc/ReflectionRequestHandlers.cs index dbb83d71a..3c8607756 100644 --- a/src/JsonRpc/ReflectionRequestHandlers.cs +++ b/src/JsonRpc/ReflectionRequestHandlers.cs @@ -6,7 +6,7 @@ namespace OmniSharp.Extensions.JsonRpc { public static class ReflectionRequestHandlers { - public static Task HandleNotification(IHandlerInstance instance) + public static Task HandleNotification(IHandlerDescriptor instance) { var method = instance.HandlerType.GetTypeInfo() .GetMethod(nameof(INotificationHandler.Handle), BindingFlags.Public | BindingFlags.Instance); @@ -14,7 +14,7 @@ public static Task HandleNotification(IHandlerInstance instance) return (Task)method.Invoke(instance.Handler, new object[0]); } - public static Task HandleNotification(IHandlerInstance instance, object @params) + public static Task HandleNotification(IHandlerDescriptor instance, object @params) { var method = instance.HandlerType.GetTypeInfo() .GetMethod(nameof(INotificationHandler.Handle), BindingFlags.Public | BindingFlags.Instance); @@ -22,7 +22,7 @@ public static Task HandleNotification(IHandlerInstance instance, object @params) return (Task)method.Invoke(instance.Handler, new[] { @params }); } - public static Task HandleRequest(IHandlerInstance instance, CancellationToken token) + public static Task HandleRequest(IHandlerDescriptor instance, CancellationToken token) { var method = instance.HandlerType.GetTypeInfo() .GetMethod(nameof(IRequestHandler.Handle), BindingFlags.Public | BindingFlags.Instance); @@ -30,7 +30,7 @@ public static Task HandleRequest(IHandlerInstance instance, CancellationToken to return (Task)method.Invoke(instance.Handler, new object[] { token }); } - public static Task HandleRequest(IHandlerInstance instance, object @params, CancellationToken token) + public static Task HandleRequest(IHandlerDescriptor instance, object @params, CancellationToken token) { var method = instance.HandlerType.GetTypeInfo() .GetMethod(nameof(IRequestHandler.Handle), BindingFlags.Public | BindingFlags.Instance); diff --git a/src/JsonRpc/RequestRouter.cs b/src/JsonRpc/RequestRouter.cs index 7d9441ad5..9591bdcbf 100644 --- a/src/JsonRpc/RequestRouter.cs +++ b/src/JsonRpc/RequestRouter.cs @@ -22,10 +22,13 @@ public IDisposable Add(IJsonRpcHandler handler) return _collection.Add(handler); } - public async Task RouteNotification(Notification notification) + private IHandlerDescriptor FindDescriptor(IMethodWithParams instance) { - var handler = _collection.FirstOrDefault(x => x.Method == notification.Method); + return _collection.FirstOrDefault(x => x.Method == instance.Method); + } + public async Task RouteNotification(IHandlerDescriptor handler, Notification notification) + { Task result; if (handler.Params is null) { @@ -39,15 +42,13 @@ public async Task RouteNotification(Notification notification) await result.ConfigureAwait(false); } - - public Task RouteRequest(Request request) + public Task RouteRequest(IHandlerDescriptor descriptor, Request request) { - return RouteRequest(request, CancellationToken.None); + return RouteRequest(descriptor, request, CancellationToken.None); } - protected virtual async Task RouteRequest(Request request, CancellationToken token) + protected virtual async Task RouteRequest(IHandlerDescriptor handler, Request request, CancellationToken token) { - var handler = _collection.FirstOrDefault(x => x.Method == request.Method); if (request.Method is null) { return new MethodNotFound(request.Id, request.Method); @@ -87,5 +88,25 @@ protected virtual async Task RouteRequest(Request request, Cancel return new Client.Response(request.Id, responseValue); } + + public IHandlerDescriptor GetDescriptor(Notification notification) + { + return FindDescriptor(notification); + } + + public IHandlerDescriptor GetDescriptor(Request request) + { + return FindDescriptor(request); + } + + Task IRequestRouter.RouteNotification(Notification notification) + { + return RouteNotification(GetDescriptor(notification), notification); + } + + Task IRequestRouter.RouteRequest(Request request) + { + return RouteRequest(GetDescriptor(request), request); + } } } diff --git a/src/JsonRpc/SerialAttribute.cs b/src/JsonRpc/SerialAttribute.cs new file mode 100644 index 000000000..da6803fb2 --- /dev/null +++ b/src/JsonRpc/SerialAttribute.cs @@ -0,0 +1,7 @@ +namespace OmniSharp.Extensions.JsonRpc +{ + public sealed class SerialAttribute : ProcessAttribute + { + public SerialAttribute() : base(RequestProcessType.Serial) { } + } +} \ No newline at end of file diff --git a/src/JsonRpc/SerialRequestProcessIdentifier.cs b/src/JsonRpc/SerialRequestProcessIdentifier.cs index bc541da8b..e2d22704f 100644 --- a/src/JsonRpc/SerialRequestProcessIdentifier.cs +++ b/src/JsonRpc/SerialRequestProcessIdentifier.cs @@ -4,9 +4,9 @@ namespace OmniSharp.Extensions.JsonRpc { public class SerialRequestProcessIdentifier : IRequestProcessIdentifier { - public RequestProcessType Identify(Renor renor) + public RequestProcessType Identify(IHandlerDescriptor descriptor) { return RequestProcessType.Serial; } } -} \ No newline at end of file +} diff --git a/src/JsonRpc/Server/IMethodWithParams.cs b/src/JsonRpc/Server/IMethodWithParams.cs new file mode 100644 index 000000000..83b2ee440 --- /dev/null +++ b/src/JsonRpc/Server/IMethodWithParams.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; + +namespace OmniSharp.Extensions.JsonRpc.Server +{ + public interface IMethodWithParams + { + string Method { get; } + JToken Params { get; } + } +} diff --git a/src/JsonRpc/Server/Messages/ErrorMessage.cs b/src/JsonRpc/Server/Messages/ErrorMessage.cs index 324c2d8c6..223f9c3b8 100644 --- a/src/JsonRpc/Server/Messages/ErrorMessage.cs +++ b/src/JsonRpc/Server/Messages/ErrorMessage.cs @@ -1,18 +1,8 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Serialization; namespace OmniSharp.Extensions.JsonRpc.Server.Messages { - public interface IErrorMessage - { - int Code { get; } - - string Message { get; } - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - object Data { get; } - } - public class ErrorMessage: ErrorMessage { public ErrorMessage(int code, string message) : base(code, message, null) diff --git a/src/JsonRpc/Server/Messages/IErrorMessage.cs b/src/JsonRpc/Server/Messages/IErrorMessage.cs new file mode 100644 index 000000000..071e8ada2 --- /dev/null +++ b/src/JsonRpc/Server/Messages/IErrorMessage.cs @@ -0,0 +1,14 @@ +using Newtonsoft.Json; + +namespace OmniSharp.Extensions.JsonRpc.Server.Messages +{ + public interface IErrorMessage + { + int Code { get; } + + string Message { get; } + + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + object Data { get; } + } +} \ No newline at end of file diff --git a/src/JsonRpc/Server/Notification.cs b/src/JsonRpc/Server/Notification.cs index ad5e3437b..b4a94d872 100644 --- a/src/JsonRpc/Server/Notification.cs +++ b/src/JsonRpc/Server/Notification.cs @@ -5,7 +5,7 @@ namespace OmniSharp.Extensions.JsonRpc.Server { [JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))] - public class Notification + public class Notification : IMethodWithParams { internal Notification( string method, @@ -25,4 +25,4 @@ internal Notification(string method, JToken @params) : this(method, @params, "2. public JToken Params { get; } } -} \ No newline at end of file +} diff --git a/src/JsonRpc/Server/Request.cs b/src/JsonRpc/Server/Request.cs index 2a8504e45..5c06ea67d 100644 --- a/src/JsonRpc/Server/Request.cs +++ b/src/JsonRpc/Server/Request.cs @@ -5,7 +5,7 @@ namespace OmniSharp.Extensions.JsonRpc.Server { [JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))] - public class Request + public class Request : IMethodWithParams { internal Request(object id, string method, JToken @params) : this(id, method, @params, "2.0") { } @@ -29,4 +29,4 @@ internal Request( public JToken Params { get; } } -} \ No newline at end of file +} diff --git a/src/JsonRpc/Server/ResponseBase.cs b/src/JsonRpc/Server/ResponseBase.cs new file mode 100644 index 000000000..7fd3c5e7b --- /dev/null +++ b/src/JsonRpc/Server/ResponseBase.cs @@ -0,0 +1,14 @@ +namespace OmniSharp.Extensions.JsonRpc.Server +{ + public class ResponseBase + { + public ResponseBase(object id) + { + Id = id; + } + + public string ProtocolVersion { get; set; } = "2.0"; + + public object Id { get; set; } + } +} \ No newline at end of file diff --git a/src/JsonRpc/Server/ServerError.cs b/src/JsonRpc/Server/ServerError.cs new file mode 100644 index 000000000..4bf902b70 --- /dev/null +++ b/src/JsonRpc/Server/ServerError.cs @@ -0,0 +1,14 @@ +using Newtonsoft.Json.Linq; + +namespace OmniSharp.Extensions.JsonRpc.Server +{ + public class ServerError : ResponseBase + { + public ServerError(object id, JToken result) : base(id) + { + Error = result; + } + + public JToken Error { get; set; } + } +} \ No newline at end of file diff --git a/src/JsonRpc/Server/ServerResponse.cs b/src/JsonRpc/Server/ServerResponse.cs index 5df7d1d45..d6271eca6 100644 --- a/src/JsonRpc/Server/ServerResponse.cs +++ b/src/JsonRpc/Server/ServerResponse.cs @@ -4,18 +4,6 @@ namespace OmniSharp.Extensions.JsonRpc.Server { - public class ResponseBase - { - public ResponseBase(object id) - { - Id = id; - } - - public string ProtocolVersion { get; set; } = "2.0"; - - public object Id { get; set; } - } - public class ServerResponse : ResponseBase { public ServerResponse(object id, JToken result) : base(id) @@ -25,14 +13,4 @@ public ServerResponse(object id, JToken result) : base(id) public JToken Result { get; set; } } - - public class ServerError : ResponseBase - { - public ServerError(object id, JToken result) : base(id) - { - Error = result; - } - - public JToken Error { get; set; } - } } diff --git a/src/Lsp/Abstractions/IHandlerCollection.cs b/src/Lsp/Abstractions/IHandlerCollection.cs index 66a88aed9..98ed251b7 100644 --- a/src/Lsp/Abstractions/IHandlerCollection.cs +++ b/src/Lsp/Abstractions/IHandlerCollection.cs @@ -4,7 +4,7 @@ namespace OmniSharp.Extensions.LanguageServer.Abstractions { - interface IHandlerCollection : IEnumerable + public interface IHandlerCollection : IEnumerable { IDisposable Add(params IJsonRpcHandler[] handlers); IDisposable Add(IEnumerable handlers); diff --git a/src/Lsp/Abstractions/ILspHandlerDescriptor.cs b/src/Lsp/Abstractions/ILspHandlerDescriptor.cs index 8642e4306..1cbc31f2f 100644 --- a/src/Lsp/Abstractions/ILspHandlerDescriptor.cs +++ b/src/Lsp/Abstractions/ILspHandlerDescriptor.cs @@ -4,7 +4,7 @@ namespace OmniSharp.Extensions.LanguageServer.Abstractions { - public interface ILspHandlerDescriptor : IHandlerInstance + public interface ILspHandlerDescriptor : IHandlerDescriptor { bool HasRegistration { get; } Type RegistrationType { get; } @@ -16,4 +16,4 @@ public interface ILspHandlerDescriptor : IHandlerInstance bool IsDynamicCapability { get; } bool AllowsDynamicRegistration { get; } } -} \ No newline at end of file +} diff --git a/src/Lsp/LspRequestRouter.cs b/src/Lsp/LspRequestRouter.cs index 61261066b..d116bb535 100644 --- a/src/Lsp/LspRequestRouter.cs +++ b/src/Lsp/LspRequestRouter.cs @@ -44,6 +44,11 @@ private string GetId(object id) return id?.ToString(); } + private ILspHandlerDescriptor FindDescriptor(IMethodWithParams instance) + { + return FindDescriptor(instance.Method, instance.Params); + } + private ILspHandlerDescriptor FindDescriptor(string method, JToken @params) { _logger.LogDebug("Finding descriptor for {Method}", method); @@ -128,11 +133,8 @@ private ILspHandlerDescriptor GetHandler(string method, TextDocumentAttributes a return null; } - public async Task RouteNotification(Notification notification) + public async Task RouteNotification(IHandlerDescriptor handler, Notification notification) { - var handler = FindDescriptor(notification.Method, notification.Params); - if (handler is null) { return; } - try { Task result; @@ -154,7 +156,7 @@ public async Task RouteNotification(Notification notification) } } - public async Task RouteRequest(Request request) + public async Task RouteRequest(IHandlerDescriptor descriptor, Request request) { var id = GetId(request.Id); var cts = new CancellationTokenSource(); @@ -163,30 +165,29 @@ public async Task RouteRequest(Request request) // TODO: Try / catch for Internal Error try { - var method = FindDescriptor(request.Method, request.Params); - if (method is null) + if (descriptor is null) { return new MethodNotFound(request.Id, request.Method); } Task result; - if (method.Params is null) + if (descriptor.Params is null) { - result = ReflectionRequestHandlers.HandleRequest(method, cts.Token); + result = ReflectionRequestHandlers.HandleRequest(descriptor, cts.Token); } else { object @params; try { - @params = request.Params.ToObject(method.Params); + @params = request.Params.ToObject(descriptor.Params); } catch { return new InvalidParams(request.Id); } - result = ReflectionRequestHandlers.HandleRequest(method, @params, cts.Token); + result = ReflectionRequestHandlers.HandleRequest(descriptor, @params, cts.Token); } await result.ConfigureAwait(false); @@ -226,5 +227,25 @@ public void CancelRequest(object id) cts.Cancel(); } } + + public IHandlerDescriptor GetDescriptor(Notification notification) + { + return FindDescriptor(notification); + } + + public IHandlerDescriptor GetDescriptor(Request request) + { + return FindDescriptor(request); + } + + Task IRequestRouter.RouteNotification(Notification notification) + { + return RouteNotification(FindDescriptor(notification), notification); + } + + Task IRequestRouter.RouteRequest(Request request) + { + return RouteRequest(FindDescriptor(request), request); + } } } diff --git a/src/Lsp/Models/ISignatureHelpOptions.cs b/src/Lsp/Models/ISignatureHelpOptions.cs index 58f0cd10b..645961dea 100644 --- a/src/Lsp/Models/ISignatureHelpOptions.cs +++ b/src/Lsp/Models/ISignatureHelpOptions.cs @@ -4,24 +4,4 @@ public interface ISignatureHelpOptions { Container TriggerCharacters { get; set; } } - - public interface ISynchronizationOptions - { - /// - /// The client supports sending will save notifications. - /// - bool WillSave { get; } - - /// - /// The client supports sending a will save request and - /// waits for a response providing text edits which will - /// be applied to the document before it is saved. - /// - bool WillSaveWaitUntil { get; } - - /// - /// The client supports did save notifications. - /// - bool DidSave { get; } - } } diff --git a/src/Lsp/Models/ISynchronizationOptions.cs b/src/Lsp/Models/ISynchronizationOptions.cs new file mode 100644 index 000000000..710720c82 --- /dev/null +++ b/src/Lsp/Models/ISynchronizationOptions.cs @@ -0,0 +1,22 @@ +namespace OmniSharp.Extensions.LanguageServer.Models +{ + public interface ISynchronizationOptions + { + /// + /// The client supports sending will save notifications. + /// + bool WillSave { get; } + + /// + /// The client supports sending a will save request and + /// waits for a response providing text edits which will + /// be applied to the document before it is saved. + /// + bool WillSaveWaitUntil { get; } + + /// + /// The client supports did save notifications. + /// + bool DidSave { get; } + } +} \ No newline at end of file diff --git a/src/Lsp/Protocol/Document/ICodeActionHandler.cs b/src/Lsp/Protocol/Document/ICodeActionHandler.cs index 1bd900b8c..db3154c6e 100644 --- a/src/Lsp/Protocol/Document/ICodeActionHandler.cs +++ b/src/Lsp/Protocol/Document/ICodeActionHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/codeAction")] + [Parallel, Method("textDocument/codeAction")] public interface ICodeActionHandler : IRequestHandler, IRegistration, ICapability { } } diff --git a/src/Lsp/Protocol/Document/ICodeLensHandler.cs b/src/Lsp/Protocol/Document/ICodeLensHandler.cs index 4afc61834..6fcbe603a 100644 --- a/src/Lsp/Protocol/Document/ICodeLensHandler.cs +++ b/src/Lsp/Protocol/Document/ICodeLensHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/codeLens")] + [Parallel, Method("textDocument/codeLens")] public interface ICodeLensHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/ICodeLensResolveHandler.cs b/src/Lsp/Protocol/Document/ICodeLensResolveHandler.cs index 7817d248e..c9662bd65 100644 --- a/src/Lsp/Protocol/Document/ICodeLensResolveHandler.cs +++ b/src/Lsp/Protocol/Document/ICodeLensResolveHandler.cs @@ -1,10 +1,10 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Models; // ReSharper disable CheckNamespace namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("codeLens/resolve")] + [Parallel, Method("codeLens/resolve")] public interface ICodeLensResolveHandler : IRequestHandler { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/ICompletionHandler.cs b/src/Lsp/Protocol/Document/ICompletionHandler.cs index ad2397c44..857b77c9d 100644 --- a/src/Lsp/Protocol/Document/ICompletionHandler.cs +++ b/src/Lsp/Protocol/Document/ICompletionHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/completion")] + [Parallel, Method("textDocument/completion")] public interface ICompletionHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/ICompletionResolveHandler.cs b/src/Lsp/Protocol/Document/ICompletionResolveHandler.cs index c8e1bb476..ed668d993 100644 --- a/src/Lsp/Protocol/Document/ICompletionResolveHandler.cs +++ b/src/Lsp/Protocol/Document/ICompletionResolveHandler.cs @@ -1,10 +1,10 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Models; // ReSharper disable CheckNamespace namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("completionItem/resolve")] + [Serial, Method("completionItem/resolve")] public interface ICompletionResolveHandler : IRequestHandler { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IDefinitionHandler.cs b/src/Lsp/Protocol/Document/IDefinitionHandler.cs index 546ef5cb1..6b008ec62 100644 --- a/src/Lsp/Protocol/Document/IDefinitionHandler.cs +++ b/src/Lsp/Protocol/Document/IDefinitionHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/definition")] + [Parallel, Method("textDocument/definition")] public interface IDefinitionHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IDidChangeTextDocumentHandler.cs b/src/Lsp/Protocol/Document/IDidChangeTextDocumentHandler.cs index 4146632e5..d5da5b61a 100644 --- a/src/Lsp/Protocol/Document/IDidChangeTextDocumentHandler.cs +++ b/src/Lsp/Protocol/Document/IDidChangeTextDocumentHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/didChange")] + [Serial, Method("textDocument/didChange")] public interface IDidChangeTextDocumentHandler : INotificationHandler, IRegistration, ICapability { } } diff --git a/src/Lsp/Protocol/Document/IDidCloseTextDocumentHandler.cs b/src/Lsp/Protocol/Document/IDidCloseTextDocumentHandler.cs index 2d19f058d..74f6289a5 100644 --- a/src/Lsp/Protocol/Document/IDidCloseTextDocumentHandler.cs +++ b/src/Lsp/Protocol/Document/IDidCloseTextDocumentHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/didClose")] + [Parallel, Method("textDocument/didClose")] public interface IDidCloseTextDocumentHandler : INotificationHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IDidOpenTextDocumentHandler.cs b/src/Lsp/Protocol/Document/IDidOpenTextDocumentHandler.cs index 9e7f0db62..ba3e631cb 100644 --- a/src/Lsp/Protocol/Document/IDidOpenTextDocumentHandler.cs +++ b/src/Lsp/Protocol/Document/IDidOpenTextDocumentHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/didOpen")] + [Serial, Method("textDocument/didOpen")] public interface IDidOpenTextDocumentHandler : INotificationHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IDidSaveTextDocumentHandler.cs b/src/Lsp/Protocol/Document/IDidSaveTextDocumentHandler.cs index 6816caeee..259f3c0cd 100644 --- a/src/Lsp/Protocol/Document/IDidSaveTextDocumentHandler.cs +++ b/src/Lsp/Protocol/Document/IDidSaveTextDocumentHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/didSave")] + [Serial, Method("textDocument/didSave")] public interface IDidSaveTextDocumentHandler : INotificationHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IDocumentFormattingHandler.cs b/src/Lsp/Protocol/Document/IDocumentFormattingHandler.cs index 70f13e7ca..1931b6bdf 100644 --- a/src/Lsp/Protocol/Document/IDocumentFormattingHandler.cs +++ b/src/Lsp/Protocol/Document/IDocumentFormattingHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/formatting")] + [Serial, Method("textDocument/formatting")] public interface IDocumentFormattingHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IDocumentHighlightHandler.cs b/src/Lsp/Protocol/Document/IDocumentHighlightHandler.cs index e1a77ffbf..cc67d38de 100644 --- a/src/Lsp/Protocol/Document/IDocumentHighlightHandler.cs +++ b/src/Lsp/Protocol/Document/IDocumentHighlightHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/documentHighlight")] + [Parallel, Method("textDocument/documentHighlight")] public interface IDocumentHighlightHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IDocumentLinkHandler.cs b/src/Lsp/Protocol/Document/IDocumentLinkHandler.cs index 6c6d56181..1b43e6443 100644 --- a/src/Lsp/Protocol/Document/IDocumentLinkHandler.cs +++ b/src/Lsp/Protocol/Document/IDocumentLinkHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/documentLink")] + [Parallel, Method("textDocument/documentLink")] public interface IDocumentLinkHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IDocumentLinkResolveHandler.cs b/src/Lsp/Protocol/Document/IDocumentLinkResolveHandler.cs index 18ee30f61..cda9d7a2c 100644 --- a/src/Lsp/Protocol/Document/IDocumentLinkResolveHandler.cs +++ b/src/Lsp/Protocol/Document/IDocumentLinkResolveHandler.cs @@ -1,10 +1,10 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Models; // ReSharper disable CheckNamespace namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("documentLink/resolve")] + [Parallel, Method("documentLink/resolve")] public interface IDocumentLinkResolveHandler : IRequestHandler { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IDocumentOnTypeFormatHandler.cs b/src/Lsp/Protocol/Document/IDocumentOnTypeFormatHandler.cs index 8551b5e00..0d10c9d8b 100644 --- a/src/Lsp/Protocol/Document/IDocumentOnTypeFormatHandler.cs +++ b/src/Lsp/Protocol/Document/IDocumentOnTypeFormatHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/onTypeFormatting")] + [Serial, Method("textDocument/onTypeFormatting")] public interface IDocumentOnTypeFormatHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IDocumentRangeFormattingHandler.cs b/src/Lsp/Protocol/Document/IDocumentRangeFormattingHandler.cs index 37a9f0ba6..40633c626 100644 --- a/src/Lsp/Protocol/Document/IDocumentRangeFormattingHandler.cs +++ b/src/Lsp/Protocol/Document/IDocumentRangeFormattingHandler.cs @@ -5,6 +5,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol.Document { - [Method("textDocument/rangeFormatting")] + [Serial, Method("textDocument/rangeFormatting")] public interface IDocumentRangeFormattingHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IDocumentSymbolHandler.cs b/src/Lsp/Protocol/Document/IDocumentSymbolHandler.cs index aeb7a254b..bdd645ec8 100644 --- a/src/Lsp/Protocol/Document/IDocumentSymbolHandler.cs +++ b/src/Lsp/Protocol/Document/IDocumentSymbolHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/documentSymbol")] + [Parallel, Method("textDocument/documentSymbol")] public interface IDocumentSymbolHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IHoverHandler.cs b/src/Lsp/Protocol/Document/IHoverHandler.cs index 321d61ffb..f2a3c4625 100644 --- a/src/Lsp/Protocol/Document/IHoverHandler.cs +++ b/src/Lsp/Protocol/Document/IHoverHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/hover")] + [Parallel, Method("textDocument/hover")] public interface IHoverHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IReferencesHandler.cs b/src/Lsp/Protocol/Document/IReferencesHandler.cs index 0b46c85c6..edc60374d 100644 --- a/src/Lsp/Protocol/Document/IReferencesHandler.cs +++ b/src/Lsp/Protocol/Document/IReferencesHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/references")] + [Parallel, Method("textDocument/references")] public interface IReferencesHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IRenameHandler.cs b/src/Lsp/Protocol/Document/IRenameHandler.cs index 967af9e56..d61ca26c2 100644 --- a/src/Lsp/Protocol/Document/IRenameHandler.cs +++ b/src/Lsp/Protocol/Document/IRenameHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/rename")] + [Serial, Method("textDocument/rename")] public interface IRenameHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/ISignatureHelpHandler.cs b/src/Lsp/Protocol/Document/ISignatureHelpHandler.cs index d3a629c5a..c616732cc 100644 --- a/src/Lsp/Protocol/Document/ISignatureHelpHandler.cs +++ b/src/Lsp/Protocol/Document/ISignatureHelpHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/signatureHelp")] + [Parallel, Method("textDocument/signatureHelp")] public interface ISignatureHelpHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IWillSaveTextDocumentHandler.cs b/src/Lsp/Protocol/Document/IWillSaveTextDocumentHandler.cs index 50b477818..97cc67f45 100644 --- a/src/Lsp/Protocol/Document/IWillSaveTextDocumentHandler.cs +++ b/src/Lsp/Protocol/Document/IWillSaveTextDocumentHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/willSave")] + [Parallel, Method("textDocument/willSave")] public interface IWillSaveTextDocumentHandler : INotificationHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Document/IWillSaveWaitUntilTextDocumentHandler.cs b/src/Lsp/Protocol/Document/IWillSaveWaitUntilTextDocumentHandler.cs index 811622236..be9566bc8 100644 --- a/src/Lsp/Protocol/Document/IWillSaveWaitUntilTextDocumentHandler.cs +++ b/src/Lsp/Protocol/Document/IWillSaveWaitUntilTextDocumentHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("textDocument/willSaveWaitUntil")] + [Serial, Method("textDocument/willSaveWaitUntil")] public interface IWillSaveWaitUntilTextDocumentHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/General/ICancelRequestHandler.cs b/src/Lsp/Protocol/General/ICancelRequestHandler.cs index 037f8f97e..1a2051dcb 100644 --- a/src/Lsp/Protocol/General/ICancelRequestHandler.cs +++ b/src/Lsp/Protocol/General/ICancelRequestHandler.cs @@ -1,10 +1,10 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Models; // ReSharper disable CheckNamespace namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("$/cancelRequest")] + [Parallel, Method("$/cancelRequest")] public interface ICancelRequestHandler : INotificationHandler { } } diff --git a/src/Lsp/Protocol/General/IExitHandler.cs b/src/Lsp/Protocol/General/IExitHandler.cs index 2df6fcb4b..37f344c24 100644 --- a/src/Lsp/Protocol/General/IExitHandler.cs +++ b/src/Lsp/Protocol/General/IExitHandler.cs @@ -1,9 +1,9 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; // ReSharper disable CheckNamespace namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("exit")] + [Serial, Method("exit")] public interface IExitHandler : INotificationHandler { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/General/IInitializeHandler.cs b/src/Lsp/Protocol/General/IInitializeHandler.cs index d6c982cf9..edcf3dedf 100644 --- a/src/Lsp/Protocol/General/IInitializeHandler.cs +++ b/src/Lsp/Protocol/General/IInitializeHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Models; // ReSharper disable CheckNamespace @@ -8,6 +8,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol /// /// InitializeError /// - [Method("initialize")] + [Serial, Method("initialize")] public interface IInitializeHandler : IRequestHandler { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/General/IInitializedHandler.cs b/src/Lsp/Protocol/General/IInitializedHandler.cs index a62d22762..d1a2ef05f 100644 --- a/src/Lsp/Protocol/General/IInitializedHandler.cs +++ b/src/Lsp/Protocol/General/IInitializedHandler.cs @@ -1,9 +1,9 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; // ReSharper disable CheckNamespace namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("initialized")] + [Serial, Method("initialized")] public interface IInitializedHandler : INotificationHandler { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/General/IShutdownHandler.cs b/src/Lsp/Protocol/General/IShutdownHandler.cs index 25b3e8e2c..39e118ade 100644 --- a/src/Lsp/Protocol/General/IShutdownHandler.cs +++ b/src/Lsp/Protocol/General/IShutdownHandler.cs @@ -1,9 +1,9 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; // ReSharper disable CheckNamespace namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("shutdown")] + [Serial, Method("shutdown")] public interface IShutdownHandler : INotificationHandler { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Workspace/IDidChangeConfigurationHandler.cs b/src/Lsp/Protocol/Workspace/IDidChangeConfigurationHandler.cs index 015b03b3e..2e1e2982f 100644 --- a/src/Lsp/Protocol/Workspace/IDidChangeConfigurationHandler.cs +++ b/src/Lsp/Protocol/Workspace/IDidChangeConfigurationHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("workspace/didChangeConfiguration")] + [Serial, Method("workspace/didChangeConfiguration")] public interface IDidChangeConfigurationHandler : INotificationHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Workspace/IDidChangeWatchedFilesHandler.cs b/src/Lsp/Protocol/Workspace/IDidChangeWatchedFilesHandler.cs index 0efb2edf3..ac0d7fa41 100644 --- a/src/Lsp/Protocol/Workspace/IDidChangeWatchedFilesHandler.cs +++ b/src/Lsp/Protocol/Workspace/IDidChangeWatchedFilesHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("workspace/didChangeWatchedFiles")] + [Serial, Method("workspace/didChangeWatchedFiles")] public interface IDidChangeWatchedFilesHandler : INotificationHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Workspace/IExecuteCommandHandler.cs b/src/Lsp/Protocol/Workspace/IExecuteCommandHandler.cs index 02be53b21..9ff3eee10 100644 --- a/src/Lsp/Protocol/Workspace/IExecuteCommandHandler.cs +++ b/src/Lsp/Protocol/Workspace/IExecuteCommandHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("workspace/executeCommand")] + [Serial, Method("workspace/executeCommand")] public interface IExecuteCommandHandler : IRequestHandler, IRegistration, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/Protocol/Workspace/IWorkspaceSymbolsHandler.cs b/src/Lsp/Protocol/Workspace/IWorkspaceSymbolsHandler.cs index 7acec6132..fbc644cb6 100644 --- a/src/Lsp/Protocol/Workspace/IWorkspaceSymbolsHandler.cs +++ b/src/Lsp/Protocol/Workspace/IWorkspaceSymbolsHandler.cs @@ -1,4 +1,4 @@ -using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.LanguageServer.Abstractions; using OmniSharp.Extensions.LanguageServer.Capabilities.Client; using OmniSharp.Extensions.LanguageServer.Models; @@ -7,6 +7,6 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol { - [Method("workspace/symbol")] + [Parallel, Method("workspace/symbol")] public interface IWorkspaceSymbolsHandler : IRequestHandler, ICapability { } -} \ No newline at end of file +} diff --git a/src/Lsp/RequestProcessIdentifier.cs b/src/Lsp/RequestProcessIdentifier.cs index e02d0a061..835b2fa1d 100644 --- a/src/Lsp/RequestProcessIdentifier.cs +++ b/src/Lsp/RequestProcessIdentifier.cs @@ -1,14 +1,42 @@ +using System; +using System.Collections.Concurrent; +using System.Linq; +using System.Reflection; using OmniSharp.Extensions.JsonRpc; using OmniSharp.Extensions.JsonRpc.Server; +using OmniSharp.Extensions.LanguageServer.Abstractions; namespace OmniSharp.Extensions.LanguageServer { - class RequestProcessIdentifier : IRequestProcessIdentifier + public class RequestProcessIdentifier : IRequestProcessIdentifier { - public RequestProcessType Identify(Renor renor) + private readonly ConcurrentDictionary _cache = new ConcurrentDictionary(); + private readonly RequestProcessType _defaultRequestProcessType; + + public RequestProcessIdentifier(RequestProcessType defaultRequestProcessType = RequestProcessType.Serial) + { + _defaultRequestProcessType = defaultRequestProcessType; + } + + public RequestProcessType Identify(IHandlerDescriptor descriptor) { - // TODO: Update to it infer based on incoming messages - return RequestProcessType.Serial; + if (_cache.TryGetValue(descriptor.HandlerType, out var type)) return type; + + type = _defaultRequestProcessType; + var handlerType = descriptor.Handler.GetType().GetTypeInfo(); + var processAttribute = handlerType + .GetCustomAttributes(true) + .Concat(descriptor.HandlerType.GetTypeInfo().GetCustomAttributes(true)) + .OfType() + .FirstOrDefault(); + if (processAttribute != null) + { + type = processAttribute.Type; + } + + _cache.TryAdd(descriptor.HandlerType, type); + + return type; } } -} \ No newline at end of file +} diff --git a/test/JsonRpc.Tests/InputHandlerTests.cs b/test/JsonRpc.Tests/InputHandlerTests.cs index 61c7f617c..85125de38 100644 --- a/test/JsonRpc.Tests/InputHandlerTests.cs +++ b/test/JsonRpc.Tests/InputHandlerTests.cs @@ -148,7 +148,7 @@ public void ShouldHandleRequest() var response = new Response(1); - incomingRequestRouter.RouteRequest(req) + incomingRequestRouter.RouteRequest(Arg.Any(), req) .Returns(response); using (NewHandler( @@ -227,14 +227,14 @@ public async Task ShouldHandleNotification() Substitute.For(), cts => { - incomingRequestRouter.When(x => x.RouteNotification(Arg.Any())) + incomingRequestRouter.When(x => x.RouteNotification(Arg.Any(), Arg.Any())) .Do(x => { cts.Cancel(); }); })) { - await incomingRequestRouter.Received().RouteNotification(notification); + await incomingRequestRouter.Received().RouteNotification(Arg.Any(), notification); } } diff --git a/test/JsonRpc.Tests/MediatorTestsNotificationHandler.cs b/test/JsonRpc.Tests/MediatorTestsNotificationHandler.cs index fddc2c0b6..df5d628fb 100644 --- a/test/JsonRpc.Tests/MediatorTestsNotificationHandler.cs +++ b/test/JsonRpc.Tests/MediatorTestsNotificationHandler.cs @@ -19,7 +19,7 @@ public async Task ExecutesHandler() var exitHandler = Substitute.For(); var collection = new HandlerCollection { exitHandler }; - var mediator = new RequestRouter(collection); + IRequestRouter mediator = new RequestRouter(collection); var notification = new Notification("exit", null); diff --git a/test/JsonRpc.Tests/MediatorTestsNotificationHandlerOfT.cs b/test/JsonRpc.Tests/MediatorTestsNotificationHandlerOfT.cs index 6c0a54a77..55a2fd3c7 100644 --- a/test/JsonRpc.Tests/MediatorTestsNotificationHandlerOfT.cs +++ b/test/JsonRpc.Tests/MediatorTestsNotificationHandlerOfT.cs @@ -28,7 +28,7 @@ public async Task ExecutesHandler() var cancelRequestHandler = Substitute.For(); var collection = new HandlerCollection { cancelRequestHandler }; - var mediator = new RequestRouter(collection); + IRequestRouter mediator = new RequestRouter(collection); var @params = new CancelParams() { Id = Guid.NewGuid() }; var notification = new Notification("$/cancelRequest", JObject.Parse(JsonConvert.SerializeObject(@params))); diff --git a/test/JsonRpc.Tests/MediatorTestsRequestHandlerOfTRequest.cs b/test/JsonRpc.Tests/MediatorTestsRequestHandlerOfTRequest.cs index 53657d02e..63e775ceb 100644 --- a/test/JsonRpc.Tests/MediatorTestsRequestHandlerOfTRequest.cs +++ b/test/JsonRpc.Tests/MediatorTestsRequestHandlerOfTRequest.cs @@ -31,7 +31,7 @@ public async Task ExecutesHandler() var executeCommandHandler = Substitute.For(); var collection = new HandlerCollection { executeCommandHandler }; - var mediator = new RequestRouter(collection); + IRequestRouter mediator = new RequestRouter(collection); var id = Guid.NewGuid().ToString(); var @params = new ExecuteCommandParams() { Command = "123" }; @@ -44,4 +44,4 @@ public async Task ExecutesHandler() } } -} \ No newline at end of file +} diff --git a/test/JsonRpc.Tests/MediatorTestsRequestHandlerOfTRequestTResponse.cs b/test/JsonRpc.Tests/MediatorTestsRequestHandlerOfTRequestTResponse.cs index 9911db930..0d871920a 100644 --- a/test/JsonRpc.Tests/MediatorTestsRequestHandlerOfTRequestTResponse.cs +++ b/test/JsonRpc.Tests/MediatorTestsRequestHandlerOfTRequestTResponse.cs @@ -43,7 +43,7 @@ public async Task ExecutesHandler() var codeActionHandler = Substitute.For(); var collection = new HandlerCollection { codeActionHandler }; - var mediator = new RequestRouter(collection); + IRequestRouter mediator = new RequestRouter(collection); var id = Guid.NewGuid().ToString(); var @params = new CodeActionParams() { TextDocument = "TextDocument", Range = "Range", Context = "Context" }; @@ -54,4 +54,4 @@ public async Task ExecutesHandler() await codeActionHandler.Received(1).Handle(Arg.Any(), Arg.Any()); } } -} \ No newline at end of file +} diff --git a/test/Lsp.Tests/LspRequestRouterTests.cs b/test/Lsp.Tests/LspRequestRouterTests.cs index 40918b144..582bbaa07 100644 --- a/test/Lsp.Tests/LspRequestRouterTests.cs +++ b/test/Lsp.Tests/LspRequestRouterTests.cs @@ -4,7 +4,6 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -using FluentAssertions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NSubstitute; @@ -17,6 +16,7 @@ using Xunit; using Xunit.Abstractions; using Xunit.Sdk; +using HandlerCollection = OmniSharp.Extensions.LanguageServer.HandlerCollection; namespace Lsp.Tests { @@ -44,7 +44,7 @@ public async Task ShouldRouteToCorrect_Notification() var request = new Notification("textDocument/didSave", JObject.Parse(JsonConvert.SerializeObject(@params))); - await mediator.RouteNotification(request); + await mediator.RouteNotification(mediator.GetDescriptor(request), request); await textDocumentSyncHandler.Received(1).Handle(Arg.Any()); } @@ -66,7 +66,7 @@ public async Task ShouldRouteToCorrect_Notification_WithManyHandlers() var request = new Notification("textDocument/didSave", JObject.Parse(JsonConvert.SerializeObject(@params))); - await mediator.RouteNotification(request); + await mediator.RouteNotification(mediator.GetDescriptor(request), request); await textDocumentSyncHandler.Received(0).Handle(Arg.Any()); await textDocumentSyncHandler2.Received(1).Handle(Arg.Any()); @@ -94,7 +94,7 @@ public async Task ShouldRouteToCorrect_Request() var request = new Request(id, "textDocument/codeAction", JObject.Parse(JsonConvert.SerializeObject(@params))); - await mediator.RouteRequest(request); + await mediator.RouteRequest(mediator.GetDescriptor(request), request); await codeActionHandler.Received(1).Handle(Arg.Any(), Arg.Any()); } @@ -119,7 +119,7 @@ public async Task ShouldRouteToCorrect_Request_WithManyHandlers() .Handle(Arg.Any(), Arg.Any()) .Returns(new CommandContainer()); - var collection = new HandlerCollection { textDocumentSyncHandler, textDocumentSyncHandler2, codeActionHandler , codeActionHandler2 }; + var collection = new HandlerCollection { textDocumentSyncHandler, textDocumentSyncHandler2, codeActionHandler, codeActionHandler2 }; var mediator = new LspRequestRouter(collection, _testLoggerFactory); var id = Guid.NewGuid().ToString(); @@ -129,7 +129,7 @@ public async Task ShouldRouteToCorrect_Request_WithManyHandlers() var request = new Request(id, "textDocument/codeAction", JObject.Parse(JsonConvert.SerializeObject(@params))); - await mediator.RouteRequest(request); + await mediator.RouteRequest(mediator.GetDescriptor(request), request); await codeActionHandler.Received(0).Handle(Arg.Any(), Arg.Any()); await codeActionHandler2.Received(1).Handle(Arg.Any(), Arg.Any()); diff --git a/test/Lsp.Tests/MediatorTestsRequestHandlerOfTRequest.cs b/test/Lsp.Tests/MediatorTestsRequestHandlerOfTRequest.cs index dea24ff7e..6ab140522 100644 --- a/test/Lsp.Tests/MediatorTestsRequestHandlerOfTRequest.cs +++ b/test/Lsp.Tests/MediatorTestsRequestHandlerOfTRequest.cs @@ -16,6 +16,7 @@ using Xunit.Abstractions; using Xunit.Sdk; using HandlerCollection = OmniSharp.Extensions.LanguageServer.HandlerCollection; +using OmniSharp.Extensions.JsonRpc; namespace Lsp.Tests { @@ -46,7 +47,7 @@ public async Task RequestsCancellation() var @params = new ExecuteCommandParams() { Command = "123" }; var request = new Request(id, "workspace/executeCommand", JObject.Parse(JsonConvert.SerializeObject(@params))); - var response = mediator.RouteRequest(request); + var response = ((IRequestRouter)mediator).RouteRequest(request); mediator.CancelRequest(id); var result = await response; diff --git a/test/Lsp.Tests/MediatorTestsRequestHandlerOfTRequestTResponse.cs b/test/Lsp.Tests/MediatorTestsRequestHandlerOfTRequestTResponse.cs index 577f928e6..c441e799b 100644 --- a/test/Lsp.Tests/MediatorTestsRequestHandlerOfTRequestTResponse.cs +++ b/test/Lsp.Tests/MediatorTestsRequestHandlerOfTRequestTResponse.cs @@ -18,6 +18,7 @@ using Xunit.Abstractions; using Xunit.Sdk; using HandlerCollection = OmniSharp.Extensions.LanguageServer.HandlerCollection; +using OmniSharp.Extensions.JsonRpc; namespace Lsp.Tests { @@ -60,7 +61,7 @@ public async Task RequestsCancellation() var request = new Request(id, "textDocument/codeAction", JObject.Parse(JsonConvert.SerializeObject(@params))); - var response = mediator.RouteRequest(request); + var response = ((IRequestRouter)mediator).RouteRequest(request); mediator.CancelRequest(id); var result = await response; diff --git a/test/Lsp.Tests/Minimatch/MinimatcherTests.cs b/test/Lsp.Tests/Minimatch/BasicTests.cs similarity index 100% rename from test/Lsp.Tests/Minimatch/MinimatcherTests.cs rename to test/Lsp.Tests/Minimatch/BasicTests.cs diff --git a/test/Lsp.Tests/RequestProcessIdentifierTests.cs b/test/Lsp.Tests/RequestProcessIdentifierTests.cs new file mode 100644 index 000000000..25135fb2c --- /dev/null +++ b/test/Lsp.Tests/RequestProcessIdentifierTests.cs @@ -0,0 +1,85 @@ +using System; +using FluentAssertions; +using NSubstitute; +using OmniSharp.Extensions.JsonRpc; +using OmniSharp.Extensions.LanguageServer; +using OmniSharp.Extensions.LanguageServer.Models; +using OmniSharp.Extensions.LanguageServer.Protocol; +using OmniSharp.Extensions.LanguageServer.Protocol.Document; +using Xunit; +using Xunit.Abstractions; + +namespace Lsp.Tests +{ + public class RequestProcessIdentifierTests + { + private readonly TestLoggerFactory _testLoggerFactory; + + public RequestProcessIdentifierTests(ITestOutputHelper testOutputHelper) + { + _testLoggerFactory = new TestLoggerFactory(testOutputHelper); + } + + [Fact] + public void ShouldIdentifyAs_Default() + { + var identifier = new RequestProcessIdentifier(RequestProcessType.Parallel); + var handler = Substitute.For(); + handler.Handler.Returns(Substitute.For()); + handler.HandlerType.Returns(typeof(IJsonRpcHandler)); + + identifier.Identify(handler).Should().Be(RequestProcessType.Parallel); + } + + [Theory] + [InlineData(typeof(ICodeActionHandler))] + [InlineData(typeof(ICodeLensHandler))] + [InlineData(typeof(ICodeLensResolveHandler))] + [InlineData(typeof(IDefinitionHandler))] + [InlineData(typeof(IDidCloseTextDocumentHandler))] + [InlineData(typeof(IDocumentHighlightHandler))] + [InlineData(typeof(IDocumentLinkHandler))] + [InlineData(typeof(IDocumentLinkResolveHandler))] + [InlineData(typeof(IDocumentSymbolHandler))] + [InlineData(typeof(IWorkspaceSymbolsHandler))] + [InlineData(typeof(IWillSaveTextDocumentHandler))] + [InlineData(typeof(IHoverHandler))] + [InlineData(typeof(IReferencesHandler))] + [InlineData(typeof(ISignatureHelpHandler))] + [InlineData(typeof(ICancelRequestHandler))] + public void ShouldIdentifyAs_Parallel(Type type) + { + var identifier = new RequestProcessIdentifier(RequestProcessType.Serial); + var handler = Substitute.For(); + handler.Handler.Returns((IJsonRpcHandler)Substitute.For(new Type[] { type }, new object[0])); + handler.HandlerType.Returns(type); + + identifier.Identify(handler).Should().Be(RequestProcessType.Parallel); + } + + [Theory] + [InlineData(typeof(IDidChangeTextDocumentHandler))] + [InlineData(typeof(IDidOpenTextDocumentHandler))] + [InlineData(typeof(IDidSaveTextDocumentHandler))] + [InlineData(typeof(IDocumentFormattingHandler))] + [InlineData(typeof(IDocumentOnTypeFormatHandler))] + [InlineData(typeof(IDocumentRangeFormattingHandler))] + [InlineData(typeof(IWillSaveWaitUntilTextDocumentHandler))] + [InlineData(typeof(IExitHandler))] + [InlineData(typeof(IShutdownHandler))] + [InlineData(typeof(IInitializeHandler))] + [InlineData(typeof(IInitializedHandler))] + [InlineData(typeof(IDidChangeConfigurationHandler))] + [InlineData(typeof(IDidChangeWatchedFilesHandler))] + [InlineData(typeof(IExecuteCommandHandler))] + public void ShouldIdentifyAs_Serial(Type type) + { + var identifier = new RequestProcessIdentifier(RequestProcessType.Parallel); + var handler = Substitute.For(); + handler.Handler.Returns((IJsonRpcHandler)Substitute.For(new Type[] { type }, new object[0])); + handler.HandlerType.Returns(type); + + identifier.Identify(handler).Should().Be(RequestProcessType.Serial); + } + } +}