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.rs | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/crates/proc-macro-api/src/process.rs b/crates/proc-macro-api/src/process.rs index fe274a027a..95b12d0b24 100644 --- a/crates/proc-macro-api/src/process.rs +++ b/crates/proc-macro-api/src/process.rs @@ -31,6 +31,7 @@ pub(crate) struct ProcMacroServerProcess { #[derive(Debug)] enum Protocol { LegacyJson { mode: SpanMode }, + Postcard { mode: SpanMode }, } /// Maintains the state of the proc-macro server process. @@ -82,7 +83,11 @@ impl ProcMacroServerProcess { if srv.version >= version::RUST_ANALYZER_SPAN_SUPPORT && let Ok(mode) = srv.enable_rust_analyzer_spans() { - srv.protocol = Protocol::LegacyJson { mode }; + if srv.version >= version::POSTCARD_WIRE { + srv.protocol = Protocol::Postcard { mode }; + } else { + srv.protocol = Protocol::LegacyJson { mode }; + } } tracing::info!("Proc-macro server protocol: {:?}", srv.protocol); Ok(srv) @@ -99,6 +104,10 @@ impl ProcMacroServerProcess { self.exited.get().map(|it| &it.0) } + pub(crate) fn use_postcard(&self) -> bool { + matches!(self.protocol, Protocol::Postcard { .. }) + } + /// Retrieves the API version of the proc-macro server. pub(crate) fn version(&self) -> u32 { self.version @@ -108,6 +117,7 @@ impl ProcMacroServerProcess { pub(crate) fn rust_analyzer_spans(&self) -> bool { match self.protocol { Protocol::LegacyJson { mode } => mode == SpanMode::RustAnalyzer, + Protocol::Postcard { mode } => mode == SpanMode::RustAnalyzer, } } @@ -115,6 +125,7 @@ impl ProcMacroServerProcess { fn version_check(&self) -> Result<u32, ServerError> { match self.protocol { Protocol::LegacyJson { .. } => legacy_protocol::version_check(self), + Protocol::Postcard { .. } => legacy_protocol::version_check(self), } } @@ -122,6 +133,7 @@ impl ProcMacroServerProcess { fn enable_rust_analyzer_spans(&self) -> Result<SpanMode, ServerError> { match self.protocol { Protocol::LegacyJson { .. } => legacy_protocol::enable_rust_analyzer_spans(self), + Protocol::Postcard { .. } => legacy_protocol::enable_rust_analyzer_spans(self), } } @@ -132,6 +144,7 @@ impl ProcMacroServerProcess { ) -> Result<Result<Vec<(String, ProcMacroKind)>, String>, ServerError> { match self.protocol { Protocol::LegacyJson { .. } => legacy_protocol::find_proc_macros(self, dylib_path), + Protocol::Postcard { .. } => legacy_protocol::find_proc_macros(self, dylib_path), } } @@ -188,6 +201,55 @@ impl ProcMacroServerProcess { } }) } + + pub(crate) fn send_task_bin<Request, Response>( + &self, + serialize_req: impl FnOnce( + &mut dyn Write, + &mut dyn BufRead, + Request, + &mut Vec<u8>, + ) -> Result<Option<Response>, ServerError>, + req: Request, + ) -> Result<Response, ServerError> { + let state = &mut *self.state.lock().unwrap(); + let mut buf = Vec::<u8>::new(); + serialize_req(&mut state.stdin, &mut state.stdout, req, &mut buf) + .and_then(|res| { + res.ok_or_else(|| ServerError { + message: "proc-macro server did not respond with data".to_owned(), + io: Some(Arc::new(io::Error::new( + io::ErrorKind::BrokenPipe, + "proc-macro server did not respond with data", + ))), + }) + }) + .map_err(|e| { + if e.io.as_ref().map(|it| it.kind()) == Some(io::ErrorKind::BrokenPipe) { + match state.process.child.try_wait() { + Ok(None) | Err(_) => e, + Ok(Some(status)) => { + let mut msg = String::new(); + if !status.success() + && let Some(stderr) = state.process.child.stderr.as_mut() + { + _ = stderr.read_to_string(&mut msg); + } + let server_error = ServerError { + message: format!( + "proc-macro server exited with {status}{}{msg}", + if msg.is_empty() { "" } else { ": " } + ), + io: None, + }; + self.exited.get_or_init(|| AssertUnwindSafe(server_error)).0.clone() + } + } + } else { + e + } + }) + } } /// Manages the execution of the proc-macro server process. |