Skip to content

Commit e4b82fe

Browse files
Merge pull request #37 from OmniSharp/hashandler-fix
Updated capabilities to indicate which handler they are tied too, th…
2 parents 99ce493 + a804cf9 commit e4b82fe

26 files changed

+370
-139
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Abstractions;
2+
using OmniSharp.Extensions.LanguageServer.Protocol;
3+
4+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
25
{
3-
public class CodeActionCapability : DynamicCapability { }
6+
public class CodeActionCapability : DynamicCapability, ConnectedCapability<ICodeActionHandler> { }
47
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Capabilities.Server;
2+
using OmniSharp.Extensions.LanguageServer.Protocol;
3+
4+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
25
{
3-
public class CodeLensCapability : DynamicCapability { }
6+
public class CodeLensCapability : DynamicCapability, ConnectedCapability<ICodeLensHandler> { }
47
}

src/Lsp/Capabilities/Client/CompletionCapability.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class CompletionCapability : DynamicCapability
5+
public class CompletionCapability : DynamicCapability, ConnectedCapability<ICompletionHandler>
46
{
57
/// <summary>
68
/// The client supports the following `CompletionItem` specific
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using OmniSharp.Extensions.JsonRpc;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
4+
{
5+
internal interface ConnectedCapability<out T>
6+
where T : IJsonRpcHandler
7+
{ }
8+
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class DefinitionCapability : DynamicCapability { }
5+
public class DefinitionCapability : DynamicCapability, ConnectedCapability<IDefinitionHandler> { }
46
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class DocumentFormattingCapability : DynamicCapability { }
5+
public class DocumentFormattingCapability : DynamicCapability, ConnectedCapability<IDocumentFormattingHandler> { }
46
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class DocumentHighlightCapability : DynamicCapability { }
5+
public class DocumentHighlightCapability : DynamicCapability, ConnectedCapability<IDocumentHighlightHandler> { }
46
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class DocumentLinkCapability : DynamicCapability { }
5+
public class DocumentLinkCapability : DynamicCapability, ConnectedCapability<IDocumentLinkHandler> { }
46
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class DocumentOnTypeFormattingCapability : DynamicCapability { }
5+
public class DocumentOnTypeFormattingCapability : DynamicCapability, ConnectedCapability<IDocumentOnTypeFormatHandler> { }
46
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol.Document;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class DocumentRangeFormattingCapability : DynamicCapability { }
5+
public class DocumentRangeFormattingCapability : DynamicCapability, ConnectedCapability<IDocumentRangeFormattingHandler> { }
46
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class DocumentSymbolCapability : DynamicCapability { }
5+
public class DocumentSymbolCapability : DynamicCapability, ConnectedCapability<IDocumentSymbolHandler> { }
46
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class ExecuteCommandCapability : DynamicCapability { }
5+
public class ExecuteCommandCapability : DynamicCapability, ConnectedCapability<IExecuteCommandHandler> { }
46
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class HoverCapability : DynamicCapability { }
5+
public class HoverCapability : DynamicCapability, ConnectedCapability<IHoverHandler> { }
46
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class ReferencesCapability : DynamicCapability { }
5+
public class ReferencesCapability : DynamicCapability, ConnectedCapability<IReferencesHandler> { }
46
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class RenameCapability : DynamicCapability { }
5+
public class RenameCapability : DynamicCapability, ConnectedCapability<IRenameHandler> { }
46
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class SignatureHelpCapability : DynamicCapability { }
5+
public class SignatureHelpCapability : DynamicCapability, ConnectedCapability<ISignatureHelpHandler> { }
46
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
1+
using OmniSharp.Extensions.LanguageServer.Protocol;
2+
3+
namespace OmniSharp.Extensions.LanguageServer.Capabilities.Client
24
{
3-
public class WorkspaceSymbolCapability : DynamicCapability { }
5+
public class WorkspaceSymbolCapability : DynamicCapability, ConnectedCapability<IWorkspaceSymbolsHandler> { }
46
}

src/Lsp/ClientCapabilityProvider.cs

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using System;
2+
using System.Linq;
3+
using System.Reflection;
4+
using OmniSharp.Extensions.JsonRpc;
5+
using OmniSharp.Extensions.LanguageServer.Abstractions;
6+
using OmniSharp.Extensions.LanguageServer.Capabilities.Client;
7+
8+
namespace OmniSharp.Extensions.LanguageServer
9+
{
10+
internal class ClientCapabilityProvider
11+
{
12+
private readonly IHandlerCollection _collection;
13+
14+
public ClientCapabilityProvider(IHandlerCollection collection)
15+
{
16+
_collection = collection;
17+
}
18+
19+
public bool HasHandler<T>(Supports<T> capability)
20+
where T : DynamicCapability, ConnectedCapability<IJsonRpcHandler>
21+
{
22+
if (!capability.IsSupported) return false;
23+
if (capability.Value == null) return false;
24+
if (capability.Value.DynamicRegistration) return false;
25+
26+
var handlerType = typeof(T).GetTypeInfo().ImplementedInterfaces
27+
.Single(x => x.GetTypeInfo().IsGenericType && x.GetTypeInfo().GetGenericTypeDefinition() == typeof(ConnectedCapability<>))
28+
.GetTypeInfo().GetGenericArguments()[0].GetTypeInfo();
29+
return !capability.Value.DynamicRegistration && _collection.Any(z => z.HandlerType.GetTypeInfo().IsAssignableFrom(handlerType));
30+
}
31+
32+
public IOptionsGetter GetOptions<T>(Supports<T> capability)
33+
where T : DynamicCapability, ConnectedCapability<IJsonRpcHandler>
34+
{
35+
return !HasHandler(capability) ? Null : new OptionsGetter(_collection);
36+
}
37+
38+
private static readonly IOptionsGetter Null = new NullOptionsGetter();
39+
40+
public interface IOptionsGetter
41+
{
42+
TOptions Get<TInterface, TOptions>(Func<TInterface, TOptions> action)
43+
where TOptions : class;
44+
}
45+
46+
private class NullOptionsGetter : IOptionsGetter
47+
{
48+
public TOptions Get<TInterface, TOptions>(Func<TInterface, TOptions> action)
49+
where TOptions : class
50+
{
51+
return null;
52+
}
53+
}
54+
55+
private class OptionsGetter : IOptionsGetter
56+
{
57+
private readonly IHandlerCollection _collection;
58+
59+
public OptionsGetter(IHandlerCollection collection)
60+
{
61+
_collection = collection;
62+
}
63+
64+
public TOptions Get<TInterface, TOptions>(Func<TInterface, TOptions> action)
65+
where TOptions : class
66+
{
67+
return _collection
68+
.Select(x => x.Registration?.RegisterOptions is TInterface cl ? action(cl) : null)
69+
.FirstOrDefault(x => x != null);
70+
}
71+
}
72+
}
73+
}

src/Lsp/HandlerCollection.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ public IDisposable Add(params IJsonRpcHandler[] handlers)
5050
var key = "default";
5151
if (handler is IRegistration<TextDocumentRegistrationOptions>)
5252
{
53-
var options = GetTextDocumentRegistrationOptionsMethod
53+
if (GetTextDocumentRegistrationOptionsMethod
5454
.MakeGenericMethod(registration)
55-
.Invoke(handler, new object[] { handler }) as TextDocumentRegistrationOptions;
56-
key = options.DocumentSelector;
55+
.Invoke(handler, new object[] { handler }) is TextDocumentRegistrationOptions options)
56+
key = options.DocumentSelector;
5757
}
5858

5959
var h = new HandlerDescriptor(

src/Lsp/HandlerDescriptor.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Reflection;
33
using OmniSharp.Extensions.JsonRpc;
44
using OmniSharp.Extensions.LanguageServer.Abstractions;
@@ -59,17 +59,17 @@ public Registration Registration
5959

6060
public void SetCapability(object instance)
6161
{
62+
if (instance is DynamicCapability dc)
63+
{
64+
AllowsDynamicRegistration = dc.DynamicRegistration;
65+
}
66+
6267
// TODO: Cache this
6368
GetType()
6469
.GetTypeInfo()
6570
.GetMethod(nameof(SetCapability), BindingFlags.NonPublic | BindingFlags.Static)
6671
.MakeGenericMethod(CapabilityType)
6772
.Invoke(this, new[] { Handler, instance });
68-
69-
if (instance is DynamicCapability dc)
70-
{
71-
AllowsDynamicRegistration = dc.DynamicRegistration;
72-
}
7373
}
7474

7575
public string Method { get; }

0 commit comments

Comments
 (0)