private async Task<PsesDebugServer> CreateDebugServerWithLanguageServerAsync(PsesLanguageServer languageServer, bool usePSReadLine) { _logger.Log(PsesLogLevel.Verbose, $"Creating debug adapter transport with endpoint {_config.DebugServiceTransport.EndpointDetails}"); (Stream inStream, Stream outStream) = await _config.DebugServiceTransport.ConnectStreamsAsync().ConfigureAwait(false); _logger.Log(PsesLogLevel.Diagnostic, "Creating debug adapter"); return _serverFactory.CreateDebugServerWithLanguageServer(inStream, outStream, languageServer, usePSReadLine); }
/// <summary> /// Starts the language service with the specified config. /// </summary> /// <param name="config">The config that contains information on the communication protocol that will be used.</param> /// <param name="profilePaths">The profiles that will be loaded in the session.</param> public void StartLanguageService( EditorServiceTransportConfig config, ProfilePaths profilePaths) { _logger.LogInformation($"LSP NamedPipe: {config.InOutPipeName}\nLSP OutPipe: {config.OutPipeName}"); switch (config.TransportType) { case EditorServiceTransportType.NamedPipe: _languageServer = new NamedPipePsesLanguageServer( _factory, LogLevel.Trace, _enableConsoleRepl, _useLegacyReadLine, _featureFlags, _hostDetails, _additionalModules, _internalHost, profilePaths, config.InOutPipeName ?? config.InPipeName, config.OutPipeName); break; case EditorServiceTransportType.Stdio: _languageServer = new StdioPsesLanguageServer( _factory, LogLevel.Trace, _featureFlags, _hostDetails, _additionalModules, _internalHost, profilePaths); break; } _logger.LogInformation("Starting language server"); Task.Run(_languageServer.StartAsync); _logger.LogInformation( string.Format( "Language service started, type = {0}, endpoint = {1}", config.TransportType, config.Endpoint)); }
/// <summary> /// Master method for instantiating, running and waiting for the LSP and debug servers at the heart of Editor Services. /// </summary> /// <returns>A task that ends when Editor Services shuts down.</returns> private async Task CreateEditorServicesAndRunUntilShutdown() { try { bool creatingLanguageServer = _config.LanguageServiceTransport != null; bool creatingDebugServer = _config.DebugServiceTransport != null; bool isTempDebugSession = creatingDebugServer && !creatingLanguageServer; // Set up information required to instantiate servers HostStartupInfo hostStartupInfo = CreateHostStartupInfo(); // If we just want a temp debug session, run that and do nothing else if (isTempDebugSession) { await RunTempDebugSessionAsync(hostStartupInfo).ConfigureAwait(false); return; } // We want LSP and maybe debugging // To do that we: // - Create the LSP server // - Possibly kick off the debug server creation // - Start the LSP server // - Possibly start the debug server // - Wait for the LSP server to finish // Unsubscribe the host logger here so that the integrated console is not polluted with input after the first prompt _logger.Log(PsesLogLevel.Verbose, "Starting server, deregistering host logger and registering shutdown listener"); if (_loggersToUnsubscribe != null) { foreach (IDisposable loggerToUnsubscribe in _loggersToUnsubscribe) { loggerToUnsubscribe.Dispose(); } } WriteStartupBanner(); PsesLanguageServer languageServer = await CreateLanguageServerAsync(hostStartupInfo).ConfigureAwait(false); Task <PsesDebugServer> debugServerCreation = null; if (creatingDebugServer) { debugServerCreation = CreateDebugServerWithLanguageServerAsync(languageServer, usePSReadLine: _config.ConsoleRepl == ConsoleReplKind.PSReadLine); } languageServer.StartAsync(); if (creatingDebugServer) { StartDebugServer(debugServerCreation); } await languageServer.WaitForShutdown().ConfigureAwait(false); } finally { // Resubscribe host logger to log shutdown events to the console _logger.Subscribe(new PSHostLogger(_config.PSHost.UI)); } }