Merge pull request #2 from yeger00/send-result-wip

Send result
This commit is contained in:
yeger00 2019-01-12 14:17:20 +02:00 committed by GitHub
commit 2e79d10803
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 30 deletions

View File

@ -9,10 +9,10 @@ class ReadPipe(threading.Thread):
self.pipe = pipe self.pipe = pipe
def run(self): def run(self):
line = self.pipe.readline() line = self.pipe.readline().decode('utf-8')
while line: while line:
print(line) print(line)
line = self.pipe.readline() line = self.pipe.readline().decode('utf-8')
if __name__ == "__main__": if __name__ == "__main__":
clangd_path = "/usr/bin/clangd-6.0" clangd_path = "/usr/bin/clangd-6.0"

View File

@ -54,7 +54,7 @@ class JsonRpcEndpoint(object):
def recv_response(self): def recv_response(self):
''' '''
Recives a message. Recives a message.
:return: a message :return: a message
''' '''
@ -62,7 +62,7 @@ class JsonRpcEndpoint(object):
line = self.stdout.readline() line = self.stdout.readline()
if not line: if not line:
return None return None
line = line.decode() line = line.decode("utf-8")
# TODO: handle content type as well. # TODO: handle content type as well.
match = re.match(JSON_RPC_RES_REGEX, line) match = re.match(JSON_RPC_RES_REGEX, line)
if match is None or not match.groups(): if match is None or not match.groups():
@ -71,8 +71,8 @@ class JsonRpcEndpoint(object):
line = self.stdout.readline() line = self.stdout.readline()
if not line: if not line:
return None return None
line = line.decode() line = line.decode("utf-8")
if line != "\r\n": if line != "\r\n":
raise RuntimeError("Bad header: missing newline") 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) return json.loads(jsonrpc_res)

View File

@ -1,21 +1,24 @@
from __future__ import print_function from __future__ import print_function
import threading import threading
import collections
from pylspclient import lsp_structs
class LspEndpoint(threading.Thread): 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) threading.Thread.__init__(self)
self.json_rpc_endpoint = json_rpc_endpoint self.json_rpc_endpoint = json_rpc_endpoint
self.callbacks = callbacks self.notify_callbacks = notify_callbacks
self.default_callback = default_callback self.method_callbacks = method_callbacks
self.event_dict = {} self.event_dict = {}
self.response_dict = {} self.response_dict = {}
self.next_id = 0 self.next_id = 0
self.shutdown_flag = False self.shutdown_flag = False
def handle_result(self, jsonrpc_res): def handle_result(self, rpc_id, result, error):
self.response_dict[jsonrpc_res["id"]] = jsonrpc_res self.response_dict[rpc_id] = (result, error)
cond = self.event_dict[jsonrpc_res["id"]] cond = self.event_dict[rpc_id]
cond.acquire() cond.acquire()
cond.notify() cond.notify()
cond.release() cond.release()
@ -27,21 +30,46 @@ class LspEndpoint(threading.Thread):
def run(self): def run(self):
while not self.shutdown_flag: while not self.shutdown_flag:
jsonrpc_message = self.json_rpc_endpoint.recv_response() 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: if jsonrpc_message is None:
print("server quit") print("server quit")
break break
if "result" in jsonrpc_message or "error" in jsonrpc_message: if method:
self.handle_result(jsonrpc_message) if rpc_id:
elif "method" in jsonrpc_message: # a call for method
if jsonrpc_message["method"] in self.callbacks: if method not in self.method_callbacks:
self.callbacks[jsonrpc_message["method"]](jsonrpc_message) 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:
# 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: else:
self.default_callback(jsonrpc_message) self.handle_result(rpc_id, result, error)
else: except lsp_structs.ResponseError as e:
print("unknown jsonrpc message") 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): 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) self.send_message(method_name, kwargs, current_id)
cond.wait() cond.wait()
cond.release() cond.release()
# TODO: check if error, and throw an exception result, error = self.response_dict[current_id]
response = self.response_dict[current_id] if error:
return response["result"] raise lsp_structs.ResponseError(error.get("code"), error.get("message"), error.get("data"))
return result
def send_notification(self, method_name, **kwargs): def send_notification(self, method_name, **kwargs):

View File

@ -425,3 +425,26 @@ class CompletionList(object):
""" """
self.isIncomplete = isIncomplete self.isIncomplete = isIncomplete
self.items = [to_type(i, CompletionItem) for i in items] 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