11//! The main loop of the proc-macro server.
2- use std:: io ;
2+ use std:: { io , thread } ;
33
44use proc_macro_api:: {
55 legacy_protocol:: {
@@ -14,6 +14,7 @@ use proc_macro_api::{
1414use proc_macro_srv:: { EnvSnapshot , SpanId } ;
1515
1616use crate :: ProtocolFormat ;
17+ use std:: io:: BufReader ;
1718
1819struct SpanTrans ;
1920
@@ -37,8 +38,7 @@ impl SpanTransformer for SpanTrans {
3738pub ( 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