Skip to content

Commit 83edf8f

Browse files
committed
make postcard first class member of proc-macro-srv-cli
1 parent 59dafb3 commit 83edf8f

File tree

3 files changed

+146
-10
lines changed

3 files changed

+146
-10
lines changed

src/tools/rust-analyzer/crates/proc-macro-srv-cli/Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,13 @@ publish = false
1414
proc-macro-srv.workspace = true
1515
proc-macro-api.workspace = true
1616
tt.workspace = true
17+
postcard.workspace = true
1718
clap = {version = "4.5.42", default-features = false, features = ["std"]}
18-
postcard = { version = "1.1.3", optional = true }
1919

2020
[features]
2121
default = ["postcard"]
2222
sysroot-abi = ["proc-macro-srv/sysroot-abi", "proc-macro-api/sysroot-abi"]
2323
in-rust-tree = ["proc-macro-srv/in-rust-tree", "sysroot-abi"]
24-
postcard = ["dep:postcard"]
2524

2625

2726
[[bin]]

src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fn main() -> std::io::Result<()> {
3131
clap::Arg::new("format")
3232
.long("format")
3333
.action(clap::ArgAction::Set)
34-
.default_value("json")
34+
.default_value("postcard")
3535
.value_parser(clap::builder::EnumValueParser::<ProtocolFormat>::new()),
3636
clap::Arg::new("version")
3737
.long("version")
@@ -51,26 +51,23 @@ fn main() -> std::io::Result<()> {
5151
#[derive(Copy, Clone)]
5252
enum ProtocolFormat {
5353
Json,
54-
#[cfg(feature = "postcard")]
5554
Postcard,
5655
}
5756

5857
impl ValueEnum for ProtocolFormat {
5958
fn value_variants<'a>() -> &'a [Self] {
60-
&[ProtocolFormat::Json]
59+
&[ProtocolFormat::Json, ProtocolFormat::Postcard]
6160
}
6261

6362
fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
6463
match self {
6564
ProtocolFormat::Json => Some(clap::builder::PossibleValue::new("json")),
66-
#[cfg(feature = "postcard")]
6765
ProtocolFormat::Postcard => Some(clap::builder::PossibleValue::new("postcard")),
6866
}
6967
}
7068
fn from_str(input: &str, _ignore_case: bool) -> Result<Self, String> {
7169
match input {
7270
"json" => Ok(ProtocolFormat::Json),
73-
#[cfg(feature = "postcard")]
7471
"postcard" => Ok(ProtocolFormat::Postcard),
7572
_ => Err(format!("unknown protocol format: {input}")),
7673
}

src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs

Lines changed: 143 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! The main loop of the proc-macro server.
2-
use std::io;
2+
use std::{io, thread};
33

44
use proc_macro_api::{
55
legacy_protocol::{
@@ -14,6 +14,7 @@ use proc_macro_api::{
1414
use proc_macro_srv::{EnvSnapshot, SpanId};
1515

1616
use crate::ProtocolFormat;
17+
use std::io::BufReader;
1718

1819
struct SpanTrans;
1920

@@ -37,8 +38,7 @@ impl SpanTransformer for SpanTrans {
3738
pub(crate) fn run(format: ProtocolFormat) -> io::Result<()> {
3839
match format {
3940
ProtocolFormat::Json => run_json(),
40-
#[cfg(feature = "postcard")]
41-
ProtocolFormat::Postcard => unimplemented!(),
41+
ProtocolFormat::Postcard => run_postcard(),
4242
}
4343
}
4444

@@ -171,3 +171,143 @@ fn run_json() -> io::Result<()> {
171171

172172
Ok(())
173173
}
174+
175+
fn run_postcard() -> io::Result<()> {
176+
fn macro_kind_to_api(kind: proc_macro_srv::ProcMacroKind) -> proc_macro_api::ProcMacroKind {
177+
match kind {
178+
proc_macro_srv::ProcMacroKind::CustomDerive => {
179+
proc_macro_api::ProcMacroKind::CustomDerive
180+
}
181+
proc_macro_srv::ProcMacroKind::Bang => proc_macro_api::ProcMacroKind::Bang,
182+
proc_macro_srv::ProcMacroKind::Attr => proc_macro_api::ProcMacroKind::Attr,
183+
}
184+
}
185+
186+
let stdin = io::stdin();
187+
let stdout = io::stdout();
188+
let mut reader = BufReader::new(stdin.lock());
189+
let mut writer = stdout.lock();
190+
let mut buf = vec![0; 1024];
191+
192+
let env = proc_macro_srv::EnvSnapshot::default();
193+
let srv = proc_macro_srv::ProcMacroSrv::new(&env);
194+
195+
let mut span_mode = msg::SpanMode::Id;
196+
use proc_macro_api::legacy_protocol::postcard_wire;
197+
198+
while let Some(req) = postcard_wire::read_postcard(&mut reader, &mut buf)? {
199+
let Ok(req) = postcard_wire::decode_cobs(req) else {
200+
thread::sleep(std::time::Duration::from_secs(1));
201+
continue;
202+
};
203+
dbg!(&req);
204+
205+
let res = match req {
206+
msg::Request::ListMacros { dylib_path } => {
207+
msg::Response::ListMacros(srv.list_macros(&dylib_path).map(|macros| {
208+
macros.into_iter().map(|(name, kind)| (name, macro_kind_to_api(kind))).collect()
209+
}))
210+
}
211+
msg::Request::ExpandMacro(task) => {
212+
let msg::ExpandMacro {
213+
lib,
214+
env,
215+
current_dir,
216+
data:
217+
msg::ExpandMacroData {
218+
macro_body,
219+
macro_name,
220+
attributes,
221+
has_global_spans:
222+
msg::ExpnGlobals { serialize: _, def_site, call_site, mixed_site },
223+
span_data_table,
224+
},
225+
} = *task;
226+
match span_mode {
227+
msg::SpanMode::Id => msg::Response::ExpandMacro({
228+
let def_site = proc_macro_srv::SpanId(def_site as u32);
229+
let call_site = proc_macro_srv::SpanId(call_site as u32);
230+
let mixed_site = proc_macro_srv::SpanId(mixed_site as u32);
231+
232+
let macro_body =
233+
macro_body.to_subtree_unresolved::<SpanTrans>(CURRENT_API_VERSION);
234+
let attributes = attributes
235+
.map(|it| it.to_subtree_unresolved::<SpanTrans>(CURRENT_API_VERSION));
236+
237+
srv.expand(
238+
lib,
239+
&env,
240+
current_dir,
241+
&macro_name,
242+
macro_body,
243+
attributes,
244+
def_site,
245+
call_site,
246+
mixed_site,
247+
)
248+
.map(|it| {
249+
msg::FlatTree::new_raw::<SpanTrans>(
250+
tt::SubtreeView::new(&it),
251+
CURRENT_API_VERSION,
252+
)
253+
})
254+
.map_err(|e| e.into_string().unwrap_or_default())
255+
.map_err(msg::PanicMessage)
256+
}),
257+
msg::SpanMode::RustAnalyzer => msg::Response::ExpandMacroExtended({
258+
let mut span_data_table =
259+
msg::deserialize_span_data_index_map(&span_data_table);
260+
261+
let def_site = span_data_table[def_site];
262+
let call_site = span_data_table[call_site];
263+
let mixed_site = span_data_table[mixed_site];
264+
265+
let macro_body =
266+
macro_body.to_subtree_resolved(CURRENT_API_VERSION, &span_data_table);
267+
let attributes = attributes.map(|it| {
268+
it.to_subtree_resolved(CURRENT_API_VERSION, &span_data_table)
269+
});
270+
srv.expand(
271+
lib,
272+
&env,
273+
current_dir,
274+
&macro_name,
275+
macro_body,
276+
attributes,
277+
def_site,
278+
call_site,
279+
mixed_site,
280+
)
281+
.map(|it| {
282+
(
283+
msg::FlatTree::new(
284+
tt::SubtreeView::new(&it),
285+
CURRENT_API_VERSION,
286+
&mut span_data_table,
287+
),
288+
msg::serialize_span_data_index_map(&span_data_table),
289+
)
290+
})
291+
.map(|(tree, span_data_table)| msg::ExpandMacroExtended {
292+
tree,
293+
span_data_table,
294+
})
295+
.map_err(|e| e.into_string().unwrap_or_default())
296+
.map_err(msg::PanicMessage)
297+
}),
298+
}
299+
}
300+
msg::Request::ApiVersionCheck {} => msg::Response::ApiVersionCheck(CURRENT_API_VERSION),
301+
msg::Request::SetConfig(config) => {
302+
span_mode = config.span_mode;
303+
msg::Response::SetConfig(config)
304+
}
305+
};
306+
307+
dbg!(&res);
308+
let res = postcard_wire::encode_cobs(&res).unwrap();
309+
postcard_wire::write_postcard(&mut writer, &res)?;
310+
}
311+
312+
Ok(())
313+
}

0 commit comments

Comments
 (0)