diff options
author | Aleksey Kladov <[email protected]> | 2019-01-04 13:01:06 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-01-04 13:58:10 +0000 |
commit | 291d578938d7dc9b1f9bbd1174e444cc831531d9 (patch) | |
tree | 153e44aa0ccb17be658acbc9ae2e62d2a87178ab /crates | |
parent | 821fa7a50ab8c4886adc60a2093aa8e06cc3a9d6 (diff) |
extract area to a crate
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_arena/Cargo.toml | 5 | ||||
-rw-r--r-- | crates/ra_arena/src/lib.rs | 97 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 4 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 5 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/server_world.rs | 32 | ||||
-rw-r--r-- | crates/ra_vfs/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_vfs/src/arena.rs | 53 | ||||
-rw-r--r-- | crates/ra_vfs/src/lib.rs | 34 |
8 files changed, 137 insertions, 94 deletions
diff --git a/crates/ra_arena/Cargo.toml b/crates/ra_arena/Cargo.toml new file mode 100644 index 000000000..9594e2d0f --- /dev/null +++ b/crates/ra_arena/Cargo.toml | |||
@@ -0,0 +1,5 @@ | |||
1 | [package] | ||
2 | edition = "2018" | ||
3 | name = "ra_arena" | ||
4 | version = "0.1.0" | ||
5 | authors = ["Aleksey Kladov <[email protected]>"] | ||
diff --git a/crates/ra_arena/src/lib.rs b/crates/ra_arena/src/lib.rs new file mode 100644 index 000000000..44d9e826b --- /dev/null +++ b/crates/ra_arena/src/lib.rs | |||
@@ -0,0 +1,97 @@ | |||
1 | //! Yet another index-based arena. | ||
2 | |||
3 | use std::{ | ||
4 | fmt, | ||
5 | marker::PhantomData, | ||
6 | ops::{Index, IndexMut}, | ||
7 | }; | ||
8 | |||
9 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
10 | pub struct RawId(u32); | ||
11 | |||
12 | impl From<RawId> for u32 { | ||
13 | fn from(raw: RawId) -> u32 { | ||
14 | raw.0 | ||
15 | } | ||
16 | } | ||
17 | |||
18 | impl From<u32> for RawId { | ||
19 | fn from(id: u32) -> RawId { | ||
20 | RawId(id) | ||
21 | } | ||
22 | } | ||
23 | |||
24 | impl fmt::Debug for RawId { | ||
25 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
26 | self.0.fmt(f) | ||
27 | } | ||
28 | } | ||
29 | |||
30 | impl fmt::Display for RawId { | ||
31 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
32 | self.0.fmt(f) | ||
33 | } | ||
34 | } | ||
35 | |||
36 | #[derive(Clone, Debug)] | ||
37 | pub struct Arena<ID: ArenaId, T> { | ||
38 | data: Vec<T>, | ||
39 | _ty: PhantomData<ID>, | ||
40 | } | ||
41 | |||
42 | #[macro_export] | ||
43 | macro_rules! impl_arena_id { | ||
44 | ($name:ident) => { | ||
45 | impl $crate::ArenaId for $name { | ||
46 | fn from_raw(raw: $crate::RawId) -> Self { | ||
47 | $name(raw) | ||
48 | } | ||
49 | fn into_raw(self) -> $crate::RawId { | ||
50 | self.0 | ||
51 | } | ||
52 | } | ||
53 | }; | ||
54 | } | ||
55 | |||
56 | pub trait ArenaId { | ||
57 | fn from_raw(raw: RawId) -> Self; | ||
58 | fn into_raw(self) -> RawId; | ||
59 | } | ||
60 | |||
61 | impl<ID: ArenaId, T> Arena<ID, T> { | ||
62 | pub fn alloc(&mut self, value: T) -> ID { | ||
63 | let id = RawId(self.data.len() as u32); | ||
64 | self.data.push(value); | ||
65 | ID::from_raw(id) | ||
66 | } | ||
67 | pub fn iter<'a>(&'a self) -> impl Iterator<Item = (ID, &'a T)> { | ||
68 | self.data | ||
69 | .iter() | ||
70 | .enumerate() | ||
71 | .map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value)) | ||
72 | } | ||
73 | } | ||
74 | |||
75 | impl<ID: ArenaId, T> Default for Arena<ID, T> { | ||
76 | fn default() -> Arena<ID, T> { | ||
77 | Arena { | ||
78 | data: Vec::new(), | ||
79 | _ty: PhantomData, | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | |||
84 | impl<ID: ArenaId, T> Index<ID> for Arena<ID, T> { | ||
85 | type Output = T; | ||
86 | fn index(&self, idx: ID) -> &T { | ||
87 | let idx = idx.into_raw().0 as usize; | ||
88 | &self.data[idx] | ||
89 | } | ||
90 | } | ||
91 | |||
92 | impl<ID: ArenaId, T> IndexMut<ID> for Arena<ID, T> { | ||
93 | fn index_mut(&mut self, idx: ID) -> &mut T { | ||
94 | let idx = idx.into_raw().0 as usize; | ||
95 | &mut self.data[idx] | ||
96 | } | ||
97 | } | ||
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 06dd373c0..60d9671de 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -350,7 +350,7 @@ fn on_notification( | |||
350 | .write() | 350 | .write() |
351 | .add_file_overlay(&path, params.text_document.text) | 351 | .add_file_overlay(&path, params.text_document.text) |
352 | { | 352 | { |
353 | subs.add_sub(FileId(file_id.0)); | 353 | subs.add_sub(FileId(file_id.0.into())); |
354 | } | 354 | } |
355 | return Ok(()); | 355 | return Ok(()); |
356 | } | 356 | } |
@@ -379,7 +379,7 @@ fn on_notification( | |||
379 | .to_file_path() | 379 | .to_file_path() |
380 | .map_err(|()| format_err!("invalid uri: {}", uri))?; | 380 | .map_err(|()| format_err!("invalid uri: {}", uri))?; |
381 | if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { | 381 | if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { |
382 | subs.remove_sub(FileId(file_id.0)); | 382 | subs.remove_sub(FileId(file_id.0.into())); |
383 | } | 383 | } |
384 | let params = req::PublishDiagnosticsParams { | 384 | let params = req::PublishDiagnosticsParams { |
385 | uri, | 385 | uri, |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index b5792f3b8..4e895a9a9 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -337,7 +337,10 @@ pub fn handle_runnables( | |||
337 | None => return Ok(None), | 337 | None => return Ok(None), |
338 | }; | 338 | }; |
339 | let file_id = world.analysis().crate_root(crate_id)?; | 339 | let file_id = world.analysis().crate_root(crate_id)?; |
340 | let path = world.vfs.read().file2path(ra_vfs::VfsFile(file_id.0)); | 340 | let path = world |
341 | .vfs | ||
342 | .read() | ||
343 | .file2path(ra_vfs::VfsFile(file_id.0.into())); | ||
341 | let res = world.workspaces.iter().find_map(|ws| { | 344 | let res = world.workspaces.iter().find_map(|ws| { |
342 | let tgt = ws.target_by_root(&path)?; | 345 | let tgt = ws.target_by_root(&path)?; |
343 | let res = CargoTargetSpec { | 346 | let res = CargoTargetSpec { |
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs index c183c25af..ebf2b15cc 100644 --- a/crates/ra_lsp_server/src/server_world.rs +++ b/crates/ra_lsp_server/src/server_world.rs | |||
@@ -49,7 +49,7 @@ impl ServerWorldState { | |||
49 | let (mut vfs, roots) = Vfs::new(roots); | 49 | let (mut vfs, roots) = Vfs::new(roots); |
50 | for r in roots { | 50 | for r in roots { |
51 | let is_local = vfs.root2path(r).starts_with(&root); | 51 | let is_local = vfs.root2path(r).starts_with(&root); |
52 | change.add_root(SourceRootId(r.0), is_local); | 52 | change.add_root(SourceRootId(r.0.into()), is_local); |
53 | } | 53 | } |
54 | 54 | ||
55 | let mut crate_graph = CrateGraph::default(); | 55 | let mut crate_graph = CrateGraph::default(); |
@@ -60,7 +60,7 @@ impl ServerWorldState { | |||
60 | for tgt in pkg.targets(ws) { | 60 | for tgt in pkg.targets(ws) { |
61 | let root = tgt.root(ws); | 61 | let root = tgt.root(ws); |
62 | if let Some(file_id) = vfs.load(root) { | 62 | if let Some(file_id) = vfs.load(root) { |
63 | let file_id = FileId(file_id.0); | 63 | let file_id = FileId(file_id.0.into()); |
64 | let crate_id = crate_graph.add_crate_root(file_id); | 64 | let crate_id = crate_graph.add_crate_root(file_id); |
65 | if tgt.kind(ws) == TargetKind::Lib { | 65 | if tgt.kind(ws) == TargetKind::Lib { |
66 | pkg_to_lib_crate.insert(pkg, crate_id); | 66 | pkg_to_lib_crate.insert(pkg, crate_id); |
@@ -113,14 +113,19 @@ impl ServerWorldState { | |||
113 | if root_path.starts_with(&self.root) { | 113 | if root_path.starts_with(&self.root) { |
114 | self.roots_to_scan -= 1; | 114 | self.roots_to_scan -= 1; |
115 | for (file, path, text) in files { | 115 | for (file, path, text) in files { |
116 | change.add_file(SourceRootId(root.0), FileId(file.0), path, text); | 116 | change.add_file( |
117 | SourceRootId(root.0.into()), | ||
118 | FileId(file.0.into()), | ||
119 | path, | ||
120 | text, | ||
121 | ); | ||
117 | } | 122 | } |
118 | } else { | 123 | } else { |
119 | let files = files | 124 | let files = files |
120 | .into_iter() | 125 | .into_iter() |
121 | .map(|(vfsfile, path, text)| (FileId(vfsfile.0), path, text)) | 126 | .map(|(vfsfile, path, text)| (FileId(vfsfile.0.into()), path, text)) |
122 | .collect(); | 127 | .collect(); |
123 | libs.push((SourceRootId(root.0), files)); | 128 | libs.push((SourceRootId(root.0.into()), files)); |
124 | } | 129 | } |
125 | } | 130 | } |
126 | VfsChange::AddFile { | 131 | VfsChange::AddFile { |
@@ -129,13 +134,18 @@ impl ServerWorldState { | |||
129 | path, | 134 | path, |
130 | text, | 135 | text, |
131 | } => { | 136 | } => { |
132 | change.add_file(SourceRootId(root.0), FileId(file.0), path, text); | 137 | change.add_file( |
138 | SourceRootId(root.0.into()), | ||
139 | FileId(file.0.into()), | ||
140 | path, | ||
141 | text, | ||
142 | ); | ||
133 | } | 143 | } |
134 | VfsChange::RemoveFile { root, file, path } => { | 144 | VfsChange::RemoveFile { root, file, path } => { |
135 | change.remove_file(SourceRootId(root.0), FileId(file.0), path) | 145 | change.remove_file(SourceRootId(root.0.into()), FileId(file.0.into()), path) |
136 | } | 146 | } |
137 | VfsChange::ChangeFile { file, text } => { | 147 | VfsChange::ChangeFile { file, text } => { |
138 | change.change_file(FileId(file.0), text); | 148 | change.change_file(FileId(file.0.into()), text); |
139 | } | 149 | } |
140 | } | 150 | } |
141 | } | 151 | } |
@@ -173,18 +183,18 @@ impl ServerWorld { | |||
173 | .read() | 183 | .read() |
174 | .path2file(&path) | 184 | .path2file(&path) |
175 | .ok_or_else(|| format_err!("unknown file: {}", path.display()))?; | 185 | .ok_or_else(|| format_err!("unknown file: {}", path.display()))?; |
176 | Ok(FileId(file.0)) | 186 | Ok(FileId(file.0.into())) |
177 | } | 187 | } |
178 | 188 | ||
179 | pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> { | 189 | pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> { |
180 | let path = self.vfs.read().file2path(VfsFile(id.0)); | 190 | let path = self.vfs.read().file2path(VfsFile(id.0.into())); |
181 | let url = Url::from_file_path(&path) | 191 | let url = Url::from_file_path(&path) |
182 | .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; | 192 | .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; |
183 | Ok(url) | 193 | Ok(url) |
184 | } | 194 | } |
185 | 195 | ||
186 | pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> { | 196 | pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> { |
187 | let base = self.vfs.read().root2path(VfsRoot(root.0)); | 197 | let base = self.vfs.read().root2path(VfsRoot(root.0.into())); |
188 | let path = path.to_path(base); | 198 | let path = path.to_path(base); |
189 | let url = Url::from_file_path(&path) | 199 | let url = Url::from_file_path(&path) |
190 | .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; | 200 | .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; |
diff --git a/crates/ra_vfs/Cargo.toml b/crates/ra_vfs/Cargo.toml index 7c170cdfc..e637063c9 100644 --- a/crates/ra_vfs/Cargo.toml +++ b/crates/ra_vfs/Cargo.toml | |||
@@ -12,6 +12,7 @@ crossbeam-channel = "0.3.5" | |||
12 | log = "0.4.6" | 12 | log = "0.4.6" |
13 | 13 | ||
14 | thread_worker = { path = "../thread_worker" } | 14 | thread_worker = { path = "../thread_worker" } |
15 | ra_arena = { path = "../ra_arena" } | ||
15 | 16 | ||
16 | [dev-dependencies] | 17 | [dev-dependencies] |
17 | tempfile = "3" | 18 | tempfile = "3" |
diff --git a/crates/ra_vfs/src/arena.rs b/crates/ra_vfs/src/arena.rs deleted file mode 100644 index 6b42ae26d..000000000 --- a/crates/ra_vfs/src/arena.rs +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | use std::{ | ||
2 | marker::PhantomData, | ||
3 | ops::{Index, IndexMut}, | ||
4 | }; | ||
5 | |||
6 | #[derive(Clone, Debug)] | ||
7 | pub(crate) struct Arena<ID: ArenaId, T> { | ||
8 | data: Vec<T>, | ||
9 | _ty: PhantomData<ID>, | ||
10 | } | ||
11 | |||
12 | pub(crate) trait ArenaId { | ||
13 | fn from_u32(id: u32) -> Self; | ||
14 | fn to_u32(self) -> u32; | ||
15 | } | ||
16 | |||
17 | impl<ID: ArenaId, T> Arena<ID, T> { | ||
18 | pub fn alloc(&mut self, value: T) -> ID { | ||
19 | let id = self.data.len() as u32; | ||
20 | self.data.push(value); | ||
21 | ID::from_u32(id) | ||
22 | } | ||
23 | pub fn iter<'a>(&'a self) -> impl Iterator<Item = (ID, &'a T)> { | ||
24 | self.data | ||
25 | .iter() | ||
26 | .enumerate() | ||
27 | .map(|(idx, value)| (ID::from_u32(idx as u32), value)) | ||
28 | } | ||
29 | } | ||
30 | |||
31 | impl<ID: ArenaId, T> Default for Arena<ID, T> { | ||
32 | fn default() -> Arena<ID, T> { | ||
33 | Arena { | ||
34 | data: Vec::new(), | ||
35 | _ty: PhantomData, | ||
36 | } | ||
37 | } | ||
38 | } | ||
39 | |||
40 | impl<ID: ArenaId, T> Index<ID> for Arena<ID, T> { | ||
41 | type Output = T; | ||
42 | fn index(&self, idx: ID) -> &T { | ||
43 | let idx = idx.to_u32() as usize; | ||
44 | &self.data[idx] | ||
45 | } | ||
46 | } | ||
47 | |||
48 | impl<ID: ArenaId, T> IndexMut<ID> for Arena<ID, T> { | ||
49 | fn index_mut(&mut self, idx: ID) -> &mut T { | ||
50 | let idx = idx.to_u32() as usize; | ||
51 | &mut self.data[idx] | ||
52 | } | ||
53 | } | ||
diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index 5bbc3e993..cdea18d73 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs | |||
@@ -13,7 +13,6 @@ | |||
13 | //! VFS is based on a concept of roots: a set of directories on the file system | 13 | //! VFS is based on a concept of roots: a set of directories on the file system |
14 | //! which are watched for changes. Typically, there will be a root for each | 14 | //! which are watched for changes. Typically, there will be a root for each |
15 | //! Cargo package. | 15 | //! Cargo package. |
16 | mod arena; | ||
17 | mod io; | 16 | mod io; |
18 | 17 | ||
19 | use std::{ | 18 | use std::{ |
@@ -32,10 +31,7 @@ use relative_path::RelativePathBuf; | |||
32 | use crossbeam_channel::Receiver; | 31 | use crossbeam_channel::Receiver; |
33 | use walkdir::DirEntry; | 32 | use walkdir::DirEntry; |
34 | use thread_worker::WorkerHandle; | 33 | use thread_worker::WorkerHandle; |
35 | 34 | use ra_arena::{Arena, RawId, impl_arena_id}; | |
36 | use crate::{ | ||
37 | arena::{ArenaId, Arena}, | ||
38 | }; | ||
39 | 35 | ||
40 | pub use crate::io::TaskResult as VfsTask; | 36 | pub use crate::io::TaskResult as VfsTask; |
41 | 37 | ||
@@ -68,29 +64,13 @@ fn has_rs_extension(p: &Path) -> bool { | |||
68 | p.extension() == Some(OsStr::new("rs")) | 64 | p.extension() == Some(OsStr::new("rs")) |
69 | } | 65 | } |
70 | 66 | ||
71 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 67 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
72 | pub struct VfsRoot(pub u32); | 68 | pub struct VfsRoot(pub RawId); |
73 | 69 | impl_arena_id!(VfsRoot); | |
74 | impl ArenaId for VfsRoot { | ||
75 | fn from_u32(idx: u32) -> VfsRoot { | ||
76 | VfsRoot(idx) | ||
77 | } | ||
78 | fn to_u32(self) -> u32 { | ||
79 | self.0 | ||
80 | } | ||
81 | } | ||
82 | |||
83 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
84 | pub struct VfsFile(pub u32); | ||
85 | 70 | ||
86 | impl ArenaId for VfsFile { | 71 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
87 | fn from_u32(idx: u32) -> VfsFile { | 72 | pub struct VfsFile(pub RawId); |
88 | VfsFile(idx) | 73 | impl_arena_id!(VfsFile); |
89 | } | ||
90 | fn to_u32(self) -> u32 { | ||
91 | self.0 | ||
92 | } | ||
93 | } | ||
94 | 74 | ||
95 | struct VfsFileData { | 75 | struct VfsFileData { |
96 | root: VfsRoot, | 76 | root: VfsRoot, |