aboutsummaryrefslogtreecommitdiff
path: root/crates/proc_macro_api/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/proc_macro_api/src')
-rw-r--r--crates/proc_macro_api/src/msg.rs35
-rw-r--r--crates/proc_macro_api/src/process.rs7
-rw-r--r--crates/proc_macro_api/src/rpc.rs30
3 files changed, 56 insertions, 16 deletions
diff --git a/crates/proc_macro_api/src/msg.rs b/crates/proc_macro_api/src/msg.rs
index 970f165ed..f525df152 100644
--- a/crates/proc_macro_api/src/msg.rs
+++ b/crates/proc_macro_api/src/msg.rs
@@ -55,8 +55,8 @@ pub enum ErrorCode {
55} 55}
56 56
57pub trait Message: Serialize + DeserializeOwned { 57pub trait Message: Serialize + DeserializeOwned {
58 fn read(inp: &mut impl BufRead) -> io::Result<Option<Self>> { 58 fn read(inp: &mut impl BufRead, buf: &mut String) -> io::Result<Option<Self>> {
59 Ok(match read_json(inp)? { 59 Ok(match read_json(inp, buf)? {
60 None => None, 60 None => None,
61 Some(text) => { 61 Some(text) => {
62 let mut deserializer = serde_json::Deserializer::from_str(&text); 62 let mut deserializer = serde_json::Deserializer::from_str(&text);
@@ -76,14 +76,29 @@ pub trait Message: Serialize + DeserializeOwned {
76impl Message for Request {} 76impl Message for Request {}
77impl Message for Response {} 77impl Message for Response {}
78 78
79fn read_json(inp: &mut impl BufRead) -> io::Result<Option<String>> { 79fn read_json<'a>(
80 let mut buf = String::new(); 80 inp: &mut impl BufRead,
81 inp.read_line(&mut buf)?; 81 mut buf: &'a mut String,
82 buf.pop(); // Remove trailing '\n' 82) -> io::Result<Option<&'a String>> {
83 Ok(match buf.len() { 83 loop {
84 0 => None, 84 buf.clear();
85 _ => Some(buf), 85
86 }) 86 inp.read_line(&mut buf)?;
87 buf.pop(); // Remove trailing '\n'
88
89 if buf.is_empty() {
90 return Ok(None);
91 }
92
93 // Some ill behaved macro try to use stdout for debugging
94 // We ignore it here
95 if !buf.starts_with("{") {
96 log::error!("proc-macro tried to print : {}", buf);
97 continue;
98 }
99
100 return Ok(Some(buf));
101 }
87} 102}
88 103
89fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> { 104fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> {
diff --git a/crates/proc_macro_api/src/process.rs b/crates/proc_macro_api/src/process.rs
index 30bb1b687..99d05aef3 100644
--- a/crates/proc_macro_api/src/process.rs
+++ b/crates/proc_macro_api/src/process.rs
@@ -90,8 +90,10 @@ impl ProcMacroProcessSrv {
90fn client_loop(task_rx: Receiver<Task>, mut process: Process) { 90fn client_loop(task_rx: Receiver<Task>, mut process: Process) {
91 let (mut stdin, mut stdout) = process.stdio().expect("couldn't access child stdio"); 91 let (mut stdin, mut stdout) = process.stdio().expect("couldn't access child stdio");
92 92
93 let mut buf = String::new();
94
93 for Task { req, result_tx } in task_rx { 95 for Task { req, result_tx } in task_rx {
94 match send_request(&mut stdin, &mut stdout, req) { 96 match send_request(&mut stdin, &mut stdout, req, &mut buf) {
95 Ok(res) => result_tx.send(res).unwrap(), 97 Ok(res) => result_tx.send(res).unwrap(),
96 Err(err) => { 98 Err(err) => {
97 log::error!( 99 log::error!(
@@ -152,7 +154,8 @@ fn send_request(
152 mut writer: &mut impl Write, 154 mut writer: &mut impl Write,
153 mut reader: &mut impl BufRead, 155 mut reader: &mut impl BufRead,
154 req: Request, 156 req: Request,
157 buf: &mut String,
155) -> io::Result<Option<Response>> { 158) -> io::Result<Option<Response>> {
156 req.write(&mut writer)?; 159 req.write(&mut writer)?;
157 Response::read(&mut reader) 160 Response::read(&mut reader, buf)
158} 161}
diff --git a/crates/proc_macro_api/src/rpc.rs b/crates/proc_macro_api/src/rpc.rs
index 9a68e2cc5..8f7270afe 100644
--- a/crates/proc_macro_api/src/rpc.rs
+++ b/crates/proc_macro_api/src/rpc.rs
@@ -77,7 +77,11 @@ struct TokenIdDef(u32);
77#[derive(Serialize, Deserialize)] 77#[derive(Serialize, Deserialize)]
78#[serde(remote = "Delimiter")] 78#[serde(remote = "Delimiter")]
79struct DelimiterDef { 79struct DelimiterDef {
80 #[serde(with = "TokenIdDef")] 80 #[serde(
81 with = "TokenIdDef",
82 default = "tt::TokenId::unspecified",
83 skip_serializing_if = "token_id_def::skip_if"
84 )]
81 id: TokenId, 85 id: TokenId,
82 #[serde(with = "DelimiterKindDef")] 86 #[serde(with = "DelimiterKindDef")]
83 kind: DelimiterKind, 87 kind: DelimiterKind,
@@ -116,7 +120,11 @@ enum LeafDef {
116#[serde(remote = "Literal")] 120#[serde(remote = "Literal")]
117struct LiteralDef { 121struct LiteralDef {
118 text: SmolStr, 122 text: SmolStr,
119 #[serde(with = "TokenIdDef")] 123 #[serde(
124 with = "TokenIdDef",
125 default = "tt::TokenId::unspecified",
126 skip_serializing_if = "token_id_def::skip_if"
127 )]
120 id: TokenId, 128 id: TokenId,
121} 129}
122 130
@@ -126,7 +134,11 @@ struct PunctDef {
126 char: char, 134 char: char,
127 #[serde(with = "SpacingDef")] 135 #[serde(with = "SpacingDef")]
128 spacing: Spacing, 136 spacing: Spacing,
129 #[serde(with = "TokenIdDef")] 137 #[serde(
138 with = "TokenIdDef",
139 default = "tt::TokenId::unspecified",
140 skip_serializing_if = "token_id_def::skip_if"
141 )]
130 id: TokenId, 142 id: TokenId,
131} 143}
132 144
@@ -141,10 +153,20 @@ enum SpacingDef {
141#[serde(remote = "Ident")] 153#[serde(remote = "Ident")]
142struct IdentDef { 154struct IdentDef {
143 text: SmolStr, 155 text: SmolStr,
144 #[serde(with = "TokenIdDef")] 156 #[serde(
157 with = "TokenIdDef",
158 default = "tt::TokenId::unspecified",
159 skip_serializing_if = "token_id_def::skip_if"
160 )]
145 id: TokenId, 161 id: TokenId,
146} 162}
147 163
164mod token_id_def {
165 pub(super) fn skip_if(value: &tt::TokenId) -> bool {
166 *value == tt::TokenId::unspecified()
167 }
168}
169
148mod opt_delimiter_def { 170mod opt_delimiter_def {
149 use super::{Delimiter, DelimiterDef}; 171 use super::{Delimiter, DelimiterDef};
150 use serde::{Deserialize, Deserializer, Serialize, Serializer}; 172 use serde::{Deserialize, Deserializer, Serialize, Serializer};