From 3e24444aee9db36d8de530dee9c0283ce793c6fd Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 24 Apr 2020 10:23:01 +0800 Subject: Cacheproc-macro dlls --- crates/ra_proc_macro_srv/src/dylib.rs | 68 +++++++++++++++++------------------ 1 file changed, 33 insertions(+), 35 deletions(-) (limited to 'crates/ra_proc_macro_srv/src/dylib.rs') diff --git a/crates/ra_proc_macro_srv/src/dylib.rs b/crates/ra_proc_macro_srv/src/dylib.rs index d202eb0fd..476bc5c01 100644 --- a/crates/ra_proc_macro_srv/src/dylib.rs +++ b/crates/ra_proc_macro_srv/src/dylib.rs @@ -112,7 +112,7 @@ impl ProcMacroLibraryLibloading { type ProcMacroLibraryImpl = ProcMacroLibraryLibloading; pub struct Expander { - libs: Vec, + inner: ProcMacroLibraryImpl, } impl Expander { @@ -125,7 +125,7 @@ impl Expander { let library = ProcMacroLibraryImpl::open(&lib).map_err(|e| e.to_string())?; - Ok(Expander { libs: vec![library] }) + Ok(Expander { inner: library }) } pub fn expand( @@ -141,38 +141,36 @@ impl Expander { TokenStream::with_subtree(attr.clone()) }); - for lib in &self.libs { - for proc_macro in &lib.exported_macros { - match proc_macro { - bridge::client::ProcMacro::CustomDerive { trait_name, client, .. } - if *trait_name == macro_name => - { - let res = client.run( - &crate::proc_macro::bridge::server::SameThread, - crate::rustc_server::Rustc::default(), - parsed_body, - ); - return res.map(|it| it.subtree); - } - bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => { - let res = client.run( - &crate::proc_macro::bridge::server::SameThread, - crate::rustc_server::Rustc::default(), - parsed_body, - ); - return res.map(|it| it.subtree); - } - bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => { - let res = client.run( - &crate::proc_macro::bridge::server::SameThread, - crate::rustc_server::Rustc::default(), - parsed_attributes, - parsed_body, - ); - return res.map(|it| it.subtree); - } - _ => continue, + for proc_macro in &self.inner.exported_macros { + match proc_macro { + bridge::client::ProcMacro::CustomDerive { trait_name, client, .. } + if *trait_name == macro_name => + { + let res = client.run( + &crate::proc_macro::bridge::server::SameThread, + crate::rustc_server::Rustc::default(), + parsed_body, + ); + return res.map(|it| it.subtree); + } + bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => { + let res = client.run( + &crate::proc_macro::bridge::server::SameThread, + crate::rustc_server::Rustc::default(), + parsed_body, + ); + return res.map(|it| it.subtree); + } + bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => { + let res = client.run( + &crate::proc_macro::bridge::server::SameThread, + crate::rustc_server::Rustc::default(), + parsed_attributes, + parsed_body, + ); + return res.map(|it| it.subtree); } + _ => continue, } } @@ -180,9 +178,9 @@ impl Expander { } pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> { - self.libs + self.inner + .exported_macros .iter() - .flat_map(|it| &it.exported_macros) .map(|proc_macro| match proc_macro { bridge::client::ProcMacro::CustomDerive { trait_name, .. } => { (trait_name.to_string(), ProcMacroKind::CustomDerive) -- cgit v1.2.3 From 5a5bba5a4655be4ee7978f8577ce3351526655a5 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 25 Apr 2020 12:29:49 +0800 Subject: Copy dylib to temp directory --- crates/ra_proc_macro_srv/src/dylib.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'crates/ra_proc_macro_srv/src/dylib.rs') diff --git a/crates/ra_proc_macro_srv/src/dylib.rs b/crates/ra_proc_macro_srv/src/dylib.rs index 476bc5c01..018cc7bb8 100644 --- a/crates/ra_proc_macro_srv/src/dylib.rs +++ b/crates/ra_proc_macro_srv/src/dylib.rs @@ -2,7 +2,7 @@ use crate::{proc_macro::bridge, rustc_server::TokenStream}; use std::fs::File; -use std::path::Path; +use std::path::{Path, PathBuf}; use goblin::{mach::Mach, Object}; use libloading::Library; @@ -123,6 +123,9 @@ impl Expander { .canonicalize() .unwrap_or_else(|err| panic!("Cannot canonicalize {}: {:?}", lib.display(), err)); + // Copy the dylib to temp directory to prevent locking in Windows + let lib = copy_to_temp_dir(&lib).map_err(|e| e.to_string())?; + let library = ProcMacroLibraryImpl::open(&lib).map_err(|e| e.to_string())?; Ok(Expander { inner: library }) @@ -195,3 +198,17 @@ impl Expander { .collect() } } + +fn copy_to_temp_dir(path: &Path) -> io::Result { + let mut to = std::env::temp_dir(); + let file_name = path.file_name().ok_or_else(|| { + io::Error::new( + io::ErrorKind::InvalidInput, + format!("File path is invalid: {}", path.display()), + ) + })?; + + to.push(file_name); + std::fs::copy(path, &to)?; + Ok(to) +} -- cgit v1.2.3 From fb996cae6bf5bb5f60176a4a190311d4363b3e10 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 25 Apr 2020 12:48:59 +0800 Subject: Fix --- crates/ra_proc_macro_srv/src/dylib.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'crates/ra_proc_macro_srv/src/dylib.rs') diff --git a/crates/ra_proc_macro_srv/src/dylib.rs b/crates/ra_proc_macro_srv/src/dylib.rs index 018cc7bb8..99c83481a 100644 --- a/crates/ra_proc_macro_srv/src/dylib.rs +++ b/crates/ra_proc_macro_srv/src/dylib.rs @@ -199,6 +199,7 @@ impl Expander { } } +#[cfg(windows)] fn copy_to_temp_dir(path: &Path) -> io::Result { let mut to = std::env::temp_dir(); let file_name = path.file_name().ok_or_else(|| { @@ -212,3 +213,8 @@ fn copy_to_temp_dir(path: &Path) -> io::Result { std::fs::copy(path, &to)?; Ok(to) } + +#[cfg(unix)] +fn copy_to_temp_dir(path: &Path) -> io::Result { + Ok(path.to_path_buf()) +} -- cgit v1.2.3 From 183673655f72250ee05ab1c5864feeae33a3c662 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 26 Apr 2020 17:58:56 +0800 Subject: Simpify code --- crates/ra_proc_macro_srv/src/dylib.rs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'crates/ra_proc_macro_srv/src/dylib.rs') diff --git a/crates/ra_proc_macro_srv/src/dylib.rs b/crates/ra_proc_macro_srv/src/dylib.rs index 99c83481a..209f61493 100644 --- a/crates/ra_proc_macro_srv/src/dylib.rs +++ b/crates/ra_proc_macro_srv/src/dylib.rs @@ -109,24 +109,19 @@ impl ProcMacroLibraryLibloading { } } -type ProcMacroLibraryImpl = ProcMacroLibraryLibloading; - pub struct Expander { - inner: ProcMacroLibraryImpl, + inner: ProcMacroLibraryLibloading, } impl Expander { - pub fn new(lib: &Path) -> Result { + pub fn new(lib: &Path) -> io::Result { // Some libraries for dynamic loading require canonicalized path even when it is // already absolute - let lib = lib - .canonicalize() - .unwrap_or_else(|err| panic!("Cannot canonicalize {}: {:?}", lib.display(), err)); + let lib = lib.canonicalize()?; - // Copy the dylib to temp directory to prevent locking in Windows - let lib = copy_to_temp_dir(&lib).map_err(|e| e.to_string())?; + let lib = ensure_file_with_lock_free_access(&lib)?; - let library = ProcMacroLibraryImpl::open(&lib).map_err(|e| e.to_string())?; + let library = ProcMacroLibraryLibloading::open(&lib)?; Ok(Expander { inner: library }) } @@ -199,8 +194,9 @@ impl Expander { } } +/// Copy the dylib to temp directory to prevent locking in Windows #[cfg(windows)] -fn copy_to_temp_dir(path: &Path) -> io::Result { +fn ensure_file_with_lock_free_access(path: &Path) -> io::Result { let mut to = std::env::temp_dir(); let file_name = path.file_name().ok_or_else(|| { io::Error::new( @@ -215,6 +211,6 @@ fn copy_to_temp_dir(path: &Path) -> io::Result { } #[cfg(unix)] -fn copy_to_temp_dir(path: &Path) -> io::Result { +fn ensure_file_with_lock_free_access(path: &Path) -> io::Result { Ok(path.to_path_buf()) } -- cgit v1.2.3 From bfce6573772ebb91a9b1054864c0f53669ceee2f Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 26 Apr 2020 18:52:21 +0800 Subject: Generate uniq name --- crates/ra_proc_macro_srv/src/dylib.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'crates/ra_proc_macro_srv/src/dylib.rs') diff --git a/crates/ra_proc_macro_srv/src/dylib.rs b/crates/ra_proc_macro_srv/src/dylib.rs index 209f61493..aa84e951c 100644 --- a/crates/ra_proc_macro_srv/src/dylib.rs +++ b/crates/ra_proc_macro_srv/src/dylib.rs @@ -8,7 +8,6 @@ use goblin::{mach::Mach, Object}; use libloading::Library; use memmap::Mmap; use ra_proc_macro::ProcMacroKind; - use std::io; const NEW_REGISTRAR_SYMBOL: &str = "_rustc_proc_macro_decls_"; @@ -197,7 +196,10 @@ impl Expander { /// Copy the dylib to temp directory to prevent locking in Windows #[cfg(windows)] fn ensure_file_with_lock_free_access(path: &Path) -> io::Result { + use std::{ffi::OsString, time::SystemTime}; + let mut to = std::env::temp_dir(); + let file_name = path.file_name().ok_or_else(|| { io::Error::new( io::ErrorKind::InvalidInput, @@ -205,8 +207,14 @@ fn ensure_file_with_lock_free_access(path: &Path) -> io::Result { ) })?; - to.push(file_name); - std::fs::copy(path, &to)?; + // generate a time deps unique number + let t = SystemTime::now().duration_since(std::time::UNIX_EPOCH).expect("Time went backwards"); + + let mut unique_name = OsString::from(t.as_millis().to_string()); + unique_name.push(file_name); + + to.push(unique_name); + std::fs::copy(path, &to).unwrap(); Ok(to) } -- cgit v1.2.3