aboutsummaryrefslogtreecommitdiff
path: root/crates/vfs/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-09-11 12:37:04 +0100
committerGitHub <[email protected]>2020-09-11 12:37:04 +0100
commit4f1167d8ddac9d392f034341e6bc032b51014918 (patch)
treef26520ae48d4670aaefd2d62f9de37af30ef5bac /crates/vfs/src
parenteb7136f76d3535fde25dc6f49e3035312f7cc84c (diff)
parentca698a0b8c78e5ba7738fc0f0f6f77718e70a83e (diff)
Merge #5969
5969: Propose module name completion options r=jonas-schievink a=SomeoneToIgnore <img width="539" alt="image" src="https://user-images.githubusercontent.com/2690773/92663009-cb0aec00-f308-11ea-9ef5-1faa91518031.png"> Currently traverses the whole file set every time we try to complete the module, as discussed in https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Fwg-rls-2.2E0/topic/mod.3C.7C.3E.20completion Co-authored-by: Kirill Bulatov <[email protected]>
Diffstat (limited to 'crates/vfs/src')
-rw-r--r--crates/vfs/src/file_set.rs13
-rw-r--r--crates/vfs/src/vfs_path.rs74
2 files changed, 85 insertions, 2 deletions
diff --git a/crates/vfs/src/file_set.rs b/crates/vfs/src/file_set.rs
index e9196fcd2..4aa2d6526 100644
--- a/crates/vfs/src/file_set.rs
+++ b/crates/vfs/src/file_set.rs
@@ -23,13 +23,22 @@ impl FileSet {
23 let mut base = self.paths[&anchor].clone(); 23 let mut base = self.paths[&anchor].clone();
24 base.pop(); 24 base.pop();
25 let path = base.join(path)?; 25 let path = base.join(path)?;
26 let res = self.files.get(&path).copied(); 26 self.files.get(&path).copied()
27 res 27 }
28
29 pub fn file_for_path(&self, path: &VfsPath) -> Option<&FileId> {
30 self.files.get(path)
28 } 31 }
32
33 pub fn path_for_file(&self, file: &FileId) -> Option<&VfsPath> {
34 self.paths.get(file)
35 }
36
29 pub fn insert(&mut self, file_id: FileId, path: VfsPath) { 37 pub fn insert(&mut self, file_id: FileId, path: VfsPath) {
30 self.files.insert(path.clone(), file_id); 38 self.files.insert(path.clone(), file_id);
31 self.paths.insert(file_id, path); 39 self.paths.insert(file_id, path);
32 } 40 }
41
33 pub fn iter(&self) -> impl Iterator<Item = FileId> + '_ { 42 pub fn iter(&self) -> impl Iterator<Item = FileId> + '_ {
34 self.paths.keys().copied() 43 self.paths.keys().copied()
35 } 44 }
diff --git a/crates/vfs/src/vfs_path.rs b/crates/vfs/src/vfs_path.rs
index 944a702df..022a0be1e 100644
--- a/crates/vfs/src/vfs_path.rs
+++ b/crates/vfs/src/vfs_path.rs
@@ -48,6 +48,24 @@ impl VfsPath {
48 (VfsPathRepr::VirtualPath(_), _) => false, 48 (VfsPathRepr::VirtualPath(_), _) => false,
49 } 49 }
50 } 50 }
51 pub fn parent(&self) -> Option<VfsPath> {
52 let mut parent = self.clone();
53 if parent.pop() {
54 Some(parent)
55 } else {
56 None
57 }
58 }
59
60 pub fn name_and_extension(&self) -> Option<(&str, Option<&str>)> {
61 match &self.0 {
62 VfsPathRepr::PathBuf(p) => Some((
63 p.file_stem()?.to_str()?,
64 p.extension().and_then(|extension| extension.to_str()),
65 )),
66 VfsPathRepr::VirtualPath(p) => p.name_and_extension(),
67 }
68 }
51 69
52 // Don't make this `pub` 70 // Don't make this `pub`
53 pub(crate) fn encode(&self, buf: &mut Vec<u8>) { 71 pub(crate) fn encode(&self, buf: &mut Vec<u8>) {
@@ -268,4 +286,60 @@ impl VirtualPath {
268 res.0 = format!("{}/{}", res.0, path); 286 res.0 = format!("{}/{}", res.0, path);
269 Some(res) 287 Some(res)
270 } 288 }
289
290 pub fn name_and_extension(&self) -> Option<(&str, Option<&str>)> {
291 let file_path = if self.0.ends_with('/') { &self.0[..&self.0.len() - 1] } else { &self.0 };
292 let file_name = match file_path.rfind('/') {
293 Some(position) => &file_path[position + 1..],
294 None => file_path,
295 };
296
297 if file_name.is_empty() {
298 None
299 } else {
300 let mut file_stem_and_extension = file_name.rsplitn(2, '.');
301 let extension = file_stem_and_extension.next();
302 let file_stem = file_stem_and_extension.next();
303
304 match (file_stem, extension) {
305 (None, None) => None,
306 (None, Some(_)) | (Some(""), Some(_)) => Some((file_name, None)),
307 (Some(file_stem), extension) => Some((file_stem, extension)),
308 }
309 }
310 }
311}
312
313#[cfg(test)]
314mod tests {
315 use super::*;
316
317 #[test]
318 fn virtual_path_extensions() {
319 assert_eq!(VirtualPath("/".to_string()).name_and_extension(), None);
320 assert_eq!(
321 VirtualPath("/directory".to_string()).name_and_extension(),
322 Some(("directory", None))
323 );
324 assert_eq!(
325 VirtualPath("/directory/".to_string()).name_and_extension(),
326 Some(("directory", None))
327 );
328 assert_eq!(
329 VirtualPath("/directory/file".to_string()).name_and_extension(),
330 Some(("file", None))
331 );
332 assert_eq!(
333 VirtualPath("/directory/.file".to_string()).name_and_extension(),
334 Some((".file", None))
335 );
336 assert_eq!(
337 VirtualPath("/directory/.file.rs".to_string()).name_and_extension(),
338 Some((".file", Some("rs")))
339 );
340 assert_eq!(
341 VirtualPath("/directory/file.rs".to_string()).name_and_extension(),
342 Some(("file", Some("rs")))
343 );
344 }
271} 345}