示例#1
0
        /// <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));
        }
示例#2
0
        /// <summary>
        /// Starts the debug 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>
        /// <param name="useTempSession">Determines if we will make a new session typically used for temporary console debugging.</param>
        public void StartDebugService(
            EditorServiceTransportConfig config,
            ProfilePaths profilePaths,
            bool useTempSession)
        {
            _logger.LogInformation($"Debug NamedPipe: {config.InOutPipeName}\nDebug OutPipe: {config.OutPipeName}");

            IServiceProvider serviceProvider = null;

            if (useTempSession)
            {
                serviceProvider = new ServiceCollection()
                                  .AddLogging(builder => builder
                                              .ClearProviders()
                                              .AddSerilog()
                                              .SetMinimumLevel(LogLevel.Trace))
                                  .AddSingleton <ILanguageServer>(provider => null)
                                  .AddPsesLanguageServices(
                    profilePaths,
                    _featureFlags,
                    _enableConsoleRepl,
                    _useLegacyReadLine,
                    _internalHost,
                    _hostDetails,
                    _additionalModules)
                                  .BuildServiceProvider();
            }

            switch (config.TransportType)
            {
            case EditorServiceTransportType.NamedPipe:
                NamedPipeServerStream inNamedPipe = CreateNamedPipe(
                    config.InOutPipeName ?? config.InPipeName,
                    config.OutPipeName,
                    out NamedPipeServerStream outNamedPipe);

                _debugServer = new PsesDebugServer(
                    _factory,
                    inNamedPipe,
                    outNamedPipe ?? inNamedPipe);

                Task[] tasks = outNamedPipe != null
                        ? new[] { inNamedPipe.WaitForConnectionAsync(), outNamedPipe.WaitForConnectionAsync() }
                        : new[] { inNamedPipe.WaitForConnectionAsync() };
                Task.WhenAll(tasks)
                .ContinueWith(async task =>
                {
                    _logger.LogInformation("Starting debug server");
                    await _debugServer.StartAsync(serviceProvider ?? _languageServer.LanguageServer.Services, useTempSession);
                    _logger.LogInformation(
                        $"Debug service started, type = {config.TransportType}, endpoint = {config.Endpoint}");
                });

                break;

            case EditorServiceTransportType.Stdio:
                _debugServer = new PsesDebugServer(
                    _factory,
                    Console.OpenStandardInput(),
                    Console.OpenStandardOutput());

                _logger.LogInformation("Starting debug server");
                Task.Run(async() =>
                {
                    await _debugServer.StartAsync(serviceProvider ?? _languageServer.LanguageServer.Services, useTempSession);
                    _logger.LogInformation(
                        $"Debug service started, type = {config.TransportType}, endpoint = {config.Endpoint}");
                });
                break;

            default:
                throw new NotSupportedException($"The transport {config.TransportType} is not supported");
            }

            // If the instance of PSES is being used for debugging only, then we don't want to allow automatic restarting
            // because the user can simply spin up a new PSES if they need to.
            // This design decision was done since this "debug-only PSES" is used in the "Temporary Integrated Console debugging"
            // feature which does not want PSES to be restarted so that the user can see the output of the last debug
            // session.
            if (!alreadySubscribedDebug && !useTempSession)
            {
                alreadySubscribedDebug     = true;
                _debugServer.SessionEnded += (sender, eventArgs) =>
                {
                    _debugServer.Dispose();
                    alreadySubscribedDebug = false;
                    StartDebugService(config, profilePaths, useTempSession);
                };
            }
        }