Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/proc_macro_api/src/lib.rs')
| -rw-r--r-- | crates/proc_macro_api/src/lib.rs | 110 |
1 files changed, 58 insertions, 52 deletions
diff --git a/crates/proc_macro_api/src/lib.rs b/crates/proc_macro_api/src/lib.rs index 04a4d7ca58..55754325f6 100644 --- a/crates/proc_macro_api/src/lib.rs +++ b/crates/proc_macro_api/src/lib.rs @@ -26,16 +26,33 @@ pub use rpc::{ }; pub use version::{read_dylib_info, RustCInfo}; +/// A handle to an external process which load dylibs with macros (.so or .dll) +/// and runs actual macro expansion functions. +#[derive(Debug)] +pub struct ProcMacroServer { + /// Currently, the proc macro process expands all procedural macros sequentially. + /// + /// That means that concurrent salsa requests may block each other when expanding proc macros, + /// which is unfortunate, but simple and good enough for the time being. + /// + /// Therefore, we just wrap the `ProcMacroProcessSrv` in a mutex here. + process: Arc<Mutex<ProcMacroProcessSrv>>, +} + +/// A handle to a specific macro (a `#[proc_macro]` annotated function). +/// +/// It exists withing a context of a specific [`ProcMacroProcess`] -- currently +/// we share a single expander process for all macros. #[derive(Debug, Clone)] -pub struct ProcMacroProcessExpander { +pub struct ProcMacro { process: Arc<Mutex<ProcMacroProcessSrv>>, dylib_path: AbsPathBuf, name: SmolStr, kind: ProcMacroKind, } -impl Eq for ProcMacroProcessExpander {} -impl PartialEq for ProcMacroProcessExpander { +impl Eq for ProcMacro {} +impl PartialEq for ProcMacro { fn eq(&self, other: &Self) -> bool { self.name == other.name && self.kind == other.kind @@ -44,60 +61,17 @@ impl PartialEq for ProcMacroProcessExpander { } } -impl ProcMacroProcessExpander { - pub fn name(&self) -> &str { - &self.name - } - - pub fn kind(&self) -> ProcMacroKind { - self.kind - } - - pub fn expand( - &self, - subtree: &Subtree, - attr: Option<&Subtree>, - env: Vec<(String, String)>, - ) -> Result<Subtree, tt::ExpansionError> { - let task = ExpansionTask { - macro_body: FlatTree::new(subtree), - macro_name: self.name.to_string(), - attributes: attr.map(FlatTree::new), - lib: self.dylib_path.to_path_buf().into(), - env, - }; - - let result: ExpansionResult = self - .process - .lock() - .unwrap_or_else(|e| e.into_inner()) - .send_task(msg::Request::ExpansionMacro(task))?; - Ok(result.expansion.to_subtree()) - } -} - -#[derive(Debug)] -pub struct ProcMacroClient { - /// Currently, the proc macro process expands all procedural macros sequentially. - /// - /// That means that concurrent salsa requests may block each other when expanding proc macros, - /// which is unfortunate, but simple and good enough for the time being. - /// - /// Therefore, we just wrap the `ProcMacroProcessSrv` in a mutex here. - process: Arc<Mutex<ProcMacroProcessSrv>>, -} - -impl ProcMacroClient { +impl ProcMacroServer { /// Spawns an external process as the proc macro server and returns a client connected to it. - pub fn extern_process( + pub fn spawn( process_path: AbsPathBuf, args: impl IntoIterator<Item = impl AsRef<OsStr>>, - ) -> io::Result<ProcMacroClient> { + ) -> io::Result<ProcMacroServer> { let process = ProcMacroProcessSrv::run(process_path, args)?; - Ok(ProcMacroClient { process: Arc::new(Mutex::new(process)) }) + Ok(ProcMacroServer { process: Arc::new(Mutex::new(process)) }) } - pub fn by_dylib_path(&self, dylib_path: &AbsPath) -> Vec<ProcMacroProcessExpander> { + pub fn load_dylib(&self, dylib_path: &AbsPath) -> Vec<ProcMacro> { let _p = profile::span("ProcMacroClient::by_dylib_path"); match version::read_dylib_info(dylib_path) { Ok(info) => { @@ -129,7 +103,7 @@ impl ProcMacroClient { macros .into_iter() - .map(|(name, kind)| ProcMacroProcessExpander { + .map(|(name, kind)| ProcMacro { process: self.process.clone(), name: name.into(), kind, @@ -138,3 +112,35 @@ impl ProcMacroClient { .collect() } } + +impl ProcMacro { + pub fn name(&self) -> &str { + &self.name + } + + pub fn kind(&self) -> ProcMacroKind { + self.kind + } + + pub fn expand( + &self, + subtree: &Subtree, + attr: Option<&Subtree>, + env: Vec<(String, String)>, + ) -> Result<Subtree, tt::ExpansionError> { + let task = ExpansionTask { + macro_body: FlatTree::new(subtree), + macro_name: self.name.to_string(), + attributes: attr.map(FlatTree::new), + lib: self.dylib_path.to_path_buf().into(), + env, + }; + + let result: ExpansionResult = self + .process + .lock() + .unwrap_or_else(|e| e.into_inner()) + .send_task(msg::Request::ExpansionMacro(task))?; + Ok(result.expansion.to_subtree()) + } +} |