]> git.proxmox.com Git - rustc.git/blob - src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_1_63/mod.rs
New upstream version 1.69.0+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / proc-macro-srv / src / abis / abi_1_63 / mod.rs
1 //! Macro ABI for version 1.63 of rustc
2
3 #[allow(dead_code)]
4 #[doc(hidden)]
5 mod proc_macro;
6
7 #[allow(dead_code)]
8 #[doc(hidden)]
9 mod ra_server;
10
11 use libloading::Library;
12 use proc_macro_api::ProcMacroKind;
13
14 use super::tt;
15 use super::PanicMessage;
16
17 pub use ra_server::TokenStream;
18
19 pub(crate) struct Abi {
20 exported_macros: Vec<proc_macro::bridge::client::ProcMacro>,
21 }
22
23 impl From<proc_macro::bridge::PanicMessage> for PanicMessage {
24 fn from(p: proc_macro::bridge::PanicMessage) -> Self {
25 Self { message: p.as_str().map(|s| s.to_string()) }
26 }
27 }
28
29 impl Abi {
30 pub unsafe fn from_lib(lib: &Library, symbol_name: String) -> Result<Abi, libloading::Error> {
31 let macros: libloading::Symbol<'_, &&[proc_macro::bridge::client::ProcMacro]> =
32 lib.get(symbol_name.as_bytes())?;
33 Ok(Self { exported_macros: macros.to_vec() })
34 }
35
36 pub fn expand(
37 &self,
38 macro_name: &str,
39 macro_body: &tt::Subtree,
40 attributes: Option<&tt::Subtree>,
41 ) -> Result<tt::Subtree, PanicMessage> {
42 let parsed_body = TokenStream::with_subtree(macro_body.clone());
43
44 let parsed_attributes =
45 attributes.map_or(TokenStream::new(), |attr| TokenStream::with_subtree(attr.clone()));
46
47 for proc_macro in &self.exported_macros {
48 match proc_macro {
49 proc_macro::bridge::client::ProcMacro::CustomDerive {
50 trait_name, client, ..
51 } if *trait_name == macro_name => {
52 let res = client.run(
53 &proc_macro::bridge::server::SameThread,
54 ra_server::RustAnalyzer::default(),
55 parsed_body,
56 true,
57 );
58 return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
59 }
60 proc_macro::bridge::client::ProcMacro::Bang { name, client }
61 if *name == macro_name =>
62 {
63 let res = client.run(
64 &proc_macro::bridge::server::SameThread,
65 ra_server::RustAnalyzer::default(),
66 parsed_body,
67 true,
68 );
69 return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
70 }
71 proc_macro::bridge::client::ProcMacro::Attr { name, client }
72 if *name == macro_name =>
73 {
74 let res = client.run(
75 &proc_macro::bridge::server::SameThread,
76 ra_server::RustAnalyzer::default(),
77 parsed_attributes,
78 parsed_body,
79 true,
80 );
81 return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
82 }
83 _ => continue,
84 }
85 }
86
87 Err(proc_macro::bridge::PanicMessage::String("Nothing to expand".to_string()).into())
88 }
89
90 pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
91 self.exported_macros
92 .iter()
93 .map(|proc_macro| match proc_macro {
94 proc_macro::bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
95 (trait_name.to_string(), ProcMacroKind::CustomDerive)
96 }
97 proc_macro::bridge::client::ProcMacro::Bang { name, .. } => {
98 (name.to_string(), ProcMacroKind::FuncLike)
99 }
100 proc_macro::bridge::client::ProcMacro::Attr { name, .. } => {
101 (name.to_string(), ProcMacroKind::Attr)
102 }
103 })
104 .collect()
105 }
106 }