make postcard first class member of proc-macro-srv-cli

This commit is contained in:
bit-aloo 2025-11-07 23:58:27 +05:30
parent cf4b1faea3
commit 1dad405ebe
No known key found for this signature in database
3 changed files with 146 additions and 10 deletions

View File

@ -14,14 +14,13 @@ publish = false
proc-macro-srv.workspace = true
proc-macro-api.workspace = true
tt.workspace = true
postcard.workspace = true
clap = {version = "4.5.42", default-features = false, features = ["std"]}
postcard = { version = "1.1.3", optional = true }
[features]
default = ["postcard"]
sysroot-abi = ["proc-macro-srv/sysroot-abi", "proc-macro-api/sysroot-abi"]
in-rust-tree = ["proc-macro-srv/in-rust-tree", "sysroot-abi"]
postcard = ["dep:postcard"]
[[bin]]

View File

@ -31,7 +31,7 @@ fn main() -> std::io::Result<()> {
clap::Arg::new("format")
.long("format")
.action(clap::ArgAction::Set)
.default_value("json")
.default_value("postcard")
.value_parser(clap::builder::EnumValueParser::<ProtocolFormat>::new()),
clap::Arg::new("version")
.long("version")
@ -51,26 +51,23 @@ fn main() -> std::io::Result<()> {
#[derive(Copy, Clone)]
enum ProtocolFormat {
Json,
#[cfg(feature = "postcard")]
Postcard,
}
impl ValueEnum for ProtocolFormat {
fn value_variants<'a>() -> &'a [Self] {
&[ProtocolFormat::Json]
&[ProtocolFormat::Json, ProtocolFormat::Postcard]
}
fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
match self {
ProtocolFormat::Json => Some(clap::builder::PossibleValue::new("json")),
#[cfg(feature = "postcard")]
ProtocolFormat::Postcard => Some(clap::builder::PossibleValue::new("postcard")),
}
}
fn from_str(input: &str, _ignore_case: bool) -> Result<Self, String> {
match input {
"json" => Ok(ProtocolFormat::Json),
#[cfg(feature = "postcard")]
"postcard" => Ok(ProtocolFormat::Postcard),
_ => Err(format!("unknown protocol format: {input}")),
}

View File

@ -1,5 +1,5 @@
//! The main loop of the proc-macro server.
use std::io;
use std::{io, thread};
use proc_macro_api::{
legacy_protocol::{
@ -14,6 +14,7 @@ use proc_macro_api::{
use proc_macro_srv::{EnvSnapshot, SpanId};
use crate::ProtocolFormat;
use std::io::BufReader;
struct SpanTrans;
@ -37,8 +38,7 @@ impl SpanTransformer for SpanTrans {
pub(crate) fn run(format: ProtocolFormat) -> io::Result<()> {
match format {
ProtocolFormat::Json => run_json(),
#[cfg(feature = "postcard")]
ProtocolFormat::Postcard => unimplemented!(),
ProtocolFormat::Postcard => run_postcard(),
}
}
@ -171,3 +171,143 @@ fn run_json() -> io::Result<()> {
Ok(())
}
fn run_postcard() -> 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 stdin = io::stdin();
let stdout = io::stdout();
let mut reader = BufReader::new(stdin.lock());
let mut writer = stdout.lock();
let mut buf = vec![0; 1024];
let env = proc_macro_srv::EnvSnapshot::default();
let srv = proc_macro_srv::ProcMacroSrv::new(&env);
let mut span_mode = msg::SpanMode::Id;
use proc_macro_api::legacy_protocol::postcard_wire;
while let Some(req) = postcard_wire::read_postcard(&mut reader, &mut buf)? {
let Ok(req) = postcard_wire::decode_cobs(req) else {
thread::sleep(std::time::Duration::from_secs(1));
continue;
};
dbg!(&req);
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:
msg::ExpandMacroData {
macro_body,
macro_name,
attributes,
has_global_spans:
msg::ExpnGlobals { serialize: _, def_site, call_site, mixed_site },
span_data_table,
},
} = *task;
match span_mode {
msg::SpanMode::Id => msg::Response::ExpandMacro({
let def_site = proc_macro_srv::SpanId(def_site as u32);
let call_site = proc_macro_srv::SpanId(call_site as u32);
let mixed_site = proc_macro_srv::SpanId(mixed_site as u32);
let macro_body =
macro_body.to_subtree_unresolved::<SpanTrans>(CURRENT_API_VERSION);
let attributes = attributes
.map(|it| it.to_subtree_unresolved::<SpanTrans>(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::<SpanTrans>(
tt::SubtreeView::new(&it),
CURRENT_API_VERSION,
)
})
.map_err(|e| e.into_string().unwrap_or_default())
.map_err(msg::PanicMessage)
}),
msg::SpanMode::RustAnalyzer => msg::Response::ExpandMacroExtended({
let mut span_data_table =
msg::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,
),
msg::serialize_span_data_index_map(&span_data_table),
)
})
.map(|(tree, span_data_table)| msg::ExpandMacroExtended {
tree,
span_data_table,
})
.map_err(|e| e.into_string().unwrap_or_default())
.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)
}
};
dbg!(&res);
let res = postcard_wire::encode_cobs(&res).unwrap();
postcard_wire::write_postcard(&mut writer, &res)?;
}
Ok(())
}