Skip to content

Commit 642f3f4

Browse files
bors[bot]Veetaha
andauthored
Merge #3798
3798: Simplify r=Veetaha a=Veetaha bear with me Co-authored-by: veetaha <[email protected]>
2 parents 09b8ee3 + c0cf60d commit 642f3f4

File tree

6 files changed

+94
-120
lines changed

6 files changed

+94
-120
lines changed

crates/ra_project_model/src/lib.rs

+54-75
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,16 @@ pub struct PackageRoot {
6262
/// Is a member of the current workspace
6363
is_member: bool,
6464
}
65-
6665
impl PackageRoot {
67-
pub fn new(path: PathBuf, is_member: bool) -> PackageRoot {
68-
PackageRoot { path, is_member }
66+
pub fn new_member(path: PathBuf) -> PackageRoot {
67+
Self { path, is_member: true }
6968
}
70-
71-
pub fn path(&self) -> &PathBuf {
69+
pub fn new_non_member(path: PathBuf) -> PackageRoot {
70+
Self { path, is_member: false }
71+
}
72+
pub fn path(&self) -> &Path {
7273
&self.path
7374
}
74-
7575
pub fn is_member(&self) -> bool {
7676
self.is_member
7777
}
@@ -130,70 +130,45 @@ impl ProjectWorkspace {
130130
pub fn to_roots(&self) -> Vec<PackageRoot> {
131131
match self {
132132
ProjectWorkspace::Json { project } => {
133-
let mut roots = Vec::with_capacity(project.roots.len());
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
133+
project.roots.iter().map(|r| PackageRoot::new_member(r.path.clone())).collect()
150134
}
135+
ProjectWorkspace::Cargo { cargo, sysroot } => cargo
136+
.packages()
137+
.map(|pkg| PackageRoot {
138+
path: cargo[pkg].root().to_path_buf(),
139+
is_member: cargo[pkg].is_member,
140+
})
141+
.chain(sysroot.crates().map(|krate| {
142+
PackageRoot::new_non_member(sysroot[krate].root_dir().to_path_buf())
143+
}))
144+
.collect(),
151145
}
152146
}
153147

154148
pub fn out_dirs(&self) -> Vec<PathBuf> {
155149
match self {
156150
ProjectWorkspace::Json { project } => {
157-
let mut out_dirs = Vec::with_capacity(project.crates.len());
158-
for krate in &project.crates {
159-
if let Some(out_dir) = &krate.out_dir {
160-
out_dirs.push(out_dir.to_path_buf());
161-
}
162-
}
163-
out_dirs
151+
project.crates.iter().filter_map(|krate| krate.out_dir.as_ref()).cloned().collect()
164152
}
165-
ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => {
166-
let mut out_dirs = Vec::with_capacity(cargo.packages().len());
167-
for pkg in cargo.packages() {
168-
if let Some(out_dir) = &cargo[pkg].out_dir {
169-
out_dirs.push(out_dir.to_path_buf());
170-
}
171-
}
172-
out_dirs
153+
ProjectWorkspace::Cargo { cargo, sysroot: _ } => {
154+
cargo.packages().filter_map(|pkg| cargo[pkg].out_dir.as_ref()).cloned().collect()
173155
}
174156
}
175157
}
176158

177159
pub fn proc_macro_dylib_paths(&self) -> Vec<PathBuf> {
178160
match self {
179-
ProjectWorkspace::Json { project } => {
180-
let mut proc_macro_dylib_paths = Vec::with_capacity(project.crates.len());
181-
for krate in &project.crates {
182-
if let Some(out_dir) = &krate.proc_macro_dylib_path {
183-
proc_macro_dylib_paths.push(out_dir.to_path_buf());
184-
}
185-
}
186-
proc_macro_dylib_paths
187-
}
188-
ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => {
189-
let mut proc_macro_dylib_paths = Vec::with_capacity(cargo.packages().len());
190-
for pkg in cargo.packages() {
191-
if let Some(dylib_path) = &cargo[pkg].proc_macro_dylib_path {
192-
proc_macro_dylib_paths.push(dylib_path.to_path_buf());
193-
}
194-
}
195-
proc_macro_dylib_paths
196-
}
161+
ProjectWorkspace::Json { project } => project
162+
.crates
163+
.iter()
164+
.filter_map(|krate| krate.proc_macro_dylib_path.as_ref())
165+
.cloned()
166+
.collect(),
167+
ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => cargo
168+
.packages()
169+
.filter_map(|pkg| cargo[pkg].proc_macro_dylib_path.as_ref())
170+
.cloned()
171+
.collect(),
197172
}
198173
}
199174

@@ -216,10 +191,12 @@ impl ProjectWorkspace {
216191
let mut crate_graph = CrateGraph::default();
217192
match self {
218193
ProjectWorkspace::Json { project } => {
219-
let mut crates = FxHashMap::default();
220-
for (id, krate) in project.crates.iter().enumerate() {
221-
let crate_id = json_project::CrateId(id);
222-
if let Some(file_id) = load(&krate.root_module) {
194+
let crates: FxHashMap<_, _> = project
195+
.crates
196+
.iter()
197+
.enumerate()
198+
.filter_map(|(seq_index, krate)| {
199+
let file_id = load(&krate.root_module)?;
223200
let edition = match krate.edition {
224201
json_project::Edition::Edition2015 => Edition::Edition2015,
225202
json_project::Edition::Edition2018 => Edition::Edition2018,
@@ -249,8 +226,8 @@ impl ProjectWorkspace {
249226
.clone()
250227
.map(|it| proc_macro_client.by_dylib_path(&it));
251228
// FIXME: No crate name in json definition such that we cannot add OUT_DIR to env
252-
crates.insert(
253-
crate_id,
229+
Some((
230+
json_project::CrateId(seq_index),
254231
crate_graph.add_crate_root(
255232
file_id,
256233
edition,
@@ -261,9 +238,9 @@ impl ProjectWorkspace {
261238
extern_source,
262239
proc_macro.unwrap_or_default(),
263240
),
264-
);
265-
}
266-
}
241+
))
242+
})
243+
.collect();
267244

268245
for (id, krate) in project.crates.iter().enumerate() {
269246
for dep in &krate.deps {
@@ -287,9 +264,11 @@ impl ProjectWorkspace {
287264
}
288265
}
289266
ProjectWorkspace::Cargo { cargo, sysroot } => {
290-
let mut sysroot_crates = FxHashMap::default();
291-
for krate in sysroot.crates() {
292-
if let Some(file_id) = load(&sysroot[krate].root) {
267+
let sysroot_crates: FxHashMap<_, _> = sysroot
268+
.crates()
269+
.filter_map(|krate| {
270+
let file_id = load(&sysroot[krate].root)?;
271+
293272
// Crates from sysroot have `cfg(test)` disabled
294273
let cfg_options = {
295274
let mut opts = default_cfg_options.clone();
@@ -300,22 +279,22 @@ impl ProjectWorkspace {
300279
let env = Env::default();
301280
let extern_source = ExternSource::default();
302281
let proc_macro = vec![];
282+
let crate_name = CrateName::new(&sysroot[krate].name)
283+
.expect("Sysroot crate names should not contain dashes");
303284

304285
let crate_id = crate_graph.add_crate_root(
305286
file_id,
306287
Edition::Edition2018,
307-
Some(
308-
CrateName::new(&sysroot[krate].name)
309-
.expect("Sysroot crate names should not contain dashes"),
310-
),
288+
Some(crate_name),
311289
cfg_options,
312290
env,
313291
extern_source,
314292
proc_macro,
315293
);
316-
sysroot_crates.insert(krate, crate_id);
317-
}
318-
}
294+
Some((krate, crate_id))
295+
})
296+
.collect();
297+
319298
for from in sysroot.crates() {
320299
for &to in sysroot[from].deps.iter() {
321300
let name = &sysroot[to].name;

crates/rust-analyzer/src/cli/load_cargo.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ pub(crate) fn load_cargo(
3636
extern_dirs.extend(ws.out_dirs());
3737

3838
let mut project_roots = ws.to_roots();
39-
project_roots
40-
.extend(extern_dirs.iter().map(|path| PackageRoot::new(path.to_path_buf(), false)));
39+
project_roots.extend(extern_dirs.iter().cloned().map(PackageRoot::new_non_member));
4140

4241
let (sender, receiver) = unbounded();
4342
let sender = Box::new(move |t| sender.send(t).unwrap());
@@ -46,7 +45,7 @@ pub(crate) fn load_cargo(
4645
.iter()
4746
.map(|pkg_root| {
4847
RootEntry::new(
49-
pkg_root.path().clone(),
48+
pkg_root.path().to_owned(),
5049
RustPackageFilterBuilder::default()
5150
.set_member(pkg_root.is_member())
5251
.into_vfs_filter(),
@@ -58,12 +57,12 @@ pub(crate) fn load_cargo(
5857
);
5958

6059
let source_roots = roots
61-
.iter()
62-
.map(|&vfs_root| {
60+
.into_iter()
61+
.map(|vfs_root| {
6362
let source_root_id = vfs_root_to_id(vfs_root);
6463
let project_root = project_roots
6564
.iter()
66-
.find(|it| it.path() == &vfs.root2path(vfs_root))
65+
.find(|it| it.path() == vfs.root2path(vfs_root))
6766
.unwrap()
6867
.clone();
6968
(source_root_id, project_root)

crates/rust-analyzer/src/main_loop.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use lsp_types::{
2323
use ra_flycheck::{url_from_path_with_drive_lowercasing, CheckTask};
2424
use ra_ide::{Canceled, FileId, LibraryData, SourceRootId};
2525
use ra_prof::profile;
26+
use ra_project_model::{PackageRoot, ProjectWorkspace};
2627
use ra_vfs::{VfsFile, VfsTask, Watch};
2728
use relative_path::RelativePathBuf;
2829
use rustc_hash::FxHashSet;
@@ -131,8 +132,8 @@ pub fn main_loop(ws_roots: Vec<PathBuf>, config: Config, connection: Connection)
131132
let registration_options = req::DidChangeWatchedFilesRegistrationOptions {
132133
watchers: workspaces
133134
.iter()
134-
.flat_map(|ws| ws.to_roots())
135-
.filter(|root| root.is_member())
135+
.flat_map(ProjectWorkspace::to_roots)
136+
.filter(PackageRoot::is_member)
136137
.map(|root| format!("{}/**/*.rs", root.path().display()))
137138
.map(|glob_pattern| req::FileSystemWatcher { glob_pattern, kind: None })
138139
.collect(),

crates/rust-analyzer/src/main_loop/subscriptions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ impl Subscriptions {
1717
self.subs.remove(&file_id);
1818
}
1919
pub(crate) fn subscriptions(&self) -> Vec<FileId> {
20-
self.subs.iter().cloned().collect()
20+
self.subs.iter().copied().collect()
2121
}
2222
}

crates/rust-analyzer/src/vfs_glob.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,14 @@ impl RustPackageFilterBuilder {
2929
self.is_member = is_member;
3030
self
3131
}
32-
pub fn exclude(mut self, glob: Glob) -> RustPackageFilterBuilder {
33-
self.exclude.add(glob);
32+
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+
}
3437
self
3538
}
39+
3640
pub fn into_vfs_filter(self) -> Box<dyn Filter> {
3741
let RustPackageFilterBuilder { is_member, mut exclude } = self;
3842
for &glob in ALWAYS_IGNORED {
@@ -87,7 +91,7 @@ fn test_globs() {
8791

8892
let filter = RustPackageFilterBuilder::default()
8993
.set_member(true)
90-
.exclude(Glob::new("src/llvm-project/**").unwrap())
94+
.exclude(std::iter::once(Glob::new("src/llvm-project/**").unwrap()))
9195
.into_vfs_filter();
9296

9397
assert!(!filter.include_dir(RelativePath::new("src/llvm-project/clang")));

crates/rust-analyzer/src/world.rs

+24-33
Original file line numberDiff line numberDiff line change
@@ -87,44 +87,35 @@ impl WorldState {
8787
) -> WorldState {
8888
let mut change = AnalysisChange::new();
8989

90-
let mut roots = Vec::new();
91-
roots.extend(folder_roots.iter().map(|path| {
92-
let mut filter = RustPackageFilterBuilder::default().set_member(true);
93-
for glob in exclude_globs.iter() {
94-
filter = filter.exclude(glob.clone());
95-
}
96-
RootEntry::new(path.clone(), filter.into_vfs_filter())
97-
}));
98-
for ws in workspaces.iter() {
99-
roots.extend(ws.to_roots().into_iter().map(|pkg_root| {
100-
let mut filter =
101-
RustPackageFilterBuilder::default().set_member(pkg_root.is_member());
102-
for glob in exclude_globs.iter() {
103-
filter = filter.exclude(glob.clone());
104-
}
105-
RootEntry::new(pkg_root.path().clone(), filter.into_vfs_filter())
106-
}));
107-
}
108-
109-
let mut extern_dirs = FxHashSet::default();
110-
for ws in workspaces.iter() {
111-
extern_dirs.extend(ws.out_dirs());
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-
}));
90+
let extern_dirs: FxHashSet<_> =
91+
workspaces.iter().flat_map(ProjectWorkspace::out_dirs).collect();
92+
93+
let roots: Vec<_> = {
94+
let create_filter = |is_member| {
95+
RustPackageFilterBuilder::default()
96+
.set_member(is_member)
97+
.exclude(exclude_globs.iter().cloned())
98+
.into_vfs_filter()
99+
};
100+
folder_roots
101+
.iter()
102+
.map(|path| RootEntry::new(path.clone(), create_filter(true)))
103+
.chain(workspaces.iter().flat_map(ProjectWorkspace::to_roots).map(|pkg_root| {
104+
RootEntry::new(pkg_root.path().to_owned(), create_filter(pkg_root.is_member()))
105+
}))
106+
.chain(
107+
extern_dirs
108+
.iter()
109+
.map(|path| RootEntry::new(path.to_owned(), create_filter(false))),
110+
)
111+
.collect()
112+
};
123113

124114
let (task_sender, task_receiver) = unbounded();
125115
let task_sender = Box::new(move |t| task_sender.send(t).unwrap());
126116
let (mut vfs, vfs_roots) = Vfs::new(roots, task_sender, watch);
127117

118+
let mut extern_source_roots = FxHashMap::default();
128119
for r in vfs_roots {
129120
let vfs_root_path = vfs.root2path(r);
130121
let is_local = folder_roots.iter().any(|it| vfs_root_path.starts_with(it));

0 commit comments

Comments
 (0)