Beispiel #1
0
        private void CreateCompositionHost(InitializeParams initializeParams)
        {
            _environment = new OmniSharpEnvironment(
                Helpers.FromUri(initializeParams.RootUri),
                Convert.ToInt32(initializeParams.ProcessId ?? -1L),
                GetLogLevel(initializeParams.Trace),
                _application.OtherArgs.ToArray());

            // TODO: Make this work with logger factory differently
            // Maybe create a child logger factory?
            _loggerFactory.AddProvider(_server, _environment);
            _logger = _loggerFactory.CreateLogger <LanguageServerHost>();

            var configurationRoot = new ConfigurationBuilder(_environment).Build();
            var eventEmitter      = new LanguageServerEventEmitter(_server);

            _serviceProvider = CompositionHostBuilder.CreateDefaultServiceProvider(_environment, configurationRoot, eventEmitter, _services);

            var plugins = _application.CreatePluginAssemblies();

            var assemblyLoader         = _serviceProvider.GetRequiredService <IAssemblyLoader>();
            var compositionHostBuilder = new CompositionHostBuilder(_serviceProvider)
                                         .WithOmniSharpAssemblies()
                                         .WithAssemblies(typeof(LanguageServerHost).Assembly)
                                         .WithAssemblies(assemblyLoader.LoadByAssemblyNameOrPath(plugins.AssemblyNames).ToArray());

            _compositionHost = compositionHostBuilder.Build();

            var projectSystems = _compositionHost.GetExports <IProjectSystem>();

            var documentSelectors = projectSystems
                                    .GroupBy(x => x.Language)
                                    .Select(x => (
                                                language: x.Key,
                                                selector: new DocumentSelector(x
                                                                               .SelectMany(z => z.Extensions)
                                                                               .Distinct()
                                                                               .Select(z => new DocumentFilter()
            {
                Pattern = $"**/*{z}"
            }))
                                                ));

            _logger.LogTrace(
                "Configured Document Selectors {@DocumentSelectors}",
                documentSelectors.Select(x => new { x.language, x.selector })
                );

            // TODO: Get these with metadata so we can attach languages
            // This will thne let us build up a better document filter, and add handles foreach type of handler
            // This will mean that we will have a strategy to create handlers from the interface type
            _handlers = new RequestHandlers(
                _compositionHost.GetExports <Lazy <IRequestHandler, OmniSharpRequestHandlerMetadata> >(),
                documentSelectors
                );

            _logger.LogTrace("--- Handler Definitions ---");
            foreach (var handlerCollection in _handlers)
            {
                foreach (var handler in handlerCollection)
                {
                    _logger.LogTrace(
                        "Handler: {Language}:{DocumentSelector}:{Handler}",
                        handlerCollection.Language,
                        handlerCollection.DocumentSelector.ToString(),
                        handler.GetType().FullName
                        );
                }
            }
            _logger.LogTrace("--- Handler Definitions ---");
        }
        internal static RequestHandlers ConfigureCompositionHost(ILanguageServer server,
                                                                 CompositionHost compositionHost)
        {
            var projectSystems = compositionHost.GetExports <IProjectSystem>();

            var documentSelectors = projectSystems
                                    .GroupBy(x => x.Language)
                                    .Select(x => (
                                                language: x.Key,
                                                selector: new DocumentSelector(x
                                                                               .SelectMany(z => z.Extensions)
                                                                               .Distinct()
                                                                               .SelectMany(z =>
            {
                if (x.Key == LanguageNames.CSharp && z == ".cs")
                {
                    return(new[]
                    {
                        new DocumentFilter()
                        {
                            Pattern = $"**/*{z}"
                        },
                        new DocumentFilter()
                        {
                            Scheme = "csharp"
                        }
                    });
                }

                return(new[]
                {
                    new DocumentFilter()
                    {
                        Pattern = $"**/*{z}"
                    },
                });
            })
                                                                               )
                                                ))
                                    .ToArray();

            var logger = compositionHost.GetExport <ILoggerFactory>().CreateLogger <LanguageServerHost>();

            logger.LogTrace(
                "Configured Document Selectors {@DocumentSelectors}",
                documentSelectors.Select(x => new { x.language, x.selector })
                );

            var omnisharpRequestHandlers =
                compositionHost.GetExports <Lazy <IRequestHandler, OmniSharpRequestHandlerMetadata> >();
            // TODO: Get these with metadata so we can attach languages
            // This will then let us build up a better document filter, and add handles foreach type of handler
            // This will mean that we will have a strategy to create handlers from the interface type
            var handlers = new RequestHandlers(omnisharpRequestHandlers, documentSelectors);

            logger.LogTrace("--- Handler Definitions ---");
            foreach (var handlerCollection in handlers)
            {
                foreach (var handler in handlerCollection)
                {
                    logger.LogTrace(
                        "Handler: {Language}:{DocumentSelector}:{Handler}",
                        handlerCollection.Language,
                        handlerCollection.DocumentSelector.ToString(),
                        handler.GetType().FullName
                        );
                }
            }

            // the goal here is add interoperability between omnisharp and LSP
            // This way an existing client (say vscode) that is using the custom omnisharp protocol can migrate to the new one
            // and not loose any functionality.
            server.Register(r =>
            {
                var defaultOptions = new JsonRpcHandlerOptions()
                {
                    RequestProcessType = RequestProcessType.Parallel
                };
                var interop = InitializeInterop(compositionHost);
                foreach (var osHandler in interop)
                {
                    var method = $"o#/{osHandler.Key.Trim('/').ToLowerInvariant()}";
                    r.OnJsonRequest(method, CreateInteropHandler(osHandler.Value), defaultOptions);
                    logger.LogTrace("O# Handler: {Method}", method);
                }