public void Should_AllowUnsupportedCapabilities(IJsonRpcHandler handler, object instance) { var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp"); var collection = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), new ServiceCollection().BuildServiceProvider()) { textDocumentSyncHandler, handler }; var provider = new ClientCapabilityProvider(collection, true); HasHandler(provider, instance).Should().BeTrue(); }
public void Should_Contain_AllDefinedLanguageServerMethods(string key, int count) { var handler = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(), new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly })); handler.Add( Substitute.For <ILanguageProtocolInitializeHandler>(), Substitute.For <ILanguageProtocolInitializedHandler>(), Substitute.For <IExitHandler>(), Substitute.For <IShutdownHandler>() ); handler.Should().Contain(x => x.Method == key); handler.Should().HaveCount(count); }
public async Task ShouldRouteToCorrect_Request() { var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp"); textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>()) .Returns(Unit.Value); var codeActionHandler = Substitute.For <ICodeActionHandler>(); codeActionHandler.GetRegistrationOptions().Returns(new CodeActionRegistrationOptions { DocumentSelector = DocumentSelector.ForPattern("**/*.cs") }); codeActionHandler .Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>()) .Returns(new CommandOrCodeActionContainer()); var collection = new SharedHandlerCollection( SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(), new LspHandlerTypeDescriptorProvider( new[] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly } ) ) { textDocumentSyncHandler, codeActionHandler }; AutoSubstitute.Provide <IHandlerCollection>(collection); AutoSubstitute.Provide <IEnumerable <ILspHandlerDescriptor> >(collection); var mediator = AutoSubstitute.Resolve <LspRequestRouter>(); var id = Guid.NewGuid().ToString(); var @params = new DidSaveTextDocumentParams { TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cs")) }; var request = new Request( id, TextDocumentNames.CodeAction, JObject.Parse(JsonConvert.SerializeObject(@params, new Serializer(ClientVersion.Lsp3).Settings)) ); await mediator.RouteRequest(mediator.GetDescriptors(request), request, CancellationToken.None); await codeActionHandler.Received(1).Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>()); }
public void Should_AllowNullSupportedCapabilities(IJsonRpcHandler handler, object instance) { var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp"); var collection = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(), new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly })) { textDocumentSyncHandler, handler }; var provider = new ClientCapabilityProvider(collection, true); HasHandler(provider, instance).Should().BeTrue(); }
public void Should_Contain_AllConcreteDefinedMethods() { var handler = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers()); handler.Add( Substitute.For <IExitHandler>(), Substitute.For <ILanguageProtocolInitializeHandler>(), Substitute.For <ILanguageProtocolInitializedHandler>(), Substitute.For <IShutdownHandler>() ); handler._handlers.Should().Contain(x => x.Method == "exit"); handler._handlers.Should().Contain(x => x.Method == "shutdown"); handler._handlers.Count.Should().Be(4); }
public void Should_Contain_AllDefinedMethods_ForDifferentKeys(string key, int count) { var handler = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(), new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly })); handler.Initialize(); var sub = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp"); var sub2 = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cake"), "csharp"); handler.Add(sub); handler.Add(sub2); handler.Should().Contain(x => x.Method == key); handler.Should().HaveCount(count); }
public void Should_AllowSpecificHandlers_ToBeAdded(string method, Type handlerType) { var handler = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(), new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly })); handler.Initialize(); var sub = (IJsonRpcHandler)Substitute.For(new[] { handlerType }, new object[0]); var sub2 = (IJsonRpcHandler)Substitute.For(new[] { handlerType }, new object[0]); handler.Add(method, sub, null); handler.Add(method, sub2, null); handler.Should().Contain(x => x.Method == method); handler.Should().Contain(x => x.Method == method); handler.Should().HaveCount(1); }
public ClientCapabilityProviderFixture() { var handler = Substitute.For <IExecuteCommandHandler>(); handler.GetRegistrationOptions().Returns(new ExecuteCommandRegistrationOptions()); var handlerCollection = new SharedHandlerCollection( SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), new ServiceCollection().BuildServiceProvider() ) { handler }; var capabilityProvider = new ClientCapabilityProvider(handlerCollection, true); Provider = capabilityProvider; }
public void Should_Contain_AllDefinedMethods_OnLanguageServer(Type requestHandler, Type type2, string key, string key2, int count) { var handler = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers()); var sub = (IJsonRpcHandler)Substitute.For(new Type[] { requestHandler, type2 }, new object[0]); if (sub is IRegistration <TextDocumentRegistrationOptions> reg) { reg.GetRegistrationOptions() .Returns(new TextDocumentRegistrationOptions() { DocumentSelector = new DocumentSelector() }); } handler.Add(sub); handler._handlers.Should().Contain(x => x.Method == key); handler._handlers.Should().Contain(x => x.Method == key2); handler._handlers.Count.Should().Be(count); }
public void Should_DealWithClassesThatImplementMultipleHandlers_BySettingKeyAccordingly() { var codeLensHandler = Substitute.For(new Type[] { typeof(ICodeLensHandler), typeof(ICodeLensResolveHandler) }, new object[0]); ((ICodeLensHandler)codeLensHandler).GetRegistrationOptions() .Returns(new CodeLensRegistrationOptions() { DocumentSelector = new DocumentSelector(DocumentFilter.ForLanguage("foo")) }); var handler = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers()); handler.Add(codeLensHandler as IJsonRpcHandler); var descriptor = handler._handlers.Select(x => x.Key); descriptor.Should().BeEquivalentTo(new [] { "[foo]", "[foo]" }); }
public void Should_Return_Did_Folding_Range_handler() { // Given var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.ps*1"), "powershell"); var handler = Substitute.For <IFoldingRangeHandler>(); handler.GetRegistrationOptions().Returns( new FoldingRangeRegistrationOptions { DocumentSelector = new DocumentSelector(new DocumentFilter { Pattern = "**/*.ps*1" }) } ); var textDocumentIdentifiers = new TextDocumentIdentifiers(); AutoSubstitute.Provide(textDocumentIdentifiers); var collection = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, textDocumentIdentifiers, Substitute.For <IResolverContext>(), new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly })) { textDocumentSyncHandler, handler }; AutoSubstitute.Provide <IHandlerCollection>(collection); AutoSubstitute.Provide <IEnumerable <ILspHandlerDescriptor> >(collection); var handlerMatcher = AutoSubstitute.Resolve <TextDocumentMatcher>(); // When var result = handlerMatcher.FindHandler( new FoldingRangeRequestParam { TextDocument = new TextDocumentItem { Uri = new Uri("file:///abc/123/d.ps1") } }, collection.Where(x => x.Method == TextDocumentNames.DidOpen) ); // Then var lspHandlerDescriptors = result as ILspHandlerDescriptor[] ?? result.ToArray(); lspHandlerDescriptors.Should().NotBeNullOrEmpty(); lspHandlerDescriptors.Should().Contain(x => x.Method == TextDocumentNames.DidOpen); }
public ClientCapabilityProviderFixture() { var handler = Substitute.For <IExecuteCommandHandler>(); handler.GetRegistrationOptions().Returns(new ExecuteCommandRegistrationOptions()); var handlerCollection = new SharedHandlerCollection( SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(), new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly }) ) { handler }; var capabilityProvider = new ClientCapabilityProvider(handlerCollection, true); Provider = capabilityProvider; }
public async Task ShouldRouteToCorrect_Notification_WithManyHandlers() { var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp"); var textDocumentSyncHandler2 = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cake"), "csharp"); textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>()) .Returns(Unit.Value); textDocumentSyncHandler2.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>()) .Returns(Unit.Value); var textDocumentIdentifiers = new TextDocumentIdentifiers(); AutoSubstitute.Provide(textDocumentIdentifiers); var collection = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, textDocumentIdentifiers, new ServiceCollection().BuildServiceProvider()) { textDocumentSyncHandler, textDocumentSyncHandler2 }; AutoSubstitute.Provide <IHandlerCollection>(collection); AutoSubstitute.Provide <IEnumerable <ILspHandlerDescriptor> >(collection); AutoSubstitute.Provide <IHandlerMatcher>(new TextDocumentMatcher(LoggerFactory.CreateLogger <TextDocumentMatcher>(), textDocumentIdentifiers)); var mediator = AutoSubstitute.Resolve <LspRequestRouter>(); var @params = new DidSaveTextDocumentParams { TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cake")) }; var request = new Notification( TextDocumentNames.DidSave, JObject.Parse(JsonConvert.SerializeObject(@params, new Serializer(ClientVersion.Lsp3).Settings)) ); await mediator.RouteNotification(mediator.GetDescriptors(request), request, CancellationToken.None); await textDocumentSyncHandler.Received(0) .Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>()); await textDocumentSyncHandler2.Received(1) .Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>()); }
public void Should_Contain_AllDefinedMethods_OnLanguageServer(Type requestHandler, Type type2, string key, string key2, int count) { var handler = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(), new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly })); var sub = (IJsonRpcHandler)Substitute.For(new[] { requestHandler, type2 }, new object[0]); if (sub is IRegistration <TextDocumentRegistrationOptions> reg) { reg.GetRegistrationOptions() .Returns( new TextDocumentRegistrationOptions { DocumentSelector = new DocumentSelector() } ); } handler.Add(sub); handler.Should().Contain(x => x.Method == key); handler.Should().Contain(x => x.Method == key2); handler.Should().HaveCount(count); }
public void Should_DealWithClassesThatImplementMultipleHandlers_BySettingKeyAccordingly() { var codeLensHandler = Substitute.For(new[] { typeof(ICodeLensHandler), typeof(ICodeLensResolveHandler) }, new object[0]); ((ICodeLensHandler)codeLensHandler).GetRegistrationOptions() .Returns( new CodeLensRegistrationOptions { DocumentSelector = new DocumentSelector(DocumentFilter.ForLanguage("foo")) } ); var handler = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(), new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly })); handler.Add(codeLensHandler as IJsonRpcHandler); var descriptor = handler.OfType <LspHandlerDescriptor>().Select(x => x.Key); descriptor.Should().BeEquivalentTo("[foo]", "[foo]"); }
public void Should_Contain_AllDefinedLanguageServerMethods_GivenDuplicates(string key, int count) { var handler = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers()); handler.Add( Substitute.For <ILanguageProtocolInitializeHandler>(), Substitute.For <ILanguageProtocolInitializedHandler>(), Substitute.For <IExitHandler>(), Substitute.For <IShutdownHandler>(), Substitute.For <ILanguageProtocolInitializeHandler>(), Substitute.For <ILanguageProtocolInitializedHandler>(), Substitute.For <IExitHandler>(), Substitute.For <IShutdownHandler>(), Substitute.For <ILanguageProtocolInitializeHandler>(), Substitute.For <ILanguageProtocolInitializedHandler>(), Substitute.For <IExitHandler>(), Substitute.For <IShutdownHandler>() ); handler._handlers.Should().Contain(x => x.Method == key); handler._handlers.Count.Should().Be(count); }
public void Should_Return_Did_Folding_Range_handler() { // Given var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.ps*1"), "powershell"); var handler = Substitute.For <IFoldingRangeHandler>(); handler.GetRegistrationOptions().Returns( new FoldingRangeRegistrationOptions { DocumentSelector = new DocumentSelector(new DocumentFilter { Pattern = "**/*.ps*1" }) } ); var textDocumentIdentifiers = new TextDocumentIdentifiers(); AutoSubstitute.Provide(textDocumentIdentifiers); var collection = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, textDocumentIdentifiers, new ServiceCollection().BuildServiceProvider()) { textDocumentSyncHandler, handler }; AutoSubstitute.Provide <IHandlerCollection>(collection); AutoSubstitute.Provide <IEnumerable <ILspHandlerDescriptor> >(collection); var handlerMatcher = AutoSubstitute.Resolve <TextDocumentMatcher>(); // When var result = handlerMatcher.FindHandler( new FoldingRangeRequestParam { TextDocument = new TextDocumentItem { Uri = new Uri("file:///abc/123/d.ps1") } }, collection.Where(x => x.Method == TextDocumentNames.DidOpen) ); // Then result.Should().NotBeNullOrEmpty(); result.Should().Contain(x => x.Method == TextDocumentNames.DidOpen); }
public void GH162_TextDocumentSync_Should_Work_Without_WillSave_Or_WillSaveWaitUntil() { var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp"); var collection = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), new ServiceCollection().BuildServiceProvider()) { textDocumentSyncHandler }; var provider = new ClientCapabilityProvider(collection, true); var capabilities = new ClientCapabilities { TextDocument = new TextDocumentClientCapabilities { Synchronization = new SynchronizationCapability { DidSave = true, DynamicRegistration = false, WillSave = true, WillSaveWaitUntil = true }, } }; provider.HasStaticHandler(capabilities.TextDocument.Synchronization).Should().BeTrue(); }
public void Should_Handle_Mixed_Capabilities() { var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp"); var codeActionHandler = Substitute.For <ICodeActionHandler>(); var definitionHandler = Substitute.For <IDefinitionHandler>(); var typeDefinitionHandler = Substitute.For <ITypeDefinitionHandler>(); var collection = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, new TextDocumentIdentifiers(), Substitute.For <IResolverContext>(), new LspHandlerTypeDescriptorProvider(new [] { typeof(FoundationTests).Assembly, typeof(LanguageServer).Assembly, typeof(LanguageClient).Assembly, typeof(IRegistrationManager).Assembly, typeof(LspRequestRouter).Assembly })) { textDocumentSyncHandler, codeActionHandler, definitionHandler, typeDefinitionHandler }; var provider = new ClientCapabilityProvider(collection, true); var capabilities = new ClientCapabilities { TextDocument = new TextDocumentClientCapabilities { CodeAction = new Supports <CodeActionCapability?>( true, new CodeActionCapability { DynamicRegistration = false, } ), TypeDefinition = new Supports <TypeDefinitionCapability?>( true, new TypeDefinitionCapability { DynamicRegistration = true, } ) } }; // provider.GetStaticOptions(capabilities.TextDocument.CodeAction) // .Get<ICodeActionOptions, CodeActionRegistrationOptions.StaticOptions>(CodeActionRegistrationOptions.StaticOptions.Of).Should().NotBeNull(); provider.HasStaticHandler(capabilities.TextDocument.Definition).Should().BeTrue(); provider.HasStaticHandler(capabilities.TextDocument.TypeDefinition).Should().BeFalse(); }
internal LanguageClient(LanguageClientOptions options) : base(options) { _capabilities = options.SupportedCapabilities; _clientCapabilities = options.ClientCapabilities; var services = options.Services; services.AddLogging(builder => options.LoggingBuilderAction(builder)); options.RequestProcessIdentifier ??= (options.SupportsContentModified ? new RequestProcessIdentifier(RequestProcessType.Parallel) : new RequestProcessIdentifier(RequestProcessType.Serial)); // services.AddSingleton<IOptionsMonitor<LoggerFilterOptions>, LanguageClientLoggerFilterOptions>(); _clientInfo = options.ClientInfo; _receiver = options.Receiver; var serializer = options.Serializer; var supportedCapabilities = new SupportedCapabilities(); _textDocumentIdentifiers = new TextDocumentIdentifiers(); var collection = new SharedHandlerCollection(supportedCapabilities, _textDocumentIdentifiers); services.AddSingleton <IHandlersManager>(collection); _collection = collection; // _initializeDelegates = initializeDelegates; // _initializedDelegates = initializedDelegates; _startedDelegates = options.StartedDelegates; _rootUri = options.RootUri; _trace = options.Trace; _initializationOptions = options.InitializationOptions; services.AddSingleton <IOutputHandler>(_ => new OutputHandler(options.Output, options.Serializer, options.Receiver.ShouldFilterOutput, _.GetService <ILogger <OutputHandler> >())); services.AddSingleton(_collection); services.AddSingleton(_textDocumentIdentifiers); services.AddSingleton(serializer); services.AddSingleton <OmniSharp.Extensions.JsonRpc.ISerializer>(serializer); services.AddSingleton(options.RequestProcessIdentifier); services.AddSingleton <OmniSharp.Extensions.JsonRpc.IReceiver>(options.Receiver); services.AddSingleton(options.Receiver); services.AddSingleton <ILanguageClient>(this); services.AddSingleton <LspRequestRouter>(); services.AddSingleton <IRequestRouter <ILspHandlerDescriptor> >(_ => _.GetRequiredService <LspRequestRouter>()); services.AddSingleton <IRequestRouter <IHandlerDescriptor> >(_ => _.GetRequiredService <LspRequestRouter>()); services.AddSingleton <IResponseRouter, ResponseRouter>(); services.AddSingleton <IProgressManager, ProgressManager>(); services.AddSingleton(_ => _.GetRequiredService <IProgressManager>() as IJsonRpcHandler); services.AddSingleton <IClientWorkDoneManager, ClientWorkDoneManager>(); services.AddSingleton(_ => _.GetRequiredService <IClientWorkDoneManager>() as IJsonRpcHandler); EnsureAllHandlersAreRegistered(); services.AddSingleton <RegistrationManager>(); services.AddSingleton <IRegistrationManager>(_ => _.GetRequiredService <RegistrationManager>()); if (options.DynamicRegistration) { services.AddSingleton(_ => _.GetRequiredService <RegistrationManager>() as IJsonRpcHandler); } var workspaceFoldersManager = new WorkspaceFoldersManager(this); services.AddSingleton(workspaceFoldersManager); services.AddSingleton <IWorkspaceFoldersManager>(workspaceFoldersManager); if (options.WorkspaceFolders) { services.AddSingleton <IJsonRpcHandler>(workspaceFoldersManager); } var serviceProvider = services.BuildServiceProvider(); _disposable.Add(serviceProvider); _serviceProvider = serviceProvider; collection.SetServiceProvider(_serviceProvider); _responseRouter = _serviceProvider.GetRequiredService <IResponseRouter>(); _progressManager = _serviceProvider.GetRequiredService <IProgressManager>(); _workDoneManager = _serviceProvider.GetRequiredService <IClientWorkDoneManager>(); _registrationManager = _serviceProvider.GetRequiredService <RegistrationManager>(); _workspaceFoldersManager = _serviceProvider.GetRequiredService <IWorkspaceFoldersManager>(); _connection = new Connection( options.Input, _serviceProvider.GetRequiredService <IOutputHandler>(), options.Receiver, options.RequestProcessIdentifier, _serviceProvider.GetRequiredService <IRequestRouter <IHandlerDescriptor> >(), _responseRouter, _serviceProvider.GetRequiredService <ILoggerFactory>(), options.OnUnhandledException ?? (e => { }), options.CreateResponseException, options.MaximumRequestTimeout, options.SupportsContentModified, options.Concurrency ); // We need to at least create Window here in case any handler does loggin in their constructor TextDocument = new TextDocumentLanguageClient(this, _serviceProvider); Client = new ClientLanguageClient(this, _serviceProvider); General = new GeneralLanguageClient(this, _serviceProvider); Window = new WindowLanguageClient(this, _serviceProvider); Workspace = new WorkspaceLanguageClient(this, _serviceProvider); workspaceFoldersManager.Add(options.Folders); var serviceHandlers = _serviceProvider.GetServices <IJsonRpcHandler>().ToArray(); var serviceIdentifiers = _serviceProvider.GetServices <ITextDocumentIdentifier>().ToArray(); _disposable.Add(_textDocumentIdentifiers.Add(serviceIdentifiers)); _disposable.Add(_collection.Add(serviceHandlers)); options.AddLinks(_collection); }
internal LanguageServer(LanguageServerOptions options) : base(options) { var services = options.Services; var configurationProvider = new DidChangeConfigurationProvider(this, options.ConfigurationBuilderAction); services.AddSingleton <IJsonRpcHandler>(configurationProvider); options.RequestProcessIdentifier ??= (options.SupportsContentModified ? new RequestProcessIdentifier(RequestProcessType.Parallel) : new RequestProcessIdentifier(RequestProcessType.Serial)); services.AddSingleton <IConfiguration>(configurationProvider); services.AddSingleton(Configuration = configurationProvider); services.AddLogging(builder => options.LoggingBuilderAction(builder)); services.AddSingleton <IOptionsMonitor <LoggerFilterOptions>, LanguageServerLoggerFilterOptions>(); _serverInfo = options.ServerInfo; _serverReceiver = options.Receiver; _serializer = options.Serializer; _supportedCapabilities = new SupportedCapabilities(); _textDocumentIdentifiers = new TextDocumentIdentifiers(); var collection = new SharedHandlerCollection(_supportedCapabilities, _textDocumentIdentifiers); services.AddSingleton <IHandlersManager>(collection); _collection = collection; _initializeDelegates = options.InitializeDelegates; _initializedDelegates = options.InitializedDelegates; _startedDelegates = options.StartedDelegates; services.AddSingleton <IOutputHandler>(_ => new OutputHandler( options.Output, options.Serializer, options.Receiver.ShouldFilterOutput, _.GetService <ILogger <OutputHandler> >()) ); services.AddSingleton(_collection); services.AddSingleton(_textDocumentIdentifiers); services.AddSingleton(_serializer); services.AddSingleton <OmniSharp.Extensions.JsonRpc.ISerializer>(_serializer); services.AddSingleton(options.RequestProcessIdentifier); services.AddSingleton <OmniSharp.Extensions.JsonRpc.IReceiver>(options.Receiver); services.AddSingleton <ILspServerReceiver>(options.Receiver); services.AddTransient <IHandlerMatcher, TextDocumentMatcher>(); services.AddSingleton <ILanguageServer>(this); services.AddTransient <IHandlerMatcher, ExecuteCommandMatcher>(); services.AddTransient <IHandlerMatcher, ResolveCommandMatcher>(); services.AddSingleton <LspRequestRouter>(); services.AddSingleton <IRequestRouter <ILspHandlerDescriptor> >(_ => _.GetRequiredService <LspRequestRouter>()); services.AddSingleton <IRequestRouter <IHandlerDescriptor> >(_ => _.GetRequiredService <LspRequestRouter>()); services.AddSingleton <IResponseRouter, ResponseRouter>(); services.AddTransient(typeof(IPipelineBehavior <,>), typeof(ResolveCommandPipeline <,>)); services.AddSingleton <IProgressManager, ProgressManager>(); services.AddSingleton <IJsonRpcHandler>(_ => _.GetRequiredService <IProgressManager>() as IJsonRpcHandler); services.AddSingleton <IServerWorkDoneManager, ServerWorkDoneManager>(); services.AddSingleton <IJsonRpcHandler>(_ => _.GetRequiredService <IServerWorkDoneManager>() as IJsonRpcHandler); EnsureAllHandlersAreRegistered(); var serviceProvider = services.BuildServiceProvider(); _disposable.Add(serviceProvider); _serviceProvider = serviceProvider; collection.SetServiceProvider(_serviceProvider); var requestRouter = _serviceProvider.GetRequiredService <IRequestRouter <ILspHandlerDescriptor> >(); _responseRouter = _serviceProvider.GetRequiredService <IResponseRouter>(); ProgressManager = _serviceProvider.GetRequiredService <IProgressManager>(); _serverWorkDoneManager = _serviceProvider.GetRequiredService <IServerWorkDoneManager>(); _connection = new Connection( options.Input, _serviceProvider.GetRequiredService <IOutputHandler>(), options.Receiver, options.RequestProcessIdentifier, _serviceProvider.GetRequiredService <IRequestRouter <IHandlerDescriptor> >(), _responseRouter, _serviceProvider.GetRequiredService <ILoggerFactory>(), options.OnUnhandledException ?? (e => { ForcefulShutdown(); }), options.CreateResponseException, options.MaximumRequestTimeout, options.SupportsContentModified, options.Concurrency ); // We need to at least create Window here in case any handler does loggin in their constructor TextDocument = new TextDocumentLanguageServer(this, _serviceProvider); Client = new ClientLanguageServer(this, _serviceProvider); General = new GeneralLanguageServer(this, _serviceProvider); Window = new WindowLanguageServer(this, _serviceProvider); Workspace = new WorkspaceLanguageServer(this, _serviceProvider); _disposable.Add(_collection.Add(this)); { var serviceHandlers = _serviceProvider.GetServices <IJsonRpcHandler>().ToArray(); var serviceIdentifiers = _serviceProvider.GetServices <ITextDocumentIdentifier>().ToArray(); _disposable.Add(_textDocumentIdentifiers.Add(serviceIdentifiers)); _disposable.Add(_collection.Add(serviceHandlers)); options.AddLinks(_collection); } }
internal LanguageServer( Connection connection, IResponseRouter responseRouter, IOptions <LanguageServerOptions> options, ILanguageServerConfiguration configuration, ServerInfo serverInfo, ILspServerReceiver receiver, ISerializer serializer, IResolverContext resolverContext, ISupportedCapabilities supportedCapabilities, TextDocumentIdentifiers textDocumentIdentifiers, IEnumerable <OnLanguageServerInitializeDelegate> initializeDelegates, IEnumerable <OnLanguageServerInitializedDelegate> initializedDelegates, IEnumerable <OnLanguageServerStartedDelegate> startedDelegates, IEnumerable <IOnLanguageServerStarted> startedHandlers, IServerWorkDoneManager serverWorkDoneManager, ITextDocumentLanguageServer textDocumentLanguageServer, IClientLanguageServer clientLanguageServer, IGeneralLanguageServer generalLanguageServer, IWindowLanguageServer windowLanguageServer, IWorkspaceLanguageServer workspaceLanguageServer, LanguageProtocolSettingsBag languageProtocolSettingsBag, SharedHandlerCollection handlerCollection, IProgressManager progressManager, ILanguageServerWorkspaceFolderManager workspaceFolderManager, IEnumerable <IOnLanguageServerInitialize> initializeHandlers, IEnumerable <IOnLanguageServerInitialized> initializedHandlers, IEnumerable <IRegistrationOptionsConverter> registrationOptionsConverters, InstanceHasStarted instanceHasStarted ) : base(handlerCollection, responseRouter) { Configuration = configuration; _connection = connection; _serverInfo = serverInfo; _serverReceiver = receiver; _serializer = serializer; _supportedCapabilities = supportedCapabilities; _textDocumentIdentifiers = textDocumentIdentifiers; _initializeDelegates = initializeDelegates; _initializedDelegates = initializedDelegates; _startedDelegates = startedDelegates; _startedHandlers = startedHandlers; WorkDoneManager = serverWorkDoneManager; _settingsBag = languageProtocolSettingsBag; Services = _resolverContext = resolverContext; _collection = handlerCollection; // We need to at least create Window here in case any handler does logging in their constructor TextDocument = textDocumentLanguageServer; Client = clientLanguageServer; General = generalLanguageServer; Window = windowLanguageServer; Workspace = workspaceLanguageServer; ProgressManager = progressManager; WorkspaceFolderManager = workspaceFolderManager; _initializeHandlers = initializeHandlers; _initializedHandlers = initializedHandlers; _registrationOptionsConverters = registrationOptionsConverters; _instanceHasStarted = instanceHasStarted; _concurrency = options.Value.Concurrency; _capabilityTypes = options .Value.Assemblies .SelectMany(z => z.ExportedTypes) .Where(z => z.IsClass && !z.IsAbstract) .Where(z => typeof(ICapability).IsAssignableFrom(z)) .Where(z => z.GetCustomAttributes <CapabilityKeyAttribute>().Any()) .ToLookup(z => string.Join(".", z.GetCustomAttribute <CapabilityKeyAttribute>().Keys)); _disposable.Add(_collection.Add(this)); }
public async Task ShouldRouteToCorrect_Request_WithManyHandlers() { var textDocumentSyncHandler = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cs"), "csharp"); var textDocumentSyncHandler2 = TextDocumentSyncHandlerExtensions.With(DocumentSelector.ForPattern("**/*.cake"), "csharp"); textDocumentSyncHandler.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>()) .Returns(Unit.Value); textDocumentSyncHandler2.Handle(Arg.Any <DidSaveTextDocumentParams>(), Arg.Any <CancellationToken>()) .Returns(Unit.Value); var codeActionHandler = Substitute.For <ICodeActionHandler>(); codeActionHandler.GetRegistrationOptions().Returns(new CodeActionRegistrationOptions { DocumentSelector = DocumentSelector.ForPattern("**/*.cs") }); codeActionHandler .Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>()) .Returns(new CommandOrCodeActionContainer()); var registry = new TestLanguageServerRegistry(); var codeActionDelegate = Substitute.For <Func <CodeActionParams, CancellationToken, Task <CommandOrCodeActionContainer> > >(); codeActionDelegate.Invoke(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>()) .Returns(new CommandOrCodeActionContainer()); registry.OnCodeAction( codeActionDelegate, new CodeActionRegistrationOptions { DocumentSelector = DocumentSelector.ForPattern("**/*.cake") } ); var textDocumentIdentifiers = new TextDocumentIdentifiers(); AutoSubstitute.Provide(textDocumentIdentifiers); var handlerCollection = new SharedHandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue, textDocumentIdentifiers, new ServiceCollection().BuildServiceProvider()) { textDocumentSyncHandler, textDocumentSyncHandler2, codeActionHandler }; handlerCollection.Add(registry.Handlers); AutoSubstitute.Provide <IHandlerCollection>(handlerCollection); AutoSubstitute.Provide <IEnumerable <ILspHandlerDescriptor> >(handlerCollection); AutoSubstitute.Provide <IHandlerMatcher>(new TextDocumentMatcher(LoggerFactory.CreateLogger <TextDocumentMatcher>(), textDocumentIdentifiers)); var mediator = AutoSubstitute.Resolve <LspRequestRouter>(); var id = Guid.NewGuid().ToString(); var @params = new CodeActionParams { TextDocument = new TextDocumentIdentifier(new Uri("file:///c:/test/123.cake")) }; var request = new Request( id, TextDocumentNames.CodeAction, JObject.Parse(JsonConvert.SerializeObject(@params, new Serializer(ClientVersion.Lsp3).Settings)) ); await mediator.RouteRequest(mediator.GetDescriptors(request), request, CancellationToken.None); await codeActionHandler.Received(0).Handle(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>()); await codeActionDelegate.Received(1).Invoke(Arg.Any <CodeActionParams>(), Arg.Any <CancellationToken>()); }
internal LanguageClient( Connection connection, IOptions <LanguageClientOptions> options, IEnumerable <ICapability> capabilities, ClientInfo clientInfo, ClientCapabilities clientCapabilities, ILspClientReceiver lspClientReceiver, TextDocumentIdentifiers textDocumentIdentifiers, IResolverContext resolverContext, IEnumerable <OnLanguageClientStartedDelegate> startedDelegates, IEnumerable <IOnLanguageClientStarted> startedHandlers, ITextDocumentLanguageClient textDocumentLanguageClient, IClientLanguageClient clientLanguageClient, IGeneralLanguageClient generalLanguageClient, IWindowLanguageClient windowLanguageClient, IWorkspaceLanguageClient workspaceLanguageClient, LanguageProtocolSettingsBag languageProtocolSettingsBag, SharedHandlerCollection handlerCollection, IResponseRouter responseRouter, IProgressManager progressManager, IClientWorkDoneManager clientWorkDoneManager, IRegistrationManager registrationManager, ILanguageClientWorkspaceFoldersManager languageClientWorkspaceFoldersManager, IEnumerable <OnLanguageClientInitializeDelegate> initializeDelegates, IEnumerable <IOnLanguageClientInitialize> initializeHandlers, IEnumerable <OnLanguageClientInitializedDelegate> initializedDelegates, IEnumerable <IOnLanguageClientInitialized> initializedHandlers, ISerializer serializer, InstanceHasStarted instanceHasStarted ) : base(handlerCollection, responseRouter) { _connection = connection; _capabilities = capabilities; _clientCapabilities = clientCapabilities; _clientInfo = clientInfo; _receiver = lspClientReceiver; _textDocumentIdentifiers = textDocumentIdentifiers; _startedDelegates = startedDelegates; _startedHandlers = startedHandlers; _rootUri = options.Value.RootUri; _trace = options.Value.Trace; _initializationOptions = options.Value.InitializationOptions; _settingsBag = languageProtocolSettingsBag; _collection = handlerCollection; Services = _resolverContext = resolverContext; _responseRouter = responseRouter; ProgressManager = progressManager; WorkDoneManager = clientWorkDoneManager; RegistrationManager = registrationManager; WorkspaceFoldersManager = languageClientWorkspaceFoldersManager; _initializeDelegates = initializeDelegates; _initializeHandlers = initializeHandlers; _initializedDelegates = initializedDelegates; _initializedHandlers = initializedHandlers; _serializer = serializer; _instanceHasStarted = instanceHasStarted; _concurrency = options.Value.Concurrency; // We need to at least create Window here in case any handler does loggin in their constructor TextDocument = textDocumentLanguageClient; Client = clientLanguageClient; General = generalLanguageClient; Window = windowLanguageClient; Workspace = workspaceLanguageClient; }