Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/proc-macro-api/src/transport/framing.rs | 2 | ||||
| -rw-r--r-- | crates/proc-macro-srv-cli/src/main_loop.rs | 190 | ||||
| -rw-r--r-- | crates/proc-macro-srv/src/dylib.rs | 6 | ||||
| -rw-r--r-- | crates/proc-macro-srv/src/dylib/proc_macros.rs | 2 | ||||
| -rw-r--r-- | crates/proc-macro-srv/src/lib.rs | 32 | ||||
| -rw-r--r-- | crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs | 18 | ||||
| -rw-r--r-- | crates/proc-macro-srv/src/server_impl/token_id.rs | 16 |
7 files changed, 114 insertions, 152 deletions
diff --git a/crates/proc-macro-api/src/transport/framing.rs b/crates/proc-macro-api/src/transport/framing.rs index 2a11eb19c3..1e29c1982a 100644 --- a/crates/proc-macro-api/src/transport/framing.rs +++ b/crates/proc-macro-api/src/transport/framing.rs @@ -3,7 +3,7 @@ use std::io::{self, BufRead, Write}; pub trait Framing { - type Buf: Default; + type Buf: Default + Send; fn read<'a, R: BufRead + ?Sized>( inp: &mut R, diff --git a/crates/proc-macro-srv-cli/src/main_loop.rs b/crates/proc-macro-srv-cli/src/main_loop.rs index 6ed42204df..4d98a8e29d 100644 --- a/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/crates/proc-macro-srv-cli/src/main_loop.rs @@ -6,7 +6,7 @@ use proc_macro_api::{ transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, version::CURRENT_API_VERSION, }; -use std::{io, sync::mpsc}; +use std::io; use legacy::Message; @@ -52,8 +52,8 @@ fn run_new<C: Codec>() -> io::Result<()> { } let mut buf = C::Buf::default(); - let mut stdin = io::stdin().lock(); - let mut stdout = io::stdout().lock(); + let mut stdin = io::stdin(); + let mut stdout = io::stdout(); let env_snapshot = EnvSnapshot::default(); let srv = proc_macro_srv::ProcMacroSrv::new(&env_snapshot); @@ -61,7 +61,8 @@ fn run_new<C: Codec>() -> io::Result<()> { let mut span_mode = legacy::SpanMode::Id; 'outer: loop { - let req_opt = bidirectional::BidirectionalMessage::read::<_, C>(&mut stdin, &mut buf)?; + let req_opt = + bidirectional::BidirectionalMessage::read::<_, C>(&mut stdin.lock(), &mut buf)?; let Some(req) = req_opt else { break 'outer; }; @@ -76,30 +77,23 @@ fn run_new<C: Codec>() -> io::Result<()> { .collect() }); - send_response::<_, C>(&mut stdout, bidirectional::Response::ListMacros(res))?; + send_response::<C>(&stdout, bidirectional::Response::ListMacros(res))?; } bidirectional::Request::ApiVersionCheck {} => { // bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION).write::<_, C>(stdout) - send_response::<_, C>( - &mut stdout, + send_response::<C>( + &stdout, bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION), )?; } bidirectional::Request::SetConfig(config) => { span_mode = config.span_mode; - send_response::<_, C>(&mut stdout, bidirectional::Response::SetConfig(config))?; + send_response::<C>(&stdout, bidirectional::Response::SetConfig(config))?; } bidirectional::Request::ExpandMacro(task) => { - handle_expand::<_, _, C>( - &srv, - &mut stdin, - &mut stdout, - &mut buf, - span_mode, - *task, - )?; + handle_expand::<C>(&srv, &mut stdin, &mut stdout, &mut buf, span_mode, *task)?; } }, _ => continue, @@ -109,25 +103,23 @@ fn run_new<C: Codec>() -> io::Result<()> { Ok(()) } -fn handle_expand<W: std::io::Write, R: std::io::BufRead, C: Codec>( +fn handle_expand<C: Codec>( srv: &proc_macro_srv::ProcMacroSrv<'_>, - stdin: &mut R, - stdout: &mut W, + stdin: &io::Stdin, + stdout: &io::Stdout, buf: &mut C::Buf, span_mode: legacy::SpanMode, task: bidirectional::ExpandMacro, ) -> io::Result<()> { match span_mode { - legacy::SpanMode::Id => handle_expand_id::<_, C>(srv, stdout, task), - legacy::SpanMode::RustAnalyzer => { - handle_expand_ra::<_, _, C>(srv, stdin, stdout, buf, task) - } + legacy::SpanMode::Id => handle_expand_id::<C>(srv, stdout, task), + legacy::SpanMode::RustAnalyzer => handle_expand_ra::<C>(srv, stdin, stdout, buf, task), } } -fn handle_expand_id<W: std::io::Write, C: Codec>( +fn handle_expand_id<C: Codec>( srv: &proc_macro_srv::ProcMacroSrv<'_>, - stdout: &mut W, + stdout: &io::Stdout, task: bidirectional::ExpandMacro, ) -> io::Result<()> { let bidirectional::ExpandMacro { lib, env, current_dir, data } = task; @@ -166,28 +158,46 @@ fn handle_expand_id<W: std::io::Write, C: Codec>( }) .map_err(|e| legacy::PanicMessage(e.into_string().unwrap_or_default())); - send_response::<_, C>(stdout, bidirectional::Response::ExpandMacro(res)) + send_response::<C>(&stdout, bidirectional::Response::ExpandMacro(res)) } -struct ProcMacroClientHandle { - subreq_tx: mpsc::Sender<bidirectional::SubRequest>, - subresp_rx: mpsc::Receiver<bidirectional::SubResponse>, +struct ProcMacroClientHandle<'a, C: Codec> { + stdin: &'a io::Stdin, + stdout: &'a io::Stdout, + buf: &'a mut C::Buf, } -impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle { - fn source_text(&self, file_id: u32, start: u32, end: u32) -> Option<String> { - self.subreq_tx.send(bidirectional::SubRequest::SourceText { file_id, start, end }).ok()?; +impl<C: Codec> proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_, C> { + fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option<String> { + let req = bidirectional::BidirectionalMessage::SubRequest( + bidirectional::SubRequest::SourceText { file_id, start, end }, + ); + + if req.write::<_, C>(&mut self.stdout.lock()).is_err() { + return None; + } + + let msg = match bidirectional::BidirectionalMessage::read::<_, C>( + &mut self.stdin.lock(), + self.buf, + ) { + Ok(Some(msg)) => msg, + _ => return None, + }; - match self.subresp_rx.recv().ok()? { - bidirectional::SubResponse::SourceTextResult { text } => text, + match msg { + bidirectional::BidirectionalMessage::SubResponse( + bidirectional::SubResponse::SourceTextResult { text }, + ) => text, + _ => None, } } } -fn handle_expand_ra<W: io::Write, R: io::BufRead, C: Codec>( +fn handle_expand_ra<C: Codec>( srv: &proc_macro_srv::ProcMacroSrv<'_>, - stdin: &mut R, - stdout: &mut W, + stdin: &io::Stdin, + stdout: &io::Stdout, buf: &mut C::Buf, task: bidirectional::ExpandMacro, ) -> io::Result<()> { @@ -222,81 +232,34 @@ fn handle_expand_ra<W: io::Write, R: io::BufRead, C: Codec>( }) }); - let (subreq_tx, subreq_rx) = mpsc::channel(); - let (subresp_tx, subresp_rx) = mpsc::channel(); - let (result_tx, result_rx) = mpsc::channel(); - - std::thread::scope(|s| { - s.spawn(|| { - let callback = ProcMacroClientHandle { subreq_tx, subresp_rx }; - - let res = srv - .expand( - lib, - &env, - current_dir, - ¯o_name, - macro_body, - attributes, - def_site, + let res = srv + .expand( + lib, + &env, + current_dir, + ¯o_name, + macro_body, + attributes, + def_site, + call_site, + mixed_site, + Some(Box::new(ProcMacroClientHandle::<C> { stdin, stdout, buf })), + ) + .map(|it| { + ( + legacy::FlatTree::from_tokenstream( + it, + CURRENT_API_VERSION, call_site, - mixed_site, - Some(Box::new(callback)), - ) - .map(|it| { - ( - legacy::FlatTree::from_tokenstream( - it, - CURRENT_API_VERSION, - call_site, - &mut span_data_table, - ), - legacy::serialize_span_data_index_map(&span_data_table), - ) - }) - .map(|(tree, span_data_table)| bidirectional::ExpandMacroExtended { - tree, - span_data_table, - }) - .map_err(|e| legacy::PanicMessage(e.into_string().unwrap_or_default())); - - let _ = result_tx.send(res); - }); - - loop { - if let Ok(res) = result_rx.try_recv() { - let _ = send_response::<_, C>( - stdout, - bidirectional::Response::ExpandMacroExtended(res), - ); - break; - } - - let sub_req = match subreq_rx.recv() { - Ok(r) => r, - Err(_) => break, - }; - - if bidirectional::BidirectionalMessage::SubRequest(sub_req) - .write::<_, C>(stdout) - .is_err() - { - break; - } - let resp = match bidirectional::BidirectionalMessage::read::<_, C>(stdin, buf) { - Ok(Some(r)) => r, - _ => break, - }; - match resp { - bidirectional::BidirectionalMessage::SubResponse(resp) => { - let _ = subresp_tx.send(resp); - } - other => panic!("expected SubResponse, got {other:?}"), - } - } - }); + &mut span_data_table, + ), + legacy::serialize_span_data_index_map(&span_data_table), + ) + }) + .map(|(tree, span_data_table)| bidirectional::ExpandMacroExtended { tree, span_data_table }) + .map_err(|e| legacy::PanicMessage(e.into_string().unwrap_or_default())); - Ok(()) + send_response::<C>(&stdout, bidirectional::Response::ExpandMacroExtended(res)) } fn run_<C: Codec>() -> io::Result<()> { @@ -441,10 +404,7 @@ fn run_<C: Codec>() -> io::Result<()> { Ok(()) } -fn send_response<W: std::io::Write, C: Codec>( - stdout: &mut W, - resp: bidirectional::Response, -) -> io::Result<()> { +fn send_response<C: Codec>(stdout: &io::Stdout, resp: bidirectional::Response) -> io::Result<()> { let resp = bidirectional::BidirectionalMessage::Response(resp); - resp.write::<W, C>(stdout) + resp.write::<_, C>(&mut stdout.lock()) } diff --git a/crates/proc-macro-srv/src/dylib.rs b/crates/proc-macro-srv/src/dylib.rs index d34f37b16a..02bdcc50d3 100644 --- a/crates/proc-macro-srv/src/dylib.rs +++ b/crates/proc-macro-srv/src/dylib.rs @@ -37,7 +37,7 @@ impl Expander { Ok(Expander { inner: library, modified_time }) } - pub(crate) fn expand<S: ProcMacroSrvSpan>( + pub(crate) fn expand<'a, S: ProcMacroSrvSpan + 'a>( &self, macro_name: &str, macro_body: TokenStream<S>, @@ -45,10 +45,10 @@ impl Expander { def_site: S, call_site: S, mixed_site: S, - callback: Option<ProcMacroClientHandle>, + callback: Option<ProcMacroClientHandle<'_>>, ) -> Result<TokenStream<S>, PanicMessage> where - <S::Server as bridge::server::Types>::TokenStream: Default, + <S::Server<'a> as bridge::server::Types>::TokenStream: Default, { self.inner .proc_macros diff --git a/crates/proc-macro-srv/src/dylib/proc_macros.rs b/crates/proc-macro-srv/src/dylib/proc_macros.rs index ddbb0128f5..c763301135 100644 --- a/crates/proc-macro-srv/src/dylib/proc_macros.rs +++ b/crates/proc-macro-srv/src/dylib/proc_macros.rs @@ -20,7 +20,7 @@ impl ProcMacros { def_site: S, call_site: S, mixed_site: S, - callback: Option<ProcMacroClientHandle>, + callback: Option<ProcMacroClientHandle<'_>>, ) -> Result<TokenStream<S>, crate::PanicMessage> { let parsed_attributes = attribute.unwrap_or_default(); diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs index ff5623f39e..687a4218b4 100644 --- a/crates/proc-macro-srv/src/lib.rs +++ b/crates/proc-macro-srv/src/lib.rs @@ -91,10 +91,10 @@ impl<'env> ProcMacroSrv<'env> { } } -pub type ProcMacroClientHandle = Box<dyn ProcMacroClientInterface + Send>; +pub type ProcMacroClientHandle<'a> = Box<dyn ProcMacroClientInterface + Send + 'a>; pub trait ProcMacroClientInterface { - fn source_text(&self, file_id: u32, start: u32, end: u32) -> Option<String>; + fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option<String>; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; @@ -111,7 +111,7 @@ impl ProcMacroSrv<'_> { def_site: S, call_site: S, mixed_site: S, - callback: Option<ProcMacroClientHandle>, + callback: Option<ProcMacroClientHandle<'_>>, ) -> Result<token_stream::TokenStream<S>, PanicMessage> { let snapped_env = self.env; let expander = self.expander(lib.as_ref()).map_err(|err| PanicMessage { @@ -178,24 +178,26 @@ impl ProcMacroSrv<'_> { } pub trait ProcMacroSrvSpan: Copy + Send + Sync { - type Server: proc_macro::bridge::server::Server<TokenStream = crate::token_stream::TokenStream<Self>>; - fn make_server( + type Server<'a>: proc_macro::bridge::server::Server<TokenStream = crate::token_stream::TokenStream<Self>> + where + Self: 'a; + fn make_server<'a>( call_site: Self, def_site: Self, mixed_site: Self, - callback: Option<ProcMacroClientHandle>, - ) -> Self::Server; + callback: Option<ProcMacroClientHandle<'a>>, + ) -> Self::Server<'a>; } impl ProcMacroSrvSpan for SpanId { - type Server = server_impl::token_id::SpanIdServer; + type Server<'a> = server_impl::token_id::SpanIdServer<'a>; - fn make_server( + fn make_server<'a>( call_site: Self, def_site: Self, mixed_site: Self, - callback: Option<ProcMacroClientHandle>, - ) -> Self::Server { + callback: Option<ProcMacroClientHandle<'a>>, + ) -> Self::Server<'a> { Self::Server { call_site, def_site, @@ -208,13 +210,13 @@ impl ProcMacroSrvSpan for SpanId { } impl ProcMacroSrvSpan for Span { - type Server = server_impl::rust_analyzer_span::RaSpanServer; - fn make_server( + type Server<'a> = server_impl::rust_analyzer_span::RaSpanServer<'a>; + fn make_server<'a>( call_site: Self, def_site: Self, mixed_site: Self, - callback: Option<ProcMacroClientHandle>, - ) -> Self::Server { + callback: Option<ProcMacroClientHandle<'a>>, + ) -> Self::Server<'a> { Self::Server { call_site, def_site, diff --git a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 5f7c0a5202..5d9090c060 100644 --- a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -21,7 +21,7 @@ use crate::{ pub struct FreeFunctions; -pub struct RaSpanServer { +pub struct RaSpanServer<'a> { // FIXME: Report this back to the caller to track as dependencies pub tracked_env_vars: HashMap<Box<str>, Option<Box<str>>>, // FIXME: Report this back to the caller to track as dependencies @@ -29,17 +29,17 @@ pub struct RaSpanServer { pub call_site: Span, pub def_site: Span, pub mixed_site: Span, - pub callback: Option<ProcMacroClientHandle>, + pub callback: Option<ProcMacroClientHandle<'a>>, } -impl server::Types for RaSpanServer { +impl server::Types for RaSpanServer<'_> { type FreeFunctions = FreeFunctions; type TokenStream = crate::token_stream::TokenStream<Span>; type Span = Span; type Symbol = Symbol; } -impl server::FreeFunctions for RaSpanServer { +impl server::FreeFunctions for RaSpanServer<'_> { fn injected_env_var(&mut self, _: &str) -> Option<std::string::String> { None } @@ -60,7 +60,7 @@ impl server::FreeFunctions for RaSpanServer { } } -impl server::TokenStream for RaSpanServer { +impl server::TokenStream for RaSpanServer<'_> { fn is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() } @@ -123,7 +123,7 @@ impl server::TokenStream for RaSpanServer { } } -impl server::Span for RaSpanServer { +impl server::Span for RaSpanServer<'_> { fn debug(&mut self, span: Self::Span) -> String { format!("{:?}", span) } @@ -156,7 +156,7 @@ impl server::Span for RaSpanServer { let start: u32 = span.range.start().into(); let end: u32 = span.range.end().into(); - self.callback.as_ref()?.source_text(file_id.file_id().index(), start, end) + self.callback.as_mut()?.source_text(file_id.file_id().index(), start, end) } fn parent(&mut self, _span: Self::Span) -> Option<Self::Span> { @@ -274,14 +274,14 @@ impl server::Span for RaSpanServer { } } -impl server::Symbol for RaSpanServer { +impl server::Symbol for RaSpanServer<'_> { fn normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol, ()> { // FIXME: nfc-normalize and validate idents Ok(<Self as server::Server>::intern_symbol(string)) } } -impl server::Server for RaSpanServer { +impl server::Server for RaSpanServer<'_> { fn globals(&mut self) -> ExpnGlobals<Self::Span> { ExpnGlobals { def_site: self.def_site, diff --git a/crates/proc-macro-srv/src/server_impl/token_id.rs b/crates/proc-macro-srv/src/server_impl/token_id.rs index 646dde7952..a968ea4cd2 100644 --- a/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -27,7 +27,7 @@ type Span = SpanId; pub struct FreeFunctions; -pub struct SpanIdServer { +pub struct SpanIdServer<'a> { // FIXME: Report this back to the caller to track as dependencies pub tracked_env_vars: HashMap<Box<str>, Option<Box<str>>>, // FIXME: Report this back to the caller to track as dependencies @@ -35,17 +35,17 @@ pub struct SpanIdServer { pub call_site: Span, pub def_site: Span, pub mixed_site: Span, - pub callback: Option<ProcMacroClientHandle>, + pub callback: Option<ProcMacroClientHandle<'a>>, } -impl server::Types for SpanIdServer { +impl server::Types for SpanIdServer<'_> { type FreeFunctions = FreeFunctions; type TokenStream = crate::token_stream::TokenStream<Span>; type Span = Span; type Symbol = Symbol; } -impl server::FreeFunctions for SpanIdServer { +impl server::FreeFunctions for SpanIdServer<'_> { fn injected_env_var(&mut self, _: &str) -> Option<std::string::String> { None } @@ -63,7 +63,7 @@ impl server::FreeFunctions for SpanIdServer { fn emit_diagnostic(&mut self, _: Diagnostic<Self::Span>) {} } -impl server::TokenStream for SpanIdServer { +impl server::TokenStream for SpanIdServer<'_> { fn is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() } @@ -120,7 +120,7 @@ impl server::TokenStream for SpanIdServer { } } -impl server::Span for SpanIdServer { +impl server::Span for SpanIdServer<'_> { fn debug(&mut self, span: Self::Span) -> String { format!("{:?}", span.0) } @@ -187,14 +187,14 @@ impl server::Span for SpanIdServer { } } -impl server::Symbol for SpanIdServer { +impl server::Symbol for SpanIdServer<'_> { fn normalize_and_validate_ident(&mut self, string: &str) -> Result<Self::Symbol, ()> { // FIXME: nfc-normalize and validate idents Ok(<Self as server::Server>::intern_symbol(string)) } } -impl server::Server for SpanIdServer { +impl server::Server for SpanIdServer<'_> { fn globals(&mut self) -> ExpnGlobals<Self::Span> { ExpnGlobals { def_site: self.def_site, |