aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_project_model/src/lib.rs46
-rw-r--r--crates/rust-analyzer/src/cli/analysis_bench.rs4
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs2
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs22
-rw-r--r--crates/rust-analyzer/src/main_loop.rs4
-rw-r--r--crates/rust-analyzer/src/vfs_glob.rs10
-rw-r--r--crates/rust-analyzer/src/world.rs58
7 files changed, 63 insertions, 83 deletions
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index dd9c80691..a133243b4 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -58,22 +58,16 @@ pub enum ProjectWorkspace {
58#[derive(Clone)] 58#[derive(Clone)]
59pub struct PackageRoot { 59pub struct PackageRoot {
60 /// Path to the root folder 60 /// Path to the root folder
61 path: PathBuf, 61 pub path: PathBuf,
62 /// Is a member of the current workspace 62 /// Is a member of the current workspace
63 is_member: bool, 63 pub is_member: bool,
64} 64}
65
66impl PackageRoot { 65impl PackageRoot {
67 pub fn new(path: PathBuf, is_member: bool) -> PackageRoot { 66 pub fn new_member(path: PathBuf) -> PackageRoot {
68 PackageRoot { path, is_member } 67 Self { path, is_member: true }
69 }
70
71 pub fn path(&self) -> &PathBuf {
72 &self.path
73 } 68 }
74 69 pub fn new_non_member(path: PathBuf) -> PackageRoot {
75 pub fn is_member(&self) -> bool { 70 Self { path, is_member: false }
76 self.is_member
77 } 71 }
78} 72}
79 73
@@ -130,24 +124,18 @@ impl ProjectWorkspace {
130 pub fn to_roots(&self) -> Vec<PackageRoot> { 124 pub fn to_roots(&self) -> Vec<PackageRoot> {
131 match self { 125 match self {
132 ProjectWorkspace::Json { project } => { 126 ProjectWorkspace::Json { project } => {
133 let mut roots = Vec::with_capacity(project.roots.len()); 127 project.roots.iter().map(|r| PackageRoot::new_member(r.path.clone())).collect()
134 for root in &project.roots {
135 roots.push(PackageRoot::new(root.path.clone(), true));
136 }
137 roots
138 }
139 ProjectWorkspace::Cargo { cargo, sysroot } => {
140 let mut roots = Vec::with_capacity(cargo.packages().len() + sysroot.crates().len());
141 for pkg in cargo.packages() {
142 let root = cargo[pkg].root().to_path_buf();
143 let member = cargo[pkg].is_member;
144 roots.push(PackageRoot::new(root, member));
145 }
146 for krate in sysroot.crates() {
147 roots.push(PackageRoot::new(sysroot[krate].root_dir().to_path_buf(), false))
148 }
149 roots
150 } 128 }
129 ProjectWorkspace::Cargo { cargo, sysroot } => cargo
130 .packages()
131 .map(|pkg| PackageRoot {
132 path: cargo[pkg].root().to_path_buf(),
133 is_member: cargo[pkg].is_member,
134 })
135 .chain(sysroot.crates().map(|krate| {
136 PackageRoot::new_non_member(sysroot[krate].root_dir().to_path_buf())
137 }))
138 .collect(),
151 } 139 }
152 } 140 }
153 141
diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs
index 7667873d5..0b138edd7 100644
--- a/crates/rust-analyzer/src/cli/analysis_bench.rs
+++ b/crates/rust-analyzer/src/cli/analysis_bench.rs
@@ -65,10 +65,10 @@ pub fn analysis_bench(
65 roots 65 roots
66 .iter() 66 .iter()
67 .find_map(|(source_root_id, project_root)| { 67 .find_map(|(source_root_id, project_root)| {
68 if project_root.is_member() { 68 if project_root.is_member {
69 for file_id in db.source_root(*source_root_id).walk() { 69 for file_id in db.source_root(*source_root_id).walk() {
70 let rel_path = db.file_relative_path(file_id); 70 let rel_path = db.file_relative_path(file_id);
71 let abs_path = rel_path.to_path(project_root.path()); 71 let abs_path = rel_path.to_path(&project_root.path);
72 if abs_path == path { 72 if abs_path == path {
73 return Some(file_id); 73 return Some(file_id);
74 } 74 }
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index 75cf2dae5..edd90df77 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -39,7 +39,7 @@ pub fn analysis_stats(
39 roots 39 roots
40 .into_iter() 40 .into_iter()
41 .filter_map(|(source_root_id, project_root)| { 41 .filter_map(|(source_root_id, project_root)| {
42 if with_deps || project_root.is_member() { 42 if with_deps || project_root.is_member {
43 Some(source_root_id) 43 Some(source_root_id)
44 } else { 44 } else {
45 None 45 None
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index 2c0bde920..109b1d74b 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -36,8 +36,7 @@ pub(crate) fn load_cargo(
36 extern_dirs.extend(ws.out_dirs()); 36 extern_dirs.extend(ws.out_dirs());
37 37
38 let mut project_roots = ws.to_roots(); 38 let mut project_roots = ws.to_roots();
39 project_roots 39 project_roots.extend(extern_dirs.iter().cloned().map(PackageRoot::new_non_member));
40 .extend(extern_dirs.iter().map(|path| PackageRoot::new(path.to_path_buf(), false)));
41 40
42 let (sender, receiver) = unbounded(); 41 let (sender, receiver) = unbounded();
43 let sender = Box::new(move |t| sender.send(t).unwrap()); 42 let sender = Box::new(move |t| sender.send(t).unwrap());
@@ -46,9 +45,9 @@ pub(crate) fn load_cargo(
46 .iter() 45 .iter()
47 .map(|pkg_root| { 46 .map(|pkg_root| {
48 RootEntry::new( 47 RootEntry::new(
49 pkg_root.path().clone(), 48 pkg_root.path.clone(),
50 RustPackageFilterBuilder::default() 49 RustPackageFilterBuilder::default()
51 .set_member(pkg_root.is_member()) 50 .set_member(pkg_root.is_member)
52 .into_vfs_filter(), 51 .into_vfs_filter(),
53 ) 52 )
54 }) 53 })
@@ -58,14 +57,11 @@ pub(crate) fn load_cargo(
58 ); 57 );
59 58
60 let source_roots = roots 59 let source_roots = roots
61 .iter() 60 .into_iter()
62 .map(|&vfs_root| { 61 .map(|vfs_root| {
63 let source_root_id = vfs_root_to_id(vfs_root); 62 let source_root_id = vfs_root_to_id(vfs_root);
64 let project_root = project_roots 63 let project_root =
65 .iter() 64 project_roots.iter().find(|it| it.path == vfs.root2path(vfs_root)).unwrap().clone();
66 .find(|it| it.path() == &vfs.root2path(vfs_root))
67 .unwrap()
68 .clone();
69 (source_root_id, project_root) 65 (source_root_id, project_root)
70 }) 66 })
71 .collect::<FxHashMap<_, _>>(); 67 .collect::<FxHashMap<_, _>>();
@@ -97,7 +93,7 @@ pub(crate) fn load(
97 match change { 93 match change {
98 VfsChange::AddRoot { root, files } => { 94 VfsChange::AddRoot { root, files } => {
99 let source_root_id = vfs_root_to_id(root); 95 let source_root_id = vfs_root_to_id(root);
100 let is_local = source_roots[&source_root_id].is_member(); 96 let is_local = source_roots[&source_root_id].is_member;
101 log::debug!( 97 log::debug!(
102 "loaded source root {:?} with path {:?}", 98 "loaded source root {:?} with path {:?}",
103 source_root_id, 99 source_root_id,
@@ -106,7 +102,7 @@ pub(crate) fn load(
106 analysis_change.add_root(source_root_id, is_local); 102 analysis_change.add_root(source_root_id, is_local);
107 analysis_change.set_debug_root_path( 103 analysis_change.set_debug_root_path(
108 source_root_id, 104 source_root_id,
109 source_roots[&source_root_id].path().display().to_string(), 105 source_roots[&source_root_id].path.display().to_string(),
110 ); 106 );
111 107
112 let vfs_root_path = vfs.root2path(root); 108 let vfs_root_path = vfs.root2path(root);
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 95e676e0f..e61a56935 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -132,8 +132,8 @@ pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection)
132 watchers: workspaces 132 watchers: workspaces
133 .iter() 133 .iter()
134 .flat_map(|ws| ws.to_roots()) 134 .flat_map(|ws| ws.to_roots())
135 .filter(|root| root.is_member()) 135 .filter(|root| root.is_member)
136 .map(|root| format!("{}/**/*.rs", root.path().display())) 136 .map(|root| format!("{}/**/*.rs", root.path.display()))
137 .map(|glob_pattern| req::FileSystemWatcher { glob_pattern, kind: None }) 137 .map(|glob_pattern| req::FileSystemWatcher { glob_pattern, kind: None })
138 .collect(), 138 .collect(),
139 }; 139 };
diff --git a/crates/rust-analyzer/src/vfs_glob.rs b/crates/rust-analyzer/src/vfs_glob.rs
index 91b33f94e..ff37a7008 100644
--- a/crates/rust-analyzer/src/vfs_glob.rs
+++ b/crates/rust-analyzer/src/vfs_glob.rs
@@ -29,10 +29,14 @@ impl RustPackageFilterBuilder {
29 self.is_member = is_member; 29 self.is_member = is_member;
30 self 30 self
31 } 31 }
32 pub fn exclude(mut self, glob: Glob) -> RustPackageFilterBuilder { 32
33 self.exclude.add(glob); 33 pub fn exclude(mut self, globs: impl IntoIterator<Item = Glob>) -> RustPackageFilterBuilder {
34 for glob in globs.into_iter() {
35 self.exclude.add(glob);
36 }
34 self 37 self
35 } 38 }
39
36 pub fn into_vfs_filter(self) -> Box<dyn Filter> { 40 pub fn into_vfs_filter(self) -> Box<dyn Filter> {
37 let RustPackageFilterBuilder { is_member, mut exclude } = self; 41 let RustPackageFilterBuilder { is_member, mut exclude } = self;
38 for &glob in ALWAYS_IGNORED { 42 for &glob in ALWAYS_IGNORED {
@@ -87,7 +91,7 @@ fn test_globs() {
87 91
88 let filter = RustPackageFilterBuilder::default() 92 let filter = RustPackageFilterBuilder::default()
89 .set_member(true) 93 .set_member(true)
90 .exclude(Glob::new("src/llvm-project/**").unwrap()) 94 .exclude(std::iter::once(Glob::new("src/llvm-project/**").unwrap()))
91 .into_vfs_filter(); 95 .into_vfs_filter();
92 96
93 assert!(!filter.include_dir(RelativePath::new("src/llvm-project/clang"))); 97 assert!(!filter.include_dir(RelativePath::new("src/llvm-project/clang")));
diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs
index 5674f42ef..a6549a8f4 100644
--- a/crates/rust-analyzer/src/world.rs
+++ b/crates/rust-analyzer/src/world.rs
@@ -87,44 +87,35 @@ impl WorldState {
87 ) -> WorldState { 87 ) -> WorldState {
88 let mut change = AnalysisChange::new(); 88 let mut change = AnalysisChange::new();
89 89
90 let mut roots = Vec::new(); 90 let extern_dirs: FxHashSet<_> =
91 roots.extend(folder_roots.iter().map(|path| { 91 workspaces.iter().flat_map(ProjectWorkspace::out_dirs).collect();
92 let mut filter = RustPackageFilterBuilder::default().set_member(true); 92
93 for glob in exclude_globs.iter() { 93 let roots: Vec<_> = {
94 filter = filter.exclude(glob.clone()); 94 let create_filter = |is_member| {
95 } 95 RustPackageFilterBuilder::default()
96 RootEntry::new(path.clone(), filter.into_vfs_filter()) 96 .set_member(is_member)
97 })); 97 .exclude(exclude_globs.iter().cloned())
98 for ws in workspaces.iter() { 98 .into_vfs_filter()
99 roots.extend(ws.to_roots().into_iter().map(|pkg_root| { 99 };
100 let mut filter = 100 folder_roots
101 RustPackageFilterBuilder::default().set_member(pkg_root.is_member()); 101 .iter()
102 for glob in exclude_globs.iter() { 102 .map(|path| RootEntry::new(path.clone(), create_filter(true)))
103 filter = filter.exclude(glob.clone()); 103 .chain(workspaces.iter().flat_map(ProjectWorkspace::to_roots).map(|pkg_root| {
104 } 104 RootEntry::new(pkg_root.path, create_filter(pkg_root.is_member))
105 RootEntry::new(pkg_root.path().clone(), filter.into_vfs_filter()) 105 }))
106 })); 106 .chain(
107 } 107 extern_dirs
108 108 .iter()
109 let mut extern_dirs = FxHashSet::default(); 109 .map(|path| RootEntry::new(path.to_owned(), create_filter(false))),
110 for ws in workspaces.iter() { 110 )
111 extern_dirs.extend(ws.out_dirs()); 111 .collect()
112 } 112 };
113
114 let mut extern_source_roots = FxHashMap::default();
115
116 roots.extend(extern_dirs.iter().map(|path| {
117 let mut filter = RustPackageFilterBuilder::default().set_member(false);
118 for glob in exclude_globs.iter() {
119 filter = filter.exclude(glob.clone());
120 }
121 RootEntry::new(PathBuf::from(&path), filter.into_vfs_filter())
122 }));
123 113
124 let (task_sender, task_receiver) = unbounded(); 114 let (task_sender, task_receiver) = unbounded();
125 let task_sender = Box::new(move |t| task_sender.send(t).unwrap()); 115 let task_sender = Box::new(move |t| task_sender.send(t).unwrap());
126 let (mut vfs, vfs_roots) = Vfs::new(roots, task_sender, watch); 116 let (mut vfs, vfs_roots) = Vfs::new(roots, task_sender, watch);
127 117
118 let mut extern_source_roots = FxHashMap::default();
128 for r in vfs_roots { 119 for r in vfs_roots {
129 let vfs_root_path = vfs.root2path(r); 120 let vfs_root_path = vfs.root2path(r);
130 let is_local = folder_roots.iter().any(|it| vfs_root_path.starts_with(it)); 121 let is_local = folder_roots.iter().any(|it| vfs_root_path.starts_with(it));
@@ -132,6 +123,7 @@ impl WorldState {
132 change.set_debug_root_path(SourceRootId(r.0), vfs_root_path.display().to_string()); 123 change.set_debug_root_path(SourceRootId(r.0), vfs_root_path.display().to_string());
133 124
134 // FIXME: add path2root in vfs to simpily this logic 125 // FIXME: add path2root in vfs to simpily this logic
126
135 if extern_dirs.contains(&vfs_root_path) { 127 if extern_dirs.contains(&vfs_root_path) {
136 extern_source_roots.insert(vfs_root_path, ExternSourceId(r.0)); 128 extern_source_roots.insert(vfs_root_path, ExternSourceId(r.0));
137 } 129 }