Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/Lsp/HandlerCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ IEnumerator IEnumerable.GetEnumerator()
return GetEnumerator();
}

public IDisposable Add(params IJsonRpcHandler[] handlers)
public IDisposable Add(IEnumerable<IJsonRpcHandler> handlers)
{
return Add(handlers.AsEnumerable());
return Add(handlers.ToArray());
}

public IDisposable Add(IEnumerable<IJsonRpcHandler> handlers)
public IDisposable Add(params IJsonRpcHandler[] handlers)
{
var descriptors = new List<HandlerDescriptor>();
var descriptors = new HashSet<HandlerDescriptor>();
foreach (var handler in handlers)
{
foreach (var implementedInterface in handler.GetType().GetTypeInfo()
Expand Down Expand Up @@ -65,11 +65,15 @@ public IDisposable Add(IEnumerable<IJsonRpcHandler> handlers)
() => _handlers.RemoveWhere(instance => instance.Handler == handler));

descriptors.Add(h);
_handlers.Add(h);
}
}

return new ImutableDisposable(descriptors);
foreach (var handler in descriptors)
{
_handlers.Add(handler);
}

return new ImmutableDisposable(descriptors);
}

private Type UnwrapGenericType(Type genericType, Type type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@

namespace OmniSharp.Extensions.LanguageServer
{
class ImutableDisposable : IDisposable
class ImmutableDisposable : IDisposable
{
private readonly IEnumerable<IDisposable> _instances;

public ImutableDisposable(IEnumerable<IDisposable> instances)
public ImmutableDisposable(IEnumerable<IDisposable> instances)
{
_instances = instances;
}

public ImutableDisposable(params IDisposable[] instances)
public ImmutableDisposable(params IDisposable[] instances)
{
_instances = instances;
}
Expand All @@ -25,4 +25,4 @@ public void Dispose()
}
}
}
}
}
64 changes: 41 additions & 23 deletions src/Lsp/LanguageServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,16 @@ public IDisposable AddHandler(IJsonRpcHandler handler)
return AddHandler(handler);
}

public IDisposable AddHandlers(params IJsonRpcHandler[] handlers)
public IDisposable AddHandlers(IEnumerable<IJsonRpcHandler> handlers)
{
return AddHandlers(handlers.AsEnumerable());
return AddHandlers(handlers.ToArray());
}

public IDisposable AddHandlers(IEnumerable<IJsonRpcHandler> handlers)
public IDisposable AddHandlers(params IJsonRpcHandler[] handlers)
{
var handlerDisposable = _collection.Add(handlers);

return new ImutableDisposable(
return new ImmutableDisposable(
handlerDisposable,
new Disposable(() =>
{
Expand Down Expand Up @@ -122,24 +122,27 @@ async Task<InitializeResult> IRequestHandler<InitializeParams, InitializeResult>
}
}

var textDocumentCapabilities = Client.Capabilities.TextDocument;
var workspaceCapabilities = Client.Capabilities.Workspace;

var serverCapabilities = new ServerCapabilities()
{
CodeActionProvider = HasHandler<ICodeActionHandler>(),
CodeLensProvider = GetOptions<ICodeLensOptions, CodeLensOptions>(CodeLensOptions.Of),
CompletionProvider = GetOptions<ICompletionOptions, CompletionOptions>(CompletionOptions.Of),
DefinitionProvider = HasHandler<IDefinitionHandler>(),
DocumentFormattingProvider = HasHandler<IDocumentFormattingHandler>(),
DocumentHighlightProvider = HasHandler<IDocumentHighlightHandler>(),
DocumentLinkProvider = GetOptions<IDocumentLinkOptions, DocumentLinkOptions>(DocumentLinkOptions.Of),
DocumentOnTypeFormattingProvider = GetOptions<IDocumentOnTypeFormattingOptions, DocumentOnTypeFormattingOptions>(DocumentOnTypeFormattingOptions.Of),
DocumentRangeFormattingProvider = HasHandler<IDocumentRangeFormattingHandler>(),
DocumentSymbolProvider = HasHandler<IDocumentSymbolHandler>(),
ExecuteCommandProvider = GetOptions<IExecuteCommandOptions, ExecuteCommandOptions>(ExecuteCommandOptions.Of),
HoverProvider = HasHandler<IHoverHandler>(),
ReferencesProvider = HasHandler<IReferencesHandler>(),
RenameProvider = HasHandler<IRenameHandler>(),
SignatureHelpProvider = GetOptions<ISignatureHelpOptions, SignatureHelpOptions>(SignatureHelpOptions.Of),
WorkspaceSymbolProvider = HasHandler<IWorkspaceSymbolsHandler>()
CodeActionProvider = HasHandler<ICodeActionHandler>(textDocumentCapabilities.CodeAction),
CodeLensProvider = GetOptions<ICodeLensOptions, CodeLensOptions>(textDocumentCapabilities.CodeLens, CodeLensOptions.Of),
CompletionProvider = GetOptions<ICompletionOptions, CompletionOptions>(textDocumentCapabilities.Completion, CompletionOptions.Of),
DefinitionProvider = HasHandler<IDefinitionHandler>(textDocumentCapabilities.Definition),
DocumentFormattingProvider = HasHandler<IDocumentFormattingHandler>(textDocumentCapabilities.Formatting),
DocumentHighlightProvider = HasHandler<IDocumentHighlightHandler>(textDocumentCapabilities.DocumentHighlight),
DocumentLinkProvider = GetOptions<IDocumentLinkOptions, DocumentLinkOptions>(textDocumentCapabilities.DocumentLink, DocumentLinkOptions.Of),
DocumentOnTypeFormattingProvider = GetOptions<IDocumentOnTypeFormattingOptions, DocumentOnTypeFormattingOptions>(textDocumentCapabilities.OnTypeFormatting, DocumentOnTypeFormattingOptions.Of),
DocumentRangeFormattingProvider = HasHandler<IDocumentRangeFormattingHandler>(textDocumentCapabilities.RangeFormatting),
DocumentSymbolProvider = HasHandler<IDocumentSymbolHandler>(textDocumentCapabilities.DocumentSymbol),
ExecuteCommandProvider = GetOptions<IExecuteCommandOptions, ExecuteCommandOptions>(workspaceCapabilities.ExecuteCommand, ExecuteCommandOptions.Of),
HoverProvider = HasHandler<IHoverHandler>(textDocumentCapabilities.Hover),
ReferencesProvider = HasHandler<IReferencesHandler>(textDocumentCapabilities.References),
RenameProvider = HasHandler<IRenameHandler>(textDocumentCapabilities.Rename),
SignatureHelpProvider = GetOptions<ISignatureHelpOptions, SignatureHelpOptions>(textDocumentCapabilities.SignatureHelp, SignatureHelpOptions.Of),
WorkspaceSymbolProvider = HasHandler<IWorkspaceSymbolsHandler>(workspaceCapabilities.Symbol)
};

var textSyncHandler = _collection
Expand Down Expand Up @@ -194,19 +197,34 @@ public Task Handle()
return Task.CompletedTask;
}

private bool HasHandler<T>()
private bool HasHandler<T>(DynamicCapability capability)
{
return _collection.Any(z => z.Handler is T);
return capability.DynamicRegistration ? false : _collection.Any(z => z.Handler is T);
}

private T GetOptions<O, T>(Func<O, T> action)
private bool HasHandler<T>(Supports<DynamicCapability> capability)
{
if (!capability.IsSupported) return false;
return HasHandler<T>(capability.Value);
}

private T GetOptions<O, T>(DynamicCapability capability, Func<O, T> action)
where T : class
{
if (capability.DynamicRegistration) return null;

return _collection
.Select(x => x.Registration?.RegisterOptions is O cl ? action(cl) : null)
.FirstOrDefault(x => x != null);
}

private T GetOptions<O, T>(Supports<DynamicCapability> capability, Func<O, T> action)
where T : class
{
if (!capability.IsSupported) return null;
return GetOptions<O, T>(capability.Value, action);
}

private void ProcessCapabilties(object instance)
{
var values = instance
Expand Down