Skip to content

Commit

Permalink
Merge pull request #31 from OmniSharp/latest-lsp
Browse files Browse the repository at this point in the history
Try to fix issue with handlers getting registered twice
  • Loading branch information
david-driscoll authored Oct 11, 2017
2 parents 561a96d + 47f81b9 commit a7ba5aa
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 33 deletions.
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

0 comments on commit a7ba5aa

Please sign in to comment.