aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_proc_macro_srv/src
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2020-04-24 03:23:01 +0100
committerEdwin Cheng <[email protected]>2020-04-26 10:17:37 +0100
commit3e24444aee9db36d8de530dee9c0283ce793c6fd (patch)
tree563cda6d1d536a55d24bd153bcd4188c68ae1998 /crates/ra_proc_macro_srv/src
parentef67e0a497a3f0b65c11bf443e0d35c8e51bd26f (diff)
Cacheproc-macro dlls
Diffstat (limited to 'crates/ra_proc_macro_srv/src')
-rw-r--r--crates/ra_proc_macro_srv/src/cli.rs8
-rw-r--r--crates/ra_proc_macro_srv/src/dylib.rs68
-rw-r--r--crates/ra_proc_macro_srv/src/lib.rs46
-rw-r--r--crates/ra_proc_macro_srv/src/tests/utils.rs6
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
3use crate::{expand_task, list_macros}; 3use crate::ProcMacroSrv;
4use ra_proc_macro::msg::{self, Message}; 4use ra_proc_macro::msg::{self, Message};
5use std::io; 5use std::io;
6 6
7pub fn run() -> io::Result<()> { 7pub 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 {
112type ProcMacroLibraryImpl = ProcMacroLibraryLibloading; 112type ProcMacroLibraryImpl = ProcMacroLibraryLibloading;
113 113
114pub struct Expander { 114pub struct Expander {
115 libs: Vec<ProcMacroLibraryImpl>, 115 inner: ProcMacroLibraryImpl,
116} 116}
117 117
118impl Expander { 118impl 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
22use proc_macro::bridge::client::TokenStream; 22use proc_macro::bridge::client::TokenStream;
23use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask}; 23use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask};
24use std::path::Path; 24use std::{
25 25 collections::{hash_map::Entry, HashMap},
26pub(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)]
30pub(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()) { 34impl 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
37pub(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
43fn 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
48pub mod cli; 60pub 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
3use crate::dylib; 3use crate::dylib;
4use crate::list_macros; 4use crate::ProcMacroSrv;
5pub use difference::Changeset as __Changeset; 5pub use difference::Changeset as __Changeset;
6use ra_proc_macro::ListMacrosTask; 6use ra_proc_macro::ListMacrosTask;
7use std::str::FromStr; 7use std::str::FromStr;
@@ -59,7 +59,7 @@ pub fn assert_expand(
59pub fn list(crate_name: &str, version: &str) -> Vec<String> { 59pub 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}