]> git.lizzy.rs Git - rust.git/commitdiff
Cacheproc-macro dlls
authorEdwin Cheng <edwin0cheng@gmail.com>
Fri, 24 Apr 2020 02:23:01 +0000 (10:23 +0800)
committerEdwin Cheng <edwin0cheng@gmail.com>
Sun, 26 Apr 2020 09:17:37 +0000 (17:17 +0800)
crates/ra_proc_macro_srv/src/cli.rs
crates/ra_proc_macro_srv/src/dylib.rs
crates/ra_proc_macro_srv/src/lib.rs
crates/ra_proc_macro_srv/src/tests/utils.rs

index 7282e5b9b7a9a62031afa7754f3cce033613ebce..1437794c9e23a3030a97bda224f6dc9cadaf8437 100644 (file)
@@ -1,15 +1,17 @@
 //! Driver for proc macro server
 
-use crate::{expand_task, list_macros};
+use crate::ProcMacroSrv;
 use ra_proc_macro::msg::{self, Message};
 use std::io;
 
 pub fn run() -> io::Result<()> {
+    let mut srv = ProcMacroSrv::default();
+
     while let Some(req) = read_request()? {
         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) => {
-                expand_task(&task).map(msg::Response::ExpansionMacro)
+                srv.expand(&task).map(msg::Response::ExpansionMacro)
             }
         };
 
index d202eb0fde42fb21d5fd7ba81d8453f9c2896823..476bc5c01422374fb88a7c6db67aa7054e9ce101 100644 (file)
@@ -112,7 +112,7 @@ fn open(file: &Path) -> io::Result<Self> {
 type ProcMacroLibraryImpl = ProcMacroLibraryLibloading;
 
 pub struct Expander {
-    libs: Vec<ProcMacroLibraryImpl>,
+    inner: ProcMacroLibraryImpl,
 }
 
 impl Expander {
@@ -125,7 +125,7 @@ pub fn new(lib: &Path) -> Result<Expander, String> {
 
         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 @@ pub fn expand(
                 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 @@ pub fn expand(
     }
 
     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)
index 3aca859db34b03e089c5fc8c7e9524556bc54a26..0954bd6b51521e4b4ed3cd50c7c4aae4a5491ece 100644 (file)
 
 use proc_macro::bridge::client::TokenStream;
 use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask};
-use std::path::Path;
-
-pub(crate) fn expand_task(task: &ExpansionTask) -> Result<ExpansionResult, String> {
-    let expander = create_expander(&task.lib);
+use std::{
+    collections::{hash_map::Entry, HashMap},
+    path::{Path, PathBuf},
+};
+
+#[derive(Default)]
+pub(crate) struct ProcMacroSrv {
+    expanders: HashMap<PathBuf, dylib::Expander>,
+}
 
-    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))
+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()) {
+            Ok(expansion) => Ok(ExpansionResult { expansion }),
+            Err(msg) => {
+                Err(format!("Cannot perform expansion for {}: error {:?}", &task.macro_name, msg))
+            }
         }
     }
-}
-
-pub(crate) fn list_macros(task: &ListMacrosTask) -> ListMacrosResult {
-    let expander = create_expander(&task.lib);
 
-    ListMacrosResult { macros: expander.list_macros() }
-}
+    pub fn list_macros(&mut self, task: &ListMacrosTask) -> Result<ListMacrosResult, String> {
+        let expander = self.expander(&task.lib)?;
+        Ok(ListMacrosResult { macros: expander.list_macros() })
+    }
 
-fn create_expander(lib: &Path) -> dylib::Expander {
-    dylib::Expander::new(lib)
-        .unwrap_or_else(|err| panic!("Cannot create expander for {}: {:?}", lib.display(), err))
+    fn expander(&mut self, path: &Path) -> Result<&dylib::Expander, String> {
+        Ok(match self.expanders.entry(path.to_path_buf()) {
+            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;
index 2139ec7a4dac87a960b255da09a67c265cfb2a71..646a427c5653546f4638b319c681509a11cc16eb 100644 (file)
@@ -1,7 +1,7 @@
 //! utils used in proc-macro tests
 
 use crate::dylib;
-use crate::list_macros;
+use crate::ProcMacroSrv;
 pub use difference::Changeset as __Changeset;
 use ra_proc_macro::ListMacrosTask;
 use std::str::FromStr;
@@ -59,7 +59,7 @@ pub fn assert_expand(
 pub fn list(crate_name: &str, version: &str) -> Vec<String> {
     let path = fixtures::dylib_path(crate_name, version);
     let task = ListMacrosTask { lib: path };
-
-    let res = list_macros(&task);
+    let mut srv = ProcMacroSrv::default();
+    let res = srv.list_macros(&task).unwrap();
     res.macros.into_iter().map(|(name, kind)| format!("{} [{:?}]", name, kind)).collect()
 }