diff options
Diffstat (limited to 'crates/ra_proc_macro_srv')
-rw-r--r-- | crates/ra_proc_macro_srv/src/cli.rs | 8 | ||||
-rw-r--r-- | crates/ra_proc_macro_srv/src/dylib.rs | 68 | ||||
-rw-r--r-- | crates/ra_proc_macro_srv/src/lib.rs | 46 | ||||
-rw-r--r-- | crates/ra_proc_macro_srv/src/tests/utils.rs | 6 |
4 files changed, 70 insertions, 58 deletions
diff --git a/crates/ra_proc_macro_srv/src/cli.rs b/crates/ra_proc_macro_srv/src/cli.rs index 7282e5b9b..1437794c9 100644 --- a/crates/ra_proc_macro_srv/src/cli.rs +++ b/crates/ra_proc_macro_srv/src/cli.rs | |||
@@ -1,15 +1,17 @@ | |||
1 | //! Driver for proc macro server | 1 | //! Driver for proc macro server |
2 | 2 | ||
3 | use crate::{expand_task, list_macros}; | 3 | use crate::ProcMacroSrv; |
4 | use ra_proc_macro::msg::{self, Message}; | 4 | use ra_proc_macro::msg::{self, Message}; |
5 | use std::io; | 5 | use std::io; |
6 | 6 | ||
7 | pub fn run() -> io::Result<()> { | 7 | pub fn run() -> io::Result<()> { |
8 | let mut srv = ProcMacroSrv::default(); | ||
9 | |||
8 | while let Some(req) = read_request()? { | 10 | while let Some(req) = read_request()? { |
9 | let res = match req { | 11 | let res = match req { |
10 | msg::Request::ListMacro(task) => Ok(msg::Response::ListMacro(list_macros(&task))), | 12 | msg::Request::ListMacro(task) => srv.list_macros(&task).map(msg::Response::ListMacro), |
11 | msg::Request::ExpansionMacro(task) => { | 13 | msg::Request::ExpansionMacro(task) => { |
12 | expand_task(&task).map(msg::Response::ExpansionMacro) | 14 | srv.expand(&task).map(msg::Response::ExpansionMacro) |
13 | } | 15 | } |
14 | }; | 16 | }; |
15 | 17 | ||
diff --git a/crates/ra_proc_macro_srv/src/dylib.rs b/crates/ra_proc_macro_srv/src/dylib.rs index d202eb0fd..476bc5c01 100644 --- a/crates/ra_proc_macro_srv/src/dylib.rs +++ b/crates/ra_proc_macro_srv/src/dylib.rs | |||
@@ -112,7 +112,7 @@ impl ProcMacroLibraryLibloading { | |||
112 | type ProcMacroLibraryImpl = ProcMacroLibraryLibloading; | 112 | type ProcMacroLibraryImpl = ProcMacroLibraryLibloading; |
113 | 113 | ||
114 | pub struct Expander { | 114 | pub struct Expander { |
115 | libs: Vec<ProcMacroLibraryImpl>, | 115 | inner: ProcMacroLibraryImpl, |
116 | } | 116 | } |
117 | 117 | ||
118 | impl Expander { | 118 | impl Expander { |
@@ -125,7 +125,7 @@ impl Expander { | |||
125 | 125 | ||
126 | let library = ProcMacroLibraryImpl::open(&lib).map_err(|e| e.to_string())?; | 126 | let library = ProcMacroLibraryImpl::open(&lib).map_err(|e| e.to_string())?; |
127 | 127 | ||
128 | Ok(Expander { libs: vec![library] }) | 128 | Ok(Expander { inner: library }) |
129 | } | 129 | } |
130 | 130 | ||
131 | pub fn expand( | 131 | pub fn expand( |
@@ -141,38 +141,36 @@ impl Expander { | |||
141 | TokenStream::with_subtree(attr.clone()) | 141 | TokenStream::with_subtree(attr.clone()) |
142 | }); | 142 | }); |
143 | 143 | ||
144 | for lib in &self.libs { | 144 | for proc_macro in &self.inner.exported_macros { |
145 | for proc_macro in &lib.exported_macros { | 145 | match proc_macro { |
146 | match proc_macro { | 146 | bridge::client::ProcMacro::CustomDerive { trait_name, client, .. } |
147 | bridge::client::ProcMacro::CustomDerive { trait_name, client, .. } | 147 | if *trait_name == macro_name => |
148 | if *trait_name == macro_name => | 148 | { |
149 | { | 149 | let res = client.run( |
150 | let res = client.run( | 150 | &crate::proc_macro::bridge::server::SameThread, |
151 | &crate::proc_macro::bridge::server::SameThread, | 151 | crate::rustc_server::Rustc::default(), |
152 | crate::rustc_server::Rustc::default(), | 152 | parsed_body, |
153 | parsed_body, | 153 | ); |
154 | ); | 154 | return res.map(|it| it.subtree); |
155 | return res.map(|it| it.subtree); | 155 | } |
156 | } | 156 | bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => { |
157 | bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => { | 157 | let res = client.run( |
158 | let res = client.run( | 158 | &crate::proc_macro::bridge::server::SameThread, |
159 | &crate::proc_macro::bridge::server::SameThread, | 159 | crate::rustc_server::Rustc::default(), |
160 | crate::rustc_server::Rustc::default(), | 160 | parsed_body, |
161 | parsed_body, | 161 | ); |
162 | ); | 162 | return res.map(|it| it.subtree); |
163 | return res.map(|it| it.subtree); | 163 | } |
164 | } | 164 | bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => { |
165 | bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => { | 165 | let res = client.run( |
166 | let res = client.run( | 166 | &crate::proc_macro::bridge::server::SameThread, |
167 | &crate::proc_macro::bridge::server::SameThread, | 167 | crate::rustc_server::Rustc::default(), |
168 | crate::rustc_server::Rustc::default(), | 168 | parsed_attributes, |
169 | parsed_attributes, | 169 | parsed_body, |
170 | parsed_body, | 170 | ); |
171 | ); | 171 | return res.map(|it| it.subtree); |
172 | return res.map(|it| it.subtree); | ||
173 | } | ||
174 | _ => continue, | ||
175 | } | 172 | } |
173 | _ => continue, | ||
176 | } | 174 | } |
177 | } | 175 | } |
178 | 176 | ||
@@ -180,9 +178,9 @@ impl Expander { | |||
180 | } | 178 | } |
181 | 179 | ||
182 | pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> { | 180 | pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> { |
183 | self.libs | 181 | self.inner |
182 | .exported_macros | ||
184 | .iter() | 183 | .iter() |
185 | .flat_map(|it| &it.exported_macros) | ||
186 | .map(|proc_macro| match proc_macro { | 184 | .map(|proc_macro| match proc_macro { |
187 | bridge::client::ProcMacro::CustomDerive { trait_name, .. } => { | 185 | bridge::client::ProcMacro::CustomDerive { trait_name, .. } => { |
188 | (trait_name.to_string(), ProcMacroKind::CustomDerive) | 186 | (trait_name.to_string(), ProcMacroKind::CustomDerive) |
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; |
diff --git a/crates/ra_proc_macro_srv/src/tests/utils.rs b/crates/ra_proc_macro_srv/src/tests/utils.rs index 2139ec7a4..646a427c5 100644 --- a/crates/ra_proc_macro_srv/src/tests/utils.rs +++ b/crates/ra_proc_macro_srv/src/tests/utils.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! utils used in proc-macro tests | 1 | //! utils used in proc-macro tests |
2 | 2 | ||
3 | use crate::dylib; | 3 | use crate::dylib; |
4 | use crate::list_macros; | 4 | use crate::ProcMacroSrv; |
5 | pub use difference::Changeset as __Changeset; | 5 | pub use difference::Changeset as __Changeset; |
6 | use ra_proc_macro::ListMacrosTask; | 6 | use ra_proc_macro::ListMacrosTask; |
7 | use std::str::FromStr; | 7 | use std::str::FromStr; |
@@ -59,7 +59,7 @@ pub fn assert_expand( | |||
59 | pub fn list(crate_name: &str, version: &str) -> Vec<String> { | 59 | pub fn list(crate_name: &str, version: &str) -> Vec<String> { |
60 | let path = fixtures::dylib_path(crate_name, version); | 60 | let path = fixtures::dylib_path(crate_name, version); |
61 | let task = ListMacrosTask { lib: path }; | 61 | let task = ListMacrosTask { lib: path }; |
62 | 62 | let mut srv = ProcMacroSrv::default(); | |
63 | let res = list_macros(&task); | 63 | let res = srv.list_macros(&task).unwrap(); |
64 | res.macros.into_iter().map(|(name, kind)| format!("{} [{:?}]", name, kind)).collect() | 64 | res.macros.into_iter().map(|(name, kind)| format!("{} [{:?}]", name, kind)).collect() |
65 | } | 65 | } |