internal LanguageServerTarget( AbstractRequestDispatcherFactory requestDispatcherFactory, JsonRpc jsonRpc, ICapabilitiesProvider capabilitiesProvider, ILspWorkspaceRegistrationService workspaceRegistrationService, IGlobalOptionService globalOptions, IAsynchronousOperationListenerProvider listenerProvider, ILspLogger logger, ImmutableArray <string> supportedLanguages, string?clientName, string userVisibleServerName, string telemetryServerTypeName) { GlobalOptions = globalOptions; RequestDispatcher = requestDispatcherFactory.CreateRequestDispatcher(supportedLanguages); _capabilitiesProvider = capabilitiesProvider; WorkspaceRegistrationService = workspaceRegistrationService; Logger = logger; JsonRpc = jsonRpc; JsonRpc.AddLocalRpcTarget(this); JsonRpc.Disconnected += JsonRpc_Disconnected; Listener = listenerProvider.GetListener(FeatureAttribute.LanguageServer); ClientName = clientName; _userVisibleServerName = userVisibleServerName; TelemetryServerName = telemetryServerTypeName; Queue = new RequestExecutionQueue(logger, workspaceRegistrationService, globalOptions, supportedLanguages, userVisibleServerName, TelemetryServerName); Queue.RequestServerShutdown += RequestExecutionQueue_Errored; }
internal LanguageServerTarget( AbstractRequestDispatcherFactory requestDispatcherFactory, JsonRpc jsonRpc, ICapabilitiesProvider capabilitiesProvider, LspWorkspaceRegistrationService workspaceRegistrationService, LspMiscellaneousFilesWorkspace?lspMiscellaneousFilesWorkspace, IGlobalOptionService globalOptions, IAsynchronousOperationListenerProvider listenerProvider, ILspLogger logger, ImmutableArray <string> supportedLanguages, string?clientName, WellKnownLspServerKinds serverKind) { _requestDispatcher = requestDispatcherFactory.CreateRequestDispatcher(serverKind); _capabilitiesProvider = capabilitiesProvider; _logger = logger; _jsonRpc = jsonRpc; _jsonRpc.AddLocalRpcTarget(this); _jsonRpc.Disconnected += JsonRpc_Disconnected; _listener = listenerProvider.GetListener(FeatureAttribute.LanguageServer); _clientName = clientName; _queue = new RequestExecutionQueue( logger, workspaceRegistrationService, lspMiscellaneousFilesWorkspace, globalOptions, supportedLanguages, serverKind); _queue.RequestServerShutdown += RequestExecutionQueue_Errored; var entryPointMethod = typeof(DelegatingEntryPoint).GetMethod(nameof(DelegatingEntryPoint.EntryPointAsync)); Contract.ThrowIfNull(entryPointMethod, $"{typeof(DelegatingEntryPoint).FullName} is missing method {nameof(DelegatingEntryPoint.EntryPointAsync)}"); foreach (var metadata in _requestDispatcher.GetRegisteredMethods()) { // Instead of concretely defining methods for each LSP method, we instead dynamically construct // the generic method info from the exported handler types. This allows us to define multiple handlers for the same method // but different type parameters. This is a key functionality to support TS external access as we do not want to couple // our LSP protocol version dll to theirs. // // We also do not use the StreamJsonRpc support for JToken as the rpc method parameters because we want // StreamJsonRpc to do the deserialization to handle streaming requests using IProgress<T>. var delegatingEntryPoint = new DelegatingEntryPoint(metadata.MethodName, this); var genericEntryPointMethod = entryPointMethod.MakeGenericMethod(metadata.RequestType, metadata.ResponseType); _jsonRpc.AddLocalRpcMethod(genericEntryPointMethod, delegatingEntryPoint, new JsonRpcMethodAttribute(metadata.MethodName) { UseSingleObjectParameterDeserialization = true }); } }