diff options
-rw-r--r-- | crates/ra_lsp_server/src/conv.rs | 10 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 26 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/world.rs | 12 | ||||
-rw-r--r-- | crates/ra_lsp_server/tests/heavy_tests/support.rs | 24 |
5 files changed, 62 insertions, 12 deletions
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index d0bdc94aa..82c7e757f 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs | |||
@@ -421,7 +421,15 @@ impl TryConvWith for (FileId, RangeInfo<Vec<NavigationTarget>>) { | |||
421 | .into_iter() | 421 | .into_iter() |
422 | .map(|nav| (file_id, RangeInfo::new(range, nav))) | 422 | .map(|nav| (file_id, RangeInfo::new(range, nav))) |
423 | .try_conv_with_to_vec(world)?; | 423 | .try_conv_with_to_vec(world)?; |
424 | Ok(links.into()) | 424 | if world.options.supports_location_link { |
425 | Ok(links.into()) | ||
426 | } else { | ||
427 | let locations: Vec<Location> = links | ||
428 | .into_iter() | ||
429 | .map(|link| Location { uri: link.target_uri, range: link.target_selection_range }) | ||
430 | .collect(); | ||
431 | Ok(locations.into()) | ||
432 | } | ||
425 | } | 433 | } |
426 | } | 434 | } |
427 | 435 | ||
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index 6aa6dd49f..c1f8243be 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs | |||
@@ -51,7 +51,7 @@ fn main_inner() -> Result<()> { | |||
51 | .and_then(|v| InitializationOptions::deserialize(v).ok()) | 51 | .and_then(|v| InitializationOptions::deserialize(v).ok()) |
52 | .unwrap_or_default(); | 52 | .unwrap_or_default(); |
53 | 53 | ||
54 | ra_lsp_server::main_loop(workspace_roots, opts, r, s) | 54 | ra_lsp_server::main_loop(workspace_roots, params.capabilities, opts, r, s) |
55 | })?; | 55 | })?; |
56 | log::info!("shutting down IO..."); | 56 | log::info!("shutting down IO..."); |
57 | threads.join()?; | 57 | threads.join()?; |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index c44fc6603..f7becd8fb 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -8,7 +8,7 @@ use crossbeam_channel::{select, unbounded, Receiver, RecvError, Sender}; | |||
8 | use gen_lsp_server::{ | 8 | use gen_lsp_server::{ |
9 | handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, | 9 | handle_shutdown, ErrorCode, RawMessage, RawNotification, RawRequest, RawResponse, |
10 | }; | 10 | }; |
11 | use lsp_types::NumberOrString; | 11 | use lsp_types::{ClientCapabilities, NumberOrString}; |
12 | use ra_ide_api::{Canceled, FileId, LibraryData}; | 12 | use ra_ide_api::{Canceled, FileId, LibraryData}; |
13 | use ra_prof::profile; | 13 | use ra_prof::profile; |
14 | use ra_vfs::VfsTask; | 14 | use ra_vfs::VfsTask; |
@@ -22,7 +22,7 @@ use crate::{ | |||
22 | }, | 22 | }, |
23 | project_model::workspace_loader, | 23 | project_model::workspace_loader, |
24 | req, | 24 | req, |
25 | world::{WorldSnapshot, WorldState}, | 25 | world::{Options, WorldSnapshot, WorldState}, |
26 | InitializationOptions, Result, | 26 | InitializationOptions, Result, |
27 | }; | 27 | }; |
28 | 28 | ||
@@ -51,6 +51,7 @@ impl Error for LspError {} | |||
51 | 51 | ||
52 | pub fn main_loop( | 52 | pub fn main_loop( |
53 | ws_roots: Vec<PathBuf>, | 53 | ws_roots: Vec<PathBuf>, |
54 | client_caps: ClientCapabilities, | ||
54 | options: InitializationOptions, | 55 | options: InitializationOptions, |
55 | msg_receiver: &Receiver<RawMessage>, | 56 | msg_receiver: &Receiver<RawMessage>, |
56 | msg_sender: &Sender<RawMessage>, | 57 | msg_sender: &Sender<RawMessage>, |
@@ -77,7 +78,20 @@ pub fn main_loop( | |||
77 | loaded_workspaces | 78 | loaded_workspaces |
78 | }; | 79 | }; |
79 | 80 | ||
80 | let mut state = WorldState::new(ws_roots, workspaces, options.lru_capacity); | 81 | let mut state = WorldState::new( |
82 | ws_roots, | ||
83 | workspaces, | ||
84 | options.lru_capacity, | ||
85 | Options { | ||
86 | publish_decorations: options.publish_decorations, | ||
87 | show_workspace_loaded: options.show_workspace_loaded, | ||
88 | supports_location_link: client_caps | ||
89 | .text_document | ||
90 | .and_then(|it| it.definition) | ||
91 | .and_then(|it| it.link_support) | ||
92 | .unwrap_or(false), | ||
93 | }, | ||
94 | ); | ||
81 | 95 | ||
82 | let pool = ThreadPool::new(THREADPOOL_SIZE); | 96 | let pool = ThreadPool::new(THREADPOOL_SIZE); |
83 | let (task_sender, task_receiver) = unbounded::<Task>(); | 97 | let (task_sender, task_receiver) = unbounded::<Task>(); |
@@ -85,7 +99,6 @@ pub fn main_loop( | |||
85 | 99 | ||
86 | log::info!("server initialized, serving requests"); | 100 | log::info!("server initialized, serving requests"); |
87 | let main_res = main_loop_inner( | 101 | let main_res = main_loop_inner( |
88 | options, | ||
89 | &pool, | 102 | &pool, |
90 | msg_sender, | 103 | msg_sender, |
91 | msg_receiver, | 104 | msg_receiver, |
@@ -159,7 +172,6 @@ impl fmt::Debug for Event { | |||
159 | } | 172 | } |
160 | 173 | ||
161 | fn main_loop_inner( | 174 | fn main_loop_inner( |
162 | options: InitializationOptions, | ||
163 | pool: &ThreadPool, | 175 | pool: &ThreadPool, |
164 | msg_sender: &Sender<RawMessage>, | 176 | msg_sender: &Sender<RawMessage>, |
165 | msg_receiver: &Receiver<RawMessage>, | 177 | msg_receiver: &Receiver<RawMessage>, |
@@ -258,7 +270,7 @@ fn main_loop_inner( | |||
258 | && in_flight_libraries == 0 | 270 | && in_flight_libraries == 0 |
259 | { | 271 | { |
260 | let n_packages: usize = state.workspaces.iter().map(|it| it.count()).sum(); | 272 | let n_packages: usize = state.workspaces.iter().map(|it| it.count()).sum(); |
261 | if options.show_workspace_loaded { | 273 | if state.options.show_workspace_loaded { |
262 | let msg = format!("workspace loaded, {} rust packages", n_packages); | 274 | let msg = format!("workspace loaded, {} rust packages", n_packages); |
263 | show_message(req::MessageType::Info, msg, msg_sender); | 275 | show_message(req::MessageType::Info, msg, msg_sender); |
264 | } | 276 | } |
@@ -270,7 +282,7 @@ fn main_loop_inner( | |||
270 | update_file_notifications_on_threadpool( | 282 | update_file_notifications_on_threadpool( |
271 | pool, | 283 | pool, |
272 | state.snapshot(), | 284 | state.snapshot(), |
273 | options.publish_decorations, | 285 | state.options.publish_decorations, |
274 | task_sender.clone(), | 286 | task_sender.clone(), |
275 | subs.subscriptions(), | 287 | subs.subscriptions(), |
276 | ) | 288 | ) |
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index fdc577622..9fd654305 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs | |||
@@ -19,6 +19,13 @@ use crate::{ | |||
19 | LspError, Result, | 19 | LspError, Result, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | #[derive(Debug, Clone)] | ||
23 | pub struct Options { | ||
24 | pub publish_decorations: bool, | ||
25 | pub show_workspace_loaded: bool, | ||
26 | pub supports_location_link: bool, | ||
27 | } | ||
28 | |||
22 | /// `WorldState` is the primary mutable state of the language server | 29 | /// `WorldState` is the primary mutable state of the language server |
23 | /// | 30 | /// |
24 | /// The most interesting components are `vfs`, which stores a consistent | 31 | /// The most interesting components are `vfs`, which stores a consistent |
@@ -26,6 +33,7 @@ use crate::{ | |||
26 | /// incremental salsa database. | 33 | /// incremental salsa database. |
27 | #[derive(Debug)] | 34 | #[derive(Debug)] |
28 | pub struct WorldState { | 35 | pub struct WorldState { |
36 | pub options: Options, | ||
29 | pub roots_to_scan: usize, | 37 | pub roots_to_scan: usize, |
30 | pub roots: Vec<PathBuf>, | 38 | pub roots: Vec<PathBuf>, |
31 | pub workspaces: Arc<Vec<ProjectWorkspace>>, | 39 | pub workspaces: Arc<Vec<ProjectWorkspace>>, |
@@ -36,6 +44,7 @@ pub struct WorldState { | |||
36 | 44 | ||
37 | /// An immutable snapshot of the world's state at a point in time. | 45 | /// An immutable snapshot of the world's state at a point in time. |
38 | pub struct WorldSnapshot { | 46 | pub struct WorldSnapshot { |
47 | pub options: Options, | ||
39 | pub workspaces: Arc<Vec<ProjectWorkspace>>, | 48 | pub workspaces: Arc<Vec<ProjectWorkspace>>, |
40 | pub analysis: Analysis, | 49 | pub analysis: Analysis, |
41 | pub vfs: Arc<RwLock<Vfs>>, | 50 | pub vfs: Arc<RwLock<Vfs>>, |
@@ -47,6 +56,7 @@ impl WorldState { | |||
47 | folder_roots: Vec<PathBuf>, | 56 | folder_roots: Vec<PathBuf>, |
48 | workspaces: Vec<ProjectWorkspace>, | 57 | workspaces: Vec<ProjectWorkspace>, |
49 | lru_capacity: Option<usize>, | 58 | lru_capacity: Option<usize>, |
59 | options: Options, | ||
50 | ) -> WorldState { | 60 | ) -> WorldState { |
51 | let mut change = AnalysisChange::new(); | 61 | let mut change = AnalysisChange::new(); |
52 | 62 | ||
@@ -78,6 +88,7 @@ impl WorldState { | |||
78 | let mut analysis_host = AnalysisHost::new(lru_capacity); | 88 | let mut analysis_host = AnalysisHost::new(lru_capacity); |
79 | analysis_host.apply_change(change); | 89 | analysis_host.apply_change(change); |
80 | WorldState { | 90 | WorldState { |
91 | options, | ||
81 | roots_to_scan, | 92 | roots_to_scan, |
82 | roots: folder_roots, | 93 | roots: folder_roots, |
83 | workspaces: Arc::new(workspaces), | 94 | workspaces: Arc::new(workspaces), |
@@ -140,6 +151,7 @@ impl WorldState { | |||
140 | 151 | ||
141 | pub fn snapshot(&self) -> WorldSnapshot { | 152 | pub fn snapshot(&self) -> WorldSnapshot { |
142 | WorldSnapshot { | 153 | WorldSnapshot { |
154 | options: self.options.clone(), | ||
143 | workspaces: Arc::clone(&self.workspaces), | 155 | workspaces: Arc::clone(&self.workspaces), |
144 | analysis: self.analysis_host.analysis(), | 156 | analysis: self.analysis_host.analysis(), |
145 | vfs: Arc::clone(&self.vfs), | 157 | vfs: Arc::clone(&self.vfs), |
diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index a5e352da1..5dddbbe17 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs | |||
@@ -13,7 +13,8 @@ use lsp_types::{ | |||
13 | notification::DidOpenTextDocument, | 13 | notification::DidOpenTextDocument, |
14 | notification::{Notification, ShowMessage}, | 14 | notification::{Notification, ShowMessage}, |
15 | request::{Request, Shutdown}, | 15 | request::{Request, Shutdown}, |
16 | DidOpenTextDocumentParams, TextDocumentIdentifier, TextDocumentItem, Url, | 16 | ClientCapabilities, DidOpenTextDocumentParams, GotoCapability, TextDocumentClientCapabilities, |
17 | TextDocumentIdentifier, TextDocumentItem, Url, | ||
17 | }; | 18 | }; |
18 | use serde::Serialize; | 19 | use serde::Serialize; |
19 | use serde_json::{to_string_pretty, Value}; | 20 | use serde_json::{to_string_pretty, Value}; |
@@ -92,8 +93,25 @@ impl Server { | |||
92 | "test server", | 93 | "test server", |
93 | 128, | 94 | 128, |
94 | move |msg_receiver, msg_sender| { | 95 | move |msg_receiver, msg_sender| { |
95 | main_loop(roots, InitializationOptions::default(), &msg_receiver, &msg_sender) | 96 | main_loop( |
96 | .unwrap() | 97 | roots, |
98 | ClientCapabilities { | ||
99 | workspace: None, | ||
100 | text_document: Some(TextDocumentClientCapabilities { | ||
101 | definition: Some(GotoCapability { | ||
102 | dynamic_registration: None, | ||
103 | link_support: Some(true), | ||
104 | }), | ||
105 | ..Default::default() | ||
106 | }), | ||
107 | window: None, | ||
108 | experimental: None, | ||
109 | }, | ||
110 | InitializationOptions::default(), | ||
111 | &msg_receiver, | ||
112 | &msg_sender, | ||
113 | ) | ||
114 | .unwrap() | ||
97 | }, | 115 | }, |
98 | ); | 116 | ); |
99 | let res = Server { req_id: Cell::new(1), dir, messages: Default::default(), worker }; | 117 | let res = Server { req_id: Cell::new(1), dir, messages: Default::default(), worker }; |