Skip to content

Commit 73384cf

Browse files
committed
Cleanup bidirection proc-macro-srv protocol a bit
1 parent 7f916ab commit 73384cf

13 files changed

Lines changed: 287 additions & 130 deletions

File tree

crates/load-cargo/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,8 @@ impl ProcMacroExpander for Expander {
724724

725725
Ok(SubResponse::SpanParentResult { parent_span: None })
726726
}
727+
// FIXME: implement this
728+
SubRequest::SpanJoin { .. } => Ok(SubResponse::SpanJoinResult { span: None }),
727729
};
728730
match self.0.expand(
729731
subtree.view(),

crates/proc-macro-api/src/bidirectional_protocol.rs

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use span::Span;
1212
use crate::{
1313
ProcMacro, ProcMacroKind, ServerError,
1414
bidirectional_protocol::msg::{
15-
BidirectionalMessage, ExpandMacro, ExpandMacroData, ExpnGlobals, Request, Response,
16-
SubRequest, SubResponse,
15+
ApiVersionCheck, BidirectionalMessage, ExpandMacro, ExpandMacroData, ExpnGlobals,
16+
ListMacros, Request, Response, SubRequest, SubResponse,
1717
},
1818
legacy_protocol::{
1919
SpanMode,
@@ -98,7 +98,7 @@ pub(crate) fn version_check(
9898
srv: &ProcMacroServerProcess,
9999
callback: SubCallback<'_>,
100100
) -> Result<u32, ServerError> {
101-
let request = BidirectionalMessage::Request(Request::ApiVersionCheck {});
101+
let request = BidirectionalMessage::Request(Request::ApiVersionCheck(ApiVersionCheck {}));
102102

103103
let response_payload = run_request(srv, request, callback)?;
104104

@@ -135,9 +135,9 @@ pub(crate) fn find_proc_macros(
135135
dylib_path: &AbsPath,
136136
callback: SubCallback<'_>,
137137
) -> Result<Result<Vec<(String, ProcMacroKind)>, String>, ServerError> {
138-
let request = BidirectionalMessage::Request(Request::ListMacros {
138+
let request = BidirectionalMessage::Request(Request::ListMacros(ListMacros {
139139
dylib_path: dylib_path.to_path_buf().into(),
140-
});
140+
}));
141141

142142
let response_payload = run_request(srv, request, callback)?;
143143

@@ -186,25 +186,12 @@ pub(crate) fn expand(
186186

187187
match response_payload {
188188
BidirectionalMessage::Response(Response::ExpandMacro(it)) => Ok(it
189-
.map(|tree| {
190-
let mut expanded = FlatTree::to_subtree_resolved(tree, version, &span_data_table);
191-
if proc_macro.needs_fixup_change() {
192-
proc_macro.change_fixup_to_match_old_server(&mut expanded);
193-
}
194-
expanded
195-
})
196-
.map_err(|msg| msg.0)),
197-
BidirectionalMessage::Response(Response::ExpandMacroExtended(it)) => Ok(it
198189
.map(|resp| {
199-
let mut expanded = FlatTree::to_subtree_resolved(
190+
FlatTree::to_subtree_resolved(
200191
resp.tree,
201192
version,
202193
&deserialize_span_data_index_map(&resp.span_data_table),
203-
);
204-
if proc_macro.needs_fixup_change() {
205-
proc_macro.change_fixup_to_match_old_server(&mut expanded);
206-
}
207-
expanded
194+
)
208195
})
209196
.map_err(|msg| msg.0)),
210197
_ => Err(ServerError { message: "unexpected response".to_owned(), io: None }),

crates/proc-macro-api/src/bidirectional_protocol/msg.rs

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! Bidirectional protocol messages
2+
#![expect(clippy::disallowed_types)]
23

34
use std::{
5+
collections::{HashMap, HashSet},
46
io::{self, BufRead, Write},
57
ops::Range,
68
};
@@ -16,13 +18,54 @@ use crate::{
1618

1719
#[derive(Debug, Serialize, Deserialize)]
1820
pub enum SubRequest {
19-
FilePath { file_id: u32 },
20-
SourceText { file_id: u32, ast_id: u32, start: u32, end: u32 },
21-
LocalFilePath { file_id: u32 },
22-
LineColumn { file_id: u32, ast_id: u32, offset: u32 },
23-
ByteRange { file_id: u32, ast_id: u32, start: u32, end: u32 },
24-
SpanSource { file_id: u32, ast_id: u32, start: u32, end: u32, ctx: u32 },
25-
SpanParent { file_id: u32, ast_id: u32, start: u32, end: u32, ctx: u32 },
21+
FilePath {
22+
file_id: u32,
23+
},
24+
SourceText {
25+
file_id: u32,
26+
ast_id: u32,
27+
start: u32,
28+
end: u32,
29+
},
30+
LocalFilePath {
31+
file_id: u32,
32+
},
33+
LineColumn {
34+
file_id: u32,
35+
ast_id: u32,
36+
offset: u32,
37+
},
38+
ByteRange {
39+
file_id: u32,
40+
ast_id: u32,
41+
start: u32,
42+
end: u32,
43+
},
44+
SpanSource {
45+
file_id: u32,
46+
ast_id: u32,
47+
start: u32,
48+
end: u32,
49+
ctx: u32,
50+
},
51+
SpanParent {
52+
file_id: u32,
53+
ast_id: u32,
54+
start: u32,
55+
end: u32,
56+
ctx: u32,
57+
},
58+
SpanJoin {
59+
file_id: u32,
60+
ast_id_first: u32,
61+
start_first: u32,
62+
end_first: u32,
63+
ctx_first: u32,
64+
ast_id_second: u32,
65+
start_second: u32,
66+
end_second: u32,
67+
ctx_second: u32,
68+
},
2669
}
2770

2871
#[derive(Debug, Serialize, Deserialize)]
@@ -54,6 +97,9 @@ pub enum SubResponse {
5497
SpanParentResult {
5598
parent_span: Option<ParentSpan>,
5699
},
100+
SpanJoinResult {
101+
span: Option<SpanJoin>,
102+
},
57103
Cancel {
58104
reason: String,
59105
},
@@ -68,6 +114,15 @@ pub struct ParentSpan {
68114
pub ctx: u32,
69115
}
70116

117+
#[derive(Debug, Serialize, Deserialize)]
118+
pub struct SpanJoin {
119+
pub ast_id: u32,
120+
pub start: u32,
121+
pub end: u32,
122+
pub ctx: u32,
123+
}
124+
125+
#[expect(clippy::large_enum_variant)]
71126
#[derive(Debug, Serialize, Deserialize)]
72127
pub enum BidirectionalMessage {
73128
Request(Request),
@@ -78,21 +133,29 @@ pub enum BidirectionalMessage {
78133

79134
#[derive(Debug, Serialize, Deserialize)]
80135
pub enum Request {
81-
ListMacros { dylib_path: Utf8PathBuf },
136+
ListMacros(ListMacros),
82137
ExpandMacro(Box<ExpandMacro>),
83-
ApiVersionCheck {},
138+
ApiVersionCheck(ApiVersionCheck),
84139
SetConfig(ServerConfig),
85140
}
86141

142+
#[expect(clippy::large_enum_variant)]
87143
#[derive(Debug, Serialize, Deserialize)]
88144
pub enum Response {
89145
ListMacros(Result<Vec<(String, ProcMacroKind)>, String>),
90-
ExpandMacro(Result<FlatTree, PanicMessage>),
91146
ApiVersionCheck(u32),
92147
SetConfig(ServerConfig),
93-
ExpandMacroExtended(Result<ExpandMacroExtended, PanicMessage>),
148+
ExpandMacro(Result<ExpandMacroResponse, PanicMessage>),
94149
}
95150

151+
#[derive(Debug, Serialize, Deserialize)]
152+
pub struct ListMacros {
153+
pub dylib_path: Utf8PathBuf,
154+
}
155+
156+
#[derive(Debug, Serialize, Deserialize)]
157+
pub struct ApiVersionCheck {}
158+
96159
#[derive(Debug, Serialize, Deserialize)]
97160
pub struct ExpandMacro {
98161
pub lib: Utf8PathBuf,
@@ -102,9 +165,11 @@ pub struct ExpandMacro {
102165
}
103166

104167
#[derive(Debug, Serialize, Deserialize)]
105-
pub struct ExpandMacroExtended {
168+
pub struct ExpandMacroResponse {
106169
pub tree: FlatTree,
107170
pub span_data_table: Vec<u32>,
171+
pub tracked_env_vars: HashMap<Box<str>, Option<Box<str>>>,
172+
pub tracked_paths: HashSet<Box<str>>,
108173
}
109174

110175
#[derive(Debug, Serialize, Deserialize)]

crates/proc-macro-api/src/process.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,9 @@ impl ProcMacroServerProcess {
240240
/// Enable support for rust-analyzer span mode if the server supports it.
241241
pub(crate) fn rust_analyzer_spans(&self) -> bool {
242242
match self.protocol {
243-
Protocol::LegacyJson { mode } => mode == SpanMode::RustAnalyzer,
244-
Protocol::BidirectionalPostcardPrototype { mode } => mode == SpanMode::RustAnalyzer,
243+
Protocol::LegacyJson { mode } | Protocol::BidirectionalPostcardPrototype { mode } => {
244+
mode == SpanMode::RustAnalyzer
245+
}
245246
}
246247
}
247248

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
//! Library interface for `proc-macro-srv-cli`.
2-
//!
3-
//! This module exposes the server main loop and protocol format for integration testing.
4-
5-
#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
6-
7-
#[cfg(feature = "in-rust-tree")]
8-
extern crate rustc_driver as _;
9-
10-
#[cfg(feature = "sysroot-abi")]
11-
pub mod main_loop;
1+
//! Library interface for `proc-macro-srv-cli`.
2+
//!
3+
//! This module exposes the server main loop and protocol format for integration testing.
4+
5+
#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
6+
7+
#[cfg(feature = "in-rust-tree")]
8+
extern crate rustc_driver as _;
9+
10+
#[cfg(feature = "sysroot-abi")]
11+
pub mod main_loop;

crates/proc-macro-srv-cli/src/main_loop.rs

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//! The main loop of the proc-macro server.
2+
use proc_macro_api::bidirectional_protocol::msg::{ApiVersionCheck, ListMacros};
23
use proc_macro_api::{
34
ProtocolFormat, bidirectional_protocol::msg as bidirectional, legacy_protocol::msg as legacy,
45
version::CURRENT_API_VERSION,
@@ -72,7 +73,7 @@ fn run_new(
7273

7374
match req {
7475
bidirectional::BidirectionalMessage::Request(request) => match request {
75-
bidirectional::Request::ListMacros { dylib_path } => {
76+
bidirectional::Request::ListMacros(ListMacros { dylib_path }) => {
7677
let res = srv.list_macros(&dylib_path).map(|macros| {
7778
macros
7879
.into_iter()
@@ -83,7 +84,7 @@ fn run_new(
8384
send_response(stdout, bidirectional::Response::ListMacros(res))?;
8485
}
8586

86-
bidirectional::Request::ApiVersionCheck {} => {
87+
bidirectional::Request::ApiVersionCheck(ApiVersionCheck {}) => {
8788
send_response(
8889
stdout,
8990
bidirectional::Response::ApiVersionCheck(CURRENT_API_VERSION),
@@ -142,6 +143,7 @@ fn handle_expand_id(
142143
let attributes = attributes
143144
.map(|it| it.to_tokenstream_unresolved::<SpanTrans>(CURRENT_API_VERSION, |_, b| b));
144145

146+
let mut tracked_env = Default::default();
145147
let res = srv
146148
.expand(
147149
lib,
@@ -153,11 +155,18 @@ fn handle_expand_id(
153155
def_site,
154156
call_site,
155157
mixed_site,
158+
&mut tracked_env,
156159
None,
157160
)
158161
.map(|it| {
159162
legacy::FlatTree::from_tokenstream_raw::<SpanTrans>(it, call_site, CURRENT_API_VERSION)
160163
})
164+
.map(|tree| bidirectional::ExpandMacroResponse {
165+
tree,
166+
span_data_table: vec![],
167+
tracked_env_vars: tracked_env.env_vars,
168+
tracked_paths: tracked_env.paths,
169+
})
161170
.map_err(|e| legacy::PanicMessage(e.into_string().unwrap_or_default()));
162171

163172
send_response(stdout, bidirectional::Response::ExpandMacro(res))
@@ -343,6 +352,46 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> {
343352
other => handle_failure(other),
344353
}
345354
}
355+
356+
fn span_join(
357+
&mut self,
358+
first: proc_macro_srv::span::Span,
359+
second: proc_macro_srv::span::Span,
360+
) -> Option<proc_macro_srv::span::Span> {
361+
assert_eq!(first.anchor.file_id, second.anchor.file_id);
362+
let response = self.roundtrip(bidirectional::SubRequest::SpanJoin {
363+
file_id: first.anchor.file_id.as_u32(),
364+
ast_id_first: first.anchor.ast_id.into_raw(),
365+
start_first: first.range.start().into(),
366+
end_first: first.range.end().into(),
367+
ctx_first: first.ctx.into_u32(),
368+
ast_id_second: second.anchor.ast_id.into_raw(),
369+
start_second: second.range.start().into(),
370+
end_second: second.range.end().into(),
371+
ctx_second: second.ctx.into_u32(),
372+
});
373+
374+
match response {
375+
Ok(bidirectional::SubResponse::SpanJoinResult { span }) => {
376+
span.map(|bidirectional::SpanJoin { ast_id, start, end, ctx }| {
377+
proc_macro_srv::span::Span {
378+
range: proc_macro_srv::span::TextRange::new(
379+
proc_macro_srv::span::TextSize::new(start),
380+
proc_macro_srv::span::TextSize::new(end),
381+
),
382+
anchor: proc_macro_srv::span::SpanAnchor {
383+
file_id: first.anchor.file_id,
384+
ast_id: proc_macro_srv::span::ErasedFileAstId::from_raw(ast_id),
385+
},
386+
// SAFETY: spans originate from the server. If the protocol is violated,
387+
// undefined behavior is the caller’s responsibility.
388+
ctx: unsafe { proc_macro_srv::span::SyntaxContext::from_u32(ctx) },
389+
}
390+
})
391+
}
392+
other => handle_failure(other),
393+
}
394+
}
346395
}
347396

348397
fn handle_expand_ra(
@@ -383,6 +432,8 @@ fn handle_expand_ra(
383432
})
384433
});
385434

435+
let mut tracked_env = Default::default();
436+
386437
let res = srv
387438
.expand(
388439
lib,
@@ -394,6 +445,7 @@ fn handle_expand_ra(
394445
def_site,
395446
call_site,
396447
mixed_site,
448+
&mut tracked_env,
397449
Some(&mut ProcMacroClientHandle { stdin, stdout, buf }),
398450
)
399451
.map(|it| {
@@ -407,10 +459,15 @@ fn handle_expand_ra(
407459
legacy::serialize_span_data_index_map(&span_data_table),
408460
)
409461
})
410-
.map(|(tree, span_data_table)| bidirectional::ExpandMacroExtended { tree, span_data_table })
462+
.map(|(tree, span_data_table)| bidirectional::ExpandMacroResponse {
463+
tree,
464+
span_data_table,
465+
tracked_env_vars: tracked_env.env_vars,
466+
tracked_paths: tracked_env.paths,
467+
})
411468
.map_err(|e| legacy::PanicMessage(e.into_string().unwrap_or_default()));
412469

413-
send_response(stdout, bidirectional::Response::ExpandMacroExtended(res))
470+
send_response(stdout, bidirectional::Response::ExpandMacro(res))
414471
}
415472

416473
fn run_old(
@@ -480,6 +537,7 @@ fn run_old(
480537
def_site,
481538
call_site,
482539
mixed_site,
540+
&mut Default::default(),
483541
None,
484542
)
485543
.map(|it| {
@@ -522,6 +580,7 @@ fn run_old(
522580
def_site,
523581
call_site,
524582
mixed_site,
583+
&mut Default::default(),
525584
None,
526585
)
527586
.map(|it| {

0 commit comments

Comments
 (0)