Skip to content

Try to fix issue with handlers getting registered twice #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 11, 2017
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