diff options
Diffstat (limited to 'crates/ra_proc_macro_srv/src/lib.rs')
-rw-r--r-- | crates/ra_proc_macro_srv/src/lib.rs | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/crates/ra_proc_macro_srv/src/lib.rs b/crates/ra_proc_macro_srv/src/lib.rs index 3aca859db..0954bd6b5 100644 --- a/crates/ra_proc_macro_srv/src/lib.rs +++ b/crates/ra_proc_macro_srv/src/lib.rs | |||
@@ -21,28 +21,40 @@ mod dylib; | |||
21 | 21 | ||
22 | use proc_macro::bridge::client::TokenStream; | 22 | use proc_macro::bridge::client::TokenStream; |
23 | use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask}; | 23 | use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask}; |
24 | use std::path::Path; | 24 | use std::{ |
25 | 25 | collections::{hash_map::Entry, HashMap}, | |
26 | pub(crate) fn expand_task(task: &ExpansionTask) -> Result<ExpansionResult, String> { | 26 | path::{Path, PathBuf}, |
27 | let expander = create_expander(&task.lib); | 27 | }; |
28 | |||
29 | #[derive(Default)] | ||
30 | pub(crate) struct ProcMacroSrv { | ||
31 | expanders: HashMap<PathBuf, dylib::Expander>, | ||
32 | } | ||
28 | 33 | ||
29 | match expander.expand(&task.macro_name, &task.macro_body, task.attributes.as_ref()) { | 34 | impl ProcMacroSrv { |
30 | Ok(expansion) => Ok(ExpansionResult { expansion }), | 35 | pub fn expand(&mut self, task: &ExpansionTask) -> Result<ExpansionResult, String> { |
31 | Err(msg) => { | 36 | let expander = self.expander(&task.lib)?; |
32 | Err(format!("Cannot perform expansion for {}: error {:?}", &task.macro_name, msg)) | 37 | match expander.expand(&task.macro_name, &task.macro_body, task.attributes.as_ref()) { |
38 | Ok(expansion) => Ok(ExpansionResult { expansion }), | ||
39 | Err(msg) => { | ||
40 | Err(format!("Cannot perform expansion for {}: error {:?}", &task.macro_name, msg)) | ||
41 | } | ||
33 | } | 42 | } |
34 | } | 43 | } |
35 | } | ||
36 | |||
37 | pub(crate) fn list_macros(task: &ListMacrosTask) -> ListMacrosResult { | ||
38 | let expander = create_expander(&task.lib); | ||
39 | 44 | ||
40 | ListMacrosResult { macros: expander.list_macros() } | 45 | pub fn list_macros(&mut self, task: &ListMacrosTask) -> Result<ListMacrosResult, String> { |
41 | } | 46 | let expander = self.expander(&task.lib)?; |
47 | Ok(ListMacrosResult { macros: expander.list_macros() }) | ||
48 | } | ||
42 | 49 | ||
43 | fn create_expander(lib: &Path) -> dylib::Expander { | 50 | fn expander(&mut self, path: &Path) -> Result<&dylib::Expander, String> { |
44 | dylib::Expander::new(lib) | 51 | Ok(match self.expanders.entry(path.to_path_buf()) { |
45 | .unwrap_or_else(|err| panic!("Cannot create expander for {}: {:?}", lib.display(), err)) | 52 | Entry::Vacant(v) => v.insert(dylib::Expander::new(path).map_err(|err| { |
53 | format!("Cannot create expander for {}: {:?}", path.display(), err) | ||
54 | })?), | ||
55 | Entry::Occupied(e) => e.into_mut(), | ||
56 | }) | ||
57 | } | ||
46 | } | 58 | } |
47 | 59 | ||
48 | pub mod cli; | 60 | pub mod cli; |