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