From 27ebe5d33e08d92c1a032dc27f19094571bd19cd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 10 Jun 2020 12:08:35 +0200 Subject: Reduce OUT_DIR special casing --- crates/ra_project_model/src/lib.rs | 20 ++++++---------- crates/rust-analyzer/src/cli/load_cargo.rs | 38 +++++++++++++++--------------- crates/rust-analyzer/src/global_state.rs | 35 +++++++++++++-------------- 3 files changed, 43 insertions(+), 50 deletions(-) (limited to 'crates') diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index c1f7e3ac5..cb0e27dce 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs @@ -47,17 +47,21 @@ pub struct PackageRoot { path: PathBuf, /// Is a member of the current workspace is_member: bool, + out_dir: Option, } impl PackageRoot { pub fn new_member(path: PathBuf) -> PackageRoot { - Self { path, is_member: true } + Self { path, is_member: true, out_dir: None } } pub fn new_non_member(path: PathBuf) -> PackageRoot { - Self { path, is_member: false } + Self { path, is_member: false, out_dir: None } } pub fn path(&self) -> &Path { &self.path } + pub fn out_dir(&self) -> Option<&Path> { + self.out_dir.as_deref() + } pub fn is_member(&self) -> bool { self.is_member } @@ -204,6 +208,7 @@ impl ProjectWorkspace { .map(|pkg| PackageRoot { path: cargo[pkg].root().to_path_buf(), is_member: cargo[pkg].is_member, + out_dir: cargo[pkg].out_dir.clone(), }) .chain(sysroot.crates().map(|krate| { PackageRoot::new_non_member(sysroot[krate].root_dir().to_path_buf()) @@ -212,17 +217,6 @@ impl ProjectWorkspace { } } - pub fn out_dirs(&self) -> Vec { - match self { - ProjectWorkspace::Json { project } => { - project.crates.iter().filter_map(|krate| krate.out_dir.as_ref()).cloned().collect() - } - ProjectWorkspace::Cargo { cargo, sysroot: _ } => { - cargo.packages().filter_map(|pkg| cargo[pkg].out_dir.as_ref()).cloned().collect() - } - } - } - pub fn proc_macro_dylib_paths(&self) -> Vec { match self { ProjectWorkspace::Json { project } => project diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index 8f2aeac77..45af96317 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs @@ -36,28 +36,28 @@ pub fn load_cargo( )?; let mut extern_dirs = FxHashSet::default(); - extern_dirs.extend(ws.out_dirs()); - - let mut project_roots = ws.to_roots(); - project_roots.extend(extern_dirs.iter().cloned().map(PackageRoot::new_non_member)); let (sender, receiver) = unbounded(); let sender = Box::new(move |t| sender.send(t).unwrap()); - let (mut vfs, roots) = Vfs::new( - project_roots - .iter() - .map(|pkg_root| { - RootEntry::new( - pkg_root.path().to_owned(), - RustPackageFilterBuilder::default() - .set_member(pkg_root.is_member()) - .into_vfs_filter(), - ) - }) - .collect(), - sender, - Watch(false), - ); + + let mut roots = Vec::new(); + let project_roots = ws.to_roots(); + for root in &project_roots { + roots.push(RootEntry::new( + root.path().to_owned(), + RustPackageFilterBuilder::default().set_member(root.is_member()).into_vfs_filter(), + )); + + if let Some(out_dir) = root.out_dir() { + extern_dirs.insert(out_dir.to_path_buf()); + roots.push(RootEntry::new( + out_dir.to_owned(), + RustPackageFilterBuilder::default().set_member(root.is_member()).into_vfs_filter(), + )) + } + } + + let (mut vfs, roots) = Vfs::new(roots, sender, Watch(false)); let source_roots = roots .into_iter() diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 73b0f881d..96d91b12d 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -89,8 +89,7 @@ impl GlobalState { ) -> GlobalState { let mut change = AnalysisChange::new(); - let extern_dirs: FxHashSet<_> = - workspaces.iter().flat_map(ProjectWorkspace::out_dirs).collect(); + let mut extern_dirs: FxHashSet = FxHashSet::default(); let mut local_roots = Vec::new(); let roots: Vec<_> = { @@ -100,22 +99,22 @@ impl GlobalState { .exclude(exclude_globs.iter().cloned()) .into_vfs_filter() }; - workspaces - .iter() - .flat_map(ProjectWorkspace::to_roots) - .map(|pkg_root| { - let path = pkg_root.path().to_owned(); - if pkg_root.is_member() { - local_roots.push(path.clone()); - } - RootEntry::new(path, create_filter(pkg_root.is_member())) - }) - .chain( - extern_dirs - .iter() - .map(|path| RootEntry::new(path.to_owned(), create_filter(false))), - ) - .collect() + let mut roots = Vec::new(); + for root in workspaces.iter().flat_map(ProjectWorkspace::to_roots) { + let path = root.path().to_owned(); + if root.is_member() { + local_roots.push(path.clone()); + } + roots.push(RootEntry::new(path, create_filter(root.is_member()))); + if let Some(out_dir) = root.out_dir() { + extern_dirs.insert(out_dir.to_path_buf()); + roots.push(RootEntry::new( + out_dir.to_path_buf(), + create_filter(root.is_member()), + )) + } + } + roots }; let (task_sender, task_receiver) = unbounded(); -- cgit v1.2.3