diff options
-rw-r--r-- | Cargo.lock | 7 | ||||
-rw-r--r-- | crates/ra_lsp_server/Cargo.toml | 3 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main.rs | 74 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 29 | ||||
-rw-r--r-- | crates/ra_lsp_server/tests/heavy_tests/support.rs | 57 |
5 files changed, 85 insertions, 85 deletions
diff --git a/Cargo.lock b/Cargo.lock index 17e60aa82..f02df9e76 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -662,7 +662,7 @@ dependencies = [ | |||
662 | 662 | ||
663 | [[package]] | 663 | [[package]] |
664 | name = "lsp-server" | 664 | name = "lsp-server" |
665 | version = "0.1.0" | 665 | version = "0.2.0" |
666 | source = "registry+https://github.com/rust-lang/crates.io-index" | 666 | source = "registry+https://github.com/rust-lang/crates.io-index" |
667 | dependencies = [ | 667 | dependencies = [ |
668 | "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", | 668 | "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", |
@@ -1074,8 +1074,9 @@ version = "0.1.0" | |||
1074 | dependencies = [ | 1074 | dependencies = [ |
1075 | "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", | 1075 | "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", |
1076 | "flexi_logger 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", | 1076 | "flexi_logger 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", |
1077 | "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1077 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", | 1078 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", |
1078 | "lsp-server 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1079 | "lsp-server 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1079 | "lsp-types 0.60.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1080 | "lsp-types 0.60.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1080 | "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", | 1081 | "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", |
1081 | "ra_ide_api 0.1.0", | 1082 | "ra_ide_api 0.1.0", |
@@ -1937,7 +1938,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1937 | "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" | 1938 | "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" |
1938 | "checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" | 1939 | "checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" |
1939 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" | 1940 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" |
1940 | "checksum lsp-server 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47632ec528046c1a39f14448f1ee7d66d4b7b83e1771590b62e6c08665dea053" | 1941 | "checksum lsp-server 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "148cfb1c0b3295c23d9fb4a20fd1b242f5e6f46c525fdcc7f5c0a65710362012" |
1941 | "checksum lsp-types 0.60.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe3edefcd66dde1f7f1df706f46520a3c93adc5ca4bc5747da6621195e894efd" | 1942 | "checksum lsp-types 0.60.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe3edefcd66dde1f7f1df706f46520a3c93adc5ca4bc5747da6621195e894efd" |
1942 | "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" | 1943 | "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" |
1943 | "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" | 1944 | "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" |
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml index 084a20cd9..4f834519c 100644 --- a/crates/ra_lsp_server/Cargo.toml +++ b/crates/ra_lsp_server/Cargo.toml | |||
@@ -21,12 +21,13 @@ thread_worker = { path = "../thread_worker" } | |||
21 | ra_syntax = { path = "../ra_syntax" } | 21 | ra_syntax = { path = "../ra_syntax" } |
22 | ra_text_edit = { path = "../ra_text_edit" } | 22 | ra_text_edit = { path = "../ra_text_edit" } |
23 | ra_ide_api = { path = "../ra_ide_api" } | 23 | ra_ide_api = { path = "../ra_ide_api" } |
24 | lsp-server = "0.1.0" | 24 | lsp-server = "0.2.0" |
25 | ra_project_model = { path = "../ra_project_model" } | 25 | ra_project_model = { path = "../ra_project_model" } |
26 | ra_prof = { path = "../ra_prof" } | 26 | ra_prof = { path = "../ra_prof" } |
27 | ra_vfs_glob = { path = "../ra_vfs_glob" } | 27 | ra_vfs_glob = { path = "../ra_vfs_glob" } |
28 | 28 | ||
29 | [dev-dependencies] | 29 | [dev-dependencies] |
30 | jod-thread = "0.1.0" | ||
30 | tempfile = "3" | 31 | tempfile = "3" |
31 | test_utils = { path = "../test_utils" } | 32 | test_utils = { path = "../test_utils" } |
32 | 33 | ||
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index 1debe7660..88504bb89 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use flexi_logger::{Duplicate, Logger}; | 1 | use flexi_logger::{Duplicate, Logger}; |
2 | use lsp_server::{run_server, stdio_transport, LspServerError}; | 2 | use lsp_server::Connection; |
3 | 3 | ||
4 | use ra_lsp_server::{show_message, Result, ServerConfig}; | 4 | use ra_lsp_server::{show_message, Result, ServerConfig}; |
5 | use ra_prof; | 5 | use ra_prof; |
@@ -29,46 +29,46 @@ fn main() -> Result<()> { | |||
29 | } | 29 | } |
30 | 30 | ||
31 | fn main_inner() -> Result<()> { | 31 | fn main_inner() -> Result<()> { |
32 | let (sender, receiver, io_threads) = stdio_transport(); | ||
33 | let cwd = std::env::current_dir()?; | 32 | let cwd = std::env::current_dir()?; |
34 | let caps = serde_json::to_value(ra_lsp_server::server_capabilities()).unwrap(); | 33 | let (connection, io_threads) = Connection::stdio(); |
35 | run_server(caps, sender, receiver, |params, s, r| { | 34 | let server_capabilities = serde_json::to_value(ra_lsp_server::server_capabilities()).unwrap(); |
36 | let params: lsp_types::InitializeParams = serde_json::from_value(params)?; | ||
37 | let root = params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd); | ||
38 | 35 | ||
39 | let workspace_roots = params | 36 | let initialize_params = connection.initialize(server_capabilities)?; |
40 | .workspace_folders | 37 | let initialize_params: lsp_types::InitializeParams = serde_json::from_value(initialize_params)?; |
41 | .map(|workspaces| { | ||
42 | workspaces | ||
43 | .into_iter() | ||
44 | .filter_map(|it| it.uri.to_file_path().ok()) | ||
45 | .collect::<Vec<_>>() | ||
46 | }) | ||
47 | .filter(|workspaces| !workspaces.is_empty()) | ||
48 | .unwrap_or_else(|| vec![root]); | ||
49 | 38 | ||
50 | let server_config: ServerConfig = params | 39 | let root = initialize_params.root_uri.and_then(|it| it.to_file_path().ok()).unwrap_or(cwd); |
51 | .initialization_options | 40 | |
52 | .and_then(|v| { | 41 | let workspace_roots = initialize_params |
53 | serde_json::from_value(v) | 42 | .workspace_folders |
54 | .map_err(|e| { | 43 | .map(|workspaces| { |
55 | log::error!("failed to deserialize config: {}", e); | 44 | workspaces.into_iter().filter_map(|it| it.uri.to_file_path().ok()).collect::<Vec<_>>() |
56 | show_message( | 45 | }) |
57 | lsp_types::MessageType::Error, | 46 | .filter(|workspaces| !workspaces.is_empty()) |
58 | format!("failed to deserialize config: {}", e), | 47 | .unwrap_or_else(|| vec![root]); |
59 | s, | 48 | |
60 | ); | 49 | let server_config: ServerConfig = initialize_params |
61 | }) | 50 | .initialization_options |
62 | .ok() | 51 | .and_then(|v| { |
63 | }) | 52 | serde_json::from_value(v) |
64 | .unwrap_or_default(); | 53 | .map_err(|e| { |
54 | log::error!("failed to deserialize config: {}", e); | ||
55 | show_message( | ||
56 | lsp_types::MessageType::Error, | ||
57 | format!("failed to deserialize config: {}", e), | ||
58 | &connection.sender, | ||
59 | ); | ||
60 | }) | ||
61 | .ok() | ||
62 | }) | ||
63 | .unwrap_or_default(); | ||
64 | |||
65 | ra_lsp_server::main_loop( | ||
66 | workspace_roots, | ||
67 | initialize_params.capabilities, | ||
68 | server_config, | ||
69 | &connection, | ||
70 | )?; | ||
65 | 71 | ||
66 | ra_lsp_server::main_loop(workspace_roots, params.capabilities, server_config, r, s) | ||
67 | }) | ||
68 | .map_err(|err| match err { | ||
69 | LspServerError::ProtocolError(err) => err.into(), | ||
70 | LspServerError::ServerError(err) => err, | ||
71 | })?; | ||
72 | log::info!("shutting down IO..."); | 72 | log::info!("shutting down IO..."); |
73 | io_threads.join()?; | 73 | io_threads.join()?; |
74 | log::info!("... IO is down"); | 74 | log::info!("... IO is down"); |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index fb357b36b..42ebb5cdf 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -5,7 +5,7 @@ pub(crate) mod pending_requests; | |||
5 | use std::{error::Error, fmt, path::PathBuf, sync::Arc, time::Instant}; | 5 | use std::{error::Error, fmt, path::PathBuf, sync::Arc, time::Instant}; |
6 | 6 | ||
7 | use crossbeam_channel::{select, unbounded, Receiver, RecvError, Sender}; | 7 | use crossbeam_channel::{select, unbounded, Receiver, RecvError, Sender}; |
8 | use lsp_server::{handle_shutdown, ErrorCode, Message, Notification, Request, RequestId, Response}; | 8 | use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response}; |
9 | use lsp_types::{ClientCapabilities, NumberOrString}; | 9 | use lsp_types::{ClientCapabilities, NumberOrString}; |
10 | use ra_ide_api::{Canceled, FeatureFlags, FileId, LibraryData}; | 10 | use ra_ide_api::{Canceled, FeatureFlags, FileId, LibraryData}; |
11 | use ra_prof::profile; | 11 | use ra_prof::profile; |
@@ -51,8 +51,7 @@ pub fn main_loop( | |||
51 | ws_roots: Vec<PathBuf>, | 51 | ws_roots: Vec<PathBuf>, |
52 | client_caps: ClientCapabilities, | 52 | client_caps: ClientCapabilities, |
53 | config: ServerConfig, | 53 | config: ServerConfig, |
54 | msg_receiver: &Receiver<Message>, | 54 | connection: &Connection, |
55 | msg_sender: &Sender<Message>, | ||
56 | ) -> Result<()> { | 55 | ) -> Result<()> { |
57 | log::info!("server_config: {:#?}", config); | 56 | log::info!("server_config: {:#?}", config); |
58 | // FIXME: support dynamic workspace loading. | 57 | // FIXME: support dynamic workspace loading. |
@@ -69,7 +68,7 @@ pub fn main_loop( | |||
69 | show_message( | 68 | show_message( |
70 | req::MessageType::Error, | 69 | req::MessageType::Error, |
71 | format!("rust-analyzer failed to load workspace: {}", e), | 70 | format!("rust-analyzer failed to load workspace: {}", e), |
72 | msg_sender, | 71 | &connection.sender, |
73 | ); | 72 | ); |
74 | } | 73 | } |
75 | } | 74 | } |
@@ -89,7 +88,7 @@ pub fn main_loop( | |||
89 | show_message( | 88 | show_message( |
90 | req::MessageType::Error, | 89 | req::MessageType::Error, |
91 | format!("unknown feature flag: {:?}", flag), | 90 | format!("unknown feature flag: {:?}", flag), |
92 | msg_sender, | 91 | &connection.sender, |
93 | ); | 92 | ); |
94 | } | 93 | } |
95 | } | 94 | } |
@@ -119,8 +118,7 @@ pub fn main_loop( | |||
119 | log::info!("server initialized, serving requests"); | 118 | log::info!("server initialized, serving requests"); |
120 | let main_res = main_loop_inner( | 119 | let main_res = main_loop_inner( |
121 | &pool, | 120 | &pool, |
122 | msg_sender, | 121 | connection, |
123 | msg_receiver, | ||
124 | task_sender, | 122 | task_sender, |
125 | task_receiver.clone(), | 123 | task_receiver.clone(), |
126 | &mut state, | 124 | &mut state, |
@@ -130,7 +128,7 @@ pub fn main_loop( | |||
130 | log::info!("waiting for tasks to finish..."); | 128 | log::info!("waiting for tasks to finish..."); |
131 | task_receiver | 129 | task_receiver |
132 | .into_iter() | 130 | .into_iter() |
133 | .for_each(|task| on_task(task, msg_sender, &mut pending_requests, &mut state)); | 131 | .for_each(|task| on_task(task, &connection.sender, &mut pending_requests, &mut state)); |
134 | log::info!("...tasks have finished"); | 132 | log::info!("...tasks have finished"); |
135 | log::info!("joining threadpool..."); | 133 | log::info!("joining threadpool..."); |
136 | drop(pool); | 134 | drop(pool); |
@@ -196,8 +194,7 @@ impl fmt::Debug for Event { | |||
196 | 194 | ||
197 | fn main_loop_inner( | 195 | fn main_loop_inner( |
198 | pool: &ThreadPool, | 196 | pool: &ThreadPool, |
199 | msg_sender: &Sender<Message>, | 197 | connection: &Connection, |
200 | msg_receiver: &Receiver<Message>, | ||
201 | task_sender: Sender<Task>, | 198 | task_sender: Sender<Task>, |
202 | task_receiver: Receiver<Task>, | 199 | task_receiver: Receiver<Task>, |
203 | state: &mut WorldState, | 200 | state: &mut WorldState, |
@@ -214,7 +211,7 @@ fn main_loop_inner( | |||
214 | loop { | 211 | loop { |
215 | log::trace!("selecting"); | 212 | log::trace!("selecting"); |
216 | let event = select! { | 213 | let event = select! { |
217 | recv(msg_receiver) -> msg => match msg { | 214 | recv(&connection.receiver) -> msg => match msg { |
218 | Ok(msg) => Event::Msg(msg), | 215 | Ok(msg) => Event::Msg(msg), |
219 | Err(RecvError) => Err("client exited without shutdown")?, | 216 | Err(RecvError) => Err("client exited without shutdown")?, |
220 | }, | 217 | }, |
@@ -238,7 +235,7 @@ fn main_loop_inner( | |||
238 | let mut state_changed = false; | 235 | let mut state_changed = false; |
239 | match event { | 236 | match event { |
240 | Event::Task(task) => { | 237 | Event::Task(task) => { |
241 | on_task(task, msg_sender, pending_requests, state); | 238 | on_task(task, &connection.sender, pending_requests, state); |
242 | state.maybe_collect_garbage(); | 239 | state.maybe_collect_garbage(); |
243 | } | 240 | } |
244 | Event::Vfs(task) => { | 241 | Event::Vfs(task) => { |
@@ -252,7 +249,7 @@ fn main_loop_inner( | |||
252 | } | 249 | } |
253 | Event::Msg(msg) => match msg { | 250 | Event::Msg(msg) => match msg { |
254 | Message::Request(req) => { | 251 | Message::Request(req) => { |
255 | if handle_shutdown(&req, msg_sender) { | 252 | if connection.handle_shutdown(&req)? { |
256 | return Ok(()); | 253 | return Ok(()); |
257 | }; | 254 | }; |
258 | on_request( | 255 | on_request( |
@@ -260,13 +257,13 @@ fn main_loop_inner( | |||
260 | pending_requests, | 257 | pending_requests, |
261 | pool, | 258 | pool, |
262 | &task_sender, | 259 | &task_sender, |
263 | msg_sender, | 260 | &connection.sender, |
264 | loop_start, | 261 | loop_start, |
265 | req, | 262 | req, |
266 | )? | 263 | )? |
267 | } | 264 | } |
268 | Message::Notification(not) => { | 265 | Message::Notification(not) => { |
269 | on_notification(msg_sender, state, pending_requests, &mut subs, not)?; | 266 | on_notification(&connection.sender, state, pending_requests, &mut subs, not)?; |
270 | state_changed = true; | 267 | state_changed = true; |
271 | } | 268 | } |
272 | Message::Response(resp) => log::error!("unexpected response: {:?}", resp), | 269 | Message::Response(resp) => log::error!("unexpected response: {:?}", resp), |
@@ -294,7 +291,7 @@ fn main_loop_inner( | |||
294 | let n_packages: usize = state.workspaces.iter().map(|it| it.n_packages()).sum(); | 291 | let n_packages: usize = state.workspaces.iter().map(|it| it.n_packages()).sum(); |
295 | if state.feature_flags().get("notifications.workspace-loaded") { | 292 | if state.feature_flags().get("notifications.workspace-loaded") { |
296 | let msg = format!("workspace loaded, {} rust packages", n_packages); | 293 | let msg = format!("workspace loaded, {} rust packages", n_packages); |
297 | show_message(req::MessageType::Info, msg, msg_sender); | 294 | show_message(req::MessageType::Info, msg, &connection.sender); |
298 | } | 295 | } |
299 | // Only send the notification first time | 296 | // Only send the notification first time |
300 | send_workspace_notification = false; | 297 | send_workspace_notification = false; |
diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index 45b4cacf6..89f65cef4 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs | |||
@@ -8,16 +8,17 @@ use std::{ | |||
8 | 8 | ||
9 | use crossbeam_channel::{after, select, Receiver}; | 9 | use crossbeam_channel::{after, select, Receiver}; |
10 | use flexi_logger::Logger; | 10 | use flexi_logger::Logger; |
11 | use lsp_server::{Message, Notification, Request}; | 11 | use lsp_server::{Connection, Message, Notification, Request}; |
12 | use lsp_types::{ | 12 | use lsp_types::{ |
13 | request::Shutdown, ClientCapabilities, DidOpenTextDocumentParams, GotoCapability, | 13 | notification::{DidOpenTextDocument, Exit}, |
14 | TextDocumentClientCapabilities, TextDocumentIdentifier, TextDocumentItem, Url, | 14 | request::Shutdown, |
15 | ClientCapabilities, DidOpenTextDocumentParams, GotoCapability, TextDocumentClientCapabilities, | ||
16 | TextDocumentIdentifier, TextDocumentItem, Url, | ||
15 | }; | 17 | }; |
16 | use serde::Serialize; | 18 | use serde::Serialize; |
17 | use serde_json::{to_string_pretty, Value}; | 19 | use serde_json::{to_string_pretty, Value}; |
18 | use tempfile::TempDir; | 20 | use tempfile::TempDir; |
19 | use test_utils::{find_mismatch, parse_fixture}; | 21 | use test_utils::{find_mismatch, parse_fixture}; |
20 | use thread_worker::Worker; | ||
21 | 22 | ||
22 | use ra_lsp_server::{main_loop, req, ServerConfig}; | 23 | use ra_lsp_server::{main_loop, req, ServerConfig}; |
23 | 24 | ||
@@ -83,7 +84,8 @@ pub struct Server { | |||
83 | req_id: Cell<u64>, | 84 | req_id: Cell<u64>, |
84 | messages: RefCell<Vec<Message>>, | 85 | messages: RefCell<Vec<Message>>, |
85 | dir: TempDir, | 86 | dir: TempDir, |
86 | worker: Worker<Message, Message>, | 87 | _thread: jod_thread::JoinHandle<()>, |
88 | client: Connection, | ||
87 | } | 89 | } |
88 | 90 | ||
89 | impl Server { | 91 | impl Server { |
@@ -96,11 +98,11 @@ impl Server { | |||
96 | let path = dir.path().to_path_buf(); | 98 | let path = dir.path().to_path_buf(); |
97 | 99 | ||
98 | let roots = if roots.is_empty() { vec![path] } else { roots }; | 100 | let roots = if roots.is_empty() { vec![path] } else { roots }; |
101 | let (connection, client) = Connection::memory(); | ||
99 | 102 | ||
100 | let worker = Worker::<Message, Message>::spawn( | 103 | let _thread = jod_thread::Builder::new() |
101 | "test server", | 104 | .name("test server".to_string()) |
102 | 128, | 105 | .spawn(move || { |
103 | move |msg_receiver, msg_sender| { | ||
104 | main_loop( | 106 | main_loop( |
105 | roots, | 107 | roots, |
106 | ClientCapabilities { | 108 | ClientCapabilities { |
@@ -116,26 +118,24 @@ impl Server { | |||
116 | experimental: None, | 118 | experimental: None, |
117 | }, | 119 | }, |
118 | ServerConfig { with_sysroot, ..ServerConfig::default() }, | 120 | ServerConfig { with_sysroot, ..ServerConfig::default() }, |
119 | &msg_receiver, | 121 | &connection, |
120 | &msg_sender, | ||
121 | ) | 122 | ) |
122 | .unwrap() | 123 | .unwrap() |
123 | }, | 124 | }) |
124 | ); | 125 | .expect("failed to spawn a thread"); |
125 | let res = Server { req_id: Cell::new(1), dir, messages: Default::default(), worker }; | 126 | |
127 | let res = | ||
128 | Server { req_id: Cell::new(1), dir, messages: Default::default(), client, _thread }; | ||
126 | 129 | ||
127 | for (path, text) in files { | 130 | for (path, text) in files { |
128 | res.send_notification(Notification::new( | 131 | res.notification::<DidOpenTextDocument>(DidOpenTextDocumentParams { |
129 | "textDocument/didOpen".to_string(), | 132 | text_document: TextDocumentItem { |
130 | &DidOpenTextDocumentParams { | 133 | uri: Url::from_file_path(path).unwrap(), |
131 | text_document: TextDocumentItem { | 134 | language_id: "rust".to_string(), |
132 | uri: Url::from_file_path(path).unwrap(), | 135 | version: 0, |
133 | language_id: "rust".to_string(), | 136 | text, |
134 | version: 0, | ||
135 | text, | ||
136 | }, | ||
137 | }, | 137 | }, |
138 | )) | 138 | }) |
139 | } | 139 | } |
140 | res | 140 | res |
141 | } | 141 | } |
@@ -184,7 +184,7 @@ impl Server { | |||
184 | } | 184 | } |
185 | fn send_request_(&self, r: Request) -> Value { | 185 | fn send_request_(&self, r: Request) -> Value { |
186 | let id = r.id.clone(); | 186 | let id = r.id.clone(); |
187 | self.worker.sender().send(r.into()).unwrap(); | 187 | self.client.sender.send(r.into()).unwrap(); |
188 | while let Some(msg) = self.recv() { | 188 | while let Some(msg) = self.recv() { |
189 | match msg { | 189 | match msg { |
190 | Message::Request(req) => panic!("unexpected request: {:?}", req), | 190 | Message::Request(req) => panic!("unexpected request: {:?}", req), |
@@ -225,13 +225,13 @@ impl Server { | |||
225 | } | 225 | } |
226 | } | 226 | } |
227 | fn recv(&self) -> Option<Message> { | 227 | fn recv(&self) -> Option<Message> { |
228 | recv_timeout(&self.worker.receiver()).map(|msg| { | 228 | recv_timeout(&self.client.receiver).map(|msg| { |
229 | self.messages.borrow_mut().push(msg.clone()); | 229 | self.messages.borrow_mut().push(msg.clone()); |
230 | msg | 230 | msg |
231 | }) | 231 | }) |
232 | } | 232 | } |
233 | fn send_notification(&self, not: Notification) { | 233 | fn send_notification(&self, not: Notification) { |
234 | self.worker.sender().send(Message::Notification(not)).unwrap(); | 234 | self.client.sender.send(Message::Notification(not)).unwrap(); |
235 | } | 235 | } |
236 | 236 | ||
237 | pub fn path(&self) -> &Path { | 237 | pub fn path(&self) -> &Path { |
@@ -241,7 +241,8 @@ impl Server { | |||
241 | 241 | ||
242 | impl Drop for Server { | 242 | impl Drop for Server { |
243 | fn drop(&mut self) { | 243 | fn drop(&mut self) { |
244 | self.send_request::<Shutdown>(()); | 244 | self.request::<Shutdown>((), Value::Null); |
245 | self.notification::<Exit>(()); | ||
245 | } | 246 | } |
246 | } | 247 | } |
247 | 248 | ||