diff options
-rw-r--r-- | crates/rust-analyzer/src/cargo_target_spec.rs | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/src/from_proto.rs | 8 | ||||
-rw-r--r-- | crates/rust-analyzer/src/global_state.rs (renamed from crates/rust-analyzer/src/world.rs) | 18 | ||||
-rw-r--r-- | crates/rust-analyzer/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 88 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop/handlers.rs | 357 | ||||
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 87 |
7 files changed, 291 insertions, 273 deletions
diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs index 008518a08..44f856f6b 100644 --- a/crates/rust-analyzer/src/cargo_target_spec.rs +++ b/crates/rust-analyzer/src/cargo_target_spec.rs | |||
@@ -4,7 +4,7 @@ use ra_cfg::CfgExpr; | |||
4 | use ra_ide::{FileId, RunnableKind, TestId}; | 4 | use ra_ide::{FileId, RunnableKind, TestId}; |
5 | use ra_project_model::{self, ProjectWorkspace, TargetKind}; | 5 | use ra_project_model::{self, ProjectWorkspace, TargetKind}; |
6 | 6 | ||
7 | use crate::{world::WorldSnapshot, Result}; | 7 | use crate::{global_state::GlobalStateSnapshot, Result}; |
8 | 8 | ||
9 | /// Abstract representation of Cargo target. | 9 | /// Abstract representation of Cargo target. |
10 | /// | 10 | /// |
@@ -89,7 +89,7 @@ impl CargoTargetSpec { | |||
89 | } | 89 | } |
90 | 90 | ||
91 | pub(crate) fn for_file( | 91 | pub(crate) fn for_file( |
92 | world: &WorldSnapshot, | 92 | world: &GlobalStateSnapshot, |
93 | file_id: FileId, | 93 | file_id: FileId, |
94 | ) -> Result<Option<CargoTargetSpec>> { | 94 | ) -> Result<Option<CargoTargetSpec>> { |
95 | let &crate_id = match world.analysis().crate_for(file_id)?.first() { | 95 | let &crate_id = match world.analysis().crate_for(file_id)?.first() { |
diff --git a/crates/rust-analyzer/src/from_proto.rs b/crates/rust-analyzer/src/from_proto.rs index 4bb16a496..206673829 100644 --- a/crates/rust-analyzer/src/from_proto.rs +++ b/crates/rust-analyzer/src/from_proto.rs | |||
@@ -3,7 +3,7 @@ use ra_db::{FileId, FilePosition, FileRange}; | |||
3 | use ra_ide::{LineCol, LineIndex}; | 3 | use ra_ide::{LineCol, LineIndex}; |
4 | use ra_syntax::{TextRange, TextSize}; | 4 | use ra_syntax::{TextRange, TextSize}; |
5 | 5 | ||
6 | use crate::{world::WorldSnapshot, Result}; | 6 | use crate::{global_state::GlobalStateSnapshot, Result}; |
7 | 7 | ||
8 | pub(crate) fn offset(line_index: &LineIndex, position: lsp_types::Position) -> TextSize { | 8 | pub(crate) fn offset(line_index: &LineIndex, position: lsp_types::Position) -> TextSize { |
9 | let line_col = LineCol { line: position.line as u32, col_utf16: position.character as u32 }; | 9 | let line_col = LineCol { line: position.line as u32, col_utf16: position.character as u32 }; |
@@ -16,12 +16,12 @@ pub(crate) fn text_range(line_index: &LineIndex, range: lsp_types::Range) -> Tex | |||
16 | TextRange::new(start, end) | 16 | TextRange::new(start, end) |
17 | } | 17 | } |
18 | 18 | ||
19 | pub(crate) fn file_id(world: &WorldSnapshot, url: &lsp_types::Url) -> Result<FileId> { | 19 | pub(crate) fn file_id(world: &GlobalStateSnapshot, url: &lsp_types::Url) -> Result<FileId> { |
20 | world.uri_to_file_id(url) | 20 | world.uri_to_file_id(url) |
21 | } | 21 | } |
22 | 22 | ||
23 | pub(crate) fn file_position( | 23 | pub(crate) fn file_position( |
24 | world: &WorldSnapshot, | 24 | world: &GlobalStateSnapshot, |
25 | tdpp: lsp_types::TextDocumentPositionParams, | 25 | tdpp: lsp_types::TextDocumentPositionParams, |
26 | ) -> Result<FilePosition> { | 26 | ) -> Result<FilePosition> { |
27 | let file_id = file_id(world, &tdpp.text_document.uri)?; | 27 | let file_id = file_id(world, &tdpp.text_document.uri)?; |
@@ -31,7 +31,7 @@ pub(crate) fn file_position( | |||
31 | } | 31 | } |
32 | 32 | ||
33 | pub(crate) fn file_range( | 33 | pub(crate) fn file_range( |
34 | world: &WorldSnapshot, | 34 | world: &GlobalStateSnapshot, |
35 | text_document_identifier: lsp_types::TextDocumentIdentifier, | 35 | text_document_identifier: lsp_types::TextDocumentIdentifier, |
36 | range: lsp_types::Range, | 36 | range: lsp_types::Range, |
37 | ) -> Result<FileRange> { | 37 | ) -> Result<FileRange> { |
diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/global_state.rs index c1010e86a..0bebb5bf6 100644 --- a/crates/rust-analyzer/src/world.rs +++ b/crates/rust-analyzer/src/global_state.rs | |||
@@ -50,13 +50,13 @@ fn create_flycheck(workspaces: &[ProjectWorkspace], config: &FlycheckConfig) -> | |||
50 | }) | 50 | }) |
51 | } | 51 | } |
52 | 52 | ||
53 | /// `WorldState` is the primary mutable state of the language server | 53 | /// `GlobalState` is the primary mutable state of the language server |
54 | /// | 54 | /// |
55 | /// The most interesting components are `vfs`, which stores a consistent | 55 | /// The most interesting components are `vfs`, which stores a consistent |
56 | /// snapshot of the file systems, and `analysis_host`, which stores our | 56 | /// snapshot of the file systems, and `analysis_host`, which stores our |
57 | /// incremental salsa database. | 57 | /// incremental salsa database. |
58 | #[derive(Debug)] | 58 | #[derive(Debug)] |
59 | pub struct WorldState { | 59 | pub struct GlobalState { |
60 | pub config: Config, | 60 | pub config: Config, |
61 | pub local_roots: Vec<PathBuf>, | 61 | pub local_roots: Vec<PathBuf>, |
62 | pub workspaces: Arc<Vec<ProjectWorkspace>>, | 62 | pub workspaces: Arc<Vec<ProjectWorkspace>>, |
@@ -70,7 +70,7 @@ pub struct WorldState { | |||
70 | } | 70 | } |
71 | 71 | ||
72 | /// An immutable snapshot of the world's state at a point in time. | 72 | /// An immutable snapshot of the world's state at a point in time. |
73 | pub struct WorldSnapshot { | 73 | pub struct GlobalStateSnapshot { |
74 | pub config: Config, | 74 | pub config: Config, |
75 | pub workspaces: Arc<Vec<ProjectWorkspace>>, | 75 | pub workspaces: Arc<Vec<ProjectWorkspace>>, |
76 | pub analysis: Analysis, | 76 | pub analysis: Analysis, |
@@ -79,14 +79,14 @@ pub struct WorldSnapshot { | |||
79 | vfs: Arc<RwLock<Vfs>>, | 79 | vfs: Arc<RwLock<Vfs>>, |
80 | } | 80 | } |
81 | 81 | ||
82 | impl WorldState { | 82 | impl GlobalState { |
83 | pub fn new( | 83 | pub fn new( |
84 | workspaces: Vec<ProjectWorkspace>, | 84 | workspaces: Vec<ProjectWorkspace>, |
85 | lru_capacity: Option<usize>, | 85 | lru_capacity: Option<usize>, |
86 | exclude_globs: &[Glob], | 86 | exclude_globs: &[Glob], |
87 | watch: Watch, | 87 | watch: Watch, |
88 | config: Config, | 88 | config: Config, |
89 | ) -> WorldState { | 89 | ) -> GlobalState { |
90 | let mut change = AnalysisChange::new(); | 90 | let mut change = AnalysisChange::new(); |
91 | 91 | ||
92 | let extern_dirs: FxHashSet<_> = | 92 | let extern_dirs: FxHashSet<_> = |
@@ -180,7 +180,7 @@ impl WorldState { | |||
180 | 180 | ||
181 | let mut analysis_host = AnalysisHost::new(lru_capacity); | 181 | let mut analysis_host = AnalysisHost::new(lru_capacity); |
182 | analysis_host.apply_change(change); | 182 | analysis_host.apply_change(change); |
183 | WorldState { | 183 | GlobalState { |
184 | config, | 184 | config, |
185 | local_roots, | 185 | local_roots, |
186 | workspaces: Arc::new(workspaces), | 186 | workspaces: Arc::new(workspaces), |
@@ -255,8 +255,8 @@ impl WorldState { | |||
255 | self.analysis_host.apply_change(change); | 255 | self.analysis_host.apply_change(change); |
256 | } | 256 | } |
257 | 257 | ||
258 | pub fn snapshot(&self) -> WorldSnapshot { | 258 | pub fn snapshot(&self) -> GlobalStateSnapshot { |
259 | WorldSnapshot { | 259 | GlobalStateSnapshot { |
260 | config: self.config.clone(), | 260 | config: self.config.clone(), |
261 | workspaces: Arc::clone(&self.workspaces), | 261 | workspaces: Arc::clone(&self.workspaces), |
262 | analysis: self.analysis_host.analysis(), | 262 | analysis: self.analysis_host.analysis(), |
@@ -279,7 +279,7 @@ impl WorldState { | |||
279 | } | 279 | } |
280 | } | 280 | } |
281 | 281 | ||
282 | impl WorldSnapshot { | 282 | impl GlobalStateSnapshot { |
283 | pub fn analysis(&self) -> &Analysis { | 283 | pub fn analysis(&self) -> &Analysis { |
284 | &self.analysis | 284 | &self.analysis |
285 | } | 285 | } |
diff --git a/crates/rust-analyzer/src/lib.rs b/crates/rust-analyzer/src/lib.rs index 57d0e9218..609cb69d3 100644 --- a/crates/rust-analyzer/src/lib.rs +++ b/crates/rust-analyzer/src/lib.rs | |||
@@ -26,7 +26,7 @@ mod main_loop; | |||
26 | mod markdown; | 26 | mod markdown; |
27 | pub mod lsp_ext; | 27 | pub mod lsp_ext; |
28 | pub mod config; | 28 | pub mod config; |
29 | mod world; | 29 | mod global_state; |
30 | mod diagnostics; | 30 | mod diagnostics; |
31 | mod semantic_tokens; | 31 | mod semantic_tokens; |
32 | 32 | ||
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 2e5499485..35f2d7001 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -38,12 +38,13 @@ use threadpool::ThreadPool; | |||
38 | use crate::{ | 38 | use crate::{ |
39 | config::{Config, FilesWatcher}, | 39 | config::{Config, FilesWatcher}, |
40 | diagnostics::{to_proto::url_from_path_with_drive_lowercasing, DiagnosticTask}, | 40 | diagnostics::{to_proto::url_from_path_with_drive_lowercasing, DiagnosticTask}, |
41 | from_proto, lsp_ext, | 41 | from_proto, |
42 | global_state::{GlobalState, GlobalStateSnapshot}, | ||
43 | lsp_ext, | ||
42 | main_loop::{ | 44 | main_loop::{ |
43 | pending_requests::{PendingRequest, PendingRequests}, | 45 | pending_requests::{PendingRequest, PendingRequests}, |
44 | subscriptions::Subscriptions, | 46 | subscriptions::Subscriptions, |
45 | }, | 47 | }, |
46 | world::{WorldSnapshot, WorldState}, | ||
47 | Result, | 48 | Result, |
48 | }; | 49 | }; |
49 | 50 | ||
@@ -92,7 +93,7 @@ pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection) | |||
92 | } | 93 | } |
93 | 94 | ||
94 | let mut loop_state = LoopState::default(); | 95 | let mut loop_state = LoopState::default(); |
95 | let mut world_state = { | 96 | let mut global_state = { |
96 | let workspaces = { | 97 | let workspaces = { |
97 | // FIXME: support dynamic workspace loading. | 98 | // FIXME: support dynamic workspace loading. |
98 | let project_roots: FxHashSet<_> = ws_roots | 99 | let project_roots: FxHashSet<_> = ws_roots |
@@ -163,7 +164,7 @@ pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection) | |||
163 | connection.sender.send(request.into()).unwrap(); | 164 | connection.sender.send(request.into()).unwrap(); |
164 | } | 165 | } |
165 | 166 | ||
166 | WorldState::new( | 167 | GlobalState::new( |
167 | workspaces, | 168 | workspaces, |
168 | config.lru_capacity, | 169 | config.lru_capacity, |
169 | &globs, | 170 | &globs, |
@@ -172,7 +173,7 @@ pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection) | |||
172 | ) | 173 | ) |
173 | }; | 174 | }; |
174 | 175 | ||
175 | loop_state.roots_total = world_state.vfs.read().n_roots(); | 176 | loop_state.roots_total = global_state.vfs.read().n_roots(); |
176 | 177 | ||
177 | let pool = ThreadPool::default(); | 178 | let pool = ThreadPool::default(); |
178 | let (task_sender, task_receiver) = unbounded::<Task>(); | 179 | let (task_sender, task_receiver) = unbounded::<Task>(); |
@@ -190,12 +191,12 @@ pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection) | |||
190 | Err(RecvError) => return Err("client exited without shutdown".into()), | 191 | Err(RecvError) => return Err("client exited without shutdown".into()), |
191 | }, | 192 | }, |
192 | recv(task_receiver) -> task => Event::Task(task.unwrap()), | 193 | recv(task_receiver) -> task => Event::Task(task.unwrap()), |
193 | recv(world_state.task_receiver) -> task => match task { | 194 | recv(global_state.task_receiver) -> task => match task { |
194 | Ok(task) => Event::Vfs(task), | 195 | Ok(task) => Event::Vfs(task), |
195 | Err(RecvError) => return Err("vfs died".into()), | 196 | Err(RecvError) => return Err("vfs died".into()), |
196 | }, | 197 | }, |
197 | recv(libdata_receiver) -> data => Event::Lib(data.unwrap()), | 198 | recv(libdata_receiver) -> data => Event::Lib(data.unwrap()), |
198 | recv(world_state.flycheck.as_ref().map_or(&never(), |it| &it.task_recv)) -> task => match task { | 199 | recv(global_state.flycheck.as_ref().map_or(&never(), |it| &it.task_recv)) -> task => match task { |
199 | Ok(task) => Event::CheckWatcher(task), | 200 | Ok(task) => Event::CheckWatcher(task), |
200 | Err(RecvError) => return Err("check watcher died".into()), | 201 | Err(RecvError) => return Err("check watcher died".into()), |
201 | } | 202 | } |
@@ -210,16 +211,16 @@ pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection) | |||
210 | &task_sender, | 211 | &task_sender, |
211 | &libdata_sender, | 212 | &libdata_sender, |
212 | &connection, | 213 | &connection, |
213 | &mut world_state, | 214 | &mut global_state, |
214 | &mut loop_state, | 215 | &mut loop_state, |
215 | event, | 216 | event, |
216 | )?; | 217 | )?; |
217 | } | 218 | } |
218 | } | 219 | } |
219 | world_state.analysis_host.request_cancellation(); | 220 | global_state.analysis_host.request_cancellation(); |
220 | log::info!("waiting for tasks to finish..."); | 221 | log::info!("waiting for tasks to finish..."); |
221 | task_receiver.into_iter().for_each(|task| { | 222 | task_receiver.into_iter().for_each(|task| { |
222 | on_task(task, &connection.sender, &mut loop_state.pending_requests, &mut world_state) | 223 | on_task(task, &connection.sender, &mut loop_state.pending_requests, &mut global_state) |
223 | }); | 224 | }); |
224 | libdata_receiver.into_iter().for_each(drop); | 225 | libdata_receiver.into_iter().for_each(drop); |
225 | log::info!("...tasks have finished"); | 226 | log::info!("...tasks have finished"); |
@@ -228,7 +229,7 @@ pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection) | |||
228 | drop(pool); | 229 | drop(pool); |
229 | log::info!("...threadpool has finished"); | 230 | log::info!("...threadpool has finished"); |
230 | 231 | ||
231 | let vfs = Arc::try_unwrap(world_state.vfs).expect("all snapshots should be dead"); | 232 | let vfs = Arc::try_unwrap(global_state.vfs).expect("all snapshots should be dead"); |
232 | drop(vfs); | 233 | drop(vfs); |
233 | 234 | ||
234 | Ok(()) | 235 | Ok(()) |
@@ -319,7 +320,7 @@ fn loop_turn( | |||
319 | task_sender: &Sender<Task>, | 320 | task_sender: &Sender<Task>, |
320 | libdata_sender: &Sender<LibraryData>, | 321 | libdata_sender: &Sender<LibraryData>, |
321 | connection: &Connection, | 322 | connection: &Connection, |
322 | world_state: &mut WorldState, | 323 | global_state: &mut GlobalState, |
323 | loop_state: &mut LoopState, | 324 | loop_state: &mut LoopState, |
324 | event: Event, | 325 | event: Event, |
325 | ) -> Result<()> { | 326 | ) -> Result<()> { |
@@ -335,22 +336,22 @@ fn loop_turn( | |||
335 | 336 | ||
336 | match event { | 337 | match event { |
337 | Event::Task(task) => { | 338 | Event::Task(task) => { |
338 | on_task(task, &connection.sender, &mut loop_state.pending_requests, world_state); | 339 | on_task(task, &connection.sender, &mut loop_state.pending_requests, global_state); |
339 | world_state.maybe_collect_garbage(); | 340 | global_state.maybe_collect_garbage(); |
340 | } | 341 | } |
341 | Event::Vfs(task) => { | 342 | Event::Vfs(task) => { |
342 | world_state.vfs.write().handle_task(task); | 343 | global_state.vfs.write().handle_task(task); |
343 | } | 344 | } |
344 | Event::Lib(lib) => { | 345 | Event::Lib(lib) => { |
345 | world_state.add_lib(lib); | 346 | global_state.add_lib(lib); |
346 | world_state.maybe_collect_garbage(); | 347 | global_state.maybe_collect_garbage(); |
347 | loop_state.in_flight_libraries -= 1; | 348 | loop_state.in_flight_libraries -= 1; |
348 | loop_state.roots_scanned += 1; | 349 | loop_state.roots_scanned += 1; |
349 | } | 350 | } |
350 | Event::CheckWatcher(task) => on_check_task(task, world_state, task_sender)?, | 351 | Event::CheckWatcher(task) => on_check_task(task, global_state, task_sender)?, |
351 | Event::Msg(msg) => match msg { | 352 | Event::Msg(msg) => match msg { |
352 | Message::Request(req) => on_request( | 353 | Message::Request(req) => on_request( |
353 | world_state, | 354 | global_state, |
354 | &mut loop_state.pending_requests, | 355 | &mut loop_state.pending_requests, |
355 | pool, | 356 | pool, |
356 | task_sender, | 357 | task_sender, |
@@ -359,7 +360,7 @@ fn loop_turn( | |||
359 | req, | 360 | req, |
360 | )?, | 361 | )?, |
361 | Message::Notification(not) => { | 362 | Message::Notification(not) => { |
362 | on_notification(&connection.sender, world_state, loop_state, not)?; | 363 | on_notification(&connection.sender, global_state, loop_state, not)?; |
363 | } | 364 | } |
364 | Message::Response(resp) => { | 365 | Message::Response(resp) => { |
365 | let removed = loop_state.pending_responses.remove(&resp.id); | 366 | let removed = loop_state.pending_responses.remove(&resp.id); |
@@ -378,9 +379,9 @@ fn loop_turn( | |||
378 | } | 379 | } |
379 | (None, Some(configs)) => { | 380 | (None, Some(configs)) => { |
380 | if let Some(new_config) = configs.get(0) { | 381 | if let Some(new_config) = configs.get(0) { |
381 | let mut config = world_state.config.clone(); | 382 | let mut config = global_state.config.clone(); |
382 | config.update(&new_config); | 383 | config.update(&new_config); |
383 | world_state.update_configuration(config); | 384 | global_state.update_configuration(config); |
384 | } | 385 | } |
385 | } | 386 | } |
386 | (None, None) => { | 387 | (None, None) => { |
@@ -393,7 +394,7 @@ fn loop_turn( | |||
393 | }; | 394 | }; |
394 | 395 | ||
395 | let mut state_changed = false; | 396 | let mut state_changed = false; |
396 | if let Some(changes) = world_state.process_changes(&mut loop_state.roots_scanned) { | 397 | if let Some(changes) = global_state.process_changes(&mut loop_state.roots_scanned) { |
397 | state_changed = true; | 398 | state_changed = true; |
398 | loop_state.pending_libraries.extend(changes); | 399 | loop_state.pending_libraries.extend(changes); |
399 | } | 400 | } |
@@ -415,7 +416,7 @@ fn loop_turn( | |||
415 | } | 416 | } |
416 | 417 | ||
417 | let show_progress = | 418 | let show_progress = |
418 | !loop_state.workspace_loaded && world_state.config.client_caps.work_done_progress; | 419 | !loop_state.workspace_loaded && global_state.config.client_caps.work_done_progress; |
419 | 420 | ||
420 | if !loop_state.workspace_loaded | 421 | if !loop_state.workspace_loaded |
421 | && loop_state.roots_scanned == loop_state.roots_total | 422 | && loop_state.roots_scanned == loop_state.roots_total |
@@ -424,7 +425,7 @@ fn loop_turn( | |||
424 | { | 425 | { |
425 | state_changed = true; | 426 | state_changed = true; |
426 | loop_state.workspace_loaded = true; | 427 | loop_state.workspace_loaded = true; |
427 | if let Some(flycheck) = &world_state.flycheck { | 428 | if let Some(flycheck) = &global_state.flycheck { |
428 | flycheck.update(); | 429 | flycheck.update(); |
429 | } | 430 | } |
430 | } | 431 | } |
@@ -436,13 +437,13 @@ fn loop_turn( | |||
436 | if state_changed && loop_state.workspace_loaded { | 437 | if state_changed && loop_state.workspace_loaded { |
437 | update_file_notifications_on_threadpool( | 438 | update_file_notifications_on_threadpool( |
438 | pool, | 439 | pool, |
439 | world_state.snapshot(), | 440 | global_state.snapshot(), |
440 | task_sender.clone(), | 441 | task_sender.clone(), |
441 | loop_state.subscriptions.subscriptions(), | 442 | loop_state.subscriptions.subscriptions(), |
442 | ); | 443 | ); |
443 | pool.execute({ | 444 | pool.execute({ |
444 | let subs = loop_state.subscriptions.subscriptions(); | 445 | let subs = loop_state.subscriptions.subscriptions(); |
445 | let snap = world_state.snapshot(); | 446 | let snap = global_state.snapshot(); |
446 | move || snap.analysis().prime_caches(subs).unwrap_or_else(|_: Canceled| ()) | 447 | move || snap.analysis().prime_caches(subs).unwrap_or_else(|_: Canceled| ()) |
447 | }); | 448 | }); |
448 | } | 449 | } |
@@ -466,7 +467,7 @@ fn on_task( | |||
466 | task: Task, | 467 | task: Task, |
467 | msg_sender: &Sender<Message>, | 468 | msg_sender: &Sender<Message>, |
468 | pending_requests: &mut PendingRequests, | 469 | pending_requests: &mut PendingRequests, |
469 | state: &mut WorldState, | 470 | state: &mut GlobalState, |
470 | ) { | 471 | ) { |
471 | match task { | 472 | match task { |
472 | Task::Respond(response) => { | 473 | Task::Respond(response) => { |
@@ -484,7 +485,7 @@ fn on_task( | |||
484 | } | 485 | } |
485 | 486 | ||
486 | fn on_request( | 487 | fn on_request( |
487 | world: &mut WorldState, | 488 | global_state: &mut GlobalState, |
488 | pending_requests: &mut PendingRequests, | 489 | pending_requests: &mut PendingRequests, |
489 | pool: &ThreadPool, | 490 | pool: &ThreadPool, |
490 | task_sender: &Sender<Task>, | 491 | task_sender: &Sender<Task>, |
@@ -495,7 +496,7 @@ fn on_request( | |||
495 | let mut pool_dispatcher = PoolDispatcher { | 496 | let mut pool_dispatcher = PoolDispatcher { |
496 | req: Some(req), | 497 | req: Some(req), |
497 | pool, | 498 | pool, |
498 | world, | 499 | global_state, |
499 | task_sender, | 500 | task_sender, |
500 | msg_sender, | 501 | msg_sender, |
501 | pending_requests, | 502 | pending_requests, |
@@ -551,7 +552,7 @@ fn on_request( | |||
551 | 552 | ||
552 | fn on_notification( | 553 | fn on_notification( |
553 | msg_sender: &Sender<Message>, | 554 | msg_sender: &Sender<Message>, |
554 | state: &mut WorldState, | 555 | state: &mut GlobalState, |
555 | loop_state: &mut LoopState, | 556 | loop_state: &mut LoopState, |
556 | not: Notification, | 557 | not: Notification, |
557 | ) -> Result<()> { | 558 | ) -> Result<()> { |
@@ -725,7 +726,7 @@ fn apply_document_changes( | |||
725 | 726 | ||
726 | fn on_check_task( | 727 | fn on_check_task( |
727 | task: CheckTask, | 728 | task: CheckTask, |
728 | world_state: &mut WorldState, | 729 | global_state: &mut GlobalState, |
729 | task_sender: &Sender<Task>, | 730 | task_sender: &Sender<Task>, |
730 | ) -> Result<()> { | 731 | ) -> Result<()> { |
731 | match task { | 732 | match task { |
@@ -744,7 +745,7 @@ fn on_check_task( | |||
744 | .uri | 745 | .uri |
745 | .to_file_path() | 746 | .to_file_path() |
746 | .map_err(|()| format!("invalid uri: {}", diag.location.uri))?; | 747 | .map_err(|()| format!("invalid uri: {}", diag.location.uri))?; |
747 | let file_id = match world_state.vfs.read().path2file(&path) { | 748 | let file_id = match global_state.vfs.read().path2file(&path) { |
748 | Some(file) => FileId(file.0), | 749 | Some(file) => FileId(file.0), |
749 | None => { | 750 | None => { |
750 | log::error!( | 751 | log::error!( |
@@ -764,7 +765,7 @@ fn on_check_task( | |||
764 | } | 765 | } |
765 | 766 | ||
766 | CheckTask::Status(status) => { | 767 | CheckTask::Status(status) => { |
767 | if world_state.config.client_caps.work_done_progress { | 768 | if global_state.config.client_caps.work_done_progress { |
768 | let progress = match status { | 769 | let progress = match status { |
769 | Status::Being => { | 770 | Status::Being => { |
770 | lsp_types::WorkDoneProgress::Begin(lsp_types::WorkDoneProgressBegin { | 771 | lsp_types::WorkDoneProgress::Begin(lsp_types::WorkDoneProgressBegin { |
@@ -803,7 +804,7 @@ fn on_check_task( | |||
803 | Ok(()) | 804 | Ok(()) |
804 | } | 805 | } |
805 | 806 | ||
806 | fn on_diagnostic_task(task: DiagnosticTask, msg_sender: &Sender<Message>, state: &mut WorldState) { | 807 | fn on_diagnostic_task(task: DiagnosticTask, msg_sender: &Sender<Message>, state: &mut GlobalState) { |
807 | let subscriptions = state.diagnostics.handle_task(task); | 808 | let subscriptions = state.diagnostics.handle_task(task); |
808 | 809 | ||
809 | for file_id in subscriptions { | 810 | for file_id in subscriptions { |
@@ -878,7 +879,7 @@ fn send_startup_progress(sender: &Sender<Message>, loop_state: &mut LoopState) { | |||
878 | struct PoolDispatcher<'a> { | 879 | struct PoolDispatcher<'a> { |
879 | req: Option<Request>, | 880 | req: Option<Request>, |
880 | pool: &'a ThreadPool, | 881 | pool: &'a ThreadPool, |
881 | world: &'a mut WorldState, | 882 | global_state: &'a mut GlobalState, |
882 | pending_requests: &'a mut PendingRequests, | 883 | pending_requests: &'a mut PendingRequests, |
883 | msg_sender: &'a Sender<Message>, | 884 | msg_sender: &'a Sender<Message>, |
884 | task_sender: &'a Sender<Task>, | 885 | task_sender: &'a Sender<Task>, |
@@ -889,7 +890,7 @@ impl<'a> PoolDispatcher<'a> { | |||
889 | /// Dispatches the request onto the current thread | 890 | /// Dispatches the request onto the current thread |
890 | fn on_sync<R>( | 891 | fn on_sync<R>( |
891 | &mut self, | 892 | &mut self, |
892 | f: fn(&mut WorldState, R::Params) -> Result<R::Result>, | 893 | f: fn(&mut GlobalState, R::Params) -> Result<R::Result>, |
893 | ) -> Result<&mut Self> | 894 | ) -> Result<&mut Self> |
894 | where | 895 | where |
895 | R: lsp_types::request::Request + 'static, | 896 | R: lsp_types::request::Request + 'static, |
@@ -902,18 +903,21 @@ impl<'a> PoolDispatcher<'a> { | |||
902 | return Ok(self); | 903 | return Ok(self); |
903 | } | 904 | } |
904 | }; | 905 | }; |
905 | let world = panic::AssertUnwindSafe(&mut *self.world); | 906 | let world = panic::AssertUnwindSafe(&mut *self.global_state); |
906 | let task = panic::catch_unwind(move || { | 907 | let task = panic::catch_unwind(move || { |
907 | let result = f(world.0, params); | 908 | let result = f(world.0, params); |
908 | result_to_task::<R>(id, result) | 909 | result_to_task::<R>(id, result) |
909 | }) | 910 | }) |
910 | .map_err(|_| format!("sync task {:?} panicked", R::METHOD))?; | 911 | .map_err(|_| format!("sync task {:?} panicked", R::METHOD))?; |
911 | on_task(task, self.msg_sender, self.pending_requests, self.world); | 912 | on_task(task, self.msg_sender, self.pending_requests, self.global_state); |
912 | Ok(self) | 913 | Ok(self) |
913 | } | 914 | } |
914 | 915 | ||
915 | /// Dispatches the request onto thread pool | 916 | /// Dispatches the request onto thread pool |
916 | fn on<R>(&mut self, f: fn(WorldSnapshot, R::Params) -> Result<R::Result>) -> Result<&mut Self> | 917 | fn on<R>( |
918 | &mut self, | ||
919 | f: fn(GlobalStateSnapshot, R::Params) -> Result<R::Result>, | ||
920 | ) -> Result<&mut Self> | ||
917 | where | 921 | where |
918 | R: lsp_types::request::Request + 'static, | 922 | R: lsp_types::request::Request + 'static, |
919 | R::Params: DeserializeOwned + Send + 'static, | 923 | R::Params: DeserializeOwned + Send + 'static, |
@@ -927,7 +931,7 @@ impl<'a> PoolDispatcher<'a> { | |||
927 | }; | 931 | }; |
928 | 932 | ||
929 | self.pool.execute({ | 933 | self.pool.execute({ |
930 | let world = self.world.snapshot(); | 934 | let world = self.global_state.snapshot(); |
931 | let sender = self.task_sender.clone(); | 935 | let sender = self.task_sender.clone(); |
932 | move || { | 936 | move || { |
933 | let result = f(world, params); | 937 | let result = f(world, params); |
@@ -1011,7 +1015,7 @@ where | |||
1011 | 1015 | ||
1012 | fn update_file_notifications_on_threadpool( | 1016 | fn update_file_notifications_on_threadpool( |
1013 | pool: &ThreadPool, | 1017 | pool: &ThreadPool, |
1014 | world: WorldSnapshot, | 1018 | world: GlobalStateSnapshot, |
1015 | task_sender: Sender<Task>, | 1019 | task_sender: Sender<Task>, |
1016 | subscriptions: Vec<FileId>, | 1020 | subscriptions: Vec<FileId>, |
1017 | ) { | 1021 | ) { |
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index 7fd691764..1bb8e4473 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs | |||
@@ -32,17 +32,16 @@ use crate::{ | |||
32 | config::RustfmtConfig, | 32 | config::RustfmtConfig, |
33 | diagnostics::DiagnosticTask, | 33 | diagnostics::DiagnosticTask, |
34 | from_json, from_proto, | 34 | from_json, from_proto, |
35 | global_state::GlobalStateSnapshot, | ||
35 | lsp_ext::{self, InlayHint, InlayHintsParams}, | 36 | lsp_ext::{self, InlayHint, InlayHintsParams}, |
36 | to_proto, | 37 | to_proto, LspError, Result, |
37 | world::WorldSnapshot, | ||
38 | LspError, Result, | ||
39 | }; | 38 | }; |
40 | 39 | ||
41 | pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result<String> { | 40 | pub fn handle_analyzer_status(snap: GlobalStateSnapshot, _: ()) -> Result<String> { |
42 | let _p = profile("handle_analyzer_status"); | 41 | let _p = profile("handle_analyzer_status"); |
43 | let mut buf = world.status(); | 42 | let mut buf = snap.status(); |
44 | format_to!(buf, "\n\nrequests:\n"); | 43 | format_to!(buf, "\n\nrequests:\n"); |
45 | let requests = world.latest_requests.read(); | 44 | let requests = snap.latest_requests.read(); |
46 | for (is_last, r) in requests.iter() { | 45 | for (is_last, r) in requests.iter() { |
47 | let mark = if is_last { "*" } else { " " }; | 46 | let mark = if is_last { "*" } else { " " }; |
48 | format_to!(buf, "{}{:4} {:<36}{}ms\n", mark, r.id, r.method, r.duration.as_millis()); | 47 | format_to!(buf, "{}{:4} {:<36}{}ms\n", mark, r.id, r.method, r.duration.as_millis()); |
@@ -51,37 +50,37 @@ pub fn handle_analyzer_status(world: WorldSnapshot, _: ()) -> Result<String> { | |||
51 | } | 50 | } |
52 | 51 | ||
53 | pub fn handle_syntax_tree( | 52 | pub fn handle_syntax_tree( |
54 | world: WorldSnapshot, | 53 | snap: GlobalStateSnapshot, |
55 | params: lsp_ext::SyntaxTreeParams, | 54 | params: lsp_ext::SyntaxTreeParams, |
56 | ) -> Result<String> { | 55 | ) -> Result<String> { |
57 | let _p = profile("handle_syntax_tree"); | 56 | let _p = profile("handle_syntax_tree"); |
58 | let id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 57 | let id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
59 | let line_index = world.analysis().file_line_index(id)?; | 58 | let line_index = snap.analysis().file_line_index(id)?; |
60 | let text_range = params.range.map(|r| from_proto::text_range(&line_index, r)); | 59 | let text_range = params.range.map(|r| from_proto::text_range(&line_index, r)); |
61 | let res = world.analysis().syntax_tree(id, text_range)?; | 60 | let res = snap.analysis().syntax_tree(id, text_range)?; |
62 | Ok(res) | 61 | Ok(res) |
63 | } | 62 | } |
64 | 63 | ||
65 | pub fn handle_expand_macro( | 64 | pub fn handle_expand_macro( |
66 | world: WorldSnapshot, | 65 | snap: GlobalStateSnapshot, |
67 | params: lsp_ext::ExpandMacroParams, | 66 | params: lsp_ext::ExpandMacroParams, |
68 | ) -> Result<Option<lsp_ext::ExpandedMacro>> { | 67 | ) -> Result<Option<lsp_ext::ExpandedMacro>> { |
69 | let _p = profile("handle_expand_macro"); | 68 | let _p = profile("handle_expand_macro"); |
70 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 69 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
71 | let line_index = world.analysis().file_line_index(file_id)?; | 70 | let line_index = snap.analysis().file_line_index(file_id)?; |
72 | let offset = from_proto::offset(&line_index, params.position); | 71 | let offset = from_proto::offset(&line_index, params.position); |
73 | 72 | ||
74 | let res = world.analysis().expand_macro(FilePosition { file_id, offset })?; | 73 | let res = snap.analysis().expand_macro(FilePosition { file_id, offset })?; |
75 | Ok(res.map(|it| lsp_ext::ExpandedMacro { name: it.name, expansion: it.expansion })) | 74 | Ok(res.map(|it| lsp_ext::ExpandedMacro { name: it.name, expansion: it.expansion })) |
76 | } | 75 | } |
77 | 76 | ||
78 | pub fn handle_selection_range( | 77 | pub fn handle_selection_range( |
79 | world: WorldSnapshot, | 78 | snap: GlobalStateSnapshot, |
80 | params: lsp_types::SelectionRangeParams, | 79 | params: lsp_types::SelectionRangeParams, |
81 | ) -> Result<Option<Vec<lsp_types::SelectionRange>>> { | 80 | ) -> Result<Option<Vec<lsp_types::SelectionRange>>> { |
82 | let _p = profile("handle_selection_range"); | 81 | let _p = profile("handle_selection_range"); |
83 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 82 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
84 | let line_index = world.analysis().file_line_index(file_id)?; | 83 | let line_index = snap.analysis().file_line_index(file_id)?; |
85 | let res: Result<Vec<lsp_types::SelectionRange>> = params | 84 | let res: Result<Vec<lsp_types::SelectionRange>> = params |
86 | .positions | 85 | .positions |
87 | .into_iter() | 86 | .into_iter() |
@@ -93,7 +92,7 @@ pub fn handle_selection_range( | |||
93 | loop { | 92 | loop { |
94 | ranges.push(range); | 93 | ranges.push(range); |
95 | let frange = FileRange { file_id, range }; | 94 | let frange = FileRange { file_id, range }; |
96 | let next = world.analysis().extend_selection(frange)?; | 95 | let next = snap.analysis().extend_selection(frange)?; |
97 | if next == range { | 96 | if next == range { |
98 | break; | 97 | break; |
99 | } else { | 98 | } else { |
@@ -119,18 +118,18 @@ pub fn handle_selection_range( | |||
119 | } | 118 | } |
120 | 119 | ||
121 | pub fn handle_matching_brace( | 120 | pub fn handle_matching_brace( |
122 | world: WorldSnapshot, | 121 | snap: GlobalStateSnapshot, |
123 | params: lsp_ext::MatchingBraceParams, | 122 | params: lsp_ext::MatchingBraceParams, |
124 | ) -> Result<Vec<Position>> { | 123 | ) -> Result<Vec<Position>> { |
125 | let _p = profile("handle_matching_brace"); | 124 | let _p = profile("handle_matching_brace"); |
126 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 125 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
127 | let line_index = world.analysis().file_line_index(file_id)?; | 126 | let line_index = snap.analysis().file_line_index(file_id)?; |
128 | let res = params | 127 | let res = params |
129 | .positions | 128 | .positions |
130 | .into_iter() | 129 | .into_iter() |
131 | .map(|position| { | 130 | .map(|position| { |
132 | let offset = from_proto::offset(&line_index, position); | 131 | let offset = from_proto::offset(&line_index, position); |
133 | let offset = match world.analysis().matching_brace(FilePosition { file_id, offset }) { | 132 | let offset = match snap.analysis().matching_brace(FilePosition { file_id, offset }) { |
134 | Ok(Some(matching_brace_offset)) => matching_brace_offset, | 133 | Ok(Some(matching_brace_offset)) => matching_brace_offset, |
135 | Err(_) | Ok(None) => offset, | 134 | Err(_) | Ok(None) => offset, |
136 | }; | 135 | }; |
@@ -141,17 +140,17 @@ pub fn handle_matching_brace( | |||
141 | } | 140 | } |
142 | 141 | ||
143 | pub fn handle_join_lines( | 142 | pub fn handle_join_lines( |
144 | world: WorldSnapshot, | 143 | snap: GlobalStateSnapshot, |
145 | params: lsp_ext::JoinLinesParams, | 144 | params: lsp_ext::JoinLinesParams, |
146 | ) -> Result<Vec<lsp_types::TextEdit>> { | 145 | ) -> Result<Vec<lsp_types::TextEdit>> { |
147 | let _p = profile("handle_join_lines"); | 146 | let _p = profile("handle_join_lines"); |
148 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 147 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
149 | let line_index = world.analysis().file_line_index(file_id)?; | 148 | let line_index = snap.analysis().file_line_index(file_id)?; |
150 | let line_endings = world.file_line_endings(file_id); | 149 | let line_endings = snap.file_line_endings(file_id); |
151 | let mut res = TextEdit::default(); | 150 | let mut res = TextEdit::default(); |
152 | for range in params.ranges { | 151 | for range in params.ranges { |
153 | let range = from_proto::text_range(&line_index, range); | 152 | let range = from_proto::text_range(&line_index, range); |
154 | let edit = world.analysis().join_lines(FileRange { file_id, range })?; | 153 | let edit = snap.analysis().join_lines(FileRange { file_id, range })?; |
155 | match res.union(edit) { | 154 | match res.union(edit) { |
156 | Ok(()) => (), | 155 | Ok(()) => (), |
157 | Err(_edit) => { | 156 | Err(_edit) => { |
@@ -164,37 +163,37 @@ pub fn handle_join_lines( | |||
164 | } | 163 | } |
165 | 164 | ||
166 | pub fn handle_on_enter( | 165 | pub fn handle_on_enter( |
167 | world: WorldSnapshot, | 166 | snap: GlobalStateSnapshot, |
168 | params: lsp_types::TextDocumentPositionParams, | 167 | params: lsp_types::TextDocumentPositionParams, |
169 | ) -> Result<Option<Vec<lsp_ext::SnippetTextEdit>>> { | 168 | ) -> Result<Option<Vec<lsp_ext::SnippetTextEdit>>> { |
170 | let _p = profile("handle_on_enter"); | 169 | let _p = profile("handle_on_enter"); |
171 | let position = from_proto::file_position(&world, params)?; | 170 | let position = from_proto::file_position(&snap, params)?; |
172 | let edit = match world.analysis().on_enter(position)? { | 171 | let edit = match snap.analysis().on_enter(position)? { |
173 | None => return Ok(None), | 172 | None => return Ok(None), |
174 | Some(it) => it, | 173 | Some(it) => it, |
175 | }; | 174 | }; |
176 | let line_index = world.analysis().file_line_index(position.file_id)?; | 175 | let line_index = snap.analysis().file_line_index(position.file_id)?; |
177 | let line_endings = world.file_line_endings(position.file_id); | 176 | let line_endings = snap.file_line_endings(position.file_id); |
178 | let edit = to_proto::snippet_text_edit_vec(&line_index, line_endings, true, edit); | 177 | let edit = to_proto::snippet_text_edit_vec(&line_index, line_endings, true, edit); |
179 | Ok(Some(edit)) | 178 | Ok(Some(edit)) |
180 | } | 179 | } |
181 | 180 | ||
182 | // Don't forget to add new trigger characters to `ServerCapabilities` in `caps.rs`. | 181 | // Don't forget to add new trigger characters to `ServerCapabilities` in `caps.rs`. |
183 | pub fn handle_on_type_formatting( | 182 | pub fn handle_on_type_formatting( |
184 | world: WorldSnapshot, | 183 | snap: GlobalStateSnapshot, |
185 | params: lsp_types::DocumentOnTypeFormattingParams, | 184 | params: lsp_types::DocumentOnTypeFormattingParams, |
186 | ) -> Result<Option<Vec<lsp_types::TextEdit>>> { | 185 | ) -> Result<Option<Vec<lsp_types::TextEdit>>> { |
187 | let _p = profile("handle_on_type_formatting"); | 186 | let _p = profile("handle_on_type_formatting"); |
188 | let mut position = from_proto::file_position(&world, params.text_document_position)?; | 187 | let mut position = from_proto::file_position(&snap, params.text_document_position)?; |
189 | let line_index = world.analysis().file_line_index(position.file_id)?; | 188 | let line_index = snap.analysis().file_line_index(position.file_id)?; |
190 | let line_endings = world.file_line_endings(position.file_id); | 189 | let line_endings = snap.file_line_endings(position.file_id); |
191 | 190 | ||
192 | // in `ra_ide`, the `on_type` invariant is that | 191 | // in `ra_ide`, the `on_type` invariant is that |
193 | // `text.char_at(position) == typed_char`. | 192 | // `text.char_at(position) == typed_char`. |
194 | position.offset -= TextSize::of('.'); | 193 | position.offset -= TextSize::of('.'); |
195 | let char_typed = params.ch.chars().next().unwrap_or('\0'); | 194 | let char_typed = params.ch.chars().next().unwrap_or('\0'); |
196 | assert!({ | 195 | assert!({ |
197 | let text = world.analysis().file_text(position.file_id)?; | 196 | let text = snap.analysis().file_text(position.file_id)?; |
198 | text[usize::from(position.offset)..].starts_with(char_typed) | 197 | text[usize::from(position.offset)..].starts_with(char_typed) |
199 | }); | 198 | }); |
200 | 199 | ||
@@ -206,7 +205,7 @@ pub fn handle_on_type_formatting( | |||
206 | return Ok(None); | 205 | return Ok(None); |
207 | } | 206 | } |
208 | 207 | ||
209 | let edit = world.analysis().on_char_typed(position, char_typed)?; | 208 | let edit = snap.analysis().on_char_typed(position, char_typed)?; |
210 | let mut edit = match edit { | 209 | let mut edit = match edit { |
211 | Some(it) => it, | 210 | Some(it) => it, |
212 | None => return Ok(None), | 211 | None => return Ok(None), |
@@ -220,16 +219,16 @@ pub fn handle_on_type_formatting( | |||
220 | } | 219 | } |
221 | 220 | ||
222 | pub fn handle_document_symbol( | 221 | pub fn handle_document_symbol( |
223 | world: WorldSnapshot, | 222 | snap: GlobalStateSnapshot, |
224 | params: lsp_types::DocumentSymbolParams, | 223 | params: lsp_types::DocumentSymbolParams, |
225 | ) -> Result<Option<lsp_types::DocumentSymbolResponse>> { | 224 | ) -> Result<Option<lsp_types::DocumentSymbolResponse>> { |
226 | let _p = profile("handle_document_symbol"); | 225 | let _p = profile("handle_document_symbol"); |
227 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 226 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
228 | let line_index = world.analysis().file_line_index(file_id)?; | 227 | let line_index = snap.analysis().file_line_index(file_id)?; |
229 | 228 | ||
230 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); | 229 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); |
231 | 230 | ||
232 | for symbol in world.analysis().file_structure(file_id)? { | 231 | for symbol in snap.analysis().file_structure(file_id)? { |
233 | let doc_symbol = DocumentSymbol { | 232 | let doc_symbol = DocumentSymbol { |
234 | name: symbol.label, | 233 | name: symbol.label, |
235 | detail: symbol.detail, | 234 | detail: symbol.detail, |
@@ -255,10 +254,10 @@ pub fn handle_document_symbol( | |||
255 | } | 254 | } |
256 | } | 255 | } |
257 | 256 | ||
258 | let res = if world.config.client_caps.hierarchical_symbols { | 257 | let res = if snap.config.client_caps.hierarchical_symbols { |
259 | document_symbols.into() | 258 | document_symbols.into() |
260 | } else { | 259 | } else { |
261 | let url = to_proto::url(&world, file_id)?; | 260 | let url = to_proto::url(&snap, file_id)?; |
262 | let mut symbol_information = Vec::<SymbolInformation>::new(); | 261 | let mut symbol_information = Vec::<SymbolInformation>::new(); |
263 | for symbol in document_symbols { | 262 | for symbol in document_symbols { |
264 | flatten_document_symbol(&symbol, None, &url, &mut symbol_information); | 263 | flatten_document_symbol(&symbol, None, &url, &mut symbol_information); |
@@ -288,7 +287,7 @@ pub fn handle_document_symbol( | |||
288 | } | 287 | } |
289 | 288 | ||
290 | pub fn handle_workspace_symbol( | 289 | pub fn handle_workspace_symbol( |
291 | world: WorldSnapshot, | 290 | snap: GlobalStateSnapshot, |
292 | params: lsp_types::WorkspaceSymbolParams, | 291 | params: lsp_types::WorkspaceSymbolParams, |
293 | ) -> Result<Option<Vec<SymbolInformation>>> { | 292 | ) -> Result<Option<Vec<SymbolInformation>>> { |
294 | let _p = profile("handle_workspace_symbol"); | 293 | let _p = profile("handle_workspace_symbol"); |
@@ -306,22 +305,22 @@ pub fn handle_workspace_symbol( | |||
306 | q.limit(128); | 305 | q.limit(128); |
307 | q | 306 | q |
308 | }; | 307 | }; |
309 | let mut res = exec_query(&world, query)?; | 308 | let mut res = exec_query(&snap, query)?; |
310 | if res.is_empty() && !all_symbols { | 309 | if res.is_empty() && !all_symbols { |
311 | let mut query = Query::new(params.query); | 310 | let mut query = Query::new(params.query); |
312 | query.limit(128); | 311 | query.limit(128); |
313 | res = exec_query(&world, query)?; | 312 | res = exec_query(&snap, query)?; |
314 | } | 313 | } |
315 | 314 | ||
316 | return Ok(Some(res)); | 315 | return Ok(Some(res)); |
317 | 316 | ||
318 | fn exec_query(world: &WorldSnapshot, query: Query) -> Result<Vec<SymbolInformation>> { | 317 | fn exec_query(snap: &GlobalStateSnapshot, query: Query) -> Result<Vec<SymbolInformation>> { |
319 | let mut res = Vec::new(); | 318 | let mut res = Vec::new(); |
320 | for nav in world.analysis().symbol_search(query)? { | 319 | for nav in snap.analysis().symbol_search(query)? { |
321 | let info = SymbolInformation { | 320 | let info = SymbolInformation { |
322 | name: nav.name().to_string(), | 321 | name: nav.name().to_string(), |
323 | kind: to_proto::symbol_kind(nav.kind()), | 322 | kind: to_proto::symbol_kind(nav.kind()), |
324 | location: to_proto::location(world, nav.file_range())?, | 323 | location: to_proto::location(snap, nav.file_range())?, |
325 | container_name: nav.container_name().map(|v| v.to_string()), | 324 | container_name: nav.container_name().map(|v| v.to_string()), |
326 | deprecated: None, | 325 | deprecated: None, |
327 | }; | 326 | }; |
@@ -332,73 +331,73 @@ pub fn handle_workspace_symbol( | |||
332 | } | 331 | } |
333 | 332 | ||
334 | pub fn handle_goto_definition( | 333 | pub fn handle_goto_definition( |
335 | world: WorldSnapshot, | 334 | snap: GlobalStateSnapshot, |
336 | params: lsp_types::GotoDefinitionParams, | 335 | params: lsp_types::GotoDefinitionParams, |
337 | ) -> Result<Option<lsp_types::GotoDefinitionResponse>> { | 336 | ) -> Result<Option<lsp_types::GotoDefinitionResponse>> { |
338 | let _p = profile("handle_goto_definition"); | 337 | let _p = profile("handle_goto_definition"); |
339 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 338 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
340 | let nav_info = match world.analysis().goto_definition(position)? { | 339 | let nav_info = match snap.analysis().goto_definition(position)? { |
341 | None => return Ok(None), | 340 | None => return Ok(None), |
342 | Some(it) => it, | 341 | Some(it) => it, |
343 | }; | 342 | }; |
344 | let src = FileRange { file_id: position.file_id, range: nav_info.range }; | 343 | let src = FileRange { file_id: position.file_id, range: nav_info.range }; |
345 | let res = to_proto::goto_definition_response(&world, Some(src), nav_info.info)?; | 344 | let res = to_proto::goto_definition_response(&snap, Some(src), nav_info.info)?; |
346 | Ok(Some(res)) | 345 | Ok(Some(res)) |
347 | } | 346 | } |
348 | 347 | ||
349 | pub fn handle_goto_implementation( | 348 | pub fn handle_goto_implementation( |
350 | world: WorldSnapshot, | 349 | snap: GlobalStateSnapshot, |
351 | params: lsp_types::request::GotoImplementationParams, | 350 | params: lsp_types::request::GotoImplementationParams, |
352 | ) -> Result<Option<lsp_types::request::GotoImplementationResponse>> { | 351 | ) -> Result<Option<lsp_types::request::GotoImplementationResponse>> { |
353 | let _p = profile("handle_goto_implementation"); | 352 | let _p = profile("handle_goto_implementation"); |
354 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 353 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
355 | let nav_info = match world.analysis().goto_implementation(position)? { | 354 | let nav_info = match snap.analysis().goto_implementation(position)? { |
356 | None => return Ok(None), | 355 | None => return Ok(None), |
357 | Some(it) => it, | 356 | Some(it) => it, |
358 | }; | 357 | }; |
359 | let src = FileRange { file_id: position.file_id, range: nav_info.range }; | 358 | let src = FileRange { file_id: position.file_id, range: nav_info.range }; |
360 | let res = to_proto::goto_definition_response(&world, Some(src), nav_info.info)?; | 359 | let res = to_proto::goto_definition_response(&snap, Some(src), nav_info.info)?; |
361 | Ok(Some(res)) | 360 | Ok(Some(res)) |
362 | } | 361 | } |
363 | 362 | ||
364 | pub fn handle_goto_type_definition( | 363 | pub fn handle_goto_type_definition( |
365 | world: WorldSnapshot, | 364 | snap: GlobalStateSnapshot, |
366 | params: lsp_types::request::GotoTypeDefinitionParams, | 365 | params: lsp_types::request::GotoTypeDefinitionParams, |
367 | ) -> Result<Option<lsp_types::request::GotoTypeDefinitionResponse>> { | 366 | ) -> Result<Option<lsp_types::request::GotoTypeDefinitionResponse>> { |
368 | let _p = profile("handle_goto_type_definition"); | 367 | let _p = profile("handle_goto_type_definition"); |
369 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 368 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
370 | let nav_info = match world.analysis().goto_type_definition(position)? { | 369 | let nav_info = match snap.analysis().goto_type_definition(position)? { |
371 | None => return Ok(None), | 370 | None => return Ok(None), |
372 | Some(it) => it, | 371 | Some(it) => it, |
373 | }; | 372 | }; |
374 | let src = FileRange { file_id: position.file_id, range: nav_info.range }; | 373 | let src = FileRange { file_id: position.file_id, range: nav_info.range }; |
375 | let res = to_proto::goto_definition_response(&world, Some(src), nav_info.info)?; | 374 | let res = to_proto::goto_definition_response(&snap, Some(src), nav_info.info)?; |
376 | Ok(Some(res)) | 375 | Ok(Some(res)) |
377 | } | 376 | } |
378 | 377 | ||
379 | pub fn handle_parent_module( | 378 | pub fn handle_parent_module( |
380 | world: WorldSnapshot, | 379 | snap: GlobalStateSnapshot, |
381 | params: lsp_types::TextDocumentPositionParams, | 380 | params: lsp_types::TextDocumentPositionParams, |
382 | ) -> Result<Option<lsp_types::GotoDefinitionResponse>> { | 381 | ) -> Result<Option<lsp_types::GotoDefinitionResponse>> { |
383 | let _p = profile("handle_parent_module"); | 382 | let _p = profile("handle_parent_module"); |
384 | let position = from_proto::file_position(&world, params)?; | 383 | let position = from_proto::file_position(&snap, params)?; |
385 | let navs = world.analysis().parent_module(position)?; | 384 | let navs = snap.analysis().parent_module(position)?; |
386 | let res = to_proto::goto_definition_response(&world, None, navs)?; | 385 | let res = to_proto::goto_definition_response(&snap, None, navs)?; |
387 | Ok(Some(res)) | 386 | Ok(Some(res)) |
388 | } | 387 | } |
389 | 388 | ||
390 | pub fn handle_runnables( | 389 | pub fn handle_runnables( |
391 | world: WorldSnapshot, | 390 | snap: GlobalStateSnapshot, |
392 | params: lsp_ext::RunnablesParams, | 391 | params: lsp_ext::RunnablesParams, |
393 | ) -> Result<Vec<lsp_ext::Runnable>> { | 392 | ) -> Result<Vec<lsp_ext::Runnable>> { |
394 | let _p = profile("handle_runnables"); | 393 | let _p = profile("handle_runnables"); |
395 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 394 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
396 | let line_index = world.analysis().file_line_index(file_id)?; | 395 | let line_index = snap.analysis().file_line_index(file_id)?; |
397 | let offset = params.position.map(|it| from_proto::offset(&line_index, it)); | 396 | let offset = params.position.map(|it| from_proto::offset(&line_index, it)); |
398 | let mut res = Vec::new(); | 397 | let mut res = Vec::new(); |
399 | let workspace_root = world.workspace_root_for(file_id); | 398 | let workspace_root = snap.workspace_root_for(file_id); |
400 | let cargo_spec = CargoTargetSpec::for_file(&world, file_id)?; | 399 | let cargo_spec = CargoTargetSpec::for_file(&snap, file_id)?; |
401 | for runnable in world.analysis().runnables(file_id)? { | 400 | for runnable in snap.analysis().runnables(file_id)? { |
402 | if let Some(offset) = offset { | 401 | if let Some(offset) = offset { |
403 | if !runnable.nav.full_range().contains_inclusive(offset) { | 402 | if !runnable.nav.full_range().contains_inclusive(offset) { |
404 | continue; | 403 | continue; |
@@ -413,7 +412,7 @@ pub fn handle_runnables( | |||
413 | } | 412 | } |
414 | } | 413 | } |
415 | } | 414 | } |
416 | res.push(to_proto::runnable(&world, file_id, runnable)?); | 415 | res.push(to_proto::runnable(&snap, file_id, runnable)?); |
417 | } | 416 | } |
418 | 417 | ||
419 | // Add `cargo check` and `cargo test` for the whole package | 418 | // Add `cargo check` and `cargo test` for the whole package |
@@ -453,16 +452,16 @@ pub fn handle_runnables( | |||
453 | } | 452 | } |
454 | 453 | ||
455 | pub fn handle_completion( | 454 | pub fn handle_completion( |
456 | world: WorldSnapshot, | 455 | snap: GlobalStateSnapshot, |
457 | params: lsp_types::CompletionParams, | 456 | params: lsp_types::CompletionParams, |
458 | ) -> Result<Option<lsp_types::CompletionResponse>> { | 457 | ) -> Result<Option<lsp_types::CompletionResponse>> { |
459 | let _p = profile("handle_completion"); | 458 | let _p = profile("handle_completion"); |
460 | let position = from_proto::file_position(&world, params.text_document_position)?; | 459 | let position = from_proto::file_position(&snap, params.text_document_position)?; |
461 | let completion_triggered_after_single_colon = { | 460 | let completion_triggered_after_single_colon = { |
462 | let mut res = false; | 461 | let mut res = false; |
463 | if let Some(ctx) = params.context { | 462 | if let Some(ctx) = params.context { |
464 | if ctx.trigger_character.unwrap_or_default() == ":" { | 463 | if ctx.trigger_character.unwrap_or_default() == ":" { |
465 | let source_file = world.analysis().parse(position.file_id)?; | 464 | let source_file = snap.analysis().parse(position.file_id)?; |
466 | let syntax = source_file.syntax(); | 465 | let syntax = source_file.syntax(); |
467 | let text = syntax.text(); | 466 | let text = syntax.text(); |
468 | if let Some(next_char) = text.char_at(position.offset) { | 467 | if let Some(next_char) = text.char_at(position.offset) { |
@@ -480,12 +479,12 @@ pub fn handle_completion( | |||
480 | return Ok(None); | 479 | return Ok(None); |
481 | } | 480 | } |
482 | 481 | ||
483 | let items = match world.analysis().completions(&world.config.completion, position)? { | 482 | let items = match snap.analysis().completions(&snap.config.completion, position)? { |
484 | None => return Ok(None), | 483 | None => return Ok(None), |
485 | Some(items) => items, | 484 | Some(items) => items, |
486 | }; | 485 | }; |
487 | let line_index = world.analysis().file_line_index(position.file_id)?; | 486 | let line_index = snap.analysis().file_line_index(position.file_id)?; |
488 | let line_endings = world.file_line_endings(position.file_id); | 487 | let line_endings = snap.file_line_endings(position.file_id); |
489 | let items: Vec<CompletionItem> = items | 488 | let items: Vec<CompletionItem> = items |
490 | .into_iter() | 489 | .into_iter() |
491 | .map(|item| to_proto::completion_item(&line_index, line_endings, item)) | 490 | .map(|item| to_proto::completion_item(&line_index, line_endings, item)) |
@@ -495,15 +494,15 @@ pub fn handle_completion( | |||
495 | } | 494 | } |
496 | 495 | ||
497 | pub fn handle_folding_range( | 496 | pub fn handle_folding_range( |
498 | world: WorldSnapshot, | 497 | snap: GlobalStateSnapshot, |
499 | params: FoldingRangeParams, | 498 | params: FoldingRangeParams, |
500 | ) -> Result<Option<Vec<FoldingRange>>> { | 499 | ) -> Result<Option<Vec<FoldingRange>>> { |
501 | let _p = profile("handle_folding_range"); | 500 | let _p = profile("handle_folding_range"); |
502 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 501 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
503 | let folds = world.analysis().folding_ranges(file_id)?; | 502 | let folds = snap.analysis().folding_ranges(file_id)?; |
504 | let text = world.analysis().file_text(file_id)?; | 503 | let text = snap.analysis().file_text(file_id)?; |
505 | let line_index = world.analysis().file_line_index(file_id)?; | 504 | let line_index = snap.analysis().file_line_index(file_id)?; |
506 | let line_folding_only = world.config.client_caps.line_folding_only; | 505 | let line_folding_only = snap.config.client_caps.line_folding_only; |
507 | let res = folds | 506 | let res = folds |
508 | .into_iter() | 507 | .into_iter() |
509 | .map(|it| to_proto::folding_range(&*text, &line_index, line_folding_only, it)) | 508 | .map(|it| to_proto::folding_range(&*text, &line_index, line_folding_only, it)) |
@@ -512,16 +511,16 @@ pub fn handle_folding_range( | |||
512 | } | 511 | } |
513 | 512 | ||
514 | pub fn handle_signature_help( | 513 | pub fn handle_signature_help( |
515 | world: WorldSnapshot, | 514 | snap: GlobalStateSnapshot, |
516 | params: lsp_types::SignatureHelpParams, | 515 | params: lsp_types::SignatureHelpParams, |
517 | ) -> Result<Option<lsp_types::SignatureHelp>> { | 516 | ) -> Result<Option<lsp_types::SignatureHelp>> { |
518 | let _p = profile("handle_signature_help"); | 517 | let _p = profile("handle_signature_help"); |
519 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 518 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
520 | let call_info = match world.analysis().call_info(position)? { | 519 | let call_info = match snap.analysis().call_info(position)? { |
521 | None => return Ok(None), | 520 | None => return Ok(None), |
522 | Some(it) => it, | 521 | Some(it) => it, |
523 | }; | 522 | }; |
524 | let concise = !world.config.call_info_full; | 523 | let concise = !snap.config.call_info_full; |
525 | let mut active_parameter = call_info.active_parameter.map(|it| it as i64); | 524 | let mut active_parameter = call_info.active_parameter.map(|it| it as i64); |
526 | if concise && call_info.signature.has_self_param { | 525 | if concise && call_info.signature.has_self_param { |
527 | active_parameter = active_parameter.map(|it| it.saturating_sub(1)); | 526 | active_parameter = active_parameter.map(|it| it.saturating_sub(1)); |
@@ -535,14 +534,17 @@ pub fn handle_signature_help( | |||
535 | })) | 534 | })) |
536 | } | 535 | } |
537 | 536 | ||
538 | pub fn handle_hover(world: WorldSnapshot, params: lsp_types::HoverParams) -> Result<Option<Hover>> { | 537 | pub fn handle_hover( |
538 | snap: GlobalStateSnapshot, | ||
539 | params: lsp_types::HoverParams, | ||
540 | ) -> Result<Option<Hover>> { | ||
539 | let _p = profile("handle_hover"); | 541 | let _p = profile("handle_hover"); |
540 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 542 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
541 | let info = match world.analysis().hover(position)? { | 543 | let info = match snap.analysis().hover(position)? { |
542 | None => return Ok(None), | 544 | None => return Ok(None), |
543 | Some(info) => info, | 545 | Some(info) => info, |
544 | }; | 546 | }; |
545 | let line_index = world.analysis.file_line_index(position.file_id)?; | 547 | let line_index = snap.analysis.file_line_index(position.file_id)?; |
546 | let range = to_proto::range(&line_index, info.range); | 548 | let range = to_proto::range(&line_index, info.range); |
547 | let res = Hover { | 549 | let res = Hover { |
548 | contents: HoverContents::Markup(MarkupContent { | 550 | contents: HoverContents::Markup(MarkupContent { |
@@ -555,26 +557,29 @@ pub fn handle_hover(world: WorldSnapshot, params: lsp_types::HoverParams) -> Res | |||
555 | } | 557 | } |
556 | 558 | ||
557 | pub fn handle_prepare_rename( | 559 | pub fn handle_prepare_rename( |
558 | world: WorldSnapshot, | 560 | snap: GlobalStateSnapshot, |
559 | params: lsp_types::TextDocumentPositionParams, | 561 | params: lsp_types::TextDocumentPositionParams, |
560 | ) -> Result<Option<PrepareRenameResponse>> { | 562 | ) -> Result<Option<PrepareRenameResponse>> { |
561 | let _p = profile("handle_prepare_rename"); | 563 | let _p = profile("handle_prepare_rename"); |
562 | let position = from_proto::file_position(&world, params)?; | 564 | let position = from_proto::file_position(&snap, params)?; |
563 | 565 | ||
564 | let optional_change = world.analysis().rename(position, "dummy")?; | 566 | let optional_change = snap.analysis().rename(position, "dummy")?; |
565 | let range = match optional_change { | 567 | let range = match optional_change { |
566 | None => return Ok(None), | 568 | None => return Ok(None), |
567 | Some(it) => it.range, | 569 | Some(it) => it.range, |
568 | }; | 570 | }; |
569 | 571 | ||
570 | let line_index = world.analysis().file_line_index(position.file_id)?; | 572 | let line_index = snap.analysis().file_line_index(position.file_id)?; |
571 | let range = to_proto::range(&line_index, range); | 573 | let range = to_proto::range(&line_index, range); |
572 | Ok(Some(PrepareRenameResponse::Range(range))) | 574 | Ok(Some(PrepareRenameResponse::Range(range))) |
573 | } | 575 | } |
574 | 576 | ||
575 | pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Option<WorkspaceEdit>> { | 577 | pub fn handle_rename( |
578 | snap: GlobalStateSnapshot, | ||
579 | params: RenameParams, | ||
580 | ) -> Result<Option<WorkspaceEdit>> { | ||
576 | let _p = profile("handle_rename"); | 581 | let _p = profile("handle_rename"); |
577 | let position = from_proto::file_position(&world, params.text_document_position)?; | 582 | let position = from_proto::file_position(&snap, params.text_document_position)?; |
578 | 583 | ||
579 | if params.new_name.is_empty() { | 584 | if params.new_name.is_empty() { |
580 | return Err(LspError::new( | 585 | return Err(LspError::new( |
@@ -584,36 +589,36 @@ pub fn handle_rename(world: WorldSnapshot, params: RenameParams) -> Result<Optio | |||
584 | .into()); | 589 | .into()); |
585 | } | 590 | } |
586 | 591 | ||
587 | let optional_change = world.analysis().rename(position, &*params.new_name)?; | 592 | let optional_change = snap.analysis().rename(position, &*params.new_name)?; |
588 | let source_change = match optional_change { | 593 | let source_change = match optional_change { |
589 | None => return Ok(None), | 594 | None => return Ok(None), |
590 | Some(it) => it.info, | 595 | Some(it) => it.info, |
591 | }; | 596 | }; |
592 | let workspace_edit = to_proto::workspace_edit(&world, source_change)?; | 597 | let workspace_edit = to_proto::workspace_edit(&snap, source_change)?; |
593 | Ok(Some(workspace_edit)) | 598 | Ok(Some(workspace_edit)) |
594 | } | 599 | } |
595 | 600 | ||
596 | pub fn handle_references( | 601 | pub fn handle_references( |
597 | world: WorldSnapshot, | 602 | snap: GlobalStateSnapshot, |
598 | params: lsp_types::ReferenceParams, | 603 | params: lsp_types::ReferenceParams, |
599 | ) -> Result<Option<Vec<Location>>> { | 604 | ) -> Result<Option<Vec<Location>>> { |
600 | let _p = profile("handle_references"); | 605 | let _p = profile("handle_references"); |
601 | let position = from_proto::file_position(&world, params.text_document_position)?; | 606 | let position = from_proto::file_position(&snap, params.text_document_position)?; |
602 | 607 | ||
603 | let refs = match world.analysis().find_all_refs(position, None)? { | 608 | let refs = match snap.analysis().find_all_refs(position, None)? { |
604 | None => return Ok(None), | 609 | None => return Ok(None), |
605 | Some(refs) => refs, | 610 | Some(refs) => refs, |
606 | }; | 611 | }; |
607 | 612 | ||
608 | let locations = if params.context.include_declaration { | 613 | let locations = if params.context.include_declaration { |
609 | refs.into_iter() | 614 | refs.into_iter() |
610 | .filter_map(|reference| to_proto::location(&world, reference.file_range).ok()) | 615 | .filter_map(|reference| to_proto::location(&snap, reference.file_range).ok()) |
611 | .collect() | 616 | .collect() |
612 | } else { | 617 | } else { |
613 | // Only iterate over the references if include_declaration was false | 618 | // Only iterate over the references if include_declaration was false |
614 | refs.references() | 619 | refs.references() |
615 | .iter() | 620 | .iter() |
616 | .filter_map(|reference| to_proto::location(&world, reference.file_range).ok()) | 621 | .filter_map(|reference| to_proto::location(&snap, reference.file_range).ok()) |
617 | .collect() | 622 | .collect() |
618 | }; | 623 | }; |
619 | 624 | ||
@@ -621,24 +626,24 @@ pub fn handle_references( | |||
621 | } | 626 | } |
622 | 627 | ||
623 | pub fn handle_formatting( | 628 | pub fn handle_formatting( |
624 | world: WorldSnapshot, | 629 | snap: GlobalStateSnapshot, |
625 | params: DocumentFormattingParams, | 630 | params: DocumentFormattingParams, |
626 | ) -> Result<Option<Vec<lsp_types::TextEdit>>> { | 631 | ) -> Result<Option<Vec<lsp_types::TextEdit>>> { |
627 | let _p = profile("handle_formatting"); | 632 | let _p = profile("handle_formatting"); |
628 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 633 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
629 | let file = world.analysis().file_text(file_id)?; | 634 | let file = snap.analysis().file_text(file_id)?; |
630 | let crate_ids = world.analysis().crate_for(file_id)?; | 635 | let crate_ids = snap.analysis().crate_for(file_id)?; |
631 | 636 | ||
632 | let file_line_index = world.analysis().file_line_index(file_id)?; | 637 | let file_line_index = snap.analysis().file_line_index(file_id)?; |
633 | let end_position = to_proto::position(&file_line_index, TextSize::of(file.as_str())); | 638 | let end_position = to_proto::position(&file_line_index, TextSize::of(file.as_str())); |
634 | 639 | ||
635 | let mut rustfmt = match &world.config.rustfmt { | 640 | let mut rustfmt = match &snap.config.rustfmt { |
636 | RustfmtConfig::Rustfmt { extra_args } => { | 641 | RustfmtConfig::Rustfmt { extra_args } => { |
637 | let mut cmd = process::Command::new("rustfmt"); | 642 | let mut cmd = process::Command::new("rustfmt"); |
638 | cmd.args(extra_args); | 643 | cmd.args(extra_args); |
639 | if let Some(&crate_id) = crate_ids.first() { | 644 | if let Some(&crate_id) = crate_ids.first() { |
640 | // Assume all crates are in the same edition | 645 | // Assume all crates are in the same edition |
641 | let edition = world.analysis().crate_edition(crate_id)?; | 646 | let edition = snap.analysis().crate_edition(crate_id)?; |
642 | cmd.arg("--edition"); | 647 | cmd.arg("--edition"); |
643 | cmd.arg(edition.to_string()); | 648 | cmd.arg(edition.to_string()); |
644 | } | 649 | } |
@@ -697,23 +702,23 @@ pub fn handle_formatting( | |||
697 | } | 702 | } |
698 | 703 | ||
699 | pub fn handle_code_action( | 704 | pub fn handle_code_action( |
700 | world: WorldSnapshot, | 705 | snap: GlobalStateSnapshot, |
701 | params: lsp_types::CodeActionParams, | 706 | params: lsp_types::CodeActionParams, |
702 | ) -> Result<Option<Vec<lsp_ext::CodeAction>>> { | 707 | ) -> Result<Option<Vec<lsp_ext::CodeAction>>> { |
703 | let _p = profile("handle_code_action"); | 708 | let _p = profile("handle_code_action"); |
704 | // We intentionally don't support command-based actions, as those either | 709 | // We intentionally don't support command-based actions, as those either |
705 | // requires custom client-code anyway, or requires server-initiated edits. | 710 | // requires custom client-code anyway, or requires server-initiated edits. |
706 | // Server initiated edits break causality, so we avoid those as well. | 711 | // Server initiated edits break causality, so we avoid those as well. |
707 | if !world.config.client_caps.code_action_literals { | 712 | if !snap.config.client_caps.code_action_literals { |
708 | return Ok(None); | 713 | return Ok(None); |
709 | } | 714 | } |
710 | 715 | ||
711 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 716 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
712 | let line_index = world.analysis().file_line_index(file_id)?; | 717 | let line_index = snap.analysis().file_line_index(file_id)?; |
713 | let range = from_proto::text_range(&line_index, params.range); | 718 | let range = from_proto::text_range(&line_index, params.range); |
714 | let frange = FileRange { file_id, range }; | 719 | let frange = FileRange { file_id, range }; |
715 | 720 | ||
716 | let diagnostics = world.analysis().diagnostics(file_id)?; | 721 | let diagnostics = snap.analysis().diagnostics(file_id)?; |
717 | let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); | 722 | let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); |
718 | 723 | ||
719 | let fixes_from_diagnostics = diagnostics | 724 | let fixes_from_diagnostics = diagnostics |
@@ -724,13 +729,13 @@ pub fn handle_code_action( | |||
724 | 729 | ||
725 | for fix in fixes_from_diagnostics { | 730 | for fix in fixes_from_diagnostics { |
726 | let title = fix.label; | 731 | let title = fix.label; |
727 | let edit = to_proto::snippet_workspace_edit(&world, fix.source_change)?; | 732 | let edit = to_proto::snippet_workspace_edit(&snap, fix.source_change)?; |
728 | let action = | 733 | let action = |
729 | lsp_ext::CodeAction { title, group: None, kind: None, edit: Some(edit), command: None }; | 734 | lsp_ext::CodeAction { title, group: None, kind: None, edit: Some(edit), command: None }; |
730 | res.push(action); | 735 | res.push(action); |
731 | } | 736 | } |
732 | 737 | ||
733 | for fix in world.check_fixes.get(&file_id).into_iter().flatten() { | 738 | for fix in snap.check_fixes.get(&file_id).into_iter().flatten() { |
734 | let fix_range = from_proto::text_range(&line_index, fix.range); | 739 | let fix_range = from_proto::text_range(&line_index, fix.range); |
735 | if fix_range.intersect(range).is_none() { | 740 | if fix_range.intersect(range).is_none() { |
736 | continue; | 741 | continue; |
@@ -738,31 +743,31 @@ pub fn handle_code_action( | |||
738 | res.push(fix.action.clone()); | 743 | res.push(fix.action.clone()); |
739 | } | 744 | } |
740 | 745 | ||
741 | for assist in world.analysis().assists(&world.config.assist, frange)?.into_iter() { | 746 | for assist in snap.analysis().assists(&snap.config.assist, frange)?.into_iter() { |
742 | res.push(to_proto::code_action(&world, assist)?.into()); | 747 | res.push(to_proto::code_action(&snap, assist)?.into()); |
743 | } | 748 | } |
744 | Ok(Some(res)) | 749 | Ok(Some(res)) |
745 | } | 750 | } |
746 | 751 | ||
747 | pub fn handle_code_lens( | 752 | pub fn handle_code_lens( |
748 | world: WorldSnapshot, | 753 | snap: GlobalStateSnapshot, |
749 | params: lsp_types::CodeLensParams, | 754 | params: lsp_types::CodeLensParams, |
750 | ) -> Result<Option<Vec<CodeLens>>> { | 755 | ) -> Result<Option<Vec<CodeLens>>> { |
751 | let _p = profile("handle_code_lens"); | 756 | let _p = profile("handle_code_lens"); |
752 | let mut lenses: Vec<CodeLens> = Default::default(); | 757 | let mut lenses: Vec<CodeLens> = Default::default(); |
753 | 758 | ||
754 | if world.config.lens.none() { | 759 | if snap.config.lens.none() { |
755 | // early return before any db query! | 760 | // early return before any db query! |
756 | return Ok(Some(lenses)); | 761 | return Ok(Some(lenses)); |
757 | } | 762 | } |
758 | 763 | ||
759 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 764 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
760 | let line_index = world.analysis().file_line_index(file_id)?; | 765 | let line_index = snap.analysis().file_line_index(file_id)?; |
761 | let cargo_spec = CargoTargetSpec::for_file(&world, file_id)?; | 766 | let cargo_spec = CargoTargetSpec::for_file(&snap, file_id)?; |
762 | 767 | ||
763 | if world.config.lens.runnable() { | 768 | if snap.config.lens.runnable() { |
764 | // Gather runnables | 769 | // Gather runnables |
765 | for runnable in world.analysis().runnables(file_id)? { | 770 | for runnable in snap.analysis().runnables(file_id)? { |
766 | let (run_title, debugee) = match &runnable.kind { | 771 | let (run_title, debugee) = match &runnable.kind { |
767 | RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => { | 772 | RunnableKind::Test { .. } | RunnableKind::TestMod { .. } => { |
768 | ("â–¶\u{fe0e} Run Test", true) | 773 | ("â–¶\u{fe0e} Run Test", true) |
@@ -788,8 +793,8 @@ pub fn handle_code_lens( | |||
788 | }; | 793 | }; |
789 | 794 | ||
790 | let range = to_proto::range(&line_index, runnable.nav.range()); | 795 | let range = to_proto::range(&line_index, runnable.nav.range()); |
791 | let r = to_proto::runnable(&world, file_id, runnable)?; | 796 | let r = to_proto::runnable(&snap, file_id, runnable)?; |
792 | if world.config.lens.run { | 797 | if snap.config.lens.run { |
793 | let lens = CodeLens { | 798 | let lens = CodeLens { |
794 | range, | 799 | range, |
795 | command: Some(Command { | 800 | command: Some(Command { |
@@ -802,7 +807,7 @@ pub fn handle_code_lens( | |||
802 | lenses.push(lens); | 807 | lenses.push(lens); |
803 | } | 808 | } |
804 | 809 | ||
805 | if debugee && world.config.lens.debug { | 810 | if debugee && snap.config.lens.debug { |
806 | let debug_lens = CodeLens { | 811 | let debug_lens = CodeLens { |
807 | range, | 812 | range, |
808 | command: Some(Command { | 813 | command: Some(Command { |
@@ -817,11 +822,10 @@ pub fn handle_code_lens( | |||
817 | } | 822 | } |
818 | } | 823 | } |
819 | 824 | ||
820 | if world.config.lens.impementations { | 825 | if snap.config.lens.impementations { |
821 | // Handle impls | 826 | // Handle impls |
822 | lenses.extend( | 827 | lenses.extend( |
823 | world | 828 | snap.analysis() |
824 | .analysis() | ||
825 | .file_structure(file_id)? | 829 | .file_structure(file_id)? |
826 | .into_iter() | 830 | .into_iter() |
827 | .filter(|it| match it.kind { | 831 | .filter(|it| match it.kind { |
@@ -856,14 +860,17 @@ enum CodeLensResolveData { | |||
856 | Impls(lsp_types::request::GotoImplementationParams), | 860 | Impls(lsp_types::request::GotoImplementationParams), |
857 | } | 861 | } |
858 | 862 | ||
859 | pub fn handle_code_lens_resolve(world: WorldSnapshot, code_lens: CodeLens) -> Result<CodeLens> { | 863 | pub fn handle_code_lens_resolve( |
864 | snap: GlobalStateSnapshot, | ||
865 | code_lens: CodeLens, | ||
866 | ) -> Result<CodeLens> { | ||
860 | let _p = profile("handle_code_lens_resolve"); | 867 | let _p = profile("handle_code_lens_resolve"); |
861 | let data = code_lens.data.unwrap(); | 868 | let data = code_lens.data.unwrap(); |
862 | let resolve = from_json::<Option<CodeLensResolveData>>("CodeLensResolveData", data)?; | 869 | let resolve = from_json::<Option<CodeLensResolveData>>("CodeLensResolveData", data)?; |
863 | match resolve { | 870 | match resolve { |
864 | Some(CodeLensResolveData::Impls(lens_params)) => { | 871 | Some(CodeLensResolveData::Impls(lens_params)) => { |
865 | let locations: Vec<Location> = | 872 | let locations: Vec<Location> = |
866 | match handle_goto_implementation(world, lens_params.clone())? { | 873 | match handle_goto_implementation(snap, lens_params.clone())? { |
867 | Some(lsp_types::GotoDefinitionResponse::Scalar(loc)) => vec![loc], | 874 | Some(lsp_types::GotoDefinitionResponse::Scalar(loc)) => vec![loc], |
868 | Some(lsp_types::GotoDefinitionResponse::Array(locs)) => locs, | 875 | Some(lsp_types::GotoDefinitionResponse::Array(locs)) => locs, |
869 | Some(lsp_types::GotoDefinitionResponse::Link(links)) => links | 876 | Some(lsp_types::GotoDefinitionResponse::Link(links)) => links |
@@ -902,14 +909,14 @@ pub fn handle_code_lens_resolve(world: WorldSnapshot, code_lens: CodeLens) -> Re | |||
902 | } | 909 | } |
903 | 910 | ||
904 | pub fn handle_document_highlight( | 911 | pub fn handle_document_highlight( |
905 | world: WorldSnapshot, | 912 | snap: GlobalStateSnapshot, |
906 | params: lsp_types::DocumentHighlightParams, | 913 | params: lsp_types::DocumentHighlightParams, |
907 | ) -> Result<Option<Vec<DocumentHighlight>>> { | 914 | ) -> Result<Option<Vec<DocumentHighlight>>> { |
908 | let _p = profile("handle_document_highlight"); | 915 | let _p = profile("handle_document_highlight"); |
909 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 916 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
910 | let line_index = world.analysis().file_line_index(position.file_id)?; | 917 | let line_index = snap.analysis().file_line_index(position.file_id)?; |
911 | 918 | ||
912 | let refs = match world | 919 | let refs = match snap |
913 | .analysis() | 920 | .analysis() |
914 | .find_all_refs(position, Some(SearchScope::single_file(position.file_id)))? | 921 | .find_all_refs(position, Some(SearchScope::single_file(position.file_id)))? |
915 | { | 922 | { |
@@ -929,19 +936,19 @@ pub fn handle_document_highlight( | |||
929 | } | 936 | } |
930 | 937 | ||
931 | pub fn handle_ssr( | 938 | pub fn handle_ssr( |
932 | world: WorldSnapshot, | 939 | snap: GlobalStateSnapshot, |
933 | params: lsp_ext::SsrParams, | 940 | params: lsp_ext::SsrParams, |
934 | ) -> Result<lsp_types::WorkspaceEdit> { | 941 | ) -> Result<lsp_types::WorkspaceEdit> { |
935 | let _p = profile("handle_ssr"); | 942 | let _p = profile("handle_ssr"); |
936 | let source_change = | 943 | let source_change = |
937 | world.analysis().structural_search_replace(¶ms.query, params.parse_only)??; | 944 | snap.analysis().structural_search_replace(¶ms.query, params.parse_only)??; |
938 | to_proto::workspace_edit(&world, source_change) | 945 | to_proto::workspace_edit(&snap, source_change) |
939 | } | 946 | } |
940 | 947 | ||
941 | pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<DiagnosticTask> { | 948 | pub fn publish_diagnostics(snap: &GlobalStateSnapshot, file_id: FileId) -> Result<DiagnosticTask> { |
942 | let _p = profile("publish_diagnostics"); | 949 | let _p = profile("publish_diagnostics"); |
943 | let line_index = world.analysis().file_line_index(file_id)?; | 950 | let line_index = snap.analysis().file_line_index(file_id)?; |
944 | let diagnostics: Vec<Diagnostic> = world | 951 | let diagnostics: Vec<Diagnostic> = snap |
945 | .analysis() | 952 | .analysis() |
946 | .diagnostics(file_id)? | 953 | .diagnostics(file_id)? |
947 | .into_iter() | 954 | .into_iter() |
@@ -959,28 +966,28 @@ pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<Dia | |||
959 | } | 966 | } |
960 | 967 | ||
961 | pub fn handle_inlay_hints( | 968 | pub fn handle_inlay_hints( |
962 | world: WorldSnapshot, | 969 | snap: GlobalStateSnapshot, |
963 | params: InlayHintsParams, | 970 | params: InlayHintsParams, |
964 | ) -> Result<Vec<InlayHint>> { | 971 | ) -> Result<Vec<InlayHint>> { |
965 | let _p = profile("handle_inlay_hints"); | 972 | let _p = profile("handle_inlay_hints"); |
966 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 973 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
967 | let analysis = world.analysis(); | 974 | let analysis = snap.analysis(); |
968 | let line_index = analysis.file_line_index(file_id)?; | 975 | let line_index = analysis.file_line_index(file_id)?; |
969 | Ok(analysis | 976 | Ok(analysis |
970 | .inlay_hints(file_id, &world.config.inlay_hints)? | 977 | .inlay_hints(file_id, &snap.config.inlay_hints)? |
971 | .into_iter() | 978 | .into_iter() |
972 | .map(|it| to_proto::inlay_int(&line_index, it)) | 979 | .map(|it| to_proto::inlay_int(&line_index, it)) |
973 | .collect()) | 980 | .collect()) |
974 | } | 981 | } |
975 | 982 | ||
976 | pub fn handle_call_hierarchy_prepare( | 983 | pub fn handle_call_hierarchy_prepare( |
977 | world: WorldSnapshot, | 984 | snap: GlobalStateSnapshot, |
978 | params: CallHierarchyPrepareParams, | 985 | params: CallHierarchyPrepareParams, |
979 | ) -> Result<Option<Vec<CallHierarchyItem>>> { | 986 | ) -> Result<Option<Vec<CallHierarchyItem>>> { |
980 | let _p = profile("handle_call_hierarchy_prepare"); | 987 | let _p = profile("handle_call_hierarchy_prepare"); |
981 | let position = from_proto::file_position(&world, params.text_document_position_params)?; | 988 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
982 | 989 | ||
983 | let nav_info = match world.analysis().call_hierarchy(position)? { | 990 | let nav_info = match snap.analysis().call_hierarchy(position)? { |
984 | None => return Ok(None), | 991 | None => return Ok(None), |
985 | Some(it) => it, | 992 | Some(it) => it, |
986 | }; | 993 | }; |
@@ -989,24 +996,24 @@ pub fn handle_call_hierarchy_prepare( | |||
989 | let res = navs | 996 | let res = navs |
990 | .into_iter() | 997 | .into_iter() |
991 | .filter(|it| it.kind() == SyntaxKind::FN_DEF) | 998 | .filter(|it| it.kind() == SyntaxKind::FN_DEF) |
992 | .map(|it| to_proto::call_hierarchy_item(&world, it)) | 999 | .map(|it| to_proto::call_hierarchy_item(&snap, it)) |
993 | .collect::<Result<Vec<_>>>()?; | 1000 | .collect::<Result<Vec<_>>>()?; |
994 | 1001 | ||
995 | Ok(Some(res)) | 1002 | Ok(Some(res)) |
996 | } | 1003 | } |
997 | 1004 | ||
998 | pub fn handle_call_hierarchy_incoming( | 1005 | pub fn handle_call_hierarchy_incoming( |
999 | world: WorldSnapshot, | 1006 | snap: GlobalStateSnapshot, |
1000 | params: CallHierarchyIncomingCallsParams, | 1007 | params: CallHierarchyIncomingCallsParams, |
1001 | ) -> Result<Option<Vec<CallHierarchyIncomingCall>>> { | 1008 | ) -> Result<Option<Vec<CallHierarchyIncomingCall>>> { |
1002 | let _p = profile("handle_call_hierarchy_incoming"); | 1009 | let _p = profile("handle_call_hierarchy_incoming"); |
1003 | let item = params.item; | 1010 | let item = params.item; |
1004 | 1011 | ||
1005 | let doc = TextDocumentIdentifier::new(item.uri); | 1012 | let doc = TextDocumentIdentifier::new(item.uri); |
1006 | let frange = from_proto::file_range(&world, doc, item.range)?; | 1013 | let frange = from_proto::file_range(&snap, doc, item.range)?; |
1007 | let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; | 1014 | let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; |
1008 | 1015 | ||
1009 | let call_items = match world.analysis().incoming_calls(fpos)? { | 1016 | let call_items = match snap.analysis().incoming_calls(fpos)? { |
1010 | None => return Ok(None), | 1017 | None => return Ok(None), |
1011 | Some(it) => it, | 1018 | Some(it) => it, |
1012 | }; | 1019 | }; |
@@ -1015,8 +1022,8 @@ pub fn handle_call_hierarchy_incoming( | |||
1015 | 1022 | ||
1016 | for call_item in call_items.into_iter() { | 1023 | for call_item in call_items.into_iter() { |
1017 | let file_id = call_item.target.file_id(); | 1024 | let file_id = call_item.target.file_id(); |
1018 | let line_index = world.analysis().file_line_index(file_id)?; | 1025 | let line_index = snap.analysis().file_line_index(file_id)?; |
1019 | let item = to_proto::call_hierarchy_item(&world, call_item.target)?; | 1026 | let item = to_proto::call_hierarchy_item(&snap, call_item.target)?; |
1020 | res.push(CallHierarchyIncomingCall { | 1027 | res.push(CallHierarchyIncomingCall { |
1021 | from: item, | 1028 | from: item, |
1022 | from_ranges: call_item | 1029 | from_ranges: call_item |
@@ -1031,17 +1038,17 @@ pub fn handle_call_hierarchy_incoming( | |||
1031 | } | 1038 | } |
1032 | 1039 | ||
1033 | pub fn handle_call_hierarchy_outgoing( | 1040 | pub fn handle_call_hierarchy_outgoing( |
1034 | world: WorldSnapshot, | 1041 | snap: GlobalStateSnapshot, |
1035 | params: CallHierarchyOutgoingCallsParams, | 1042 | params: CallHierarchyOutgoingCallsParams, |
1036 | ) -> Result<Option<Vec<CallHierarchyOutgoingCall>>> { | 1043 | ) -> Result<Option<Vec<CallHierarchyOutgoingCall>>> { |
1037 | let _p = profile("handle_call_hierarchy_outgoing"); | 1044 | let _p = profile("handle_call_hierarchy_outgoing"); |
1038 | let item = params.item; | 1045 | let item = params.item; |
1039 | 1046 | ||
1040 | let doc = TextDocumentIdentifier::new(item.uri); | 1047 | let doc = TextDocumentIdentifier::new(item.uri); |
1041 | let frange = from_proto::file_range(&world, doc, item.range)?; | 1048 | let frange = from_proto::file_range(&snap, doc, item.range)?; |
1042 | let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; | 1049 | let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; |
1043 | 1050 | ||
1044 | let call_items = match world.analysis().outgoing_calls(fpos)? { | 1051 | let call_items = match snap.analysis().outgoing_calls(fpos)? { |
1045 | None => return Ok(None), | 1052 | None => return Ok(None), |
1046 | Some(it) => it, | 1053 | Some(it) => it, |
1047 | }; | 1054 | }; |
@@ -1050,8 +1057,8 @@ pub fn handle_call_hierarchy_outgoing( | |||
1050 | 1057 | ||
1051 | for call_item in call_items.into_iter() { | 1058 | for call_item in call_items.into_iter() { |
1052 | let file_id = call_item.target.file_id(); | 1059 | let file_id = call_item.target.file_id(); |
1053 | let line_index = world.analysis().file_line_index(file_id)?; | 1060 | let line_index = snap.analysis().file_line_index(file_id)?; |
1054 | let item = to_proto::call_hierarchy_item(&world, call_item.target)?; | 1061 | let item = to_proto::call_hierarchy_item(&snap, call_item.target)?; |
1055 | res.push(CallHierarchyOutgoingCall { | 1062 | res.push(CallHierarchyOutgoingCall { |
1056 | to: item, | 1063 | to: item, |
1057 | from_ranges: call_item | 1064 | from_ranges: call_item |
@@ -1066,31 +1073,31 @@ pub fn handle_call_hierarchy_outgoing( | |||
1066 | } | 1073 | } |
1067 | 1074 | ||
1068 | pub fn handle_semantic_tokens( | 1075 | pub fn handle_semantic_tokens( |
1069 | world: WorldSnapshot, | 1076 | snap: GlobalStateSnapshot, |
1070 | params: SemanticTokensParams, | 1077 | params: SemanticTokensParams, |
1071 | ) -> Result<Option<SemanticTokensResult>> { | 1078 | ) -> Result<Option<SemanticTokensResult>> { |
1072 | let _p = profile("handle_semantic_tokens"); | 1079 | let _p = profile("handle_semantic_tokens"); |
1073 | 1080 | ||
1074 | let file_id = from_proto::file_id(&world, ¶ms.text_document.uri)?; | 1081 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
1075 | let text = world.analysis().file_text(file_id)?; | 1082 | let text = snap.analysis().file_text(file_id)?; |
1076 | let line_index = world.analysis().file_line_index(file_id)?; | 1083 | let line_index = snap.analysis().file_line_index(file_id)?; |
1077 | 1084 | ||
1078 | let highlights = world.analysis().highlight(file_id)?; | 1085 | let highlights = snap.analysis().highlight(file_id)?; |
1079 | let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights); | 1086 | let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights); |
1080 | Ok(Some(semantic_tokens.into())) | 1087 | Ok(Some(semantic_tokens.into())) |
1081 | } | 1088 | } |
1082 | 1089 | ||
1083 | pub fn handle_semantic_tokens_range( | 1090 | pub fn handle_semantic_tokens_range( |
1084 | world: WorldSnapshot, | 1091 | snap: GlobalStateSnapshot, |
1085 | params: SemanticTokensRangeParams, | 1092 | params: SemanticTokensRangeParams, |
1086 | ) -> Result<Option<SemanticTokensRangeResult>> { | 1093 | ) -> Result<Option<SemanticTokensRangeResult>> { |
1087 | let _p = profile("handle_semantic_tokens_range"); | 1094 | let _p = profile("handle_semantic_tokens_range"); |
1088 | 1095 | ||
1089 | let frange = from_proto::file_range(&world, params.text_document, params.range)?; | 1096 | let frange = from_proto::file_range(&snap, params.text_document, params.range)?; |
1090 | let text = world.analysis().file_text(frange.file_id)?; | 1097 | let text = snap.analysis().file_text(frange.file_id)?; |
1091 | let line_index = world.analysis().file_line_index(frange.file_id)?; | 1098 | let line_index = snap.analysis().file_line_index(frange.file_id)?; |
1092 | 1099 | ||
1093 | let highlights = world.analysis().highlight_range(frange)?; | 1100 | let highlights = snap.analysis().highlight_range(frange)?; |
1094 | let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights); | 1101 | let semantic_tokens = to_proto::semantic_tokens(&text, &line_index, highlights); |
1095 | Ok(Some(semantic_tokens.into())) | 1102 | Ok(Some(semantic_tokens.into())) |
1096 | } | 1103 | } |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 85304aa87..0915a7fcb 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -10,7 +10,8 @@ use ra_syntax::{SyntaxKind, TextRange, TextSize}; | |||
10 | use ra_vfs::LineEndings; | 10 | use ra_vfs::LineEndings; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | cargo_target_spec::CargoTargetSpec, lsp_ext, semantic_tokens, world::WorldSnapshot, Result, | 13 | cargo_target_spec::CargoTargetSpec, global_state::GlobalStateSnapshot, lsp_ext, |
14 | semantic_tokens, Result, | ||
14 | }; | 15 | }; |
15 | 16 | ||
16 | pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position { | 17 | pub(crate) fn position(line_index: &LineIndex, offset: TextSize) -> lsp_types::Position { |
@@ -384,41 +385,44 @@ pub(crate) fn folding_range( | |||
384 | } | 385 | } |
385 | } | 386 | } |
386 | 387 | ||
387 | pub(crate) fn url(world: &WorldSnapshot, file_id: FileId) -> Result<lsp_types::Url> { | 388 | pub(crate) fn url(snap: &GlobalStateSnapshot, file_id: FileId) -> Result<lsp_types::Url> { |
388 | world.file_id_to_uri(file_id) | 389 | snap.file_id_to_uri(file_id) |
389 | } | 390 | } |
390 | 391 | ||
391 | pub(crate) fn versioned_text_document_identifier( | 392 | pub(crate) fn versioned_text_document_identifier( |
392 | world: &WorldSnapshot, | 393 | snap: &GlobalStateSnapshot, |
393 | file_id: FileId, | 394 | file_id: FileId, |
394 | version: Option<i64>, | 395 | version: Option<i64>, |
395 | ) -> Result<lsp_types::VersionedTextDocumentIdentifier> { | 396 | ) -> Result<lsp_types::VersionedTextDocumentIdentifier> { |
396 | let res = lsp_types::VersionedTextDocumentIdentifier { uri: url(world, file_id)?, version }; | 397 | let res = lsp_types::VersionedTextDocumentIdentifier { uri: url(snap, file_id)?, version }; |
397 | Ok(res) | 398 | Ok(res) |
398 | } | 399 | } |
399 | 400 | ||
400 | pub(crate) fn location(world: &WorldSnapshot, frange: FileRange) -> Result<lsp_types::Location> { | 401 | pub(crate) fn location( |
401 | let url = url(world, frange.file_id)?; | 402 | snap: &GlobalStateSnapshot, |
402 | let line_index = world.analysis().file_line_index(frange.file_id)?; | 403 | frange: FileRange, |
404 | ) -> Result<lsp_types::Location> { | ||
405 | let url = url(snap, frange.file_id)?; | ||
406 | let line_index = snap.analysis().file_line_index(frange.file_id)?; | ||
403 | let range = range(&line_index, frange.range); | 407 | let range = range(&line_index, frange.range); |
404 | let loc = lsp_types::Location::new(url, range); | 408 | let loc = lsp_types::Location::new(url, range); |
405 | Ok(loc) | 409 | Ok(loc) |
406 | } | 410 | } |
407 | 411 | ||
408 | pub(crate) fn location_link( | 412 | pub(crate) fn location_link( |
409 | world: &WorldSnapshot, | 413 | snap: &GlobalStateSnapshot, |
410 | src: Option<FileRange>, | 414 | src: Option<FileRange>, |
411 | target: NavigationTarget, | 415 | target: NavigationTarget, |
412 | ) -> Result<lsp_types::LocationLink> { | 416 | ) -> Result<lsp_types::LocationLink> { |
413 | let origin_selection_range = match src { | 417 | let origin_selection_range = match src { |
414 | Some(src) => { | 418 | Some(src) => { |
415 | let line_index = world.analysis().file_line_index(src.file_id)?; | 419 | let line_index = snap.analysis().file_line_index(src.file_id)?; |
416 | let range = range(&line_index, src.range); | 420 | let range = range(&line_index, src.range); |
417 | Some(range) | 421 | Some(range) |
418 | } | 422 | } |
419 | None => None, | 423 | None => None, |
420 | }; | 424 | }; |
421 | let (target_uri, target_range, target_selection_range) = location_info(world, target)?; | 425 | let (target_uri, target_range, target_selection_range) = location_info(snap, target)?; |
422 | let res = lsp_types::LocationLink { | 426 | let res = lsp_types::LocationLink { |
423 | origin_selection_range, | 427 | origin_selection_range, |
424 | target_uri, | 428 | target_uri, |
@@ -429,12 +433,12 @@ pub(crate) fn location_link( | |||
429 | } | 433 | } |
430 | 434 | ||
431 | fn location_info( | 435 | fn location_info( |
432 | world: &WorldSnapshot, | 436 | snap: &GlobalStateSnapshot, |
433 | target: NavigationTarget, | 437 | target: NavigationTarget, |
434 | ) -> Result<(lsp_types::Url, lsp_types::Range, lsp_types::Range)> { | 438 | ) -> Result<(lsp_types::Url, lsp_types::Range, lsp_types::Range)> { |
435 | let line_index = world.analysis().file_line_index(target.file_id())?; | 439 | let line_index = snap.analysis().file_line_index(target.file_id())?; |
436 | 440 | ||
437 | let target_uri = url(world, target.file_id())?; | 441 | let target_uri = url(snap, target.file_id())?; |
438 | let target_range = range(&line_index, target.full_range()); | 442 | let target_range = range(&line_index, target.full_range()); |
439 | let target_selection_range = | 443 | let target_selection_range = |
440 | target.focus_range().map(|it| range(&line_index, it)).unwrap_or(target_range); | 444 | target.focus_range().map(|it| range(&line_index, it)).unwrap_or(target_range); |
@@ -442,14 +446,14 @@ fn location_info( | |||
442 | } | 446 | } |
443 | 447 | ||
444 | pub(crate) fn goto_definition_response( | 448 | pub(crate) fn goto_definition_response( |
445 | world: &WorldSnapshot, | 449 | snap: &GlobalStateSnapshot, |
446 | src: Option<FileRange>, | 450 | src: Option<FileRange>, |
447 | targets: Vec<NavigationTarget>, | 451 | targets: Vec<NavigationTarget>, |
448 | ) -> Result<lsp_types::GotoDefinitionResponse> { | 452 | ) -> Result<lsp_types::GotoDefinitionResponse> { |
449 | if world.config.client_caps.location_link { | 453 | if snap.config.client_caps.location_link { |
450 | let links = targets | 454 | let links = targets |
451 | .into_iter() | 455 | .into_iter() |
452 | .map(|nav| location_link(world, src, nav)) | 456 | .map(|nav| location_link(snap, src, nav)) |
453 | .collect::<Result<Vec<_>>>()?; | 457 | .collect::<Result<Vec<_>>>()?; |
454 | Ok(links.into()) | 458 | Ok(links.into()) |
455 | } else { | 459 | } else { |
@@ -457,7 +461,7 @@ pub(crate) fn goto_definition_response( | |||
457 | .into_iter() | 461 | .into_iter() |
458 | .map(|nav| { | 462 | .map(|nav| { |
459 | location( | 463 | location( |
460 | world, | 464 | snap, |
461 | FileRange { | 465 | FileRange { |
462 | file_id: nav.file_id(), | 466 | file_id: nav.file_id(), |
463 | range: nav.focus_range().unwrap_or(nav.range()), | 467 | range: nav.focus_range().unwrap_or(nav.range()), |
@@ -470,13 +474,13 @@ pub(crate) fn goto_definition_response( | |||
470 | } | 474 | } |
471 | 475 | ||
472 | pub(crate) fn snippet_text_document_edit( | 476 | pub(crate) fn snippet_text_document_edit( |
473 | world: &WorldSnapshot, | 477 | snap: &GlobalStateSnapshot, |
474 | is_snippet: bool, | 478 | is_snippet: bool, |
475 | source_file_edit: SourceFileEdit, | 479 | source_file_edit: SourceFileEdit, |
476 | ) -> Result<lsp_ext::SnippetTextDocumentEdit> { | 480 | ) -> Result<lsp_ext::SnippetTextDocumentEdit> { |
477 | let text_document = versioned_text_document_identifier(world, source_file_edit.file_id, None)?; | 481 | let text_document = versioned_text_document_identifier(snap, source_file_edit.file_id, None)?; |
478 | let line_index = world.analysis().file_line_index(source_file_edit.file_id)?; | 482 | let line_index = snap.analysis().file_line_index(source_file_edit.file_id)?; |
479 | let line_endings = world.file_line_endings(source_file_edit.file_id); | 483 | let line_endings = snap.file_line_endings(source_file_edit.file_id); |
480 | let edits = source_file_edit | 484 | let edits = source_file_edit |
481 | .edit | 485 | .edit |
482 | .into_iter() | 486 | .into_iter() |
@@ -486,17 +490,17 @@ pub(crate) fn snippet_text_document_edit( | |||
486 | } | 490 | } |
487 | 491 | ||
488 | pub(crate) fn resource_op( | 492 | pub(crate) fn resource_op( |
489 | world: &WorldSnapshot, | 493 | snap: &GlobalStateSnapshot, |
490 | file_system_edit: FileSystemEdit, | 494 | file_system_edit: FileSystemEdit, |
491 | ) -> Result<lsp_types::ResourceOp> { | 495 | ) -> Result<lsp_types::ResourceOp> { |
492 | let res = match file_system_edit { | 496 | let res = match file_system_edit { |
493 | FileSystemEdit::CreateFile { source_root, path } => { | 497 | FileSystemEdit::CreateFile { source_root, path } => { |
494 | let uri = world.path_to_uri(source_root, &path)?; | 498 | let uri = snap.path_to_uri(source_root, &path)?; |
495 | lsp_types::ResourceOp::Create(lsp_types::CreateFile { uri, options: None }) | 499 | lsp_types::ResourceOp::Create(lsp_types::CreateFile { uri, options: None }) |
496 | } | 500 | } |
497 | FileSystemEdit::MoveFile { src, dst_source_root, dst_path } => { | 501 | FileSystemEdit::MoveFile { src, dst_source_root, dst_path } => { |
498 | let old_uri = world.file_id_to_uri(src)?; | 502 | let old_uri = snap.file_id_to_uri(src)?; |
499 | let new_uri = world.path_to_uri(dst_source_root, &dst_path)?; | 503 | let new_uri = snap.path_to_uri(dst_source_root, &dst_path)?; |
500 | lsp_types::ResourceOp::Rename(lsp_types::RenameFile { old_uri, new_uri, options: None }) | 504 | lsp_types::ResourceOp::Rename(lsp_types::RenameFile { old_uri, new_uri, options: None }) |
501 | } | 505 | } |
502 | }; | 506 | }; |
@@ -504,16 +508,16 @@ pub(crate) fn resource_op( | |||
504 | } | 508 | } |
505 | 509 | ||
506 | pub(crate) fn snippet_workspace_edit( | 510 | pub(crate) fn snippet_workspace_edit( |
507 | world: &WorldSnapshot, | 511 | snap: &GlobalStateSnapshot, |
508 | source_change: SourceChange, | 512 | source_change: SourceChange, |
509 | ) -> Result<lsp_ext::SnippetWorkspaceEdit> { | 513 | ) -> Result<lsp_ext::SnippetWorkspaceEdit> { |
510 | let mut document_changes: Vec<lsp_ext::SnippetDocumentChangeOperation> = Vec::new(); | 514 | let mut document_changes: Vec<lsp_ext::SnippetDocumentChangeOperation> = Vec::new(); |
511 | for op in source_change.file_system_edits { | 515 | for op in source_change.file_system_edits { |
512 | let op = resource_op(&world, op)?; | 516 | let op = resource_op(&snap, op)?; |
513 | document_changes.push(lsp_ext::SnippetDocumentChangeOperation::Op(op)); | 517 | document_changes.push(lsp_ext::SnippetDocumentChangeOperation::Op(op)); |
514 | } | 518 | } |
515 | for edit in source_change.source_file_edits { | 519 | for edit in source_change.source_file_edits { |
516 | let edit = snippet_text_document_edit(&world, source_change.is_snippet, edit)?; | 520 | let edit = snippet_text_document_edit(&snap, source_change.is_snippet, edit)?; |
517 | document_changes.push(lsp_ext::SnippetDocumentChangeOperation::Edit(edit)); | 521 | document_changes.push(lsp_ext::SnippetDocumentChangeOperation::Edit(edit)); |
518 | } | 522 | } |
519 | let workspace_edit = | 523 | let workspace_edit = |
@@ -522,11 +526,11 @@ pub(crate) fn snippet_workspace_edit( | |||
522 | } | 526 | } |
523 | 527 | ||
524 | pub(crate) fn workspace_edit( | 528 | pub(crate) fn workspace_edit( |
525 | world: &WorldSnapshot, | 529 | snap: &GlobalStateSnapshot, |
526 | source_change: SourceChange, | 530 | source_change: SourceChange, |
527 | ) -> Result<lsp_types::WorkspaceEdit> { | 531 | ) -> Result<lsp_types::WorkspaceEdit> { |
528 | assert!(!source_change.is_snippet); | 532 | assert!(!source_change.is_snippet); |
529 | snippet_workspace_edit(world, source_change).map(|it| it.into()) | 533 | snippet_workspace_edit(snap, source_change).map(|it| it.into()) |
530 | } | 534 | } |
531 | 535 | ||
532 | impl From<lsp_ext::SnippetWorkspaceEdit> for lsp_types::WorkspaceEdit { | 536 | impl From<lsp_ext::SnippetWorkspaceEdit> for lsp_types::WorkspaceEdit { |
@@ -565,13 +569,13 @@ impl From<lsp_ext::SnippetWorkspaceEdit> for lsp_types::WorkspaceEdit { | |||
565 | } | 569 | } |
566 | 570 | ||
567 | pub fn call_hierarchy_item( | 571 | pub fn call_hierarchy_item( |
568 | world: &WorldSnapshot, | 572 | snap: &GlobalStateSnapshot, |
569 | target: NavigationTarget, | 573 | target: NavigationTarget, |
570 | ) -> Result<lsp_types::CallHierarchyItem> { | 574 | ) -> Result<lsp_types::CallHierarchyItem> { |
571 | let name = target.name().to_string(); | 575 | let name = target.name().to_string(); |
572 | let detail = target.description().map(|it| it.to_string()); | 576 | let detail = target.description().map(|it| it.to_string()); |
573 | let kind = symbol_kind(target.kind()); | 577 | let kind = symbol_kind(target.kind()); |
574 | let (uri, range, selection_range) = location_info(world, target)?; | 578 | let (uri, range, selection_range) = location_info(snap, target)?; |
575 | Ok(lsp_types::CallHierarchyItem { name, kind, tags: None, detail, uri, range, selection_range }) | 579 | Ok(lsp_types::CallHierarchyItem { name, kind, tags: None, detail, uri, range, selection_range }) |
576 | } | 580 | } |
577 | 581 | ||
@@ -619,23 +623,26 @@ fn main() <fold>{ | |||
619 | } | 623 | } |
620 | } | 624 | } |
621 | 625 | ||
622 | pub(crate) fn code_action(world: &WorldSnapshot, assist: Assist) -> Result<lsp_ext::CodeAction> { | 626 | pub(crate) fn code_action( |
627 | snap: &GlobalStateSnapshot, | ||
628 | assist: Assist, | ||
629 | ) -> Result<lsp_ext::CodeAction> { | ||
623 | let res = lsp_ext::CodeAction { | 630 | let res = lsp_ext::CodeAction { |
624 | title: assist.label, | 631 | title: assist.label, |
625 | group: if world.config.client_caps.code_action_group { assist.group_label } else { None }, | 632 | group: if snap.config.client_caps.code_action_group { assist.group_label } else { None }, |
626 | kind: Some(String::new()), | 633 | kind: Some(String::new()), |
627 | edit: Some(snippet_workspace_edit(world, assist.source_change)?), | 634 | edit: Some(snippet_workspace_edit(snap, assist.source_change)?), |
628 | command: None, | 635 | command: None, |
629 | }; | 636 | }; |
630 | Ok(res) | 637 | Ok(res) |
631 | } | 638 | } |
632 | 639 | ||
633 | pub(crate) fn runnable( | 640 | pub(crate) fn runnable( |
634 | world: &WorldSnapshot, | 641 | snap: &GlobalStateSnapshot, |
635 | file_id: FileId, | 642 | file_id: FileId, |
636 | runnable: Runnable, | 643 | runnable: Runnable, |
637 | ) -> Result<lsp_ext::Runnable> { | 644 | ) -> Result<lsp_ext::Runnable> { |
638 | let spec = CargoTargetSpec::for_file(world, file_id)?; | 645 | let spec = CargoTargetSpec::for_file(snap, file_id)?; |
639 | let target = spec.as_ref().map(|s| s.target.clone()); | 646 | let target = spec.as_ref().map(|s| s.target.clone()); |
640 | let (cargo_args, executable_args) = | 647 | let (cargo_args, executable_args) = |
641 | CargoTargetSpec::runnable_args(spec, &runnable.kind, &runnable.cfg_exprs)?; | 648 | CargoTargetSpec::runnable_args(spec, &runnable.kind, &runnable.cfg_exprs)?; |
@@ -648,14 +655,14 @@ pub(crate) fn runnable( | |||
648 | target.map_or_else(|| "run binary".to_string(), |t| format!("run {}", t)) | 655 | target.map_or_else(|| "run binary".to_string(), |t| format!("run {}", t)) |
649 | } | 656 | } |
650 | }; | 657 | }; |
651 | let location = location_link(world, None, runnable.nav)?; | 658 | let location = location_link(snap, None, runnable.nav)?; |
652 | 659 | ||
653 | Ok(lsp_ext::Runnable { | 660 | Ok(lsp_ext::Runnable { |
654 | label, | 661 | label, |
655 | location: Some(location), | 662 | location: Some(location), |
656 | kind: lsp_ext::RunnableKind::Cargo, | 663 | kind: lsp_ext::RunnableKind::Cargo, |
657 | args: lsp_ext::CargoRunnable { | 664 | args: lsp_ext::CargoRunnable { |
658 | workspace_root: world.workspace_root_for(file_id).map(|root| root.to_owned()), | 665 | workspace_root: snap.workspace_root_for(file_id).map(|root| root.to_owned()), |
659 | cargo_args, | 666 | cargo_args, |
660 | executable_args, | 667 | executable_args, |
661 | }, | 668 | }, |