From 349e6c62ada1fa45a8b80edb877b5e7c9d0c306d Mon Sep 17 00:00:00 2001 From: Pavan Kumar Sunkara Date: Thu, 13 Aug 2020 02:57:26 +0200 Subject: Rename ra_proc_macro_srv -> proc_macro_srv --- crates/proc_macro_srv/src/lib.rs | 69 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 crates/proc_macro_srv/src/lib.rs (limited to 'crates/proc_macro_srv/src/lib.rs') diff --git a/crates/proc_macro_srv/src/lib.rs b/crates/proc_macro_srv/src/lib.rs new file mode 100644 index 000000000..1fc2eef82 --- /dev/null +++ b/crates/proc_macro_srv/src/lib.rs @@ -0,0 +1,69 @@ +//! RA Proc Macro Server +//! +//! This library is able to call compiled Rust custom derive dynamic libraries on arbitrary code. +//! The general idea here is based on https://github.com/fedochet/rust-proc-macro-expander. +//! +//! But we adapt it to better fit RA needs: +//! +//! * We use `tt` for proc-macro `TokenStream` server, it is easier to manipulate and interact with +//! RA than `proc-macro2` token stream. +//! * By **copying** the whole rustc `lib_proc_macro` code, we are able to build this with `stable` +//! rustc rather than `unstable`. (Although in gerenal ABI compatibility is still an issue) + +#[allow(dead_code)] +#[doc(hidden)] +mod proc_macro; + +#[doc(hidden)] +mod rustc_server; + +mod dylib; + +use proc_macro::bridge::client::TokenStream; +use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask}; +use std::{ + collections::{hash_map::Entry, HashMap}, + fs, + path::{Path, PathBuf}, + time::SystemTime, +}; + +#[derive(Default)] +pub(crate) struct ProcMacroSrv { + expanders: HashMap<(PathBuf, SystemTime), dylib::Expander>, +} + +impl ProcMacroSrv { + pub fn expand(&mut self, task: &ExpansionTask) -> Result { + let expander = self.expander(&task.lib)?; + match expander.expand(&task.macro_name, &task.macro_body, task.attributes.as_ref()) { + Ok(expansion) => Ok(ExpansionResult { expansion }), + Err(msg) => { + Err(format!("Cannot perform expansion for {}: error {:?}", &task.macro_name, msg)) + } + } + } + + pub fn list_macros(&mut self, task: &ListMacrosTask) -> Result { + let expander = self.expander(&task.lib)?; + Ok(ListMacrosResult { macros: expander.list_macros() }) + } + + fn expander(&mut self, path: &Path) -> Result<&dylib::Expander, String> { + let time = fs::metadata(path).and_then(|it| it.modified()).map_err(|err| { + format!("Failed to get file metadata for {}: {:?}", path.display(), err) + })?; + + Ok(match self.expanders.entry((path.to_path_buf(), time)) { + Entry::Vacant(v) => v.insert(dylib::Expander::new(path).map_err(|err| { + format!("Cannot create expander for {}: {:?}", path.display(), err) + })?), + Entry::Occupied(e) => e.into_mut(), + }) + } +} + +pub mod cli; + +#[cfg(test)] +mod tests; -- cgit v1.2.3 From 2119dc23e80d77f1abc789e3d99c34d429e17905 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 13 Aug 2020 12:07:28 +0200 Subject: Rename ra_proc_macro -> proc_macro_api --- crates/proc_macro_srv/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/proc_macro_srv/src/lib.rs') diff --git a/crates/proc_macro_srv/src/lib.rs b/crates/proc_macro_srv/src/lib.rs index 1fc2eef82..7e4e4ad50 100644 --- a/crates/proc_macro_srv/src/lib.rs +++ b/crates/proc_macro_srv/src/lib.rs @@ -8,7 +8,7 @@ //! * We use `tt` for proc-macro `TokenStream` server, it is easier to manipulate and interact with //! RA than `proc-macro2` token stream. //! * By **copying** the whole rustc `lib_proc_macro` code, we are able to build this with `stable` -//! rustc rather than `unstable`. (Although in gerenal ABI compatibility is still an issue) +//! rustc rather than `unstable`. (Although in general ABI compatibility is still an issue)… #[allow(dead_code)] #[doc(hidden)] @@ -20,7 +20,7 @@ mod rustc_server; mod dylib; use proc_macro::bridge::client::TokenStream; -use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask}; +use proc_macro_api::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask}; use std::{ collections::{hash_map::Entry, HashMap}, fs, -- cgit v1.2.3