diff options
author | Edwin Cheng <[email protected]> | 2020-03-26 20:26:34 +0000 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2020-03-31 15:20:18 +0100 |
commit | 503cbd3f4b54f3be224d7a4221fa023f0e35d228 (patch) | |
tree | 101dcec6de8da790766a6e76d8f983242d8fcbfd /crates/ra_proc_macro/src/lib.rs | |
parent | fa3c7742af9fbfe5146f4158a6119fa727dcc87a (diff) |
Implement ra_proc_macro client logic
Diffstat (limited to 'crates/ra_proc_macro/src/lib.rs')
-rw-r--r-- | crates/ra_proc_macro/src/lib.rs | 83 |
1 files changed, 65 insertions, 18 deletions
diff --git a/crates/ra_proc_macro/src/lib.rs b/crates/ra_proc_macro/src/lib.rs index 5e21dd487..a0a478dc8 100644 --- a/crates/ra_proc_macro/src/lib.rs +++ b/crates/ra_proc_macro/src/lib.rs | |||
@@ -5,55 +5,102 @@ | |||
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; | ||
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, Clone)] |
32 | pub struct ProcMacroProcessSrv { | 49 | enum ProcMacroClientKind { |
33 | path: PathBuf, | ||
34 | } | ||
35 | |||
36 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
37 | pub enum ProcMacroClient { | ||
38 | Process { process: Arc<ProcMacroProcessSrv> }, | 50 | Process { process: Arc<ProcMacroProcessSrv> }, |
39 | Dummy, | 51 | Dummy, |
40 | } | 52 | } |
41 | 53 | ||
54 | #[derive(Debug, Clone)] | ||
55 | pub struct ProcMacroClient { | ||
56 | kind: ProcMacroClientKind, | ||
57 | } | ||
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 process = ProcMacroProcessSrv::run(process_path)?; |
45 | ProcMacroClient::Process { process: Arc::new(process) } | 62 | Ok(ProcMacroClient { kind: ProcMacroClientKind::Process { process: Arc::new(process) } }) |
46 | } | 63 | } |
47 | 64 | ||
48 | pub fn dummy() -> ProcMacroClient { | 65 | pub fn dummy() -> ProcMacroClient { |
49 | ProcMacroClient::Dummy | 66 | ProcMacroClient { kind: ProcMacroClientKind::Dummy } |
50 | } | 67 | } |
51 | 68 | ||
52 | pub fn by_dylib_path( | 69 | pub fn by_dylib_path( |
53 | &self, | 70 | &self, |
54 | _dylib_path: &Path, | 71 | dylib_path: &Path, |
55 | ) -> Vec<(SmolStr, Arc<dyn ra_tt::TokenExpander>)> { | 72 | ) -> Vec<(SmolStr, Arc<dyn ra_tt::TokenExpander>)> { |
56 | // FIXME: return empty for now | 73 | match &self.kind { |
57 | vec![] | 74 | ProcMacroClientKind::Dummy => vec![], |
75 | ProcMacroClientKind::Process { process } => { | ||
76 | let macros = match process.find_proc_macros(dylib_path) { | ||
77 | Err(err) => { | ||
78 | eprintln!("Fail to find proc macro. Error: {:#?}", err); | ||
79 | return vec![]; | ||
80 | } | ||
81 | Ok(macros) => macros, | ||
82 | }; | ||
83 | |||
84 | macros | ||
85 | .into_iter() | ||
86 | .filter_map(|(name, kind)| { | ||
87 | // FIXME: Support custom derive only for now. | ||
88 | match kind { | ||
89 | ProcMacroKind::CustomDerive => { | ||
90 | let name = SmolStr::new(&name); | ||
91 | let expander: Arc<dyn ra_tt::TokenExpander> = | ||
92 | Arc::new(ProcMacroProcessExpander { | ||
93 | process: process.clone(), | ||
94 | name: name.clone(), | ||
95 | dylib_path: dylib_path.into(), | ||
96 | }); | ||
97 | Some((name, expander)) | ||
98 | } | ||
99 | _ => None, | ||
100 | } | ||
101 | }) | ||
102 | .collect() | ||
103 | } | ||
104 | } | ||
58 | } | 105 | } |
59 | } | 106 | } |