Chayim Refael Friedman 3e834add61 Support spans with proc macro servers from before the ast id changes
The only thing changed is the value of the fixup ast id, so we just swap it.
2025-06-12 16:08:48 +03:00

133 lines
5.4 KiB
Rust

//! The main loop of the proc-macro server.
use std::io;
use proc_macro_api::legacy_protocol::{
json::{read_json, write_json},
msg::{
self, CURRENT_API_VERSION, ExpandMacroData, ExpnGlobals, Message, SpanMode, TokenId,
deserialize_span_data_index_map, serialize_span_data_index_map,
},
};
use proc_macro_srv::EnvSnapshot;
pub(crate) fn run() -> io::Result<()> {
fn macro_kind_to_api(kind: proc_macro_srv::ProcMacroKind) -> proc_macro_api::ProcMacroKind {
match kind {
proc_macro_srv::ProcMacroKind::CustomDerive => {
proc_macro_api::ProcMacroKind::CustomDerive
}
proc_macro_srv::ProcMacroKind::Bang => proc_macro_api::ProcMacroKind::Bang,
proc_macro_srv::ProcMacroKind::Attr => proc_macro_api::ProcMacroKind::Attr,
}
}
let mut buf = String::new();
let mut read_request = || msg::Request::read(read_json, &mut io::stdin().lock(), &mut buf);
let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock());
let env = EnvSnapshot::default();
let srv = proc_macro_srv::ProcMacroSrv::new(&env);
let mut span_mode = SpanMode::Id;
while let Some(req) = read_request()? {
let res = match req {
msg::Request::ListMacros { dylib_path } => {
msg::Response::ListMacros(srv.list_macros(&dylib_path).map(|macros| {
macros.into_iter().map(|(name, kind)| (name, macro_kind_to_api(kind))).collect()
}))
}
msg::Request::ExpandMacro(task) => {
let msg::ExpandMacro {
lib,
env,
current_dir,
data:
ExpandMacroData {
macro_body,
macro_name,
attributes,
has_global_spans:
ExpnGlobals { serialize: _, def_site, call_site, mixed_site },
span_data_table,
},
} = *task;
match span_mode {
SpanMode::Id => msg::Response::ExpandMacro({
let def_site = TokenId(def_site as u32);
let call_site = TokenId(call_site as u32);
let mixed_site = TokenId(mixed_site as u32);
let macro_body = macro_body.to_subtree_unresolved(CURRENT_API_VERSION);
let attributes =
attributes.map(|it| it.to_subtree_unresolved(CURRENT_API_VERSION));
srv.expand(
lib,
env,
current_dir,
macro_name,
macro_body,
attributes,
def_site,
call_site,
mixed_site,
)
.map(|it| {
msg::FlatTree::new_raw(tt::SubtreeView::new(&it), CURRENT_API_VERSION)
})
.map_err(msg::PanicMessage)
}),
SpanMode::RustAnalyzer => msg::Response::ExpandMacroExtended({
let mut span_data_table = deserialize_span_data_index_map(&span_data_table);
let def_site = span_data_table[def_site];
let call_site = span_data_table[call_site];
let mixed_site = span_data_table[mixed_site];
let macro_body =
macro_body.to_subtree_resolved(CURRENT_API_VERSION, &span_data_table);
let attributes = attributes.map(|it| {
it.to_subtree_resolved(CURRENT_API_VERSION, &span_data_table)
});
srv.expand(
lib,
env,
current_dir,
macro_name,
macro_body,
attributes,
def_site,
call_site,
mixed_site,
)
.map(|it| {
(
msg::FlatTree::new(
tt::SubtreeView::new(&it),
CURRENT_API_VERSION,
&mut span_data_table,
),
serialize_span_data_index_map(&span_data_table),
)
})
.map(|(tree, span_data_table)| msg::ExpandMacroExtended {
tree,
span_data_table,
})
.map_err(msg::PanicMessage)
}),
}
}
msg::Request::ApiVersionCheck {} => msg::Response::ApiVersionCheck(CURRENT_API_VERSION),
msg::Request::SetConfig(config) => {
span_mode = config.span_mode;
msg::Response::SetConfig(config)
}
};
write_response(res)?
}
Ok(())
}