Skip to content

Commit a7ba5aa

Browse files
Merge pull request #31 from OmniSharp/latest-lsp
Try to fix issue with handlers getting registered twice
2 parents 561a96d + 47f81b9 commit a7ba5aa

File tree

3 files changed

+55
-33
lines changed

3 files changed

+55
-33
lines changed

src/Lsp/HandlerCollection.cs

+10-6
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ IEnumerator IEnumerable.GetEnumerator()
2323
return GetEnumerator();
2424
}
2525

26-
public IDisposable Add(params IJsonRpcHandler[] handlers)
26+
public IDisposable Add(IEnumerable<IJsonRpcHandler> handlers)
2727
{
28-
return Add(handlers.AsEnumerable());
28+
return Add(handlers.ToArray());
2929
}
3030

31-
public IDisposable Add(IEnumerable<IJsonRpcHandler> handlers)
31+
public IDisposable Add(params IJsonRpcHandler[] handlers)
3232
{
33-
var descriptors = new List<HandlerDescriptor>();
33+
var descriptors = new HashSet<HandlerDescriptor>();
3434
foreach (var handler in handlers)
3535
{
3636
foreach (var implementedInterface in handler.GetType().GetTypeInfo()
@@ -65,11 +65,15 @@ public IDisposable Add(IEnumerable<IJsonRpcHandler> handlers)
6565
() => _handlers.RemoveWhere(instance => instance.Handler == handler));
6666

6767
descriptors.Add(h);
68-
_handlers.Add(h);
6968
}
7069
}
7170

72-
return new ImutableDisposable(descriptors);
71+
foreach (var handler in descriptors)
72+
{
73+
_handlers.Add(handler);
74+
}
75+
76+
return new ImmutableDisposable(descriptors);
7377
}
7478

7579
private Type UnwrapGenericType(Type genericType, Type type)

src/Lsp/ImutableDisposable.cs renamed to src/Lsp/ImmutableDisposable.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33

44
namespace OmniSharp.Extensions.LanguageServer
55
{
6-
class ImutableDisposable : IDisposable
6+
class ImmutableDisposable : IDisposable
77
{
88
private readonly IEnumerable<IDisposable> _instances;
99

10-
public ImutableDisposable(IEnumerable<IDisposable> instances)
10+
public ImmutableDisposable(IEnumerable<IDisposable> instances)
1111
{
1212
_instances = instances;
1313
}
1414

15-
public ImutableDisposable(params IDisposable[] instances)
15+
public ImmutableDisposable(params IDisposable[] instances)
1616
{
1717
_instances = instances;
1818
}
@@ -25,4 +25,4 @@ public void Dispose()
2525
}
2626
}
2727
}
28-
}
28+
}

src/Lsp/LanguageServer.cs

+41-23
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,16 @@ public IDisposable AddHandler(IJsonRpcHandler handler)
6060
return AddHandler(handler);
6161
}
6262

63-
public IDisposable AddHandlers(params IJsonRpcHandler[] handlers)
63+
public IDisposable AddHandlers(IEnumerable<IJsonRpcHandler> handlers)
6464
{
65-
return AddHandlers(handlers.AsEnumerable());
65+
return AddHandlers(handlers.ToArray());
6666
}
6767

68-
public IDisposable AddHandlers(IEnumerable<IJsonRpcHandler> handlers)
68+
public IDisposable AddHandlers(params IJsonRpcHandler[] handlers)
6969
{
7070
var handlerDisposable = _collection.Add(handlers);
7171

72-
return new ImutableDisposable(
72+
return new ImmutableDisposable(
7373
handlerDisposable,
7474
new Disposable(() =>
7575
{
@@ -122,24 +122,27 @@ async Task<InitializeResult> IRequestHandler<InitializeParams, InitializeResult>
122122
}
123123
}
124124

125+
var textDocumentCapabilities = Client.Capabilities.TextDocument;
126+
var workspaceCapabilities = Client.Capabilities.Workspace;
127+
125128
var serverCapabilities = new ServerCapabilities()
126129
{
127-
CodeActionProvider = HasHandler<ICodeActionHandler>(),
128-
CodeLensProvider = GetOptions<ICodeLensOptions, CodeLensOptions>(CodeLensOptions.Of),
129-
CompletionProvider = GetOptions<ICompletionOptions, CompletionOptions>(CompletionOptions.Of),
130-
DefinitionProvider = HasHandler<IDefinitionHandler>(),
131-
DocumentFormattingProvider = HasHandler<IDocumentFormattingHandler>(),
132-
DocumentHighlightProvider = HasHandler<IDocumentHighlightHandler>(),
133-
DocumentLinkProvider = GetOptions<IDocumentLinkOptions, DocumentLinkOptions>(DocumentLinkOptions.Of),
134-
DocumentOnTypeFormattingProvider = GetOptions<IDocumentOnTypeFormattingOptions, DocumentOnTypeFormattingOptions>(DocumentOnTypeFormattingOptions.Of),
135-
DocumentRangeFormattingProvider = HasHandler<IDocumentRangeFormattingHandler>(),
136-
DocumentSymbolProvider = HasHandler<IDocumentSymbolHandler>(),
137-
ExecuteCommandProvider = GetOptions<IExecuteCommandOptions, ExecuteCommandOptions>(ExecuteCommandOptions.Of),
138-
HoverProvider = HasHandler<IHoverHandler>(),
139-
ReferencesProvider = HasHandler<IReferencesHandler>(),
140-
RenameProvider = HasHandler<IRenameHandler>(),
141-
SignatureHelpProvider = GetOptions<ISignatureHelpOptions, SignatureHelpOptions>(SignatureHelpOptions.Of),
142-
WorkspaceSymbolProvider = HasHandler<IWorkspaceSymbolsHandler>()
130+
CodeActionProvider = HasHandler<ICodeActionHandler>(textDocumentCapabilities.CodeAction),
131+
CodeLensProvider = GetOptions<ICodeLensOptions, CodeLensOptions>(textDocumentCapabilities.CodeLens, CodeLensOptions.Of),
132+
CompletionProvider = GetOptions<ICompletionOptions, CompletionOptions>(textDocumentCapabilities.Completion, CompletionOptions.Of),
133+
DefinitionProvider = HasHandler<IDefinitionHandler>(textDocumentCapabilities.Definition),
134+
DocumentFormattingProvider = HasHandler<IDocumentFormattingHandler>(textDocumentCapabilities.Formatting),
135+
DocumentHighlightProvider = HasHandler<IDocumentHighlightHandler>(textDocumentCapabilities.DocumentHighlight),
136+
DocumentLinkProvider = GetOptions<IDocumentLinkOptions, DocumentLinkOptions>(textDocumentCapabilities.DocumentLink, DocumentLinkOptions.Of),
137+
DocumentOnTypeFormattingProvider = GetOptions<IDocumentOnTypeFormattingOptions, DocumentOnTypeFormattingOptions>(textDocumentCapabilities.OnTypeFormatting, DocumentOnTypeFormattingOptions.Of),
138+
DocumentRangeFormattingProvider = HasHandler<IDocumentRangeFormattingHandler>(textDocumentCapabilities.RangeFormatting),
139+
DocumentSymbolProvider = HasHandler<IDocumentSymbolHandler>(textDocumentCapabilities.DocumentSymbol),
140+
ExecuteCommandProvider = GetOptions<IExecuteCommandOptions, ExecuteCommandOptions>(workspaceCapabilities.ExecuteCommand, ExecuteCommandOptions.Of),
141+
HoverProvider = HasHandler<IHoverHandler>(textDocumentCapabilities.Hover),
142+
ReferencesProvider = HasHandler<IReferencesHandler>(textDocumentCapabilities.References),
143+
RenameProvider = HasHandler<IRenameHandler>(textDocumentCapabilities.Rename),
144+
SignatureHelpProvider = GetOptions<ISignatureHelpOptions, SignatureHelpOptions>(textDocumentCapabilities.SignatureHelp, SignatureHelpOptions.Of),
145+
WorkspaceSymbolProvider = HasHandler<IWorkspaceSymbolsHandler>(workspaceCapabilities.Symbol)
143146
};
144147

145148
var textSyncHandler = _collection
@@ -194,19 +197,34 @@ public Task Handle()
194197
return Task.CompletedTask;
195198
}
196199

197-
private bool HasHandler<T>()
200+
private bool HasHandler<T>(DynamicCapability capability)
198201
{
199-
return _collection.Any(z => z.Handler is T);
202+
return capability.DynamicRegistration ? false : _collection.Any(z => z.Handler is T);
200203
}
201204

202-
private T GetOptions<O, T>(Func<O, T> action)
205+
private bool HasHandler<T>(Supports<DynamicCapability> capability)
206+
{
207+
if (!capability.IsSupported) return false;
208+
return HasHandler<T>(capability.Value);
209+
}
210+
211+
private T GetOptions<O, T>(DynamicCapability capability, Func<O, T> action)
203212
where T : class
204213
{
214+
if (capability.DynamicRegistration) return null;
215+
205216
return _collection
206217
.Select(x => x.Registration?.RegisterOptions is O cl ? action(cl) : null)
207218
.FirstOrDefault(x => x != null);
208219
}
209220

221+
private T GetOptions<O, T>(Supports<DynamicCapability> capability, Func<O, T> action)
222+
where T : class
223+
{
224+
if (!capability.IsSupported) return null;
225+
return GetOptions<O, T>(capability.Value, action);
226+
}
227+
210228
private void ProcessCapabilties(object instance)
211229
{
212230
var values = instance

0 commit comments

Comments
 (0)