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.rs86
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,
}
}
}