Skip to content

Commit 5ae6c9a

Browse files
ensure that internal classes can be registered via Microsoft DI (#324)
* ensure that internal classes can be registered via Microsoft DI * Added facade for client and server * Fixed semantic delta params * Updated test
1 parent 82d78ec commit 5ae6c9a

16 files changed

+160
-25
lines changed

sample/SampleServer/SemanticTokensHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public override async Task<SemanticTokens> Handle(
4646
return result;
4747
}
4848

49-
public override async Task<SemanticTokensFullOrDelta> Handle(
49+
public override async Task<SemanticTokensFullOrDelta?> Handle(
5050
SemanticTokensDeltaParams request,
5151
CancellationToken cancellationToken
5252
)

src/Client/LanguageClientServiceCollectionExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ internal static IContainer AddLanguageClientInternals(this IContainer container,
4040
container.RegisterMany<GeneralLanguageClient>(serviceTypeCondition: type => type.Name.Contains(nameof(GeneralLanguageClient)), reuse: Reuse.Singleton);
4141
container.RegisterMany<WindowLanguageClient>(serviceTypeCondition: type => type.Name.Contains(nameof(WindowLanguageClient)), reuse: Reuse.Singleton);
4242
container.RegisterMany<WorkspaceLanguageClient>(serviceTypeCondition: type => type.Name.Contains(nameof(WorkspaceLanguageClient)), reuse: Reuse.Singleton);
43+
container.RegisterMany<DefaultLanguageClientFacade>(serviceTypeCondition: type => type.Name.Contains("LanguageClientFacade"), reuse: Reuse.Singleton);
4344
container.RegisterInstance<IOptionsFactory<LanguageClientOptions>>(new ValueOptionsFactory<LanguageClientOptions>(options));
4445

4546
container.RegisterMany<LanguageClient>(serviceTypeCondition: type => type == typeof(ILanguageClient) || type == typeof(LanguageClient), reuse: Reuse.Singleton);

src/JsonRpc/DryIoc/DryIocAdapter.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Dynamic;
34
using DryIoc;
45
using Microsoft.Extensions.DependencyInjection;
56
using OmniSharp.Extensions.JsonRpc;
@@ -150,7 +151,9 @@ public static void RegisterDescriptor(this IContainer container, ServiceDescript
150151
container.RegisterMany(
151152
new [] {descriptor.ImplementationType},
152153
reuse: reuse,
153-
serviceTypeCondition: type => type == descriptor.ImplementationType || type == descriptor.ServiceType || typeof(IEventingHandler).IsAssignableFrom(type) || typeof(IJsonRpcHandler).IsAssignableFrom(type));
154+
serviceTypeCondition: type => type == descriptor.ImplementationType || type == descriptor.ServiceType || typeof(IEventingHandler).IsAssignableFrom(type) || typeof(IJsonRpcHandler).IsAssignableFrom(type),
155+
nonPublicServiceTypes: true
156+
);
154157
}
155158
else if (descriptor.ImplementationFactory != null)
156159
{
@@ -160,15 +163,19 @@ public static void RegisterDescriptor(this IContainer container, ServiceDescript
160163

161164
container.RegisterDelegate(true, descriptor.ServiceType,
162165
descriptor.ImplementationFactory,
163-
reuse);
166+
reuse
167+
);
164168
}
165169
else
166170
{
167171
// ensure eventing handlers are pulled in automagically.
168172
if (!(descriptor.ImplementationInstance is IEnumerable<object>) && (descriptor.ImplementationInstance is IEventingHandler || descriptor.ImplementationInstance is IJsonRpcHandler))
169173
{
170174

171-
container.RegisterInstanceMany(descriptor.ImplementationInstance);
175+
container.RegisterInstanceMany(
176+
descriptor.ImplementationInstance,
177+
nonPublicServiceTypes: true
178+
);
172179
}
173180
else
174181
{

src/JsonRpc/JsonRpcServer.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77

88
namespace OmniSharp.Extensions.JsonRpc
99
{
10-
public class JsonRpcServer : JsonRpcServerBase, IJsonRpcServer
10+
public class JsonRpcServer : JsonRpcServerBase, IJsonRpcServer, IServiceProvider
1111
{
1212
private readonly Connection _connection;
13+
private readonly IServiceProvider _serviceProvider;
1314
private readonly CompositeDisposable _disposable;
1415

1516
internal static IContainer CreateContainer(JsonRpcServerOptions options, IServiceProvider outerServiceProvider) =>
@@ -61,6 +62,7 @@ IServiceProvider serviceProvider
6162
) : base(handlerCollection, responseRouter)
6263
{
6364
_connection = connection;
65+
_serviceProvider = serviceProvider;
6466
_disposable = options.Value.CompositeDisposable;
6567
_disposable.Add(_connection);
6668
if (serviceProvider is IDisposable disposable)
@@ -83,5 +85,7 @@ public IDisposable Register(Action<IJsonRpcServerRegistry> registryAction)
8385
registryAction(new JsonRpcServerRegistry(manager));
8486
return manager.GetDisposable();
8587
}
88+
89+
object IServiceProvider.GetService(Type serviceType) => _serviceProvider.GetService(serviceType);
8690
}
8791
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using OmniSharp.Extensions.JsonRpc;
3+
using OmniSharp.Extensions.LanguageServer.Protocol.Progress;
4+
5+
namespace OmniSharp.Extensions.LanguageServer.Protocol.Client
6+
{
7+
internal class DefaultLanguageClientFacade : LanguageProtocolProxy, ILanguageClientFacade
8+
{
9+
public DefaultLanguageClientFacade(
10+
IResponseRouter requestRouter, IServiceProvider serviceProvider, IProgressManager progressManager,
11+
ILanguageProtocolSettings languageProtocolSettings, ITextDocumentLanguageClient textDocument, IClientLanguageClient client, IGeneralLanguageClient general, IWindowLanguageClient window, IWorkspaceLanguageClient workspace
12+
) : base(requestRouter, serviceProvider, progressManager, languageProtocolSettings)
13+
{
14+
TextDocument = textDocument;
15+
Client = client;
16+
General = general;
17+
Window = window;
18+
Workspace = workspace;
19+
}
20+
21+
public ITextDocumentLanguageClient TextDocument { get; }
22+
public IClientLanguageClient Client { get; }
23+
public IGeneralLanguageClient General { get; }
24+
public IWindowLanguageClient Window { get; }
25+
public IWorkspaceLanguageClient Workspace { get; }
26+
}
27+
}

src/Protocol/Client/ILanguageClient.cs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,12 @@
77

88
namespace OmniSharp.Extensions.LanguageServer.Protocol.Client
99
{
10-
public interface ILanguageClient : ILanguageClientProxy, IJsonRpcHandlerInstance<ILanguageClientRegistry>, IDisposable
10+
public interface ILanguageClient : ILanguageClientFacade, IJsonRpcHandlerInstance<ILanguageClientRegistry>, IDisposable
1111
{
12-
ITextDocumentLanguageClient TextDocument { get; }
13-
IClientLanguageClient Client { get; }
14-
IGeneralLanguageClient General { get; }
15-
IWindowLanguageClient Window { get; }
16-
IWorkspaceLanguageClient Workspace { get; }
1712
IServiceProvider Services { get; }
1813
IClientWorkDoneManager WorkDoneManager { get; }
1914
IRegistrationManager RegistrationManager { get; }
2015
ILanguageClientWorkspaceFoldersManager WorkspaceFoldersManager { get; }
21-
InitializeParams ClientSettings { get; }
22-
InitializeResult ServerSettings { get; }
2316
Task Initialize(CancellationToken token);
2417
Task Shutdown();
2518
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace OmniSharp.Extensions.LanguageServer.Protocol.Client
2+
{
3+
public interface ILanguageClientFacade : ILanguageClientProxy
4+
{
5+
ITextDocumentLanguageClient TextDocument { get; }
6+
IClientLanguageClient Client { get; }
7+
IGeneralLanguageClient General { get; }
8+
IWindowLanguageClient Window { get; }
9+
IWorkspaceLanguageClient Workspace { get; }
10+
}
11+
}

src/Protocol/Document/Proposals/ISemanticTokensDeltaHandler.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public interface ISemanticTokensHandler : IJsonRpcRequestHandler<SemanticTokensP
2323
[Parallel]
2424
[Method(TextDocumentNames.SemanticTokensFullDelta, Direction.ClientToServer)]
2525
public interface ISemanticTokensDeltaHandler :
26-
IJsonRpcRequestHandler<SemanticTokensDeltaParams, SemanticTokensFullOrDelta>,
26+
IJsonRpcRequestHandler<SemanticTokensDeltaParams, SemanticTokensFullOrDelta?>,
2727
IRegistration<SemanticTokensRegistrationOptions>, ICapability<SemanticTokensCapability>, IDoesNotParticipateInRegistration
2828
{
2929
}
@@ -54,7 +54,7 @@ public virtual async Task<SemanticTokens> Handle(SemanticTokensParams request, C
5454
return builder.Commit().GetSemanticTokens();
5555
}
5656

57-
public virtual async Task<SemanticTokensFullOrDelta> Handle(SemanticTokensDeltaParams request, CancellationToken cancellationToken)
57+
public virtual async Task<SemanticTokensFullOrDelta?> Handle(SemanticTokensDeltaParams request, CancellationToken cancellationToken)
5858
{
5959
var document = await GetSemanticTokensDocument(request, cancellationToken);
6060
var builder = document.Edit(request);
@@ -206,7 +206,7 @@ public static IRequestProgressObservable<SemanticTokensPartialResult, SemanticTo
206206
}, cancellationToken
207207
);
208208

209-
public static IRequestProgressObservable<SemanticTokensFullOrDeltaPartialResult, SemanticTokensFullOrDelta> RequestSemanticTokensDelta(
209+
public static IRequestProgressObservable<SemanticTokensFullOrDeltaPartialResult, SemanticTokensFullOrDelta?> RequestSemanticTokensDelta(
210210
this ITextDocumentLanguageClient mediator, SemanticTokensDeltaParams @params, CancellationToken cancellationToken = default
211211
) =>
212212
mediator.ProgressManager.MonitorUntil(
@@ -216,7 +216,7 @@ public static IRequestProgressObservable<SemanticTokensFullOrDeltaPartialResult,
216216
return new SemanticTokensFullOrDelta(
217217
new SemanticTokensDelta {
218218
Edits = partial.Delta.Edits,
219-
ResultId = result.Delta?.ResultId ?? result.Full?.ResultId
219+
ResultId = result?.Delta?.ResultId ?? result?.Full?.ResultId
220220
}
221221
);
222222
}
@@ -226,7 +226,7 @@ public static IRequestProgressObservable<SemanticTokensFullOrDeltaPartialResult,
226226
return new SemanticTokensFullOrDelta(
227227
new SemanticTokens {
228228
Data = partial.Full.Data,
229-
ResultId = result.Full?.ResultId ?? result.Delta?.ResultId
229+
ResultId = result?.Full?.ResultId ?? result?.Delta?.ResultId
230230
}
231231
);
232232
}

src/Protocol/Models/Proposals/SemanticTokensDeltaParams.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol.Models.Proposals
99
[Obsolete(Constants.Proposal)]
1010
[Method(TextDocumentNames.SemanticTokensFullDelta, Direction.ClientToServer)]
1111
public class SemanticTokensDeltaParams : IWorkDoneProgressParams, ITextDocumentIdentifierParams,
12-
IPartialItemRequest<SemanticTokensFullOrDelta, SemanticTokensFullOrDeltaPartialResult>
12+
IPartialItemRequest<SemanticTokensFullOrDelta?, SemanticTokensFullOrDeltaPartialResult>
1313
{
1414
/// <summary>
1515
/// The text document.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using OmniSharp.Extensions.JsonRpc;
3+
using OmniSharp.Extensions.LanguageServer.Protocol.Progress;
4+
5+
namespace OmniSharp.Extensions.LanguageServer.Protocol.Server
6+
{
7+
internal class DefaultLanguageServerFacade : LanguageProtocolProxy, ILanguageServerFacade
8+
{
9+
public DefaultLanguageServerFacade(
10+
IResponseRouter requestRouter, IServiceProvider serviceProvider, IProgressManager progressManager,
11+
ILanguageProtocolSettings languageProtocolSettings, ITextDocumentLanguageServer textDocument, IClientLanguageServer client, IGeneralLanguageServer general, IWindowLanguageServer window, IWorkspaceLanguageServer workspace
12+
) : base(requestRouter, serviceProvider, progressManager, languageProtocolSettings)
13+
{
14+
TextDocument = textDocument;
15+
Client = client;
16+
General = general;
17+
Window = window;
18+
Workspace = workspace;
19+
}
20+
21+
public ITextDocumentLanguageServer TextDocument { get; }
22+
public IClientLanguageServer Client { get; }
23+
public IGeneralLanguageServer General { get; }
24+
public IWindowLanguageServer Window { get; }
25+
public IWorkspaceLanguageServer Workspace { get; }
26+
}
27+
}

0 commit comments

Comments
 (0)