diff options
-rw-r--r-- | crates/ra_project_model/src/lib.rs | 46 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/analysis_bench.rs | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/analysis_stats.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/cli/load_cargo.rs | 22 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/src/vfs_glob.rs | 10 | ||||
-rw-r--r-- | crates/rust-analyzer/src/world.rs | 58 |
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)] |
59 | pub struct PackageRoot { | 59 | pub 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 | |||
66 | impl PackageRoot { | 65 | impl 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 | } |