|
11 | 11 | using OmniSharp.Extensions.JsonRpc.Server;
|
12 | 12 | using OmniSharp.Extensions.JsonRpc.Server.Messages;
|
13 | 13 | using OmniSharp.Extensions.LanguageServer.Abstractions;
|
| 14 | +using OmniSharp.Extensions.LanguageServer.Capabilities.Server; |
14 | 15 | using OmniSharp.Extensions.LanguageServer.Messages;
|
15 | 16 | using OmniSharp.Extensions.LanguageServer.Models;
|
16 | 17 | using OmniSharp.Extensions.LanguageServer.Protocol.Document;
|
17 | 18 |
|
18 | 19 | namespace OmniSharp.Extensions.LanguageServer
|
19 | 20 | {
|
20 |
| - class LspRequestRouter : IRequestRouter |
| 21 | + internal class LspRequestRouter : IRequestRouter |
21 | 22 | {
|
22 | 23 | private readonly IHandlerCollection _collection;
|
| 24 | + private readonly IEnumerable<IHandlerMatcher> _routeMatchers; |
23 | 25 | private readonly ConcurrentDictionary<string, CancellationTokenSource> _requests = new ConcurrentDictionary<string, CancellationTokenSource>();
|
24 | 26 | private readonly ILogger<LspRequestRouter> _logger;
|
25 | 27 |
|
26 |
| - public LspRequestRouter(IHandlerCollection collection, ILoggerFactory loggerFactory) |
| 28 | + public LspRequestRouter(IHandlerCollection collection, |
| 29 | + ILoggerFactory loggerFactory, |
| 30 | + IHandlerMatcherCollection routeMatchers) |
27 | 31 | {
|
28 | 32 | _collection = collection;
|
| 33 | + _routeMatchers = routeMatchers; |
29 | 34 | _logger = loggerFactory.CreateLogger<LspRequestRouter>();
|
30 | 35 | }
|
31 | 36 |
|
@@ -59,78 +64,13 @@ private ILspHandlerDescriptor FindDescriptor(string method, JToken @params)
|
59 | 64 | return null;
|
60 | 65 | }
|
61 | 66 |
|
62 |
| - if (@params != null && descriptor.Params != null) |
63 |
| - { |
64 |
| - var paramsValue = @params.ToObject(descriptor.Params); |
65 |
| - if (paramsValue is ITextDocumentIdentifierParams textDocumentIdentifierParams) |
66 |
| - { |
67 |
| - var attributes = GetTextDocumentAttributes(textDocumentIdentifierParams.TextDocument.Uri); |
68 |
| - |
69 |
| - _logger.LogTrace("Found attributes {Count}, {Attributes}", attributes.Count, attributes.Select(x => $"{x.LanguageId}:{x.Scheme}:{x.Uri}")); |
70 |
| - |
71 |
| - return GetHandler(method, attributes); |
72 |
| - } |
73 |
| - else if (paramsValue is DidOpenTextDocumentParams openTextDocumentParams) |
74 |
| - { |
75 |
| - var attributes = new TextDocumentAttributes(openTextDocumentParams.TextDocument.Uri, openTextDocumentParams.TextDocument.LanguageId); |
76 |
| - |
77 |
| - _logger.LogTrace("Created attribute {Attribute}", $"{attributes.LanguageId}:{attributes.Scheme}:{attributes.Uri}"); |
| 67 | + if (@params == null || descriptor.Params == null) return descriptor; |
78 | 68 |
|
79 |
| - return GetHandler(method, attributes); |
80 |
| - } |
81 |
| - else if (paramsValue is DidChangeTextDocumentParams didChangeDocumentParams) |
82 |
| - { |
83 |
| - // TODO: Do something with document version here? |
84 |
| - var attributes = GetTextDocumentAttributes(didChangeDocumentParams.TextDocument.Uri); |
| 69 | + var paramsValue = @params.ToObject(descriptor.Params); |
85 | 70 |
|
86 |
| - _logger.LogTrace("Found attributes {Count}, {Attributes}", attributes.Count, attributes.Select(x => $"{x.LanguageId}:{x.Scheme}:{x.Uri}")); |
| 71 | + var lspHandlerDescriptors = _collection.Where(handler => handler.Method == method).ToList(); |
87 | 72 |
|
88 |
| - return GetHandler(method, attributes); |
89 |
| - } |
90 |
| - } |
91 |
| - |
92 |
| - // TODO: How to split these |
93 |
| - // Do they fork and join? |
94 |
| - return descriptor; |
95 |
| - } |
96 |
| - |
97 |
| - private List<TextDocumentAttributes> GetTextDocumentAttributes(Uri uri) |
98 |
| - { |
99 |
| - var textDocumentSyncHandlers = _collection |
100 |
| - .Select(x => x.Handler is ITextDocumentSyncHandler r ? r : null) |
101 |
| - .Where(x => x != null) |
102 |
| - .Distinct(); |
103 |
| - return textDocumentSyncHandlers |
104 |
| - .Select(x => x.GetTextDocumentAttributes(uri)) |
105 |
| - .Where(x => x != null) |
106 |
| - .Distinct() |
107 |
| - .ToList(); |
108 |
| - } |
109 |
| - |
110 |
| - private ILspHandlerDescriptor GetHandler(string method, IEnumerable<TextDocumentAttributes> attributes) |
111 |
| - { |
112 |
| - return attributes |
113 |
| - .Select(x => GetHandler(method, x)) |
114 |
| - .FirstOrDefault(x => x != null); |
115 |
| - } |
116 |
| - |
117 |
| - private ILspHandlerDescriptor GetHandler(string method, TextDocumentAttributes attributes) |
118 |
| - { |
119 |
| - _logger.LogTrace("Looking for handler for method {Method}", method); |
120 |
| - foreach (var handler in _collection.Where(x => x.Method == method)) |
121 |
| - { |
122 |
| - _logger.LogTrace("Checking handler {Method}:{Handler}", method, handler.Handler.GetType().FullName); |
123 |
| - var registrationOptions = handler.Registration.RegisterOptions as TextDocumentRegistrationOptions; |
124 |
| - |
125 |
| - _logger.LogTrace("Registration options {OptionsName}", registrationOptions.GetType().FullName); |
126 |
| - _logger.LogTrace("Document Selector {DocumentSelector}", registrationOptions.DocumentSelector.ToString()); |
127 |
| - if (registrationOptions.DocumentSelector == null || registrationOptions.DocumentSelector.IsMatch(attributes)) |
128 |
| - { |
129 |
| - _logger.LogTrace("Handler Selected: {Handler} via {DocumentSelector} (targeting {HandlerInterface})", handler.Handler.GetType().FullName, registrationOptions.DocumentSelector.ToString(), handler.HandlerType.GetType().FullName); |
130 |
| - return handler; |
131 |
| - } |
132 |
| - } |
133 |
| - return null; |
| 73 | + return _routeMatchers.SelectMany(strat => strat.FindHandler(paramsValue, lspHandlerDescriptors)).FirstOrDefault() ?? descriptor; |
134 | 74 | }
|
135 | 75 |
|
136 | 76 | public async Task RouteNotification(IHandlerDescriptor handler, Notification notification)
|
@@ -192,7 +132,6 @@ public async Task<ErrorResponse> RouteRequest(IHandlerDescriptor descriptor, Req
|
192 | 132 |
|
193 | 133 | await result.ConfigureAwait(false);
|
194 | 134 |
|
195 |
| - |
196 | 135 | object responseValue = null;
|
197 | 136 | if (result.GetType().GetTypeInfo().IsGenericType)
|
198 | 137 | {
|
|
0 commit comments