aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/rust-analyzer/src/dispatch.rs2
-rw-r--r--crates/rust-analyzer/src/global_state.rs38
-rw-r--r--crates/rust-analyzer/src/main_loop.rs20
-rw-r--r--crates/rust-analyzer/src/reload.rs10
4 files changed, 38 insertions, 32 deletions
diff --git a/crates/rust-analyzer/src/dispatch.rs b/crates/rust-analyzer/src/dispatch.rs
index 03b373dee..891fdb96d 100644
--- a/crates/rust-analyzer/src/dispatch.rs
+++ b/crates/rust-analyzer/src/dispatch.rs
@@ -59,7 +59,7 @@ impl<'a> RequestDispatcher<'a> {
59 } 59 }
60 }; 60 };
61 61
62 self.global_state.task_pool.0.spawn({ 62 self.global_state.task_pool.handle.spawn({
63 let world = self.global_state.snapshot(); 63 let world = self.global_state.snapshot();
64 move || { 64 move || {
65 let result = f(world, params); 65 let result = f(world, params);
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index 8486da627..17de2a075 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -13,7 +13,7 @@ use ra_db::{CrateId, VfsPath};
13use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FileId}; 13use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FileId};
14use ra_project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target}; 14use ra_project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target};
15use stdx::format_to; 15use stdx::format_to;
16use vfs::loader::Handle; 16use vfs::loader::Handle as _;
17 17
18use crate::{ 18use crate::{
19 config::Config, 19 config::Config,
@@ -42,19 +42,26 @@ impl Default for Status {
42 } 42 }
43} 43}
44 44
45// Enforces drop order
46pub(crate) struct Handle<H, C> {
47 pub(crate) handle: H,
48 pub(crate) receiver: C,
49}
50
45/// `GlobalState` is the primary mutable state of the language server 51/// `GlobalState` is the primary mutable state of the language server
46/// 52///
47/// The most interesting components are `vfs`, which stores a consistent 53/// The most interesting components are `vfs`, which stores a consistent
48/// snapshot of the file systems, and `analysis_host`, which stores our 54/// snapshot of the file systems, and `analysis_host`, which stores our
49/// incremental salsa database. 55/// incremental salsa database.
56///
57/// Note that this struct has more than on impl in various modules!
50pub(crate) struct GlobalState { 58pub(crate) struct GlobalState {
51 sender: Sender<lsp_server::Message>, 59 sender: Sender<lsp_server::Message>,
60 pub(crate) task_pool: Handle<TaskPool<Task>, Receiver<Task>>,
61 pub(crate) loader: Handle<Box<dyn vfs::loader::Handle>, Receiver<vfs::loader::Message>>,
62 pub(crate) flycheck: Option<Handle<FlycheckHandle, Receiver<flycheck::Message>>>,
52 pub(crate) config: Config, 63 pub(crate) config: Config,
53 pub(crate) task_pool: (TaskPool<Task>, Receiver<Task>),
54 pub(crate) analysis_host: AnalysisHost, 64 pub(crate) analysis_host: AnalysisHost,
55 pub(crate) loader: Box<dyn vfs::loader::Handle>,
56 pub(crate) task_receiver: Receiver<vfs::loader::Message>,
57 pub(crate) flycheck: Option<(FlycheckHandle, Receiver<flycheck::Message>)>,
58 pub(crate) diagnostics: DiagnosticCollection, 65 pub(crate) diagnostics: DiagnosticCollection,
59 pub(crate) mem_docs: FxHashSet<VfsPath>, 66 pub(crate) mem_docs: FxHashSet<VfsPath>,
60 pub(crate) vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>, 67 pub(crate) vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
@@ -82,37 +89,36 @@ impl GlobalState {
82 lru_capacity: Option<usize>, 89 lru_capacity: Option<usize>,
83 config: Config, 90 config: Config,
84 ) -> GlobalState { 91 ) -> GlobalState {
85 let (task_sender, task_receiver) = unbounded::<vfs::loader::Message>();
86
87 let loader = { 92 let loader = {
88 let loader = vfs_notify::NotifyHandle::spawn(Box::new(move |msg| { 93 let (sender, receiver) = unbounded::<vfs::loader::Message>();
89 task_sender.send(msg).unwrap() 94 let handle =
90 })); 95 vfs_notify::NotifyHandle::spawn(Box::new(move |msg| sender.send(msg).unwrap()));
91 Box::new(loader) 96 let handle = Box::new(handle) as Box<dyn vfs::loader::Handle>;
97 Handle { handle, receiver }
92 }; 98 };
93 99
94 let task_pool = { 100 let task_pool = {
95 let (sender, receiver) = unbounded(); 101 let (sender, receiver) = unbounded();
96 (TaskPool::new(sender), receiver) 102 let handle = TaskPool::new(sender);
103 Handle { handle, receiver }
97 }; 104 };
98 105
99 GlobalState { 106 GlobalState {
100 sender, 107 sender,
101 config,
102 task_pool, 108 task_pool,
103 analysis_host: AnalysisHost::new(lru_capacity),
104 loader, 109 loader,
105 task_receiver, 110 config,
111 analysis_host: AnalysisHost::new(lru_capacity),
106 flycheck: None, 112 flycheck: None,
107 diagnostics: Default::default(), 113 diagnostics: Default::default(),
108 mem_docs: FxHashSet::default(), 114 mem_docs: FxHashSet::default(),
109 vfs: Arc::new(RwLock::new((vfs::Vfs::default(), FxHashMap::default()))), 115 vfs: Arc::new(RwLock::new((vfs::Vfs::default(), FxHashMap::default()))),
110 status: Status::default(), 116 status: Status::default(),
111 req_queue: ReqQueue::default(), 117 req_queue: ReqQueue::default(),
112 latest_requests: Default::default(),
113 source_root_config: SourceRootConfig::default(), 118 source_root_config: SourceRootConfig::default(),
114 proc_macro_client: ProcMacroClient::dummy(), 119 proc_macro_client: ProcMacroClient::dummy(),
115 workspaces: Arc::new(Vec::new()), 120 workspaces: Arc::new(Vec::new()),
121 latest_requests: Default::default(),
116 } 122 }
117 } 123 }
118 124
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 6ac50745a..d4879283d 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -100,13 +100,13 @@ impl GlobalState {
100 recv(inbox) -> msg => 100 recv(inbox) -> msg =>
101 msg.ok().map(Event::Lsp), 101 msg.ok().map(Event::Lsp),
102 102
103 recv(self.task_pool.1) -> task => 103 recv(self.task_pool.receiver) -> task =>
104 Some(Event::Task(task.unwrap())), 104 Some(Event::Task(task.unwrap())),
105 105
106 recv(self.task_receiver) -> task => 106 recv(self.loader.receiver) -> task =>
107 Some(Event::Vfs(task.unwrap())), 107 Some(Event::Vfs(task.unwrap())),
108 108
109 recv(self.flycheck.as_ref().map_or(&never(), |it| &it.1)) -> task => 109 recv(self.flycheck.as_ref().map_or(&never(), |it| &it.receiver)) -> task =>
110 Some(Event::Flycheck(task.unwrap())), 110 Some(Event::Flycheck(task.unwrap())),
111 } 111 }
112 } 112 }
@@ -132,7 +132,7 @@ impl GlobalState {
132 let _p = profile("GlobalState::handle_event"); 132 let _p = profile("GlobalState::handle_event");
133 133
134 log::info!("handle_event({:?})", event); 134 log::info!("handle_event({:?})", event);
135 let queue_count = self.task_pool.0.len(); 135 let queue_count = self.task_pool.handle.len();
136 if queue_count > 0 { 136 if queue_count > 0 {
137 log::info!("queued count = {}", queue_count); 137 log::info!("queued count = {}", queue_count);
138 } 138 }
@@ -233,7 +233,7 @@ impl GlobalState {
233 let state_changed = self.process_changes(); 233 let state_changed = self.process_changes();
234 if became_ready { 234 if became_ready {
235 if let Some(flycheck) = &self.flycheck { 235 if let Some(flycheck) = &self.flycheck {
236 flycheck.0.update(); 236 flycheck.handle.update();
237 } 237 }
238 } 238 }
239 239
@@ -370,7 +370,7 @@ impl GlobalState {
370 log::error!("orphan DidCloseTextDocument: {}", path) 370 log::error!("orphan DidCloseTextDocument: {}", path)
371 } 371 }
372 if let Some(path) = path.as_path() { 372 if let Some(path) = path.as_path() {
373 this.loader.invalidate(path.to_path_buf()); 373 this.loader.handle.invalidate(path.to_path_buf());
374 } 374 }
375 } 375 }
376 let params = lsp_types::PublishDiagnosticsParams { 376 let params = lsp_types::PublishDiagnosticsParams {
@@ -384,7 +384,7 @@ impl GlobalState {
384 })? 384 })?
385 .on::<lsp_types::notification::DidSaveTextDocument>(|this, _params| { 385 .on::<lsp_types::notification::DidSaveTextDocument>(|this, _params| {
386 if let Some(flycheck) = &this.flycheck { 386 if let Some(flycheck) = &this.flycheck {
387 flycheck.0.update(); 387 flycheck.handle.update();
388 } 388 }
389 Ok(()) 389 Ok(())
390 })? 390 })?
@@ -427,7 +427,7 @@ impl GlobalState {
427 .on::<lsp_types::notification::DidChangeWatchedFiles>(|this, params| { 427 .on::<lsp_types::notification::DidChangeWatchedFiles>(|this, params| {
428 for change in params.changes { 428 for change in params.changes {
429 if let Ok(path) = from_proto::abs_path(&change.uri) { 429 if let Ok(path) = from_proto::abs_path(&change.uri) {
430 this.loader.invalidate(path); 430 this.loader.handle.invalidate(path);
431 } 431 }
432 } 432 }
433 Ok(()) 433 Ok(())
@@ -440,7 +440,7 @@ impl GlobalState {
440 if self.config.publish_diagnostics { 440 if self.config.publish_diagnostics {
441 let snapshot = self.snapshot(); 441 let snapshot = self.snapshot();
442 let subscriptions = subscriptions.clone(); 442 let subscriptions = subscriptions.clone();
443 self.task_pool.0.spawn(move || { 443 self.task_pool.handle.spawn(move || {
444 let diagnostics = subscriptions 444 let diagnostics = subscriptions
445 .into_iter() 445 .into_iter()
446 .filter_map(|file_id| { 446 .filter_map(|file_id| {
@@ -458,7 +458,7 @@ impl GlobalState {
458 Task::Diagnostics(diagnostics) 458 Task::Diagnostics(diagnostics)
459 }) 459 })
460 } 460 }
461 self.task_pool.0.spawn({ 461 self.task_pool.handle.spawn({
462 let subs = subscriptions; 462 let subs = subscriptions;
463 let snap = self.snapshot(); 463 let snap = self.snapshot();
464 move || { 464 move || {
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index 1981a97da..a22d3e262 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -11,7 +11,7 @@ use vfs::{file_set::FileSetConfig, AbsPath};
11 11
12use crate::{ 12use crate::{
13 config::{Config, FilesWatcher, LinkedProject}, 13 config::{Config, FilesWatcher, LinkedProject},
14 global_state::GlobalState, 14 global_state::{GlobalState, Handle},
15}; 15};
16 16
17impl GlobalState { 17impl GlobalState {
@@ -105,7 +105,7 @@ impl GlobalState {
105 FilesWatcher::Client => vec![], 105 FilesWatcher::Client => vec![],
106 FilesWatcher::Notify => project_folders.watch, 106 FilesWatcher::Notify => project_folders.watch,
107 }; 107 };
108 self.loader.set_config(vfs::loader::Config { load: project_folders.load, watch }); 108 self.loader.handle.set_config(vfs::loader::Config { load: project_folders.load, watch });
109 109
110 // Create crate graph from all the workspaces 110 // Create crate graph from all the workspaces
111 let crate_graph = { 111 let crate_graph = {
@@ -113,7 +113,7 @@ impl GlobalState {
113 let vfs = &mut self.vfs.write().0; 113 let vfs = &mut self.vfs.write().0;
114 let loader = &mut self.loader; 114 let loader = &mut self.loader;
115 let mut load = |path: &AbsPath| { 115 let mut load = |path: &AbsPath| {
116 let contents = loader.load_sync(path); 116 let contents = loader.handle.load_sync(path);
117 let path = vfs::VfsPath::from(path.to_path_buf()); 117 let path = vfs::VfsPath::from(path.to_path_buf());
118 vfs.set_file_contents(path.clone(), contents); 118 vfs.set_file_contents(path.clone(), contents);
119 vfs.file_id(&path) 119 vfs.file_id(&path)
@@ -153,9 +153,9 @@ impl GlobalState {
153 let (sender, receiver) = unbounded(); 153 let (sender, receiver) = unbounded();
154 let sender = Box::new(move |msg| sender.send(msg).unwrap()); 154 let sender = Box::new(move |msg| sender.send(msg).unwrap());
155 let cargo_project_root = cargo.workspace_root().to_path_buf(); 155 let cargo_project_root = cargo.workspace_root().to_path_buf();
156 let flycheck = 156 let handle =
157 FlycheckHandle::spawn(sender, config.clone(), cargo_project_root.into()); 157 FlycheckHandle::spawn(sender, config.clone(), cargo_project_root.into());
158 Some((flycheck, receiver)) 158 Some(Handle { handle, receiver })
159 } 159 }
160 ProjectWorkspace::Json { .. } => { 160 ProjectWorkspace::Json { .. } => {
161 log::warn!("Cargo check watching only supported for cargo workspaces, disabling"); 161 log::warn!("Cargo check watching only supported for cargo workspaces, disabling");