Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21377 from Shourya742/2025-12-31-add-more-proc-macro-bidirectional-flow
proc-macro-srv: support file and local_file via bidirectional callbacks
| -rw-r--r-- | crates/load-cargo/src/lib.rs | 25 | ||||
| -rw-r--r-- | crates/proc-macro-api/src/bidirectional_protocol/msg.rs | 4 | ||||
| -rw-r--r-- | crates/proc-macro-srv-cli/src/main_loop.rs | 53 | ||||
| -rw-r--r-- | crates/proc-macro-srv/src/lib.rs | 2 | ||||
| -rw-r--r-- | crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs | 15 |
5 files changed, 75 insertions, 24 deletions
diff --git a/crates/load-cargo/src/lib.rs b/crates/load-cargo/src/lib.rs index 5122051fb3..e01ce0b129 100644 --- a/crates/load-cargo/src/lib.rs +++ b/crates/load-cargo/src/lib.rs @@ -540,12 +540,37 @@ impl ProcMacroExpander for Expander { current_dir: String, ) -> Result<tt::TopSubtree, ProcMacroExpansionError> { let mut cb = |req| match req { + SubRequest::LocalFilePath { file_id } => { + let file = FileId::from_raw(file_id); + let source_root_id = db.file_source_root(file).source_root_id(db); + let source_root = db.source_root(source_root_id).source_root(db); + + let name = source_root + .path_for_file(&file) + .and_then(|path| path.as_path()) + .map(|path| path.to_string()); + + Ok(SubResponse::LocalFilePathResult { name }) + } SubRequest::SourceText { file_id, start, end } => { let file = FileId::from_raw(file_id); let text = db.file_text(file).text(db); let slice = text.get(start as usize..end as usize).map(ToOwned::to_owned); Ok(SubResponse::SourceTextResult { text: slice }) } + SubRequest::FilePath { file_id } => { + let file = FileId::from_raw(file_id); + let source_root_id = db.file_source_root(file).source_root_id(db); + let source_root = db.source_root(source_root_id).source_root(db); + + let name = source_root + .path_for_file(&file) + .and_then(|path| path.as_path()) + .map(|path| path.to_string()) + .unwrap_or_default(); + + Ok(SubResponse::FilePathResult { name }) + } }; match self.0.expand( subtree.view(), diff --git a/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index cf8becd922..558954f761 100644 --- a/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -10,12 +10,16 @@ use crate::{ #[derive(Debug, Serialize, Deserialize)] pub enum SubRequest { + FilePath { file_id: u32 }, SourceText { file_id: u32, start: u32, end: u32 }, + LocalFilePath { file_id: u32 }, } #[derive(Debug, Serialize, Deserialize)] pub enum SubResponse { + FilePathResult { name: String }, SourceTextResult { text: Option<String> }, + LocalFilePathResult { name: Option<String> }, } #[derive(Debug, Serialize, Deserialize)] diff --git a/crates/proc-macro-srv-cli/src/main_loop.rs b/crates/proc-macro-srv-cli/src/main_loop.rs index 25a5104c5d..8fe3e93e47 100644 --- a/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/crates/proc-macro-srv-cli/src/main_loop.rs @@ -81,7 +81,6 @@ fn run_new<C: Codec>() -> io::Result<()> { } bidirectional::Request::ApiVersionCheck {} => { - // bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION).write::<_, C>(stdout) send_response::<C>( &stdout, bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION), @@ -167,28 +166,48 @@ struct ProcMacroClientHandle<'a, C: Codec> { buf: &'a mut C::Buf, } -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 }, - ); +impl<'a, C: Codec> ProcMacroClientHandle<'a, C> { + fn roundtrip( + &mut self, + req: bidirectional::SubRequest, + ) -> Option<bidirectional::BidirectionalMessage> { + let msg = bidirectional::BidirectionalMessage::SubRequest(req); - if req.write::<_, C>(&mut self.stdout.lock()).is_err() { + if msg.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 bidirectional::BidirectionalMessage::read::<_, C>(&mut self.stdin.lock(), self.buf) { + Ok(Some(msg)) => Some(msg), + _ => None, + } + } +} + +impl<C: Codec> proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_, C> { + fn file(&mut self, file_id: u32) -> String { + match self.roundtrip(bidirectional::SubRequest::FilePath { file_id }) { + Some(bidirectional::BidirectionalMessage::SubResponse( + bidirectional::SubResponse::FilePathResult { name }, + )) => name, + _ => String::new(), + } + } - match msg { - bidirectional::BidirectionalMessage::SubResponse( + fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option<String> { + match self.roundtrip(bidirectional::SubRequest::SourceText { file_id, start, end }) { + Some(bidirectional::BidirectionalMessage::SubResponse( bidirectional::SubResponse::SourceTextResult { text }, - ) => text, + )) => text, + _ => None, + } + } + + fn local_file(&mut self, file_id: u32) -> Option<String> { + match self.roundtrip(bidirectional::SubRequest::LocalFilePath { file_id }) { + Some(bidirectional::BidirectionalMessage::SubResponse( + bidirectional::SubResponse::LocalFilePathResult { name }, + )) => name, _ => None, } } diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs index 17ffa29ce1..8de712dbd3 100644 --- a/crates/proc-macro-srv/src/lib.rs +++ b/crates/proc-macro-srv/src/lib.rs @@ -94,7 +94,9 @@ impl<'env> ProcMacroSrv<'env> { pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Sync + Send); pub trait ProcMacroClientInterface { + fn file(&mut self, file_id: u32) -> String; fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option<String>; + fn local_file(&mut self, file_id: u32) -> Option<String>; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; 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 5d9090c060..7a9d655431 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 @@ -127,13 +127,14 @@ impl server::Span for RaSpanServer<'_> { fn debug(&mut self, span: Self::Span) -> String { format!("{:?}", span) } - fn file(&mut self, _: Self::Span) -> String { - // FIXME - String::new() - } - fn local_file(&mut self, _: Self::Span) -> Option<String> { - // FIXME - None + fn file(&mut self, span: Self::Span) -> String { + self.callback + .as_mut() + .map(|cb| cb.file(span.anchor.file_id.file_id().index())) + .unwrap_or_default() + } + fn local_file(&mut self, span: Self::Span) -> Option<String> { + self.callback.as_mut().and_then(|cb| cb.local_file(span.anchor.file_id.file_id().index())) } fn save_span(&mut self, _span: Self::Span) -> usize { // FIXME, quote is incompatible with third-party tools |