diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index 85c23e4d970..9429f8f5522 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs @@ -15,6 +15,8 @@ use rayon::prelude::*; use std::{ + fmt, + path::Path, sync::{ Arc, atomic::{AtomicUsize, Ordering::SeqCst}, @@ -35,15 +37,24 @@ pub type Result = ::std::result::Result; const INDEXING_THRESHOLD: usize = 128; +pub type FileResolver = dyn Fn(FileId, &Path) -> Option + Send + Sync; + pub struct WorldState { data: Arc } -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct World { + file_resolver: Arc, data: Arc, } +impl fmt::Debug for World { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + (&*self.data).fmt(f) + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct FileId(pub u32); @@ -54,8 +65,11 @@ pub fn new() -> WorldState { } } - pub fn snapshot(&self) -> World { - World { data: self.data.clone() } + pub fn snapshot(&self, file_resolver: impl Fn(FileId, &Path) -> Option + 'static + Send + Sync) -> World { + World { + file_resolver: Arc::new(file_resolver), + data: self.data.clone() + } } pub fn change_file(&mut self, file_id: FileId, text: Option) { @@ -134,6 +148,10 @@ pub fn approximately_resolve_symbol<'a>( Ok(self.world_symbols(query).collect()) } + fn resolve_relative_path(&self, id: FileId, path: &Path) -> Option { + (self.file_resolver)(id, path) + } + fn reindex(&self) { let data = &*self.data; let unindexed = data.unindexed.load(SeqCst); diff --git a/crates/server/src/main_loop/mod.rs b/crates/server/src/main_loop/mod.rs index 1fbcc7d1f85..a8340df5911 100644 --- a/crates/server/src/main_loop/mod.rs +++ b/crates/server/src/main_loop/mod.rs @@ -167,7 +167,10 @@ fn on_request( dispatch::handle_request::(&mut req, |params, resp| { io.send(RawMsg::Response(resp.into_response(Ok(None))?)); - let world = world.snapshot(); + let world = world.snapshot({ + let pm = path_map.clone(); + move |id, path| pm.resolve(id, path) + }); let path_map = path_map.clone(); let sender = sender.clone(); pool.execute(move || { @@ -234,7 +237,14 @@ fn on_notification( mem_map.insert(file_id, None); world.change_file(file_id, Some(params.text_document.text)); update_file_notifications_on_threadpool( - pool, world.snapshot(), path_map.clone(), sender.clone(), uri, + pool, + world.snapshot({ + let pm = path_map.clone(); + move |id, path| pm.resolve(id, path) + }), + path_map.clone(), + sender.clone(), + uri, ); Ok(()) })?; @@ -245,7 +255,14 @@ fn on_notification( .text; world.change_file(file_id, Some(text)); update_file_notifications_on_threadpool( - pool, world.snapshot(), path_map.clone(), sender.clone(), params.text_document.uri, + pool, + world.snapshot({ + let pm = path_map.clone(); + move |id, path| pm.resolve(id, path) + }), + path_map.clone(), + sender.clone(), + params.text_document.uri, ); Ok(()) })?; @@ -281,7 +298,10 @@ fn handle_request_on_threadpool( ) -> Result<()> { dispatch::handle_request::(req, |params, resp| { - let world = world.snapshot(); + let world = world.snapshot({ + let pm = path_map.clone(); + move |id, path| pm.resolve(id, path) + }); let path_map = path_map.clone(); let sender = sender.clone(); pool.execute(move || { diff --git a/crates/server/src/path_map.rs b/crates/server/src/path_map.rs index 2454ba05fed..e198e165deb 100644 --- a/crates/server/src/path_map.rs +++ b/crates/server/src/path_map.rs @@ -34,6 +34,11 @@ pub fn get_path(&self, id: FileId) -> &Path { .as_path() } + pub fn resolve(&self, id: FileId, relpath: &Path) -> Option { + let path = self.get_path(id).join(relpath); + self.get_id(&path) + } + fn insert(&mut self, path: PathBuf, id: FileId) { self.path2id.insert(path.clone(), id); self.id2path.insert(id, path.clone());