aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_project_model/src/lib.rs20
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs38
-rw-r--r--crates/rust-analyzer/src/global_state.rs35
3 files changed, 43 insertions, 50 deletions
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 {
47 path: PathBuf, 47 path: PathBuf,
48 /// Is a member of the current workspace 48 /// Is a member of the current workspace
49 is_member: bool, 49 is_member: bool,
50 out_dir: Option<PathBuf>,
50} 51}
51impl PackageRoot { 52impl PackageRoot {
52 pub fn new_member(path: PathBuf) -> PackageRoot { 53 pub fn new_member(path: PathBuf) -> PackageRoot {
53 Self { path, is_member: true } 54 Self { path, is_member: true, out_dir: None }
54 } 55 }
55 pub fn new_non_member(path: PathBuf) -> PackageRoot { 56 pub fn new_non_member(path: PathBuf) -> PackageRoot {
56 Self { path, is_member: false } 57 Self { path, is_member: false, out_dir: None }
57 } 58 }
58 pub fn path(&self) -> &Path { 59 pub fn path(&self) -> &Path {
59 &self.path 60 &self.path
60 } 61 }
62 pub fn out_dir(&self) -> Option<&Path> {
63 self.out_dir.as_deref()
64 }
61 pub fn is_member(&self) -> bool { 65 pub fn is_member(&self) -> bool {
62 self.is_member 66 self.is_member
63 } 67 }
@@ -204,6 +208,7 @@ impl ProjectWorkspace {
204 .map(|pkg| PackageRoot { 208 .map(|pkg| PackageRoot {
205 path: cargo[pkg].root().to_path_buf(), 209 path: cargo[pkg].root().to_path_buf(),
206 is_member: cargo[pkg].is_member, 210 is_member: cargo[pkg].is_member,
211 out_dir: cargo[pkg].out_dir.clone(),
207 }) 212 })
208 .chain(sysroot.crates().map(|krate| { 213 .chain(sysroot.crates().map(|krate| {
209 PackageRoot::new_non_member(sysroot[krate].root_dir().to_path_buf()) 214 PackageRoot::new_non_member(sysroot[krate].root_dir().to_path_buf())
@@ -212,17 +217,6 @@ impl ProjectWorkspace {
212 } 217 }
213 } 218 }
214 219
215 pub fn out_dirs(&self) -> Vec<PathBuf> {
216 match self {
217 ProjectWorkspace::Json { project } => {
218 project.crates.iter().filter_map(|krate| krate.out_dir.as_ref()).cloned().collect()
219 }
220 ProjectWorkspace::Cargo { cargo, sysroot: _ } => {
221 cargo.packages().filter_map(|pkg| cargo[pkg].out_dir.as_ref()).cloned().collect()
222 }
223 }
224 }
225
226 pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> { 220 pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> {
227 match self { 221 match self {
228 ProjectWorkspace::Json { project } => project 222 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(
36 )?; 36 )?;
37 37
38 let mut extern_dirs = FxHashSet::default(); 38 let mut extern_dirs = FxHashSet::default();
39 extern_dirs.extend(ws.out_dirs());
40
41 let mut project_roots = ws.to_roots();
42 project_roots.extend(extern_dirs.iter().cloned().map(PackageRoot::new_non_member));
43 39
44 let (sender, receiver) = unbounded(); 40 let (sender, receiver) = unbounded();
45 let sender = Box::new(move |t| sender.send(t).unwrap()); 41 let sender = Box::new(move |t| sender.send(t).unwrap());
46 let (mut vfs, roots) = Vfs::new( 42
47 project_roots 43 let mut roots = Vec::new();
48 .iter() 44 let project_roots = ws.to_roots();
49 .map(|pkg_root| { 45 for root in &project_roots {
50 RootEntry::new( 46 roots.push(RootEntry::new(
51 pkg_root.path().to_owned(), 47 root.path().to_owned(),
52 RustPackageFilterBuilder::default() 48 RustPackageFilterBuilder::default().set_member(root.is_member()).into_vfs_filter(),
53 .set_member(pkg_root.is_member()) 49 ));
54 .into_vfs_filter(), 50
55 ) 51 if let Some(out_dir) = root.out_dir() {
56 }) 52 extern_dirs.insert(out_dir.to_path_buf());
57 .collect(), 53 roots.push(RootEntry::new(
58 sender, 54 out_dir.to_owned(),
59 Watch(false), 55 RustPackageFilterBuilder::default().set_member(root.is_member()).into_vfs_filter(),
60 ); 56 ))
57 }
58 }
59
60 let (mut vfs, roots) = Vfs::new(roots, sender, Watch(false));
61 61
62 let source_roots = roots 62 let source_roots = roots
63 .into_iter() 63 .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 {
89 ) -> GlobalState { 89 ) -> GlobalState {
90 let mut change = AnalysisChange::new(); 90 let mut change = AnalysisChange::new();
91 91
92 let extern_dirs: FxHashSet<_> = 92 let mut extern_dirs: FxHashSet<PathBuf> = FxHashSet::default();
93 workspaces.iter().flat_map(ProjectWorkspace::out_dirs).collect();
94 93
95 let mut local_roots = Vec::new(); 94 let mut local_roots = Vec::new();
96 let roots: Vec<_> = { 95 let roots: Vec<_> = {
@@ -100,22 +99,22 @@ impl GlobalState {
100 .exclude(exclude_globs.iter().cloned()) 99 .exclude(exclude_globs.iter().cloned())
101 .into_vfs_filter() 100 .into_vfs_filter()
102 }; 101 };
103 workspaces 102 let mut roots = Vec::new();
104 .iter() 103 for root in workspaces.iter().flat_map(ProjectWorkspace::to_roots) {
105 .flat_map(ProjectWorkspace::to_roots) 104 let path = root.path().to_owned();
106 .map(|pkg_root| { 105 if root.is_member() {
107 let path = pkg_root.path().to_owned(); 106 local_roots.push(path.clone());
108 if pkg_root.is_member() { 107 }
109 local_roots.push(path.clone()); 108 roots.push(RootEntry::new(path, create_filter(root.is_member())));
110 } 109 if let Some(out_dir) = root.out_dir() {
111 RootEntry::new(path, create_filter(pkg_root.is_member())) 110 extern_dirs.insert(out_dir.to_path_buf());
112 }) 111 roots.push(RootEntry::new(
113 .chain( 112 out_dir.to_path_buf(),
114 extern_dirs 113 create_filter(root.is_member()),
115 .iter() 114 ))
116 .map(|path| RootEntry::new(path.to_owned(), create_filter(false))), 115 }
117 ) 116 }
118 .collect() 117 roots
119 }; 118 };
120 119
121 let (task_sender, task_receiver) = unbounded(); 120 let (task_sender, task_receiver) = unbounded();