Skip to content

Commit 45362de

Browse files
committed
Abstract proc-macro-srv protocol format
1 parent b1518b2 commit 45362de

File tree

6 files changed

+60
-39
lines changed

6 files changed

+60
-39
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use std::io::{self, BufRead, Write};
2+
3+
pub fn read_json<'a>(
4+
inp: &mut impl BufRead,
5+
buf: &'a mut String,
6+
) -> io::Result<Option<&'a String>> {
7+
loop {
8+
buf.clear();
9+
10+
inp.read_line(buf)?;
11+
buf.pop(); // Remove trailing '\n'
12+
13+
if buf.is_empty() {
14+
return Ok(None);
15+
}
16+
17+
// Some ill behaved macro try to use stdout for debugging
18+
// We ignore it here
19+
if !buf.starts_with('{') {
20+
tracing::error!("proc-macro tried to print : {}", buf);
21+
continue;
22+
}
23+
24+
return Ok(Some(buf));
25+
}
26+
}
27+
28+
pub fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> {
29+
tracing::debug!("> {}", msg);
30+
out.write_all(msg.as_bytes())?;
31+
out.write_all(b"\n")?;
32+
out.flush()?;
33+
Ok(())
34+
}

src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//! is used to provide basic infrastructure for communication between two
66
//! processes: Client (RA itself), Server (the external program)
77
8+
pub mod json;
89
pub mod msg;
910
mod process;
1011

src/tools/rust-analyzer/crates/proc-macro-api/src/msg.rs

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,12 @@ impl ExpnGlobals {
122122
}
123123

124124
pub trait Message: Serialize + DeserializeOwned {
125-
fn read(inp: &mut impl BufRead, buf: &mut String) -> io::Result<Option<Self>> {
126-
Ok(match read_json(inp, buf)? {
125+
fn read<R: BufRead>(
126+
from_proto: ProtocolRead<R>,
127+
inp: &mut R,
128+
buf: &mut String,
129+
) -> io::Result<Option<Self>> {
130+
Ok(match from_proto(inp, buf)? {
127131
None => None,
128132
Some(text) => {
129133
let mut deserializer = serde_json::Deserializer::from_str(text);
@@ -134,44 +138,20 @@ pub trait Message: Serialize + DeserializeOwned {
134138
}
135139
})
136140
}
137-
fn write(self, out: &mut impl Write) -> io::Result<()> {
141+
fn write<W: Write>(self, to_proto: ProtocolWrite<W>, out: &mut W) -> io::Result<()> {
138142
let text = serde_json::to_string(&self)?;
139-
write_json(out, &text)
143+
to_proto(out, &text)
140144
}
141145
}
142146

143147
impl Message for Request {}
144148
impl Message for Response {}
145149

146-
fn read_json<'a>(inp: &mut impl BufRead, buf: &'a mut String) -> io::Result<Option<&'a String>> {
147-
loop {
148-
buf.clear();
149-
150-
inp.read_line(buf)?;
151-
buf.pop(); // Remove trailing '\n'
152-
153-
if buf.is_empty() {
154-
return Ok(None);
155-
}
156-
157-
// Some ill behaved macro try to use stdout for debugging
158-
// We ignore it here
159-
if !buf.starts_with('{') {
160-
tracing::error!("proc-macro tried to print : {}", buf);
161-
continue;
162-
}
163-
164-
return Ok(Some(buf));
165-
}
166-
}
167-
168-
fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> {
169-
tracing::debug!("> {}", msg);
170-
out.write_all(msg.as_bytes())?;
171-
out.write_all(b"\n")?;
172-
out.flush()?;
173-
Ok(())
174-
}
150+
#[allow(type_alias_bounds)]
151+
type ProtocolRead<R: BufRead> =
152+
for<'i, 'buf> fn(inp: &'i mut R, buf: &'buf mut String) -> io::Result<Option<&'buf String>>;
153+
#[allow(type_alias_bounds)]
154+
type ProtocolWrite<W: Write> = for<'o, 'msg> fn(out: &'o mut W, msg: &'msg str) -> io::Result<()>;
175155

176156
#[cfg(test)]
177157
mod tests {

src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use paths::AbsPath;
1010
use stdx::JodChild;
1111

1212
use crate::{
13+
json::{read_json, write_json},
1314
msg::{Message, Request, Response, SpanMode, CURRENT_API_VERSION, RUST_ANALYZER_SPAN_SUPPORT},
1415
ProcMacroKind, ServerError,
1516
};
@@ -201,11 +202,11 @@ fn send_request(
201202
req: Request,
202203
buf: &mut String,
203204
) -> Result<Response, ServerError> {
204-
req.write(&mut writer).map_err(|err| ServerError {
205+
req.write(write_json, &mut writer).map_err(|err| ServerError {
205206
message: "failed to write request".into(),
206207
io: Some(Arc::new(err)),
207208
})?;
208-
let res = Response::read(&mut reader, buf).map_err(|err| ServerError {
209+
let res = Response::read(read_json, &mut reader, buf).map_err(|err| ServerError {
209210
message: "failed to read response".into(),
210211
io: Some(Arc::new(err)),
211212
})?;

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#[cfg(feature = "in-rust-tree")]
77
extern crate rustc_driver as _;
88

9+
use proc_macro_api::json::{read_json, write_json};
10+
911
use std::io;
1012

1113
fn main() -> std::io::Result<()> {
@@ -30,9 +32,10 @@ fn run() -> io::Result<()> {
3032
eprintln!("{err}");
3133
use proc_macro_api::msg::{self, Message};
3234

33-
let read_request = |buf: &mut String| msg::Request::read(&mut io::stdin().lock(), buf);
35+
let read_request =
36+
|buf: &mut String| msg::Request::read(read_json, &mut io::stdin().lock(), buf);
3437

35-
let write_response = |msg: msg::Response| msg.write(&mut io::stdout().lock());
38+
let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock());
3639

3740
let mut buf = String::new();
3841

@@ -61,9 +64,10 @@ fn run() -> io::Result<()> {
6164
use proc_macro_api::msg::{self, Message};
6265
use proc_macro_srv::EnvSnapshot;
6366

64-
let read_request = |buf: &mut String| msg::Request::read(&mut io::stdin().lock(), buf);
67+
let read_request =
68+
|buf: &mut String| msg::Request::read(read_json, &mut io::stdin().lock(), buf);
6569

66-
let write_response = |msg: msg::Response| msg.write(&mut io::stdout().lock());
70+
let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock());
6771

6872
let env = EnvSnapshot::new();
6973
let mut srv = proc_macro_srv::ProcMacroSrv::new(&env);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ impl Drop for Expander {
142142
fn drop(&mut self) {
143143
#[cfg(windows)]
144144
std::fs::remove_file(&self.path).ok();
145+
_ = self.path;
145146
}
146147
}
147148

0 commit comments

Comments
 (0)