Decouple proc-macro server protocol from the server implementation

This commit is contained in:
Lukas Wirth 2024-12-30 10:03:51 +01:00
parent 90b724afad
commit 714b81bec1
17 changed files with 242 additions and 217 deletions

View file

@ -13,18 +13,16 @@ use paths::{AbsPath, AbsPathBuf};
use span::Span;
use std::{fmt, io, sync::Arc};
use serde::{Deserialize, Serialize};
use crate::{
msg::{
deserialize_span_data_index_map, flat::serialize_span_data_index_map, ExpandMacro,
ExpnGlobals, FlatTree, PanicMessage, SpanDataIndexMap, HAS_GLOBAL_SPANS,
RUST_ANALYZER_SPAN_SUPPORT,
},
process::ProcMacroProcessSrv,
process::ProcMacroServerProcess,
};
#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
#[derive(Copy, Clone, Eq, PartialEq, Debug, serde_derive::Serialize, serde_derive::Deserialize)]
pub enum ProcMacroKind {
CustomDerive,
Attr,
@ -37,12 +35,12 @@ pub enum ProcMacroKind {
/// A handle to an external process which load dylibs with macros (.so or .dll)
/// and runs actual macro expansion functions.
#[derive(Debug)]
pub struct ProcMacroServer {
pub struct ProcMacroClient {
/// Currently, the proc macro process expands all procedural macros sequentially.
///
/// That means that concurrent salsa requests may block each other when expanding proc macros,
/// which is unfortunate, but simple and good enough for the time being.
process: Arc<ProcMacroProcessSrv>,
process: Arc<ProcMacroServerProcess>,
path: AbsPathBuf,
}
@ -62,7 +60,7 @@ impl MacroDylib {
/// we share a single expander process for all macros.
#[derive(Debug, Clone)]
pub struct ProcMacro {
process: Arc<ProcMacroProcessSrv>,
process: Arc<ProcMacroServerProcess>,
dylib_path: Arc<AbsPathBuf>,
name: Box<str>,
kind: ProcMacroKind,
@ -95,15 +93,15 @@ impl fmt::Display for ServerError {
}
}
impl ProcMacroServer {
impl ProcMacroClient {
/// Spawns an external process as the proc macro server and returns a client connected to it.
pub fn spawn(
process_path: &AbsPath,
env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>
+ Clone,
) -> io::Result<ProcMacroServer> {
let process = ProcMacroProcessSrv::run(process_path, env)?;
Ok(ProcMacroServer { process: Arc::new(process), path: process_path.to_owned() })
) -> io::Result<ProcMacroClient> {
let process = ProcMacroServerProcess::run(process_path, env)?;
Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() })
}
pub fn path(&self) -> &AbsPath {

View file

@ -11,8 +11,8 @@ use crate::ProcMacroKind;
pub use crate::msg::flat::{
deserialize_span_data_index_map, serialize_span_data_index_map, FlatTree, SpanDataIndexMap,
TokenId,
};
pub use span::TokenId;
// The versions of the server protocol
pub const NO_VERSION_CHECK_VERSION: u32 = 0;

View file

@ -40,7 +40,9 @@ use std::collections::VecDeque;
use intern::Symbol;
use rustc_hash::FxHashMap;
use serde_derive::{Deserialize, Serialize};
use span::{EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange};
use span::{
EditionedFileId, ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, TextRange, TokenId,
};
use crate::msg::{ENCODE_CLOSE_SPAN_VERSION, EXTENDED_LEAF_DATA};
@ -78,15 +80,6 @@ pub fn deserialize_span_data_index_map(map: &[u32]) -> SpanDataIndexMap {
.collect()
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct TokenId(pub u32);
impl std::fmt::Debug for TokenId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct FlatTree {
subtree: Vec<u32>,

View file

@ -17,7 +17,7 @@ use crate::{
};
#[derive(Debug)]
pub(crate) struct ProcMacroProcessSrv {
pub(crate) struct ProcMacroServerProcess {
/// The state of the proc-macro server process, the protocol is currently strictly sequential
/// hence the lock on the state.
state: Mutex<ProcessSrvState>,
@ -34,17 +34,17 @@ struct ProcessSrvState {
stdout: BufReader<ChildStdout>,
}
impl ProcMacroProcessSrv {
impl ProcMacroServerProcess {
pub(crate) fn run(
process_path: &AbsPath,
env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>
+ Clone,
) -> io::Result<ProcMacroProcessSrv> {
) -> io::Result<ProcMacroServerProcess> {
let create_srv = |null_stderr| {
let mut process = Process::run(process_path, env.clone(), null_stderr)?;
let (stdin, stdout) = process.stdio().expect("couldn't access child stdio");
io::Result::Ok(ProcMacroProcessSrv {
io::Result::Ok(ProcMacroServerProcess {
state: Mutex::new(ProcessSrvState { process, stdin, stdout }),
version: 0,
mode: SpanMode::Id,