commit
2e79d10803
@ -9,10 +9,10 @@ class ReadPipe(threading.Thread):
|
||||
self.pipe = pipe
|
||||
|
||||
def run(self):
|
||||
line = self.pipe.readline()
|
||||
line = self.pipe.readline().decode('utf-8')
|
||||
while line:
|
||||
print(line)
|
||||
line = self.pipe.readline()
|
||||
line = self.pipe.readline().decode('utf-8')
|
||||
|
||||
if __name__ == "__main__":
|
||||
clangd_path = "/usr/bin/clangd-6.0"
|
||||
|
@ -62,7 +62,7 @@ class JsonRpcEndpoint(object):
|
||||
line = self.stdout.readline()
|
||||
if not line:
|
||||
return None
|
||||
line = line.decode()
|
||||
line = line.decode("utf-8")
|
||||
# TODO: handle content type as well.
|
||||
match = re.match(JSON_RPC_RES_REGEX, line)
|
||||
if match is None or not match.groups():
|
||||
@ -71,8 +71,8 @@ class JsonRpcEndpoint(object):
|
||||
line = self.stdout.readline()
|
||||
if not line:
|
||||
return None
|
||||
line = line.decode()
|
||||
line = line.decode("utf-8")
|
||||
if line != "\r\n":
|
||||
raise RuntimeError("Bad header: missing newline")
|
||||
jsonrpc_res = self.stdout.read(size)
|
||||
jsonrpc_res = self.stdout.read(size).decode("utf-8")
|
||||
return json.loads(jsonrpc_res)
|
||||
|
@ -1,21 +1,24 @@
|
||||
from __future__ import print_function
|
||||
import threading
|
||||
import collections
|
||||
from pylspclient import lsp_structs
|
||||
|
||||
|
||||
class LspEndpoint(threading.Thread):
|
||||
def __init__(self, json_rpc_endpoint, default_callback=print, callbacks={}):
|
||||
def __init__(self, json_rpc_endpoint, method_callbacks={}, notify_callbacks={}):
|
||||
threading.Thread.__init__(self)
|
||||
self.json_rpc_endpoint = json_rpc_endpoint
|
||||
self.callbacks = callbacks
|
||||
self.default_callback = default_callback
|
||||
self.notify_callbacks = notify_callbacks
|
||||
self.method_callbacks = method_callbacks
|
||||
self.event_dict = {}
|
||||
self.response_dict = {}
|
||||
self.next_id = 0
|
||||
self.shutdown_flag = False
|
||||
|
||||
|
||||
def handle_result(self, jsonrpc_res):
|
||||
self.response_dict[jsonrpc_res["id"]] = jsonrpc_res
|
||||
cond = self.event_dict[jsonrpc_res["id"]]
|
||||
def handle_result(self, rpc_id, result, error):
|
||||
self.response_dict[rpc_id] = (result, error)
|
||||
cond = self.event_dict[rpc_id]
|
||||
cond.acquire()
|
||||
cond.notify()
|
||||
cond.release()
|
||||
@ -27,21 +30,46 @@ class LspEndpoint(threading.Thread):
|
||||
|
||||
def run(self):
|
||||
while not self.shutdown_flag:
|
||||
try:
|
||||
jsonrpc_message = self.json_rpc_endpoint.recv_response()
|
||||
method = jsonrpc_message.get("method")
|
||||
result = jsonrpc_message.get("result")
|
||||
error = jsonrpc_message.get("error")
|
||||
rpc_id = jsonrpc_message.get("id")
|
||||
params = jsonrpc_message.get("params")
|
||||
|
||||
if jsonrpc_message is None:
|
||||
print("server quit")
|
||||
break
|
||||
|
||||
if "result" in jsonrpc_message or "error" in jsonrpc_message:
|
||||
self.handle_result(jsonrpc_message)
|
||||
elif "method" in jsonrpc_message:
|
||||
if jsonrpc_message["method"] in self.callbacks:
|
||||
self.callbacks[jsonrpc_message["method"]](jsonrpc_message)
|
||||
if method:
|
||||
if rpc_id:
|
||||
# a call for method
|
||||
if method not in self.method_callbacks:
|
||||
raise lsp_structs.ResponseError("Method not found: {method}".format(method=method), lsp_structs.ErrorCodes.MethodNotFound)
|
||||
result = self.method_callbacks[method](params)
|
||||
self.send_response(rpc_id, result, None)
|
||||
else:
|
||||
self.default_callback(jsonrpc_message)
|
||||
# a call for notify
|
||||
if method not in self.notify_callbacks:
|
||||
raise lsp_structs.ResponseError("Method not found: {method}".format(method=method), lsp_structs.ErrorCodes.MethodNotFound)
|
||||
|
||||
self.notify_callbacks[method](params)
|
||||
else:
|
||||
print("unknown jsonrpc message")
|
||||
self.handle_result(rpc_id, result, error)
|
||||
except lsp_structs.ResponseError as e:
|
||||
self.send_response(rpc_id, None, e)
|
||||
|
||||
|
||||
def send_response(self, id, result, error):
|
||||
message_dict = {}
|
||||
message_dict["jsonrpc"] = "2.0"
|
||||
message_dict["id"] = id
|
||||
if result:
|
||||
message_dict["result"] = result
|
||||
if error:
|
||||
message_dict["error"] = error
|
||||
self.json_rpc_endpoint.send_request(message_dict)
|
||||
|
||||
|
||||
def send_message(self, method_name, params, id = None):
|
||||
@ -63,9 +91,10 @@ class LspEndpoint(threading.Thread):
|
||||
self.send_message(method_name, kwargs, current_id)
|
||||
cond.wait()
|
||||
cond.release()
|
||||
# TODO: check if error, and throw an exception
|
||||
response = self.response_dict[current_id]
|
||||
return response["result"]
|
||||
result, error = self.response_dict[current_id]
|
||||
if error:
|
||||
raise lsp_structs.ResponseError(error.get("code"), error.get("message"), error.get("data"))
|
||||
return result
|
||||
|
||||
|
||||
def send_notification(self, method_name, **kwargs):
|
||||
|
@ -425,3 +425,26 @@ class CompletionList(object):
|
||||
"""
|
||||
self.isIncomplete = isIncomplete
|
||||
self.items = [to_type(i, CompletionItem) for i in items]
|
||||
|
||||
class ErrorCodes(object):
|
||||
# Defined by JSON RPC
|
||||
ParseError = -32700
|
||||
InvalidRequest = -32600
|
||||
MethodNotFound = -32601
|
||||
InvalidParams = -32602
|
||||
InternalError = -32603
|
||||
serverErrorStart = -32099
|
||||
serverErrorEnd = -32000
|
||||
ServerNotInitialized = -32002
|
||||
UnknownErrorCode = -32001
|
||||
|
||||
# Defined by the protocol.
|
||||
RequestCancelled = -32800
|
||||
ContentModified = -32801
|
||||
|
||||
class ResponseError(Exception):
|
||||
def __init__(self, code, message, data = None):
|
||||
self.code = code
|
||||
self.message = message
|
||||
if data:
|
||||
self.data = data
|
Loading…
Reference in New Issue
Block a user