forked from jeapostrophe/racket-langserver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmethods.rkt
126 lines (114 loc) · 4.03 KB
/
methods.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#lang racket/base
(require json
racket/contract/base
racket/exn
racket/match
"error-codes.rkt"
"msg-io.rkt"
"responses.rkt"
(prefix-in text-document/ "text-document.rkt"))
;; TextDocumentSynKind enumeration
(define TextDocSync-None 0)
(define TextDocSync-Full 1)
(define TextDocSync-Incremental 2)
;; Mutable variables
(define already-initialized? #f)
(define already-shutdown? #f)
;;
;; Dispatch
;;;;;;;;;;;;;
;; Processes a message. This displays any repsonse it generates
;; and should always return void.
(define (process-message msg)
(match msg
;; Request
[(hash-table ['id (? (or/c number? string?) id)]
['method (? string? method)])
(define params (hash-ref msg 'params hasheq))
(define response (process-request id method params))
(display-message/flush response)]
;; Notification
[(hash-table ['method (? string? method)])
(define params (hash-ref msg 'params hasheq))
(process-notification method params)]
;; Batch Request
[(? (non-empty-listof (and/c hash? jsexpr?)))
(for-each process-message msg)]
;; Invalid Message
[_
(define id-ref (hash-ref msg 'id void))
(define id (if ((or/c number? string?) id-ref) id-ref (json-null)))
(define err "The JSON sent is not a valid request object.")
(display-message/flush (error-response id INVALID-REQUEST err))]))
(define ((report-request-error id method) exn)
(eprintf "Caught exn in request ~v\n~a\n" method (exn->string exn))
(define err (format "internal error in method ~v" method))
(error-response id INTERNAL-ERROR err))
;; Processes a request. This procedure should always return a jsexpr
;; which is a suitable response object.
(define (process-request id method params)
(with-handlers ([exn:fail? (report-request-error id method)])
(match method
["initialize"
(initialize id params)]
["shutdown"
(shutdown id)]
["textDocument/hover"
(text-document/hover id params)]
["textDocument/definition"
(text-document/definition id params)]
["textDocument/documentHighlight"
(text-document/document-highlight id params)]
["textDocument/references"
(text-document/references id params)]
["textDocument/documentSymbol"
(text-document/document-symbol id params)]
[_
(eprintf "invalid request for method ~v\n" method)
(define err (format "The method ~v was not found" method))
(error-response id METHOD-NOT-FOUND err)])))
;; Processes a notification. Because notifications do not require
;; a response, this procedure always returns void.
(define (process-notification method params)
(match method
["exit"
(exit (if already-shutdown? 0 1))]
["textDocument/didOpen"
(text-document/did-open! params)]
["textDocument/didClose"
(text-document/did-close! params)]
["textDocument/didChange"
(text-document/did-change! params)]
[_ (void)]))
;;
;; Requests
;;;;;;;;;;;;;
(define (initialize id params)
(match params
[(hash-table ['processId (? (or/c number? (json-null)) process-id)]
['capabilities (? jsexpr? capabilities)])
(define sync-options
(hasheq 'openClose #t
'change TextDocSync-Incremental
'willSave #f
'willSaveWaitUntil #f))
(define server-capabilities
(hasheq 'textDocumentSync sync-options
'hoverProvider #t
'definitionProvider #t
'referencesProvider #t
'documentHighlightProvider #t
'documentSymbolProvider #t))
(define resp (success-response id (hasheq 'capabilities server-capabilities)))
(set! already-initialized? #t)
resp]
[_
(error-response id INVALID-PARAMS "initialize failed")]))
(define (shutdown id)
(set! already-shutdown? #t)
(success-response id (json-null)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(provide
(contract-out
[process-message
(jsexpr? . -> . void?)]))