Skip to content

Commit c90c3be

Browse files
authored
Merge pull request #489 from Jafaral/jrpc
ulsp: add a json rpc lib, including a jrpc test
2 parents 87d5de3 + 127790e commit c90c3be

8 files changed

+474
-149
lines changed

uni/ulsp/Makefile

+7-4
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,25 @@ UFLAGS=-s -u
66
prog=ulsp
77

88
SRC=launch-lsp.icn workspace.icn database.icn server.icn completion.icn signature.icn hover.icn \
9-
definition.icn logger.icn
10-
OBJ=launch-lsp.u workspace.u database.u server.u completion.u signature.u hover.u definition.u logger.u
9+
definition.icn jsonrpc.icn logger.icn
10+
OBJ=launch-lsp.u workspace.u database.u server.u completion.u signature.u hover.u definition.u \
11+
jsonrpc.u logger.u
1112

1213
export IPATH=$(UNI)/unidoc
1314

1415
.PHONY: all
1516

1617
all: $(prog)
17-
1818
$(prog): $(OBJ)
1919
$(UC) -o $(prog) $(OBJ)
2020
$(CP) $(prog)$(EXE) ../../bin
2121

22+
jsonrpc-test: jsonrpc-test.u jsonrpc.u
23+
$(UC) -o jsonrpc-test jsonrpc-test.u jsonrpc.u
24+
2225
launch-lsp.u:launch-lsp.icn workspace.u database.u server.u completion.u signature.u hover.u definition.u
2326

24-
server.u:server.icn database.u completion.u workspace.u signature.u hover.u definition.u logger.u
27+
server.u:server.icn database.u completion.u workspace.u signature.u hover.u definition.u jsonrpc.u logger.u
2528
hover.u:hover.icn signature.u
2629
definition.u: definition.icn hover.u
2730

uni/ulsp/completion.icn

+1-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@ class CompletionHandler(
5050
}
5151
}
5252

53-
results := tojson(results_table)
54-
return results
53+
return results_table
5554
end
5655

5756
method addBuiltInFunctionsCompletionItems(results_table)

uni/ulsp/definition.icn

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ class DefinitionHandler(
3333
signatureHandler.handleNewSignature(context)
3434

3535
possibleItems := signatureHandler.getCurrentSigItems()
36-
\possibleItems | return tojson(results_table)
37-
member(item := possibleItems[1], "source") | return tojson(results_table)
36+
\possibleItems | return results_table
37+
member(item := possibleItems[1], "source") | return results_table
3838

3939
if source := open(item["source"]) then {
4040
every line := !source do {
@@ -58,6 +58,6 @@ class DefinitionHandler(
5858
results_table["uri"] := item["source"]
5959
results_table["range"] := ["start":["line":i;"character":startPos];"end":["line":i;"character":endPos]]
6060

61-
return tojson(results_table)
61+
return results_table
6262
end
6363
end

uni/ulsp/hover.icn

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ class HoverHandler(
3131
signatureHandler := SignatureHandler()
3232
signatureHandler.setVariables(workspace)
3333

34-
hover_item := \getHoverItem(desired_line, character) | return tojson(results_table)
35-
_context := \getContext(context) | return tojson(results_table)
34+
hover_item := \getHoverItem(desired_line, character) | return results_table
35+
_context := \getContext(context) | return results_table
3636

3737
if _context == "function" | _context == "built-in-function" | _context == "method" |
3838
_context == "procedure" | _context == "constructor" then {
@@ -48,7 +48,7 @@ class HoverHandler(
4848
results_table["contents"] := table("kind", "markdown", "value", "(_" || _context || "_) " || hover_item )
4949
}
5050

51-
return tojson(results_table)
51+
return results_table
5252
end
5353

5454
method getContext(context)

uni/ulsp/jsonrpc-test.icn

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import ulsp
2+
3+
global work_items
4+
5+
#############################
6+
# JRPC server Calculator
7+
#############################
8+
class JRPC_Calc(jrpc_server)
9+
10+
method start(addr)
11+
local sock, msg
12+
if not (jrpc_server := JRPC_HTTPSocket(addr,"n")) then
13+
write("server open(",addr,") ERROR: ", \&errortext | "Unknown") & fail
14+
15+
repeat {
16+
msg := jrpc_server.get_msg() | next
17+
case msg.get_kind() of {
18+
"request" : thread handle_request(msg)
19+
default:
20+
write("jrpc:msg: " || msg.get_kind(), image(msg.get_content()))
21+
}
22+
}
23+
end
24+
25+
method handle_request(msg)
26+
local id := msg.get_id(),
27+
x := integer(msg.get_params()[1]),
28+
y := integer(msg.get_params()[2])
29+
30+
# uncomment to trigger some test failures
31+
#if x = 9 then fail
32+
case msg.get_method() of {
33+
"+" : {jrpc_server.send_msg(msg.make_result_response(x + y))}
34+
"-" : jrpc_server.send_msg(msg.make_result_response(x - y))
35+
"*" : jrpc_server.send_msg(msg.make_result_response(x * y))
36+
"/" : jrpc_server.send_msg(msg.make_result_response(x / y))
37+
default: write("jrpc:request:unsupported: ", msg.get_method())
38+
}
39+
40+
end
41+
end
42+
43+
###############################
44+
# client
45+
###############################
46+
class JRPC_client(jrpc_client)
47+
48+
method listen(addr)
49+
if not (jrpc_client := JRPC_HTTPSocket(addr,"na")) then
50+
stop("client open(", addr, ") ERROR: ", \&errortext | "Unknown")
51+
end
52+
53+
method test(op, params, answer)
54+
local id
55+
static idx := 0, mtx := mutex()
56+
critical mtx: id := idx +:=1
57+
jrpc_client.send_msg(JRPC_Message().make_request(id, op, params))
58+
work_items[id] := [op, params, answer]
59+
end
60+
61+
method start()
62+
local x := ?9, y := ?8+1
63+
test("+", [x, y], x+y)
64+
test("-", [x, y], x-y)
65+
test("*", [x, y], x*y)
66+
test("/", [x, y], x/y)
67+
end
68+
69+
end
70+
71+
global port
72+
procedure main()
73+
local calc, client, jobset, addr, id, op, x, y, answer,
74+
workers, i, response, job
75+
76+
addr := ":" || 5000 + ?1000
77+
if &features == ("MacOS" | "MS Windows NT") then
78+
addr := "127.0.0.1" || addr
79+
80+
client := JRPC_client()
81+
calc := JRPC_Calc()
82+
thread calc.start(addr)
83+
client.listen(addr)
84+
workers:=[]
85+
work_items := mutex(table())
86+
every !10 do put(workers, thread client.start())
87+
every wait(!workers)
88+
jobset:=set()
89+
every insert(jobset, !*work_items)
90+
91+
every i := !(*work_items*2) do {
92+
if *jobset = 0 then break
93+
if response := client.jrpc_client.get_msg(100) then {
94+
delete(jobset, id:=response.get_id())
95+
job := work_items[id]
96+
op:=job[1]; x:=job[2][1]; y:=job[2][2]; answer := job[3]
97+
write(left(id, 2), ": ", x, " ", op, " ", y, " = ", right(response.get_result(), 3),
98+
" ", if response.get_result()=answer then "Pass" else "Fail")
99+
}
100+
}
101+
102+
every job := work_items[id:=!jobset] do {
103+
op:=job[1]; x:=job[2][1]; y:=job[2][2]
104+
write(left(id, 2), ": ", x, " ", op, " ", y, " = Failed to get a response")
105+
}
106+
107+
end

0 commit comments

Comments
 (0)