about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs')
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs39
1 files changed, 29 insertions, 10 deletions
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
index dc3328ebcda..25c30b6db4a 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
@@ -13,20 +13,23 @@ mod process;
 
 use paths::{AbsPath, AbsPathBuf};
 use span::Span;
-use std::{fmt, io, sync::Arc};
+use std::{fmt, io, sync::Arc, time::SystemTime};
 
 use crate::{
     legacy_protocol::msg::{
-        deserialize_span_data_index_map, flat::serialize_span_data_index_map, ExpandMacro,
-        ExpandMacroData, ExpnGlobals, FlatTree, PanicMessage, Request, Response, SpanDataIndexMap,
-        HAS_GLOBAL_SPANS, RUST_ANALYZER_SPAN_SUPPORT,
+        ExpandMacro, ExpandMacroData, ExpnGlobals, FlatTree, HAS_GLOBAL_SPANS, PanicMessage,
+        RUST_ANALYZER_SPAN_SUPPORT, Request, Response, SpanDataIndexMap,
+        deserialize_span_data_index_map, flat::serialize_span_data_index_map,
     },
     process::ProcMacroServerProcess,
 };
 
+/// Represents different kinds of procedural macros that can be expanded by the external server.
 #[derive(Copy, Clone, Eq, PartialEq, Debug, serde_derive::Serialize, serde_derive::Deserialize)]
 pub enum ProcMacroKind {
+    /// A macro that derives implementations for a struct or enum.
     CustomDerive,
+    /// An attribute-like procedural macro.
     Attr,
     // This used to be called FuncLike, so that's what the server expects currently.
     #[serde(alias = "Bang")]
@@ -46,11 +49,13 @@ pub struct ProcMacroClient {
     path: AbsPathBuf,
 }
 
+/// Represents a dynamically loaded library containing procedural macros.
 pub struct MacroDylib {
     path: AbsPathBuf,
 }
 
 impl MacroDylib {
+    /// Creates a new MacroDylib instance with the given path.
     pub fn new(path: AbsPathBuf) -> MacroDylib {
         MacroDylib { path }
     }
@@ -66,6 +71,7 @@ pub struct ProcMacro {
     dylib_path: Arc<AbsPathBuf>,
     name: Box<str>,
     kind: ProcMacroKind,
+    dylib_last_modified: Option<SystemTime>,
 }
 
 impl Eq for ProcMacro {}
@@ -73,11 +79,13 @@ impl PartialEq for ProcMacro {
     fn eq(&self, other: &Self) -> bool {
         self.name == other.name
             && self.kind == other.kind
-            && Arc::ptr_eq(&self.dylib_path, &other.dylib_path)
+            && self.dylib_path == other.dylib_path
+            && self.dylib_last_modified == other.dylib_last_modified
             && Arc::ptr_eq(&self.process, &other.process)
     }
 }
 
+/// Represents errors encountered when communicating with the proc-macro server.
 #[derive(Clone, Debug)]
 pub struct ServerError {
     pub message: String,
@@ -97,15 +105,17 @@ impl fmt::Display for ServerError {
 
 impl ProcMacroClient {
     /// Spawns an external process as the proc macro server and returns a client connected to it.
-    pub fn spawn(
+    pub fn spawn<'a>(
         process_path: &AbsPath,
-        env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>
-            + Clone,
+        env: impl IntoIterator<
+            Item = (impl AsRef<std::ffi::OsStr>, &'a Option<impl 'a + AsRef<std::ffi::OsStr>>),
+        > + Clone,
     ) -> io::Result<ProcMacroClient> {
         let process = ProcMacroServerProcess::run(process_path, env)?;
         Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() })
     }
 
+    /// Returns the absolute path to the proc-macro server.
     pub fn server_path(&self) -> &AbsPath {
         &self.path
     }
@@ -116,6 +126,9 @@ impl ProcMacroClient {
         let macros = self.process.find_proc_macros(&dylib.path)?;
 
         let dylib_path = Arc::new(dylib.path);
+        let dylib_last_modified = std::fs::metadata(dylib_path.as_path())
+            .ok()
+            .and_then(|metadata| metadata.modified().ok());
         match macros {
             Ok(macros) => Ok(macros
                 .into_iter()
@@ -124,26 +137,32 @@ impl ProcMacroClient {
                     name: name.into(),
                     kind,
                     dylib_path: dylib_path.clone(),
+                    dylib_last_modified,
                 })
                 .collect()),
             Err(message) => Err(ServerError { message, io: None }),
         }
     }
 
+    /// Checks if the proc-macro server has exited.
     pub fn exited(&self) -> Option<&ServerError> {
         self.process.exited()
     }
 }
 
 impl ProcMacro {
+    /// Returns the name of the procedural macro.
     pub fn name(&self) -> &str {
         &self.name
     }
 
+    /// Returns the type of procedural macro.
     pub fn kind(&self) -> ProcMacroKind {
         self.kind
     }
 
+    /// Expands the procedural macro by sending an expansion request to the server.
+    /// This includes span information and environmental context.
     pub fn expand(
         &self,
         subtree: tt::SubtreeView<'_, Span>,
@@ -152,7 +171,7 @@ impl ProcMacro {
         def_site: Span,
         call_site: Span,
         mixed_site: Span,
-        current_dir: Option<String>,
+        current_dir: String,
     ) -> Result<Result<tt::TopSubtree<Span>, PanicMessage>, ServerError> {
         let version = self.process.version();
 
@@ -180,7 +199,7 @@ impl ProcMacro {
             },
             lib: self.dylib_path.to_path_buf().into(),
             env,
-            current_dir,
+            current_dir: Some(current_dir),
         };
 
         let response = self.process.send_task(Request::ExpandMacro(Box::new(task)))?;