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 | 98 |
1 files changed, 71 insertions, 27 deletions
diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs index cb97882c58..17ffa29ce1 100644 --- a/crates/proc-macro-srv/src/lib.rs +++ b/crates/proc-macro-srv/src/lib.rs @@ -10,11 +10,16 @@ //! * By **copying** the whole rustc `lib_proc_macro` code, we are able to build this with `stable` //! rustc rather than `unstable`. (Although in general ABI compatibility is still an issue)… -#![cfg(any(feature = "sysroot-abi", rust_analyzer))] -#![cfg_attr(not(feature = "sysroot-abi"), allow(unused_crate_dependencies))] +#![cfg(feature = "sysroot-abi")] #![cfg_attr(feature = "in-rust-tree", feature(rustc_private))] #![feature(proc_macro_internals, proc_macro_diagnostic, proc_macro_span)] -#![allow(unreachable_pub, internal_features, clippy::disallowed_types, clippy::print_stderr)] +#![allow( + unreachable_pub, + internal_features, + clippy::disallowed_types, + clippy::print_stderr, + unused_crate_dependencies +)] #![deny(deprecated_safe, clippy::undocumented_unsafe_blocks)] extern crate proc_macro; @@ -26,8 +31,10 @@ extern crate ra_ap_rustc_lexer as rustc_lexer; #[cfg(feature = "in-rust-tree")] extern crate rustc_lexer; +mod bridge; mod dylib; mod server_impl; +mod token_stream; use std::{ collections::{HashMap, hash_map::Entry}, @@ -43,10 +50,14 @@ use paths::{Utf8Path, Utf8PathBuf}; use span::Span; use temp_dir::TempDir; -use crate::server_impl::TokenStream; - pub use crate::server_impl::token_id::SpanId; +pub use proc_macro::Delimiter; + +pub use crate::bridge::*; +pub use crate::server_impl::literal_from_str; +pub use crate::token_stream::{TokenStream, TokenStreamIter, literal_to_string}; + #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub enum ProcMacroKind { CustomDerive, @@ -70,6 +81,20 @@ impl<'env> ProcMacroSrv<'env> { temp_dir: TempDir::with_prefix("proc-macro-srv").unwrap(), } } + + pub fn join_spans(&self, first: Span, second: Span) -> Option<Span> { + first.join(second, |_, _| { + // FIXME: Once we can talk back to the client, implement a "long join" request for anchors + // that differ in [AstId]s as joining those spans requires resolving the AstIds. + None + }) + } +} + +pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Sync + Send); + +pub trait ProcMacroClientInterface { + fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option<String>; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; @@ -81,12 +106,13 @@ impl ProcMacroSrv<'_> { env: &[(String, String)], current_dir: Option<impl AsRef<Path>>, macro_name: &str, - macro_body: tt::TopSubtree<S>, - attribute: Option<tt::TopSubtree<S>>, + macro_body: token_stream::TokenStream<S>, + attribute: Option<token_stream::TokenStream<S>>, def_site: S, call_site: S, mixed_site: S, - ) -> Result<Vec<tt::TokenTree<S>>, PanicMessage> { + 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 { message: Some(format!("failed to load macro: {err}")), @@ -101,16 +127,10 @@ impl ProcMacroSrv<'_> { .stack_size(EXPANDER_STACK_SIZE) .name(macro_name.to_owned()) .spawn_scoped(s, move || { - expander - .expand( - macro_name, - server_impl::TopSubtree(macro_body.0.into_vec()), - attribute.map(|it| server_impl::TopSubtree(it.0.into_vec())), - def_site, - call_site, - mixed_site, - ) - .map(|tt| tt.0) + expander.expand( + macro_name, macro_body, attribute, def_site, call_site, mixed_site, + callback, + ) }); match thread.unwrap().join() { Ok(res) => res, @@ -157,25 +177,49 @@ impl ProcMacroSrv<'_> { } } -pub trait ProcMacroSrvSpan: Copy + Send { - type Server: proc_macro::bridge::server::Server<TokenStream = TokenStream<Self>>; - fn make_server(call_site: Self, def_site: Self, mixed_site: Self) -> Self::Server; +pub trait ProcMacroSrvSpan: Copy + Send + Sync { + type Server<'a>: proc_macro::bridge::server::Server<TokenStream = crate::token_stream::TokenStream<Self>>; + fn make_server<'a>( + call_site: Self, + def_site: Self, + mixed_site: Self, + callback: Option<ProcMacroClientHandle<'a>>, + ) -> Self::Server<'a>; } 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 { - Self::Server { call_site, def_site, mixed_site } + type Server<'a> = server_impl::token_id::SpanIdServer<'a>; + + fn make_server<'a>( + call_site: Self, + def_site: Self, + mixed_site: Self, + callback: Option<ProcMacroClientHandle<'a>>, + ) -> Self::Server<'a> { + Self::Server { + call_site, + def_site, + mixed_site, + callback, + 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 { + 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<'a>>, + ) -> Self::Server<'a> { Self::Server { call_site, def_site, mixed_site, + callback, tracked_env_vars: Default::default(), tracked_paths: Default::default(), } |