Skip to content

Commit 0abd71e

Browse files
committed
Test changing project root
1 parent 69f94d5 commit 0abd71e

File tree

1 file changed

+71
-11
lines changed
  • crates/rust-analyzer/src/config

1 file changed

+71
-11
lines changed

crates/rust-analyzer/src/config/tree.rs

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ impl ConfigDb {
209209
.iter()
210210
.flat_map(|path: &AbsPathBuf| {
211211
path.ancestors()
212+
// Note that Path::new("/root2/abc").starts_with(Path::new("/root")) is false
212213
.take_while(|x| x.starts_with(&self.project_root))
213214
.map(|dir| dir.join("rust-analyzer.toml"))
214215
.map(|path| vfs.alloc_file_id(path.into()))
@@ -236,7 +237,17 @@ impl ConfigDb {
236237
}
237238
}
238239

239-
// Could delete (self.known_file_ids - parent_changes.keys) here.
240+
// Remove source roots (& their parent config files) that are no longer part of the project root
241+
self.known_file_ids
242+
.iter()
243+
.cloned()
244+
.filter(|&x| x != self.xdg_config_file_id && !parent_changes.contains_key(&x))
245+
.collect_vec()
246+
.into_iter()
247+
.for_each(|deleted| {
248+
self.known_file_ids.remove(&deleted);
249+
self.reset_node(deleted);
250+
});
240251

241252
let inner = ConfigChangesInner {
242253
ra_toml_changes: changes.ra_toml_changes,
@@ -307,17 +318,17 @@ impl ConfigDb {
307318
/// if it's never been seen before
308319
fn ensure_node(&mut self, file_id: FileId) {
309320
if self.known_file_ids.insert(file_id) {
310-
self.set_config_input(file_id, None);
311-
self.set_parent(
312-
file_id,
313-
if file_id == self.xdg_config_file_id {
314-
None
315-
} else {
316-
Some(self.xdg_config_file_id)
317-
},
318-
);
321+
self.reset_node(file_id);
319322
}
320323
}
324+
325+
fn reset_node(&mut self, file_id: FileId) {
326+
self.set_config_input(file_id, None);
327+
self.set_parent(
328+
file_id,
329+
if file_id == self.xdg_config_file_id { None } else { Some(self.xdg_config_file_id) },
330+
);
331+
}
321332
}
322333

323334
fn parse_toml(
@@ -527,7 +538,7 @@ mod tests {
527538

528539
// Now move crate b to the root. This gives a new FileId for crate_b/ra.toml.
529540
let source_roots = ["/root/crate_a", "/root/crate_b"].map(Path::new).map(AbsPath::assert);
530-
let [crate_a, crate_b] = source_roots
541+
let [_crate_a, crate_b] = source_roots
531542
.map(|dir| dir.join("rust-analyzer.toml"))
532543
.map(|path| vfs.alloc_file_id(path.into()));
533544
let new_source_roots = source_roots.into_iter().map(|abs| abs.to_path_buf()).collect();
@@ -549,4 +560,53 @@ mod tests {
549560
// new crate_b does not inherit from crate_a
550561
assert_eq!(local.completion_autoself_enable, true);
551562
}
563+
564+
#[test]
565+
fn change_project_root() {
566+
tracing_subscriber::fmt().try_init().ok();
567+
let mut vfs = Vfs::default();
568+
569+
let project_root = AbsPath::assert(Path::new("/root"));
570+
let xdg =
571+
alloc_file_id(&mut vfs, "/home/username/.config/rust-analyzer/rust-analyzer.toml");
572+
let mut config_tree = ConfigDb::new(xdg, project_root.to_path_buf());
573+
574+
let source_roots = ["/root/crate_a"].map(Path::new).map(AbsPath::assert);
575+
let crate_a = vfs.alloc_file_id(source_roots[0].join("rust-analyzer.toml").into());
576+
577+
let _root = alloc_config(
578+
&mut vfs,
579+
"/root/rust-analyzer.toml",
580+
r#"
581+
[completion.autoself]
582+
enable = false
583+
"#,
584+
);
585+
586+
let new_source_roots = source_roots.into_iter().map(|abs| abs.to_path_buf()).collect();
587+
let changes = ConfigChanges {
588+
client_change: None,
589+
set_project_root: None, // already set in ConfigDb::new(...)
590+
set_source_roots: Some(new_source_roots),
591+
ra_toml_changes: dbg!(vfs.take_changes()),
592+
};
593+
config_tree.apply_changes(changes, &mut vfs);
594+
let local = config_tree.local_config(crate_a);
595+
// initially crate_a is part of the project root, so it does inherit
596+
// from /root/rust-analyzer.toml
597+
assert_eq!(local.completion_autoself_enable, false);
598+
599+
// change project root
600+
let changes = ConfigChanges {
601+
client_change: None,
602+
set_project_root: Some(AbsPath::assert(Path::new("/ro")).to_path_buf()),
603+
set_source_roots: None,
604+
ra_toml_changes: dbg!(vfs.take_changes()),
605+
};
606+
config_tree.apply_changes(changes, &mut vfs);
607+
// crate_a is now outside the project root and hence inherit (1) xdg (2)
608+
// crate_a/ra.toml, but not /root/rust-analyzer.toml any more
609+
let local = config_tree.local_config(crate_a);
610+
assert_eq!(local.completion_autoself_enable, true);
611+
}
552612
}

0 commit comments

Comments
 (0)