Skip to content

[6.1] Read stdout from sourcekit-lsp in binary mode instead of text mode #153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 11, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions test-sourcekit-lsp/test-sourcekit-lsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ def __init__(self, server_path: str):
self.process = subprocess.Popen(
[server_path],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
encoding="utf-8",
stdout=subprocess.PIPE
)

def send_data(self, dict: Dict[str, object]):
Expand All @@ -40,8 +39,8 @@ def send_data(self, dict: Dict[str, object]):
"""
assert self.process.stdin
body = json.dumps(dict)
data = "Content-Length: {}\r\n\r\n{}".format(len(body), body)
self.process.stdin.write(data)
data = f"Content-Length: {len(body)}\r\n\r\n{body}"
self.process.stdin.write(data.encode('utf-8'))
self.process.stdin.flush()

def read_message_from_lsp_server(self) -> str:
Expand All @@ -51,17 +50,16 @@ def read_message_from_lsp_server(self) -> str:
"""
assert self.process.stdout
# Read Content-Length: 123\r\n
# Note: Even though the Content-Length header ends with \r\n, `readline` returns it with a single \n.
header = self.process.stdout.readline()
match = re.match(r"Content-Length: ([0-9]+)\n$", header)
header = self.process.stdout.readline().decode('utf-8')
match = re.match(r"Content-Length: ([0-9]+)\r\n$", header)
assert match, f"Expected Content-Length header, got '{header}'"

# The Content-Length header is followed by an empty line
empty_line = self.process.stdout.readline()
assert empty_line == "\n", f"Expected empty line, got '{empty_line}'"
empty_line = self.process.stdout.readline().decode('utf-8')
assert empty_line == "\r\n", f"Expected empty line, got '{empty_line}'"

# Read the actual response
return self.process.stdout.read(int(match.group(1)))
return self.process.stdout.read(int(match.group(1))).decode('utf-8')

def read_request_reply_from_lsp_server(self, request_id: int) -> str:
"""
Expand All @@ -71,7 +69,7 @@ def read_request_reply_from_lsp_server(self, request_id: int) -> str:
message = self.read_message_from_lsp_server()
message_obj = json.loads(message)
if "result" not in message_obj:
# We received a message that wasn't the request reply.
# We received a message that wasn't the request reply.
# Log it, ignore it and wait for the next message.
print("Received message")
print(message)
Expand Down