示例#1
0
        /// <summary>
        /// Infrastructure. Asynchronously sends the request and wait for the response.
        /// </summary>
        /// <typeparam name="TResult">Response type.</typeparam>
        /// <param name="methodIndex">The JSON RPC method index in <see cref="MethodTable"/>.</param>
        /// <param name="paramValues">Parameters, in the order of expected parameter order.</param>
        /// <exception cref="JsonRpcRemoteException">An error has occurred on the remote-side.</exception>
        /// <exception cref="JsonRpcContractException">An error has occurred when generating the request or parsing the response.</exception>
        /// <exception cref="OperationCanceledException">The operation has been cancelled.</exception>
        /// <returns>The response.</returns>
        public async Task <TResult> SendAsync <TResult>(int methodIndex, IList paramValues)
        {
            var method = MethodTable[methodIndex];
            MarshaledRequestParameters marshaled;

            try
            {
                marshaled = Marshaler.MarshalParameters(method.Parameters, paramValues);
            }
            catch (Exception ex)
            {
                throw new JsonRpcContractException("An exception occurred while marshalling the request. " + ex.Message,
                                                   ex);
            }
            marshaled.CancellationToken.ThrowIfCancellationRequested();
            var request = new RequestMessage(method.MethodName, marshaled.Parameters);

            // Send the request
            if (!method.IsNotification)
            {
                request.Id = Client.NextRequestId();
            }
            var response = await Client.SendAsync(request, marshaled.CancellationToken).ConfigureAwait(false);

            // For notification, we do not have a response.
            if (response != null)
            {
                if (response.Error != null)
                {
                    throw new JsonRpcRemoteException(response.Error);
                }
                if (method.ReturnParameter.ParameterType != typeof(void))
                {
                    // VSCode will return void for null in `window/showMessageRequest`.
                    // I mean, https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#window_showMessageRequest
                    // So just don't be picky…
                    //if (response.Result == null)
                    //    throw new JsonRpcContractException(
                    //        $"Expect \"{method.ReturnParameter.ParameterType}\" result, got void.",
                    //        message);
                    try
                    {
                        return((TResult)method.ReturnParameter.Converter.JsonToValue(response.Result, typeof(TResult)));
                    }
                    catch (Exception ex)
                    {
                        throw new JsonRpcContractException(
                                  "An exception occurred while unmarshalling the response. " + ex.Message,
                                  request, ex);
                    }
                }
            }
            return(default(TResult));
        }