Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/proc-macro-srv/src/lib.rs')
| -rw-r--r-- | crates/proc-macro-srv/src/lib.rs | 86 |
1 files changed, 82 insertions, 4 deletions
diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs index 93319df824..f369ab93a2 100644 --- a/crates/proc-macro-srv/src/lib.rs +++ b/crates/proc-macro-srv/src/lib.rs @@ -47,7 +47,7 @@ use std::{ }; use paths::{Utf8Path, Utf8PathBuf}; -use span::Span; +use span::{EditionedFileId, Span}; use temp_dir::TempDir; pub use crate::server_impl::token_id::SpanId; @@ -91,6 +91,14 @@ impl<'env> ProcMacroSrv<'env> { } } +pub enum SubRequest { + SourceText { file_id: EditionedFileId, start: u32, end: u32 }, +} + +pub enum SubResponse { + SourceTextResult { text: Option<String> }, +} + const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; impl ProcMacroSrv<'_> { @@ -133,6 +141,53 @@ impl ProcMacroSrv<'_> { result } + pub fn expand_with_channels<S: ProcMacroSrvSpan>( + &self, + lib: impl AsRef<Utf8Path>, + env: &[(String, String)], + current_dir: Option<impl AsRef<Path>>, + macro_name: &str, + macro_body: token_stream::TokenStream<S>, + attribute: Option<token_stream::TokenStream<S>>, + def_site: S, + call_site: S, + mixed_site: S, + cli_to_server: crossbeam_channel::Receiver<SubResponse>, + server_to_cli: crossbeam_channel::Sender<SubRequest>, + ) -> Result<token_stream::TokenStream<S>, PanicMessage> { + let snapped_env = self.env; + let expander = self.expander(lib.as_ref()).map_err(|err| PanicMessage { + message: Some(format!("failed to load macro: {err}")), + })?; + + let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref)); + + let result = thread::scope(|s| { + let thread = thread::Builder::new() + .stack_size(EXPANDER_STACK_SIZE) + .name(macro_name.to_owned()) + .spawn_scoped(s, move || { + expander.expand_with_channels( + macro_name, + macro_body, + attribute, + def_site, + call_site, + mixed_site, + cli_to_server, + server_to_cli, + ) + }); + match thread.unwrap().join() { + Ok(res) => res, + Err(e) => std::panic::resume_unwind(e), + } + }); + prev_env.rollback(); + + result + } + pub fn list_macros( &self, dylib_path: &Utf8Path, @@ -170,31 +225,54 @@ impl ProcMacroSrv<'_> { pub trait ProcMacroSrvSpan: Copy + Send + Sync { type Server: proc_macro::bridge::server::Server<TokenStream = crate::token_stream::TokenStream<Self>>; - fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server; + fn make_server( + call_site: Self, + def_site: Self, + mixed_site: Self, + cli_to_server: Option<crossbeam_channel::Receiver<SubResponse>>, + server_to_cli: Option<crossbeam_channel::Sender<SubRequest>>, + ) -> Self::Server; } impl ProcMacroSrvSpan for SpanId { type Server = server_impl::token_id::SpanIdServer; - fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server { + fn make_server( + call_site: Self, + def_site: Self, + mixed_site: Self, + cli_to_server: Option<crossbeam_channel::Receiver<SubResponse>>, + server_to_cli: Option<crossbeam_channel::Sender<SubRequest>>, + ) -> Self::Server { Self::Server { call_site, def_site, mixed_site, + cli_to_server, + server_to_cli, tracked_env_vars: Default::default(), tracked_paths: Default::default(), } } } + impl ProcMacroSrvSpan for Span { type Server = server_impl::rust_analyzer_span::RaSpanServer; - fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server { + fn make_server( + call_site: Self, + def_site: Self, + mixed_site: Self, + cli_to_server: Option<crossbeam_channel::Receiver<SubResponse>>, + server_to_cli: Option<crossbeam_channel::Sender<SubRequest>>, + ) -> Self::Server { Self::Server { call_site, def_site, mixed_site, tracked_env_vars: Default::default(), tracked_paths: Default::default(), + cli_to_server, + server_to_cli, } } } |