diff options
Diffstat (limited to 'crates/proc_macro_api/src')
-rw-r--r-- | crates/proc_macro_api/src/msg.rs | 35 | ||||
-rw-r--r-- | crates/proc_macro_api/src/process.rs | 7 | ||||
-rw-r--r-- | crates/proc_macro_api/src/rpc.rs | 30 |
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 | ||
57 | pub trait Message: Serialize + DeserializeOwned { | 57 | pub 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 { | |||
76 | impl Message for Request {} | 76 | impl Message for Request {} |
77 | impl Message for Response {} | 77 | impl Message for Response {} |
78 | 78 | ||
79 | fn read_json(inp: &mut impl BufRead) -> io::Result<Option<String>> { | 79 | fn 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 | ||
89 | fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> { | 104 | fn 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 { | |||
90 | fn client_loop(task_rx: Receiver<Task>, mut process: Process) { | 90 | fn 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")] |
79 | struct DelimiterDef { | 79 | struct 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")] |
117 | struct LiteralDef { | 121 | struct 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")] |
142 | struct IdentDef { | 154 | struct 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 | ||
164 | mod token_id_def { | ||
165 | pub(super) fn skip_if(value: &tt::TokenId) -> bool { | ||
166 | *value == tt::TokenId::unspecified() | ||
167 | } | ||
168 | } | ||
169 | |||
148 | mod opt_delimiter_def { | 170 | mod 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}; |