about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/vfs/src/file_set.rs4
-rw-r--r--crates/vfs/src/file_set/tests.rs23
2 files changed, 27 insertions, 0 deletions
diff --git a/crates/vfs/src/file_set.rs b/crates/vfs/src/file_set.rs
index 7eeb10d544a..d7d283c3eb8 100644
--- a/crates/vfs/src/file_set.rs
+++ b/crates/vfs/src/file_set.rs
@@ -132,6 +132,10 @@ impl FileSetConfig {
     ///
     /// `scratch_space` is used as a buffer and will be entirely replaced.
     fn classify(&self, path: &VfsPath, scratch_space: &mut Vec<u8>) -> usize {
+        // `path` is a file, but r-a only cares about the containing directory. We don't
+        // want `/foo/bar_baz.rs` to be attributed to source root directory `/foo/bar`.
+        let path = path.parent().unwrap_or_else(|| path.clone());
+
         scratch_space.clear();
         path.encode(scratch_space);
         let automaton = PrefixOf::new(scratch_space.as_slice());
diff --git a/crates/vfs/src/file_set/tests.rs b/crates/vfs/src/file_set/tests.rs
index 2146df185d3..3cdb60dcb26 100644
--- a/crates/vfs/src/file_set/tests.rs
+++ b/crates/vfs/src/file_set/tests.rs
@@ -40,3 +40,26 @@ fn name_prefix() {
     let partition = file_set.partition(&vfs).into_iter().map(|it| it.len()).collect::<Vec<_>>();
     assert_eq!(partition, vec![1, 1, 0]);
 }
+
+/// Ensure that we don't consider `/foo/bar_baz.rs` to be in the
+/// `/foo/bar/` root.
+#[test]
+fn name_prefix_partially_matches() {
+    let mut file_set = FileSetConfig::builder();
+    file_set.add_file_set(vec![VfsPath::new_virtual_path("/foo".into())]);
+    file_set.add_file_set(vec![VfsPath::new_virtual_path("/foo/bar".into())]);
+    let file_set = file_set.build();
+
+    let mut vfs = Vfs::default();
+
+    // These two are both in /foo.
+    vfs.set_file_contents(VfsPath::new_virtual_path("/foo/lib.rs".into()), Some(Vec::new()));
+    vfs.set_file_contents(VfsPath::new_virtual_path("/foo/bar_baz.rs".into()), Some(Vec::new()));
+
+    // Only this file is in /foo/bar.
+    vfs.set_file_contents(VfsPath::new_virtual_path("/foo/bar/biz.rs".into()), Some(Vec::new()));
+
+    let partition = file_set.partition(&vfs).into_iter().map(|it| it.len()).collect::<Vec<_>>();
+
+    assert_eq!(partition, vec![2, 1, 0]);
+}