diff options
Diffstat (limited to 'crates/ra_proc_macro/src/lib.rs')
-rw-r--r-- | crates/ra_proc_macro/src/lib.rs | 85 |
1 files changed, 67 insertions, 18 deletions
diff --git a/crates/ra_proc_macro/src/lib.rs b/crates/ra_proc_macro/src/lib.rs index 5e21dd487..51fbb046a 100644 --- a/crates/ra_proc_macro/src/lib.rs +++ b/crates/ra_proc_macro/src/lib.rs | |||
@@ -5,55 +5,104 @@ | |||
5 | //! is used to provide basic infrastructure for communication between two | 5 | //! is used to provide basic infrastructure for communication between two |
6 | //! processes: Client (RA itself), Server (the external program) | 6 | //! processes: Client (RA itself), Server (the external program) |
7 | 7 | ||
8 | mod rpc; | ||
9 | mod process; | ||
10 | pub mod msg; | ||
11 | |||
12 | use process::{ProcMacroProcessSrv, ProcMacroProcessThread}; | ||
8 | use ra_tt::{SmolStr, Subtree}; | 13 | use ra_tt::{SmolStr, Subtree}; |
14 | use rpc::ProcMacroKind; | ||
9 | use std::{ | 15 | use std::{ |
10 | path::{Path, PathBuf}, | 16 | path::{Path, PathBuf}, |
11 | sync::Arc, | 17 | sync::Arc, |
12 | }; | 18 | }; |
13 | 19 | ||
14 | #[derive(Debug, Clone, PartialEq, Eq)] | 20 | pub use rpc::{ExpansionResult, ExpansionTask}; |
21 | |||
22 | #[derive(Debug, Clone)] | ||
15 | pub struct ProcMacroProcessExpander { | 23 | pub struct ProcMacroProcessExpander { |
16 | process: Arc<ProcMacroProcessSrv>, | 24 | process: Arc<ProcMacroProcessSrv>, |
25 | dylib_path: PathBuf, | ||
17 | name: SmolStr, | 26 | name: SmolStr, |
18 | } | 27 | } |
19 | 28 | ||
29 | impl Eq for ProcMacroProcessExpander {} | ||
30 | impl PartialEq for ProcMacroProcessExpander { | ||
31 | fn eq(&self, other: &Self) -> bool { | ||
32 | self.name == other.name | ||
33 | && self.dylib_path == other.dylib_path | ||
34 | && Arc::ptr_eq(&self.process, &other.process) | ||
35 | } | ||
36 | } | ||
37 | |||
20 | impl ra_tt::TokenExpander for ProcMacroProcessExpander { | 38 | impl ra_tt::TokenExpander for ProcMacroProcessExpander { |
21 | fn expand( | 39 | fn expand( |
22 | &self, | 40 | &self, |
23 | _subtree: &Subtree, | 41 | subtree: &Subtree, |
24 | _attr: Option<&Subtree>, | 42 | _attr: Option<&Subtree>, |
25 | ) -> Result<Subtree, ra_tt::ExpansionError> { | 43 | ) -> Result<Subtree, ra_tt::ExpansionError> { |
26 | // FIXME: do nothing for now | 44 | self.process.custom_derive(&self.dylib_path, subtree, &self.name) |
27 | Ok(Subtree::default()) | ||
28 | } | 45 | } |
29 | } | 46 | } |
30 | 47 | ||
31 | #[derive(Debug, Clone, PartialEq, Eq)] | 48 | #[derive(Debug)] |
32 | pub struct ProcMacroProcessSrv { | 49 | enum ProcMacroClientKind { |
33 | path: PathBuf, | 50 | Process { process: Arc<ProcMacroProcessSrv>, thread: ProcMacroProcessThread }, |
51 | Dummy, | ||
34 | } | 52 | } |
35 | 53 | ||
36 | #[derive(Debug, Clone, PartialEq, Eq)] | 54 | #[derive(Debug)] |
37 | pub enum ProcMacroClient { | 55 | pub struct ProcMacroClient { |
38 | Process { process: Arc<ProcMacroProcessSrv> }, | 56 | kind: ProcMacroClientKind, |
39 | Dummy, | ||
40 | } | 57 | } |
41 | 58 | ||
42 | impl ProcMacroClient { | 59 | impl ProcMacroClient { |
43 | pub fn extern_process(process_path: &Path) -> ProcMacroClient { | 60 | pub fn extern_process(process_path: &Path) -> Result<ProcMacroClient, std::io::Error> { |
44 | let process = ProcMacroProcessSrv { path: process_path.into() }; | 61 | let (thread, process) = ProcMacroProcessSrv::run(process_path)?; |
45 | ProcMacroClient::Process { process: Arc::new(process) } | 62 | Ok(ProcMacroClient { |
63 | kind: ProcMacroClientKind::Process { process: Arc::new(process), thread }, | ||
64 | }) | ||
46 | } | 65 | } |
47 | 66 | ||
48 | pub fn dummy() -> ProcMacroClient { | 67 | pub fn dummy() -> ProcMacroClient { |
49 | ProcMacroClient::Dummy | 68 | ProcMacroClient { kind: ProcMacroClientKind::Dummy } |
50 | } | 69 | } |
51 | 70 | ||
52 | pub fn by_dylib_path( | 71 | pub fn by_dylib_path( |
53 | &self, | 72 | &self, |
54 | _dylib_path: &Path, | 73 | dylib_path: &Path, |
55 | ) -> Vec<(SmolStr, Arc<dyn ra_tt::TokenExpander>)> { | 74 | ) -> Vec<(SmolStr, Arc<dyn ra_tt::TokenExpander>)> { |
56 | // FIXME: return empty for now | 75 | match &self.kind { |
57 | vec![] | 76 | ProcMacroClientKind::Dummy => vec![], |
77 | ProcMacroClientKind::Process { process, .. } => { | ||
78 | let macros = match process.find_proc_macros(dylib_path) { | ||
79 | Err(err) => { | ||
80 | eprintln!("Fail to find proc macro. Error: {:#?}", err); | ||
81 | return vec![]; | ||
82 | } | ||
83 | Ok(macros) => macros, | ||
84 | }; | ||
85 | |||
86 | macros | ||
87 | .into_iter() | ||
88 | .filter_map(|(name, kind)| { | ||
89 | // FIXME: Support custom derive only for now. | ||
90 | match kind { | ||
91 | ProcMacroKind::CustomDerive => { | ||
92 | let name = SmolStr::new(&name); | ||
93 | let expander: Arc<dyn ra_tt::TokenExpander> = | ||
94 | Arc::new(ProcMacroProcessExpander { | ||
95 | process: process.clone(), | ||
96 | name: name.clone(), | ||
97 | dylib_path: dylib_path.into(), | ||
98 | }); | ||
99 | Some((name, expander)) | ||
100 | } | ||
101 | _ => None, | ||
102 | } | ||
103 | }) | ||
104 | .collect() | ||
105 | } | ||
106 | } | ||
58 | } | 107 | } |
59 | } | 108 | } |