@@ -19,7 +19,7 @@ use serde_json;
19
19
20
20
use version;
21
21
use lsp_data;
22
- use lsp_data:: * ;
22
+ use lsp_data:: { LSPNotification , LSPRequest , InitializationOptions } ;
23
23
use actions:: { notifications, requests, ActionContext } ;
24
24
use config:: Config ;
25
25
use server:: dispatch:: Dispatcher ;
@@ -32,6 +32,7 @@ pub use server::message::{Ack, NoResponse, Response, Request, BlockingRequestAct
32
32
pub use ls_types:: request:: Shutdown as ShutdownRequest ;
33
33
pub use ls_types:: request:: Initialize as InitializeRequest ;
34
34
pub use ls_types:: notification:: Exit as ExitNotification ;
35
+ use ls_types:: { InitializeResult , InitializeParams , ServerCapabilities , CompletionOptions , TextDocumentSyncCapability , TextDocumentSyncKind , ExecuteCommandOptions } ;
35
36
36
37
use std:: path:: PathBuf ;
37
38
use std:: sync:: { Arc , Mutex } ;
@@ -55,14 +56,6 @@ pub fn run_server(analysis: Arc<AnalysisHost>, vfs: Arc<Vfs>) {
55
56
debug ! ( "Server shutting down" ) ;
56
57
}
57
58
58
- /// A service implementing a language server.
59
- pub struct LsService < O : Output > {
60
- msg_reader : Box < MessageReader + Send + Sync > ,
61
- output : O ,
62
- ctx : ActionContext ,
63
- dispatcher : Dispatcher ,
64
- }
65
-
66
59
impl BlockingRequestAction for ShutdownRequest {
67
60
type Response = Ack ;
68
61
@@ -90,23 +83,6 @@ impl BlockingNotificationAction for ExitNotification {
90
83
}
91
84
}
92
85
93
- fn get_root_path ( params : & InitializeParams ) -> PathBuf {
94
- params
95
- . root_uri
96
- . as_ref ( )
97
- . map ( |uri| {
98
- assert ! ( uri. scheme( ) == "file" ) ;
99
- uri. to_file_path ( ) . expect ( "Could not convert URI to path" )
100
- } )
101
- . unwrap_or_else ( || {
102
- params
103
- . root_path
104
- . as_ref ( )
105
- . map ( PathBuf :: from)
106
- . expect ( "No root path or URI" )
107
- } )
108
- }
109
-
110
86
impl BlockingRequestAction for InitializeRequest {
111
87
type Response = NoResponse ;
112
88
@@ -124,56 +100,22 @@ impl BlockingRequestAction for InitializeRequest {
124
100
125
101
trace ! ( "init: {:?}" , init_options) ;
126
102
127
- let capabilities = lsp_data:: ClientCapabilities :: new ( & params) ;
128
-
129
- let result = InitializeResult {
130
- capabilities : ServerCapabilities {
131
- text_document_sync : Some ( TextDocumentSyncCapability :: Kind ( TextDocumentSyncKind :: Incremental ) ) ,
132
- hover_provider : Some ( true ) ,
133
- completion_provider : Some ( CompletionOptions {
134
- resolve_provider : Some ( true ) ,
135
- trigger_characters : vec ! [ "." . to_string( ) , ":" . to_string( ) ] ,
136
- } ) ,
137
- definition_provider : Some ( true ) ,
138
- references_provider : Some ( true ) ,
139
- document_highlight_provider : Some ( true ) ,
140
- document_symbol_provider : Some ( true ) ,
141
- workspace_symbol_provider : Some ( true ) ,
142
- code_action_provider : Some ( true ) ,
143
- document_formatting_provider : Some ( true ) ,
144
- execute_command_provider : Some ( ExecuteCommandOptions {
145
- commands : vec ! [
146
- "rls.applySuggestion" . to_owned( ) ,
147
- "rls.deglobImports" . to_owned( ) ,
148
- ] ,
149
- } ) ,
150
- rename_provider : Some ( true ) ,
151
- // These are supported if the `unstable_features` option is set.
152
- // We'll update these capabilities dynamically when we get config
153
- // info from the client.
154
- document_range_formatting_provider : Some ( false ) ,
155
-
156
- code_lens_provider : None ,
157
- document_on_type_formatting_provider : None ,
158
- signature_help_provider : None ,
159
- } ,
160
- } ;
103
+ let result = InitializeResult { capabilities : server_caps ( ) } ;
161
104
out. success ( id, & result) ;
162
105
106
+ let capabilities = lsp_data:: ClientCapabilities :: new ( & params) ;
163
107
ctx. init ( get_root_path ( & params) , & init_options, capabilities, & out) ;
164
108
165
109
Ok ( NoResponse )
166
110
}
167
111
}
168
112
169
- /// How should the server proceed?
170
- #[ derive( Eq , PartialEq , Debug , Clone , Copy ) ]
171
- pub enum ServerStateChange {
172
- /// Continue serving responses to requests and sending notifications to the
173
- /// client.
174
- Continue ,
175
- /// Stop the server.
176
- Break ,
113
+ /// A service implementing a language server.
114
+ pub struct LsService < O : Output > {
115
+ msg_reader : Box < MessageReader + Send + Sync > ,
116
+ output : O ,
117
+ ctx : ActionContext ,
118
+ dispatcher : Dispatcher ,
177
119
}
178
120
179
121
impl < O : Output > LsService < O > {
@@ -246,6 +188,16 @@ impl<O: Output> LsService<O> {
246
188
}
247
189
}
248
190
191
+ // Notifications and blocking requests are handled immediately on the
192
+ // main thread. They will never be dropped.
193
+ // Blocking requests wait for all non-blocking requests to complete,
194
+ // notifications do not.
195
+ // Other requests are read and then forwarded to a worker thread, they
196
+ // might timeout and will return an error but should not be dropped.
197
+ // Some requests might block again when executing due to waiting for a
198
+ // build or access to the VFS or real file system.
199
+ // Requests must not mutate RLS state, but may ask the client to mutate
200
+ // the client state.
249
201
match_action ! (
250
202
msg. method;
251
203
notifications:
@@ -331,6 +283,66 @@ impl<O: Output> LsService<O> {
331
283
}
332
284
}
333
285
286
+ /// How should the server proceed?
287
+ #[ derive( Eq , PartialEq , Debug , Clone , Copy ) ]
288
+ pub enum ServerStateChange {
289
+ /// Continue serving responses to requests and sending notifications to the
290
+ /// client.
291
+ Continue ,
292
+ /// Stop the server.
293
+ Break ,
294
+ }
295
+
296
+ fn server_caps ( ) -> ServerCapabilities {
297
+ ServerCapabilities {
298
+ text_document_sync : Some ( TextDocumentSyncCapability :: Kind ( TextDocumentSyncKind :: Incremental ) ) ,
299
+ hover_provider : Some ( true ) ,
300
+ completion_provider : Some ( CompletionOptions {
301
+ resolve_provider : Some ( true ) ,
302
+ trigger_characters : vec ! [ "." . to_string( ) , ":" . to_string( ) ] ,
303
+ } ) ,
304
+ definition_provider : Some ( true ) ,
305
+ references_provider : Some ( true ) ,
306
+ document_highlight_provider : Some ( true ) ,
307
+ document_symbol_provider : Some ( true ) ,
308
+ workspace_symbol_provider : Some ( true ) ,
309
+ code_action_provider : Some ( true ) ,
310
+ document_formatting_provider : Some ( true ) ,
311
+ execute_command_provider : Some ( ExecuteCommandOptions {
312
+ commands : vec ! [
313
+ "rls.applySuggestion" . to_owned( ) ,
314
+ "rls.deglobImports" . to_owned( ) ,
315
+ ] ,
316
+ } ) ,
317
+ rename_provider : Some ( true ) ,
318
+ // These are supported if the `unstable_features` option is set.
319
+ // We'll update these capabilities dynamically when we get config
320
+ // info from the client.
321
+ document_range_formatting_provider : Some ( false ) ,
322
+
323
+ code_lens_provider : None ,
324
+ document_on_type_formatting_provider : None ,
325
+ signature_help_provider : None ,
326
+ }
327
+ }
328
+
329
+ fn get_root_path ( params : & InitializeParams ) -> PathBuf {
330
+ params
331
+ . root_uri
332
+ . as_ref ( )
333
+ . map ( |uri| {
334
+ assert ! ( uri. scheme( ) == "file" ) ;
335
+ uri. to_file_path ( ) . expect ( "Could not convert URI to path" )
336
+ } )
337
+ . unwrap_or_else ( || {
338
+ params
339
+ . root_path
340
+ . as_ref ( )
341
+ . map ( PathBuf :: from)
342
+ . expect ( "No root path or URI" )
343
+ } )
344
+ }
345
+
334
346
#[ cfg( test) ]
335
347
mod test {
336
348
use super :: * ;
0 commit comments