aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs2
-rw-r--r--crates/rust-analyzer/src/diagnostics.rs22
-rw-r--r--crates/rust-analyzer/src/diagnostics/to_proto.rs6
-rw-r--r--crates/rust-analyzer/src/global_state.rs48
-rw-r--r--crates/rust-analyzer/src/handlers.rs15
-rw-r--r--crates/rust-analyzer/src/main_loop.rs24
6 files changed, 53 insertions, 64 deletions
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index b1250f2fe..d8677c231 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -54,7 +54,7 @@ pub fn load_cargo(
54 Ok((host, vfs)) 54 Ok((host, vfs))
55} 55}
56 56
57pub(crate) fn load( 57fn load(
58 crate_graph: CrateGraph, 58 crate_graph: CrateGraph,
59 source_root_config: SourceRootConfig, 59 source_root_config: SourceRootConfig,
60 vfs: &mut vfs::Vfs, 60 vfs: &mut vfs::Vfs,
diff --git a/crates/rust-analyzer/src/diagnostics.rs b/crates/rust-analyzer/src/diagnostics.rs
index f3cdb842b..1cf50b677 100644
--- a/crates/rust-analyzer/src/diagnostics.rs
+++ b/crates/rust-analyzer/src/diagnostics.rs
@@ -3,7 +3,6 @@ pub(crate) mod to_proto;
3 3
4use std::{collections::HashMap, mem, sync::Arc}; 4use std::{collections::HashMap, mem, sync::Arc};
5 5
6use lsp_types::{Diagnostic, Range};
7use ra_ide::FileId; 6use ra_ide::FileId;
8use rustc_hash::FxHashSet; 7use rustc_hash::FxHashSet;
9 8
@@ -19,15 +18,15 @@ pub struct DiagnosticsConfig {
19 18
20#[derive(Debug, Default, Clone)] 19#[derive(Debug, Default, Clone)]
21pub(crate) struct DiagnosticCollection { 20pub(crate) struct DiagnosticCollection {
22 pub(crate) native: HashMap<FileId, Vec<Diagnostic>>, 21 pub(crate) native: HashMap<FileId, Vec<lsp_types::Diagnostic>>,
23 pub(crate) check: HashMap<FileId, Vec<Diagnostic>>, 22 pub(crate) check: HashMap<FileId, Vec<lsp_types::Diagnostic>>,
24 pub(crate) check_fixes: CheckFixes, 23 pub(crate) check_fixes: CheckFixes,
25 changes: FxHashSet<FileId>, 24 changes: FxHashSet<FileId>,
26} 25}
27 26
28#[derive(Debug, Clone)] 27#[derive(Debug, Clone)]
29pub(crate) struct Fix { 28pub(crate) struct Fix {
30 pub(crate) range: Range, 29 pub(crate) range: lsp_types::Range,
31 pub(crate) action: lsp_ext::CodeAction, 30 pub(crate) action: lsp_ext::CodeAction,
32} 31}
33 32
@@ -40,7 +39,7 @@ impl DiagnosticCollection {
40 pub(crate) fn add_check_diagnostic( 39 pub(crate) fn add_check_diagnostic(
41 &mut self, 40 &mut self,
42 file_id: FileId, 41 file_id: FileId,
43 diagnostic: Diagnostic, 42 diagnostic: lsp_types::Diagnostic,
44 fixes: Vec<lsp_ext::CodeAction>, 43 fixes: Vec<lsp_ext::CodeAction>,
45 ) { 44 ) {
46 let diagnostics = self.check.entry(file_id).or_default(); 45 let diagnostics = self.check.entry(file_id).or_default();
@@ -59,12 +58,19 @@ impl DiagnosticCollection {
59 self.changes.insert(file_id); 58 self.changes.insert(file_id);
60 } 59 }
61 60
62 pub(crate) fn set_native_diagnostics(&mut self, file_id: FileId, diagnostics: Vec<Diagnostic>) { 61 pub(crate) fn set_native_diagnostics(
62 &mut self,
63 file_id: FileId,
64 diagnostics: Vec<lsp_types::Diagnostic>,
65 ) {
63 self.native.insert(file_id, diagnostics); 66 self.native.insert(file_id, diagnostics);
64 self.changes.insert(file_id); 67 self.changes.insert(file_id);
65 } 68 }
66 69
67 pub(crate) fn diagnostics_for(&self, file_id: FileId) -> impl Iterator<Item = &Diagnostic> { 70 pub(crate) fn diagnostics_for(
71 &self,
72 file_id: FileId,
73 ) -> impl Iterator<Item = &lsp_types::Diagnostic> {
68 let native = self.native.get(&file_id).into_iter().flatten(); 74 let native = self.native.get(&file_id).into_iter().flatten();
69 let check = self.check.get(&file_id).into_iter().flatten(); 75 let check = self.check.get(&file_id).into_iter().flatten();
70 native.chain(check) 76 native.chain(check)
@@ -78,7 +84,7 @@ impl DiagnosticCollection {
78 } 84 }
79} 85}
80 86
81fn are_diagnostics_equal(left: &Diagnostic, right: &Diagnostic) -> bool { 87fn are_diagnostics_equal(left: &lsp_types::Diagnostic, right: &lsp_types::Diagnostic) -> bool {
82 left.source == right.source 88 left.source == right.source
83 && left.severity == right.severity 89 && left.severity == right.severity
84 && left.range == right.range 90 && left.range == right.range
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs
index f379f5ed0..3eed118a9 100644
--- a/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -167,9 +167,9 @@ fn map_rust_child_diagnostic(
167 167
168#[derive(Debug)] 168#[derive(Debug)]
169pub(crate) struct MappedRustDiagnostic { 169pub(crate) struct MappedRustDiagnostic {
170 pub location: Location, 170 pub(crate) location: Location,
171 pub diagnostic: Diagnostic, 171 pub(crate) diagnostic: Diagnostic,
172 pub fixes: Vec<lsp_ext::CodeAction>, 172 pub(crate) fixes: Vec<lsp_ext::CodeAction>,
173} 173}
174 174
175/// Converts a Rust root diagnostic to LSP form 175/// Converts a Rust root diagnostic to LSP form
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index a9a1d09fd..4da094083 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -12,8 +12,6 @@ use parking_lot::RwLock;
12use ra_db::{CrateId, VfsPath}; 12use 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;
16use vfs::loader::Handle as _;
17 15
18use crate::{ 16use crate::{
19 config::Config, 17 config::Config,
@@ -83,15 +81,15 @@ pub(crate) struct GlobalStateSnapshot {
83 pub(crate) check_fixes: CheckFixes, 81 pub(crate) check_fixes: CheckFixes,
84 pub(crate) latest_requests: Arc<RwLock<LatestRequests>>, 82 pub(crate) latest_requests: Arc<RwLock<LatestRequests>>,
85 vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>, 83 vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>,
86 workspaces: Arc<Vec<ProjectWorkspace>>, 84 pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>,
87} 85}
88 86
89impl GlobalState { 87impl GlobalState {
90 pub(crate) fn new(sender: Sender<lsp_server::Message>, config: Config) -> GlobalState { 88 pub(crate) fn new(sender: Sender<lsp_server::Message>, config: Config) -> GlobalState {
91 let loader = { 89 let loader = {
92 let (sender, receiver) = unbounded::<vfs::loader::Message>(); 90 let (sender, receiver) = unbounded::<vfs::loader::Message>();
93 let handle = 91 let handle: vfs_notify::NotifyHandle =
94 vfs_notify::NotifyHandle::spawn(Box::new(move |msg| sender.send(msg).unwrap())); 92 vfs::loader::Handle::spawn(Box::new(move |msg| sender.send(msg).unwrap()));
95 let handle = Box::new(handle) as Box<dyn vfs::loader::Handle>; 93 let handle = Box::new(handle) as Box<dyn vfs::loader::Handle>;
96 Handle { handle, receiver } 94 Handle { handle, receiver }
97 }; 95 };
@@ -171,14 +169,6 @@ impl GlobalState {
171 } 169 }
172 } 170 }
173 171
174 pub(crate) fn maybe_collect_garbage(&mut self) {
175 self.analysis_host.maybe_collect_garbage()
176 }
177
178 pub(crate) fn collect_garbage(&mut self) {
179 self.analysis_host.collect_garbage()
180 }
181
182 pub(crate) fn send(&mut self, message: lsp_server::Message) { 172 pub(crate) fn send(&mut self, message: lsp_server::Message) {
183 self.sender.send(message).unwrap() 173 self.sender.send(message).unwrap()
184 } 174 }
@@ -205,11 +195,7 @@ impl Drop for GlobalState {
205 195
206impl GlobalStateSnapshot { 196impl GlobalStateSnapshot {
207 pub(crate) fn url_to_file_id(&self, url: &Url) -> Result<FileId> { 197 pub(crate) fn url_to_file_id(&self, url: &Url) -> Result<FileId> {
208 let path = from_proto::abs_path(url)?; 198 url_to_file_id(&self.vfs.read().0, url)
209 let path = path.into();
210 let res =
211 self.vfs.read().0.file_id(&path).ok_or_else(|| format!("file not found: {}", path))?;
212 Ok(res)
213 } 199 }
214 200
215 pub(crate) fn file_id_to_url(&self, id: FileId) -> Url { 201 pub(crate) fn file_id_to_url(&self, id: FileId) -> Url {
@@ -242,26 +228,6 @@ impl GlobalStateSnapshot {
242 ProjectWorkspace::Json { .. } => None, 228 ProjectWorkspace::Json { .. } => None,
243 }) 229 })
244 } 230 }
245
246 pub(crate) fn status(&self) -> String {
247 let mut buf = String::new();
248 if self.workspaces.is_empty() {
249 buf.push_str("no workspaces\n")
250 } else {
251 buf.push_str("workspaces:\n");
252 for w in self.workspaces.iter() {
253 format_to!(buf, "{} packages loaded\n", w.n_packages());
254 }
255 }
256 buf.push_str("\nanalysis:\n");
257 buf.push_str(
258 &self
259 .analysis
260 .status()
261 .unwrap_or_else(|_| "Analysis retrieval was cancelled".to_owned()),
262 );
263 buf
264 }
265} 231}
266 232
267pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Url { 233pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Url {
@@ -269,3 +235,9 @@ pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Url {
269 let path = path.as_path().unwrap(); 235 let path = path.as_path().unwrap();
270 url_from_abs_path(&path) 236 url_from_abs_path(&path)
271} 237}
238
239pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Url) -> Result<FileId> {
240 let path = from_proto::vfs_path(url)?;
241 let res = vfs.file_id(&path).ok_or_else(|| format!("file not found: {}", path))?;
242 Ok(res)
243}
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 12b494496..6c21f25fe 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -39,7 +39,20 @@ use crate::{
39 39
40pub(crate) fn handle_analyzer_status(snap: GlobalStateSnapshot, _: ()) -> Result<String> { 40pub(crate) fn handle_analyzer_status(snap: GlobalStateSnapshot, _: ()) -> Result<String> {
41 let _p = profile("handle_analyzer_status"); 41 let _p = profile("handle_analyzer_status");
42 let mut buf = snap.status(); 42
43 let mut buf = String::new();
44 if snap.workspaces.is_empty() {
45 buf.push_str("no workspaces\n")
46 } else {
47 buf.push_str("workspaces:\n");
48 for w in snap.workspaces.iter() {
49 format_to!(buf, "{} packages loaded\n", w.n_packages());
50 }
51 }
52 buf.push_str("\nanalysis:\n");
53 buf.push_str(
54 &snap.analysis.status().unwrap_or_else(|_| "Analysis retrieval was cancelled".to_owned()),
55 );
43 format_to!(buf, "\n\nrequests:\n"); 56 format_to!(buf, "\n\nrequests:\n");
44 let requests = snap.latest_requests.read(); 57 let requests = snap.latest_requests.read();
45 for (is_last, r) in requests.iter() { 58 for (is_last, r) in requests.iter() {
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 386a47621..8fc816cbd 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -16,7 +16,7 @@ use crate::{
16 config::Config, 16 config::Config,
17 dispatch::{NotificationDispatcher, RequestDispatcher}, 17 dispatch::{NotificationDispatcher, RequestDispatcher},
18 from_proto, 18 from_proto,
19 global_state::{file_id_to_url, GlobalState, Status}, 19 global_state::{file_id_to_url, url_to_file_id, GlobalState, Status},
20 handlers, lsp_ext, 20 handlers, lsp_ext,
21 lsp_utils::{apply_document_changes, is_canceled, notification_is, notification_new}, 21 lsp_utils::{apply_document_changes, is_canceled, notification_is, notification_new},
22 Result, 22 Result,
@@ -158,7 +158,7 @@ impl GlobalState {
158 } 158 }
159 Task::Unit => (), 159 Task::Unit => (),
160 } 160 }
161 self.maybe_collect_garbage(); 161 self.analysis_host.maybe_collect_garbage();
162 } 162 }
163 Event::Vfs(task) => match task { 163 Event::Vfs(task) => match task {
164 vfs::loader::Message::Loaded { files } => { 164 vfs::loader::Message::Loaded { files } => {
@@ -200,18 +200,16 @@ impl GlobalState {
200 &workspace_root, 200 &workspace_root,
201 ); 201 );
202 for diag in diagnostics { 202 for diag in diagnostics {
203 let path = from_proto::vfs_path(&diag.location.uri)?; 203 match url_to_file_id(&self.vfs.read().0, &diag.location.uri) {
204 let file_id = match self.vfs.read().0.file_id(&path) { 204 Ok(file_id) => self.diagnostics.add_check_diagnostic(
205 Some(file) => FileId(file.0), 205 file_id,
206 None => { 206 diag.diagnostic,
207 log::error!( 207 diag.fixes,
208 "File with cargo diagnostic not found in VFS: {}", 208 ),
209 path 209 Err(err) => {
210 ); 210 log::error!("File with cargo diagnostic not found in VFS: {}", err);
211 return Ok(());
212 } 211 }
213 }; 212 };
214 self.diagnostics.add_check_diagnostic(file_id, diag.diagnostic, diag.fixes)
215 } 213 }
216 } 214 }
217 215
@@ -274,7 +272,7 @@ impl GlobalState {
274 self.req_queue.incoming.register(req.id.clone(), (req.method.clone(), request_received)); 272 self.req_queue.incoming.register(req.id.clone(), (req.method.clone(), request_received));
275 273
276 RequestDispatcher { req: Some(req), global_state: self } 274 RequestDispatcher { req: Some(req), global_state: self }
277 .on_sync::<lsp_ext::CollectGarbage>(|s, ()| Ok(s.collect_garbage()))? 275 .on_sync::<lsp_ext::CollectGarbage>(|s, ()| Ok(s.analysis_host.collect_garbage()))?
278 .on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))? 276 .on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))?
279 .on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))? 277 .on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))?
280 .on_sync::<lsp_types::request::Shutdown>(|_, ()| Ok(()))? 278 .on_sync::<lsp_types::request::Shutdown>(|_, ()| Ok(()))?