diff options
author | Aleksey Kladov <[email protected]> | 2018-09-16 10:54:24 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-09-16 11:07:39 +0100 |
commit | b5021411a84822cb3f1e3aeffad9550dd15bdeb6 (patch) | |
tree | 9dca564f8e51b298dced01c4ce669c756dce3142 /crates/ra_lsp_server/src/path_map.rs | |
parent | ba0bfeee12e19da40b5eabc8d0408639af10e96f (diff) |
rename all things
Diffstat (limited to 'crates/ra_lsp_server/src/path_map.rs')
-rw-r--r-- | crates/ra_lsp_server/src/path_map.rs | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/crates/ra_lsp_server/src/path_map.rs b/crates/ra_lsp_server/src/path_map.rs new file mode 100644 index 000000000..19c3b1d3b --- /dev/null +++ b/crates/ra_lsp_server/src/path_map.rs | |||
@@ -0,0 +1,110 @@ | |||
1 | use std::path::{PathBuf, Path, Component}; | ||
2 | use im; | ||
3 | use relative_path::RelativePath; | ||
4 | use ra_analysis::{FileId, FileResolver}; | ||
5 | |||
6 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
7 | pub enum Root { | ||
8 | Workspace, Lib | ||
9 | } | ||
10 | |||
11 | #[derive(Debug, Default, Clone)] | ||
12 | pub struct PathMap { | ||
13 | next_id: u32, | ||
14 | path2id: im::HashMap<PathBuf, FileId>, | ||
15 | id2path: im::HashMap<FileId, PathBuf>, | ||
16 | id2root: im::HashMap<FileId, Root>, | ||
17 | } | ||
18 | |||
19 | impl PathMap { | ||
20 | pub fn new() -> PathMap { | ||
21 | Default::default() | ||
22 | } | ||
23 | pub fn get_or_insert(&mut self, path: PathBuf, root: Root) -> FileId { | ||
24 | self.path2id.get(path.as_path()) | ||
25 | .map(|&id| id) | ||
26 | .unwrap_or_else(|| { | ||
27 | let id = self.new_file_id(); | ||
28 | self.insert(path, id, root); | ||
29 | id | ||
30 | }) | ||
31 | } | ||
32 | pub fn get_id(&self, path: &Path) -> Option<FileId> { | ||
33 | self.path2id.get(path).map(|&id| id) | ||
34 | } | ||
35 | pub fn get_path(&self, file_id: FileId) -> &Path { | ||
36 | self.id2path.get(&file_id) | ||
37 | .unwrap() | ||
38 | .as_path() | ||
39 | } | ||
40 | pub fn get_root(&self, file_id: FileId) -> Root { | ||
41 | self.id2root[&file_id] | ||
42 | } | ||
43 | fn insert(&mut self, path: PathBuf, file_id: FileId, root: Root) { | ||
44 | self.path2id.insert(path.clone(), file_id); | ||
45 | self.id2path.insert(file_id, path.clone()); | ||
46 | self.id2root.insert(file_id, root); | ||
47 | } | ||
48 | |||
49 | fn new_file_id(&mut self) -> FileId { | ||
50 | let id = FileId(self.next_id); | ||
51 | self.next_id += 1; | ||
52 | id | ||
53 | } | ||
54 | } | ||
55 | |||
56 | impl FileResolver for PathMap { | ||
57 | fn file_stem(&self, file_id: FileId) -> String { | ||
58 | self.get_path(file_id).file_stem().unwrap().to_str().unwrap().to_string() | ||
59 | } | ||
60 | |||
61 | fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId> { | ||
62 | let path = path.to_path(&self.get_path(file_id)); | ||
63 | let path = normalize(&path); | ||
64 | self.get_id(&path) | ||
65 | } | ||
66 | } | ||
67 | |||
68 | fn normalize(path: &Path) -> PathBuf { | ||
69 | let mut components = path.components().peekable(); | ||
70 | let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { | ||
71 | components.next(); | ||
72 | PathBuf::from(c.as_os_str()) | ||
73 | } else { | ||
74 | PathBuf::new() | ||
75 | }; | ||
76 | |||
77 | for component in components { | ||
78 | match component { | ||
79 | Component::Prefix(..) => unreachable!(), | ||
80 | Component::RootDir => { | ||
81 | ret.push(component.as_os_str()); | ||
82 | } | ||
83 | Component::CurDir => {} | ||
84 | Component::ParentDir => { | ||
85 | ret.pop(); | ||
86 | } | ||
87 | Component::Normal(c) => { | ||
88 | ret.push(c); | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | ret | ||
93 | } | ||
94 | |||
95 | #[cfg(test)] | ||
96 | mod test { | ||
97 | use super::*; | ||
98 | |||
99 | #[test] | ||
100 | fn test_resolve() { | ||
101 | let mut m = PathMap::new(); | ||
102 | let id1 = m.get_or_insert(PathBuf::from("/foo"), Root::Workspace); | ||
103 | let id2 = m.get_or_insert(PathBuf::from("/foo/bar.rs"), Root::Workspace); | ||
104 | assert_eq!( | ||
105 | m.resolve(id1, &RelativePath::new("bar.rs")), | ||
106 | Some(id2), | ||
107 | ) | ||
108 | } | ||
109 | } | ||
110 | |||