Cacheproc-macro dlls

This commit is contained in:
Edwin Cheng 2020-04-24 10:23:01 +08:00
parent ef67e0a497
commit 3e24444aee
4 changed files with 69 additions and 57 deletions

View file

@ -1,15 +1,17 @@
//! Driver for proc macro server //! Driver for proc macro server
use crate::{expand_task, list_macros}; use crate::ProcMacroSrv;
use ra_proc_macro::msg::{self, Message}; use ra_proc_macro::msg::{self, Message};
use std::io; use std::io;
pub fn run() -> io::Result<()> { pub fn run() -> io::Result<()> {
let mut srv = ProcMacroSrv::default();
while let Some(req) = read_request()? { while let Some(req) = read_request()? {
let res = match req { let res = match req {
msg::Request::ListMacro(task) => Ok(msg::Response::ListMacro(list_macros(&task))), msg::Request::ListMacro(task) => srv.list_macros(&task).map(msg::Response::ListMacro),
msg::Request::ExpansionMacro(task) => { msg::Request::ExpansionMacro(task) => {
expand_task(&task).map(msg::Response::ExpansionMacro) srv.expand(&task).map(msg::Response::ExpansionMacro)
} }
}; };

View file

@ -112,7 +112,7 @@ impl ProcMacroLibraryLibloading {
type ProcMacroLibraryImpl = ProcMacroLibraryLibloading; type ProcMacroLibraryImpl = ProcMacroLibraryLibloading;
pub struct Expander { pub struct Expander {
libs: Vec<ProcMacroLibraryImpl>, inner: ProcMacroLibraryImpl,
} }
impl Expander { impl Expander {
@ -125,7 +125,7 @@ impl Expander {
let library = ProcMacroLibraryImpl::open(&lib).map_err(|e| e.to_string())?; let library = ProcMacroLibraryImpl::open(&lib).map_err(|e| e.to_string())?;
Ok(Expander { libs: vec![library] }) Ok(Expander { inner: library })
} }
pub fn expand( pub fn expand(
@ -141,8 +141,7 @@ impl Expander {
TokenStream::with_subtree(attr.clone()) TokenStream::with_subtree(attr.clone())
}); });
for lib in &self.libs { for proc_macro in &self.inner.exported_macros {
for proc_macro in &lib.exported_macros {
match proc_macro { match proc_macro {
bridge::client::ProcMacro::CustomDerive { trait_name, client, .. } bridge::client::ProcMacro::CustomDerive { trait_name, client, .. }
if *trait_name == macro_name => if *trait_name == macro_name =>
@ -174,15 +173,14 @@ impl Expander {
_ => continue, _ => continue,
} }
} }
}
Err(bridge::PanicMessage::String("Nothing to expand".to_string())) Err(bridge::PanicMessage::String("Nothing to expand".to_string()))
} }
pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> { pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
self.libs self.inner
.exported_macros
.iter() .iter()
.flat_map(|it| &it.exported_macros)
.map(|proc_macro| match proc_macro { .map(|proc_macro| match proc_macro {
bridge::client::ProcMacro::CustomDerive { trait_name, .. } => { bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
(trait_name.to_string(), ProcMacroKind::CustomDerive) (trait_name.to_string(), ProcMacroKind::CustomDerive)

View file

@ -21,11 +21,19 @@ mod dylib;
use proc_macro::bridge::client::TokenStream; use proc_macro::bridge::client::TokenStream;
use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask}; use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask};
use std::path::Path; use std::{
collections::{hash_map::Entry, HashMap},
path::{Path, PathBuf},
};
pub(crate) fn expand_task(task: &ExpansionTask) -> Result<ExpansionResult, String> { #[derive(Default)]
let expander = create_expander(&task.lib); pub(crate) struct ProcMacroSrv {
expanders: HashMap<PathBuf, dylib::Expander>,
}
impl ProcMacroSrv {
pub fn expand(&mut self, task: &ExpansionTask) -> Result<ExpansionResult, String> {
let expander = self.expander(&task.lib)?;
match expander.expand(&task.macro_name, &task.macro_body, task.attributes.as_ref()) { match expander.expand(&task.macro_name, &task.macro_body, task.attributes.as_ref()) {
Ok(expansion) => Ok(ExpansionResult { expansion }), Ok(expansion) => Ok(ExpansionResult { expansion }),
Err(msg) => { Err(msg) => {
@ -34,15 +42,19 @@ pub(crate) fn expand_task(task: &ExpansionTask) -> Result<ExpansionResult, Strin
} }
} }
pub(crate) fn list_macros(task: &ListMacrosTask) -> ListMacrosResult { pub fn list_macros(&mut self, task: &ListMacrosTask) -> Result<ListMacrosResult, String> {
let expander = create_expander(&task.lib); let expander = self.expander(&task.lib)?;
Ok(ListMacrosResult { macros: expander.list_macros() })
ListMacrosResult { macros: expander.list_macros() }
} }
fn create_expander(lib: &Path) -> dylib::Expander { fn expander(&mut self, path: &Path) -> Result<&dylib::Expander, String> {
dylib::Expander::new(lib) Ok(match self.expanders.entry(path.to_path_buf()) {
.unwrap_or_else(|err| panic!("Cannot create expander for {}: {:?}", lib.display(), err)) 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; pub mod cli;

View file

@ -1,7 +1,7 @@
//! utils used in proc-macro tests //! utils used in proc-macro tests
use crate::dylib; use crate::dylib;
use crate::list_macros; use crate::ProcMacroSrv;
pub use difference::Changeset as __Changeset; pub use difference::Changeset as __Changeset;
use ra_proc_macro::ListMacrosTask; use ra_proc_macro::ListMacrosTask;
use std::str::FromStr; use std::str::FromStr;
@ -59,7 +59,7 @@ pub fn assert_expand(
pub fn list(crate_name: &str, version: &str) -> Vec<String> { pub fn list(crate_name: &str, version: &str) -> Vec<String> {
let path = fixtures::dylib_path(crate_name, version); let path = fixtures::dylib_path(crate_name, version);
let task = ListMacrosTask { lib: path }; let task = ListMacrosTask { lib: path };
let mut srv = ProcMacroSrv::default();
let res = list_macros(&task); let res = srv.list_macros(&task).unwrap();
res.macros.into_iter().map(|(name, kind)| format!("{} [{:?}]", name, kind)).collect() res.macros.into_iter().map(|(name, kind)| format!("{} [{:?}]", name, kind)).collect()
} }