Move proc-macro protocol into legacy module

This commit is contained in:
Lukas Wirth 2024-12-30 11:47:08 +01:00
parent f5a6826137
commit b2d9486ebd
7 changed files with 38 additions and 33 deletions

View file

@ -82,7 +82,7 @@ pub fn load_workspace(
}; };
match &proc_macro_server { match &proc_macro_server {
Ok(server) => { Ok(server) => {
tracing::info!(path=%server.path(), "Proc-macro server started") tracing::info!(path=%server.server_path(), "Proc-macro server started")
} }
Err((e, _)) => { Err((e, _)) => {
tracing::info!(%e, "Failed to start proc-macro server") tracing::info!(%e, "Failed to start proc-macro server")

View file

@ -9,7 +9,7 @@ use serde_derive::{Deserialize, Serialize};
use crate::ProcMacroKind; use crate::ProcMacroKind;
pub use crate::msg::flat::{ pub use self::flat::{
deserialize_span_data_index_map, serialize_span_data_index_map, FlatTree, SpanDataIndexMap, deserialize_span_data_index_map, serialize_span_data_index_map, FlatTree, SpanDataIndexMap,
}; };
pub use span::TokenId; pub use span::TokenId;

View file

@ -44,7 +44,7 @@ use span::{
EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange, TokenId, EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange, TokenId,
}; };
use crate::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA}; use crate::legacy_protocol::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA};
pub type SpanDataIndexMap = pub type SpanDataIndexMap =
indexmap::IndexSet<Span, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>; indexmap::IndexSet<Span, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;

View file

@ -5,8 +5,10 @@
//! is used to provide basic infrastructure for communication between two //! is used to provide basic infrastructure for communication between two
//! processes: Client (RA itself), Server (the external program) //! processes: Client (RA itself), Server (the external program)
pub mod json; pub mod legacy_protocol {
pub mod msg; pub mod json;
pub mod msg;
}
mod process; mod process;
use paths::{AbsPath, AbsPathBuf}; use paths::{AbsPath, AbsPathBuf};
@ -14,10 +16,10 @@ use span::Span;
use std::{fmt, io, sync::Arc}; use std::{fmt, io, sync::Arc};
use crate::{ use crate::{
msg::{ legacy_protocol::msg::{
deserialize_span_data_index_map, flat::serialize_span_data_index_map, ExpandMacro, deserialize_span_data_index_map, flat::serialize_span_data_index_map, ExpandMacro,
ExpnGlobals, FlatTree, PanicMessage, SpanDataIndexMap, HAS_GLOBAL_SPANS, ExpandMacroData, ExpnGlobals, FlatTree, PanicMessage, Request, Response, SpanDataIndexMap,
RUST_ANALYZER_SPAN_SUPPORT, HAS_GLOBAL_SPANS, RUST_ANALYZER_SPAN_SUPPORT,
}, },
process::ProcMacroServerProcess, process::ProcMacroServerProcess,
}; };
@ -54,10 +56,10 @@ impl MacroDylib {
} }
} }
/// A handle to a specific macro (a `#[proc_macro]` annotated function). /// A handle to a specific proc-macro (a `#[proc_macro]` annotated function).
/// ///
/// It exists within a context of a specific [`ProcMacroProcess`] -- currently /// It exists within the context of a specific proc-macro server -- currently
/// we share a single expander process for all macros. /// we share a single expander process for all macros within a workspace.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ProcMacro { pub struct ProcMacro {
process: Arc<ProcMacroServerProcess>, process: Arc<ProcMacroServerProcess>,
@ -104,10 +106,11 @@ impl ProcMacroClient {
Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() }) Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() })
} }
pub fn path(&self) -> &AbsPath { pub fn server_path(&self) -> &AbsPath {
&self.path &self.path
} }
/// Loads a proc-macro dylib into the server process returning a list of `ProcMacro`s loaded.
pub fn load_dylib(&self, dylib: MacroDylib) -> Result<Vec<ProcMacro>, ServerError> { pub fn load_dylib(&self, dylib: MacroDylib) -> Result<Vec<ProcMacro>, ServerError> {
let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered(); let _p = tracing::info_span!("ProcMacroServer::load_dylib").entered();
let macros = self.process.find_proc_macros(&dylib.path)?; let macros = self.process.find_proc_macros(&dylib.path)?;
@ -158,7 +161,7 @@ impl ProcMacro {
let call_site = span_data_table.insert_full(call_site).0; let call_site = span_data_table.insert_full(call_site).0;
let mixed_site = span_data_table.insert_full(mixed_site).0; let mixed_site = span_data_table.insert_full(mixed_site).0;
let task = ExpandMacro { let task = ExpandMacro {
data: msg::ExpandMacroData { data: ExpandMacroData {
macro_body: FlatTree::new(subtree, version, &mut span_data_table), macro_body: FlatTree::new(subtree, version, &mut span_data_table),
macro_name: self.name.to_string(), macro_name: self.name.to_string(),
attributes: attr attributes: attr
@ -180,13 +183,13 @@ impl ProcMacro {
current_dir, current_dir,
}; };
let response = self.process.send_task(msg::Request::ExpandMacro(Box::new(task)))?; let response = self.process.send_task(Request::ExpandMacro(Box::new(task)))?;
match response { match response {
msg::Response::ExpandMacro(it) => { Response::ExpandMacro(it) => {
Ok(it.map(|tree| FlatTree::to_subtree_resolved(tree, version, &span_data_table))) Ok(it.map(|tree| FlatTree::to_subtree_resolved(tree, version, &span_data_table)))
} }
msg::Response::ExpandMacroExtended(it) => Ok(it.map(|resp| { Response::ExpandMacroExtended(it) => Ok(it.map(|resp| {
FlatTree::to_subtree_resolved( FlatTree::to_subtree_resolved(
resp.tree, resp.tree,
version, version,

View file

@ -11,8 +11,13 @@ use paths::AbsPath;
use stdx::JodChild; use stdx::JodChild;
use crate::{ use crate::{
json::{read_json, write_json}, legacy_protocol::{
msg::{Message, Request, Response, SpanMode, CURRENT_API_VERSION, RUST_ANALYZER_SPAN_SUPPORT}, json::{read_json, write_json},
msg::{
Message, Request, Response, ServerConfig, SpanMode, CURRENT_API_VERSION,
RUST_ANALYZER_SPAN_SUPPORT,
},
},
ProcMacroKind, ServerError, ProcMacroKind, ServerError,
}; };
@ -40,8 +45,8 @@ impl ProcMacroServerProcess {
env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)> env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>
+ Clone, + Clone,
) -> io::Result<ProcMacroServerProcess> { ) -> io::Result<ProcMacroServerProcess> {
let create_srv = |null_stderr| { let create_srv = || {
let mut process = Process::run(process_path, env.clone(), null_stderr)?; let mut process = Process::run(process_path, env.clone())?;
let (stdin, stdout) = process.stdio().expect("couldn't access child stdio"); let (stdin, stdout) = process.stdio().expect("couldn't access child stdio");
io::Result::Ok(ProcMacroServerProcess { io::Result::Ok(ProcMacroServerProcess {
@ -51,7 +56,7 @@ impl ProcMacroServerProcess {
exited: OnceLock::new(), exited: OnceLock::new(),
}) })
}; };
let mut srv = create_srv(true)?; let mut srv = create_srv()?;
tracing::info!("sending proc-macro server version check"); tracing::info!("sending proc-macro server version check");
match srv.version_check() { match srv.version_check() {
Ok(v) if v > CURRENT_API_VERSION => Err(io::Error::new( Ok(v) if v > CURRENT_API_VERSION => Err(io::Error::new(
@ -62,7 +67,6 @@ impl ProcMacroServerProcess {
)), )),
Ok(v) => { Ok(v) => {
tracing::info!("Proc-macro server version: {v}"); tracing::info!("Proc-macro server version: {v}");
srv = create_srv(false)?;
srv.version = v; srv.version = v;
if srv.version >= RUST_ANALYZER_SPAN_SUPPORT { if srv.version >= RUST_ANALYZER_SPAN_SUPPORT {
if let Ok(mode) = srv.enable_rust_analyzer_spans() { if let Ok(mode) = srv.enable_rust_analyzer_spans() {
@ -73,8 +77,10 @@ impl ProcMacroServerProcess {
Ok(srv) Ok(srv)
} }
Err(e) => { Err(e) => {
tracing::info!(%e, "proc-macro version check failed, restarting and assuming version 0"); tracing::info!(%e, "proc-macro version check failed");
create_srv(false) Err(
io::Error::new(io::ErrorKind::Other, format!("proc-macro server version check failed: {e}")),
)
} }
} }
} }
@ -98,13 +104,11 @@ impl ProcMacroServerProcess {
} }
fn enable_rust_analyzer_spans(&self) -> Result<SpanMode, ServerError> { fn enable_rust_analyzer_spans(&self) -> Result<SpanMode, ServerError> {
let request = Request::SetConfig(crate::msg::ServerConfig { let request = Request::SetConfig(ServerConfig { span_mode: SpanMode::RustAnalyzer });
span_mode: crate::msg::SpanMode::RustAnalyzer,
});
let response = self.send_task(request)?; let response = self.send_task(request)?;
match response { match response {
Response::SetConfig(crate::msg::ServerConfig { span_mode }) => Ok(span_mode), Response::SetConfig(ServerConfig { span_mode }) => Ok(span_mode),
_ => Err(ServerError { message: "unexpected response".to_owned(), io: None }), _ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),
} }
} }
@ -182,9 +186,8 @@ impl Process {
fn run( fn run(
path: &AbsPath, path: &AbsPath,
env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>, env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>,
null_stderr: bool,
) -> io::Result<Process> { ) -> io::Result<Process> {
let child = JodChild(mk_child(path, env, null_stderr)?); let child = JodChild(mk_child(path, env)?);
Ok(Process { child }) Ok(Process { child })
} }
@ -200,7 +203,6 @@ impl Process {
fn mk_child( fn mk_child(
path: &AbsPath, path: &AbsPath,
env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>, env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>,
null_stderr: bool,
) -> io::Result<Child> { ) -> io::Result<Child> {
#[allow(clippy::disallowed_methods)] #[allow(clippy::disallowed_methods)]
let mut cmd = Command::new(path); let mut cmd = Command::new(path);
@ -208,7 +210,7 @@ fn mk_child(
.env("RUST_ANALYZER_INTERNALS_DO_NOT_USE", "this is unstable") .env("RUST_ANALYZER_INTERNALS_DO_NOT_USE", "this is unstable")
.stdin(Stdio::piped()) .stdin(Stdio::piped())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(if null_stderr { Stdio::null() } else { Stdio::inherit() }); .stderr(Stdio::inherit());
if cfg!(windows) { if cfg!(windows) {
let mut path_var = std::ffi::OsString::new(); let mut path_var = std::ffi::OsString::new();
path_var.push(path.parent().unwrap().parent().unwrap()); path_var.push(path.parent().unwrap().parent().unwrap());

View file

@ -1,7 +1,7 @@
//! The main loop of the proc-macro server. //! The main loop of the proc-macro server.
use std::io; use std::io;
use proc_macro_api::{ use proc_macro_api::legacy_protocol::{
json::{read_json, write_json}, json::{read_json, write_json},
msg::{ msg::{
self, deserialize_span_data_index_map, serialize_span_data_index_map, ExpandMacroData, self, deserialize_span_data_index_map, serialize_span_data_index_map, ExpandMacroData,