Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/proc-macro-api/src/process.rs')
-rw-r--r--crates/proc-macro-api/src/process.rs94
1 files changed, 85 insertions, 9 deletions
diff --git a/crates/proc-macro-api/src/process.rs b/crates/proc-macro-api/src/process.rs
index cd387dad0d..a206e9fc5d 100644
--- a/crates/proc-macro-api/src/process.rs
+++ b/crates/proc-macro-api/src/process.rs
@@ -1,8 +1,9 @@
//! Handle process life-time and message passing for proc-macro client
use std::{
+ fmt::Debug,
io::{self, BufRead, BufReader, Read, Write},
- panic::AssertUnwindSafe,
+ panic::{AssertUnwindSafe, RefUnwindSafe},
process::{Child, ChildStdin, ChildStdout, Command, Stdio},
sync::{Arc, Mutex, OnceLock},
};
@@ -74,12 +75,79 @@ impl ProcessExit for Process {
}
/// Maintains the state of the proc-macro server process.
-struct ProcessSrvState {
+pub(crate) struct ProcessSrvState {
process: Box<dyn ProcessExit>,
stdin: Box<dyn Write + Send + Sync>,
stdout: Box<dyn BufRead + Send + Sync>,
}
+impl ProcMacroWorker for ProcMacroServerProcess {
+ fn find_proc_macros(
+ &self,
+ dylib_path: &AbsPath,
+ callback: Option<SubCallback<'_>>,
+ ) -> Result<Result<Vec<(String, ProcMacroKind)>, String>, ServerError> {
+ ProcMacroServerProcess::find_proc_macros(self, dylib_path, callback)
+ }
+
+ fn expand(
+ &self,
+ proc_macro: &ProcMacro,
+ subtree: tt::SubtreeView<'_>,
+ attr: Option<tt::SubtreeView<'_>>,
+ env: Vec<(String, String)>,
+ def_site: Span,
+ call_site: Span,
+ mixed_site: Span,
+ current_dir: String,
+ callback: Option<SubCallback<'_>>,
+ ) -> Result<Result<tt::TopSubtree, String>, ServerError> {
+ ProcMacroServerProcess::expand(
+ self,
+ proc_macro,
+ subtree,
+ attr,
+ env,
+ def_site,
+ call_site,
+ mixed_site,
+ current_dir,
+ callback,
+ )
+ }
+
+ fn exited(&self) -> Option<&ServerError> {
+ ProcMacroServerProcess::exited(self)
+ }
+
+ fn version(&self) -> u32 {
+ ProcMacroServerProcess::version(self)
+ }
+
+ fn rust_analyzer_spans(&self) -> bool {
+ ProcMacroServerProcess::rust_analyzer_spans(self)
+ }
+
+ fn enable_rust_analyzer_spans(
+ &self,
+ callback: Option<SubCallback<'_>>,
+ ) -> Result<SpanMode, ServerError> {
+ ProcMacroServerProcess::enable_rust_analyzer_spans(self, callback)
+ }
+
+ fn use_postcard(&self) -> bool {
+ ProcMacroServerProcess::use_postcard(self)
+ }
+
+ fn state(&self) -> &Mutex<ProcessSrvState> {
+ &self.state
+ }
+
+ fn get_exited(&self) -> &OnceLock<AssertUnwindSafe<ServerError>> {
+ &self.exited
+ }
+}
+
impl ProcMacroServerProcess {
/// Starts the proc-macro server and performs a version check
pub(crate) fn spawn<'a>(
@@ -291,9 +359,13 @@ impl ProcMacroServerProcess {
),
}
}
+}
+
+pub(crate) struct SynIO;
+impl SynIO {
pub(crate) fn send_task<Request, Response, C: Codec>(
- &self,
+ proc_macro_worker: &dyn ProcMacroWorker,
send: impl FnOnce(
&mut dyn Write,
&mut dyn BufRead,
@@ -302,7 +374,7 @@ impl ProcMacroServerProcess {
) -> Result<Option<Response>, ServerError>,
req: Request,
) -> Result<Response, ServerError> {
- self.with_locked_io::<C, _>(|writer, reader, buf| {
+ SynIO::with_locked_io::<C, _>(proc_macro_worker, |writer, reader, buf| {
send(writer, reader, req, buf).and_then(|res| {
res.ok_or_else(|| {
let message = "proc-macro server did not respond with data".to_owned();
@@ -319,10 +391,10 @@ impl ProcMacroServerProcess {
}
pub(crate) fn with_locked_io<C: Codec, R>(
- &self,
+ proc_macro_worker: &dyn ProcMacroWorker,
f: impl FnOnce(&mut dyn Write, &mut dyn BufRead, &mut C::Buf) -> Result<R, ServerError>,
) -> Result<R, ServerError> {
- let state = &mut *self.state.lock().unwrap();
+ let state = &mut *proc_macro_worker.state().lock().unwrap();
let mut buf = C::Buf::default();
f(&mut state.stdin, &mut state.stdout, &mut buf).map_err(|e| {
@@ -330,7 +402,11 @@ impl ProcMacroServerProcess {
match state.process.exit_err() {
None => e,
Some(server_error) => {
- self.exited.get_or_init(|| AssertUnwindSafe(server_error)).0.clone()
+ proc_macro_worker
+ .get_exited()
+ .get_or_init(|| AssertUnwindSafe(server_error))
+ .0
+ .clone()
}
}
} else {
@@ -340,11 +416,11 @@ impl ProcMacroServerProcess {
}
pub(crate) fn run_bidirectional<C: Codec>(
- &self,
+ proc_macro_worker: &dyn ProcMacroWorker,
initial: BidirectionalMessage,
callback: SubCallback<'_>,
) -> Result<BidirectionalMessage, ServerError> {
- self.with_locked_io::<C, _>(|writer, reader, buf| {
+ SynIO::with_locked_io::<C, _>(proc_macro_worker, |writer, reader, buf| {
bidirectional_protocol::run_conversation::<C>(writer, reader, buf, initial, callback)
})
}