Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/proc-macro-srv-cli/src/main_loop.rs')
| -rw-r--r-- | crates/proc-macro-srv-cli/src/main_loop.rs | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/crates/proc-macro-srv-cli/src/main_loop.rs b/crates/proc-macro-srv-cli/src/main_loop.rs new file mode 100644 index 0000000000..ba1fcd8e33 --- /dev/null +++ b/crates/proc-macro-srv-cli/src/main_loop.rs @@ -0,0 +1,134 @@ +//! The main loop of the proc-macro server. +use std::io; + +use proc_macro_api::legacy_protocol::{ + json::{read_json, write_json}, + msg::{ + self, deserialize_span_data_index_map, serialize_span_data_index_map, ExpandMacroData, + ExpnGlobals, Message, SpanMode, TokenId, CURRENT_API_VERSION, + }, +}; +use proc_macro_srv::EnvSnapshot; + +pub(crate) fn run() -> io::Result<()> { + fn macro_kind_to_api(kind: proc_macro_srv::ProcMacroKind) -> proc_macro_api::ProcMacroKind { + match kind { + proc_macro_srv::ProcMacroKind::CustomDerive => { + proc_macro_api::ProcMacroKind::CustomDerive + } + proc_macro_srv::ProcMacroKind::Bang => proc_macro_api::ProcMacroKind::Bang, + proc_macro_srv::ProcMacroKind::Attr => proc_macro_api::ProcMacroKind::Attr, + } + } + + let read_request = + |buf: &mut String| msg::Request::read(read_json, &mut io::stdin().lock(), buf); + + let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock()); + + let env = EnvSnapshot::default(); + let mut srv = proc_macro_srv::ProcMacroSrv::new(&env); + let mut buf = String::new(); + + let mut span_mode = SpanMode::Id; + + while let Some(req) = read_request(&mut buf)? { + let res = match req { + msg::Request::ListMacros { dylib_path } => { + msg::Response::ListMacros(srv.list_macros(&dylib_path).map(|macros| { + macros.into_iter().map(|(name, kind)| (name, macro_kind_to_api(kind))).collect() + })) + } + msg::Request::ExpandMacro(task) => { + let msg::ExpandMacro { + lib, + env, + current_dir, + data: + ExpandMacroData { + macro_body, + macro_name, + attributes, + has_global_spans: + ExpnGlobals { serialize: _, def_site, call_site, mixed_site }, + span_data_table, + }, + } = *task; + match span_mode { + SpanMode::Id => msg::Response::ExpandMacro({ + let def_site = TokenId(def_site as u32); + let call_site = TokenId(call_site as u32); + let mixed_site = TokenId(mixed_site as u32); + + let macro_body = macro_body.to_subtree_unresolved(CURRENT_API_VERSION); + let attributes = + attributes.map(|it| it.to_subtree_unresolved(CURRENT_API_VERSION)); + + srv.expand( + lib, + env, + current_dir, + macro_name, + macro_body, + attributes, + def_site, + call_site, + mixed_site, + ) + .map(|it| { + msg::FlatTree::new_raw(tt::SubtreeView::new(&it), CURRENT_API_VERSION) + }) + .map_err(msg::PanicMessage) + }), + SpanMode::RustAnalyzer => msg::Response::ExpandMacroExtended({ + let mut span_data_table = deserialize_span_data_index_map(&span_data_table); + + let def_site = span_data_table[def_site]; + let call_site = span_data_table[call_site]; + let mixed_site = span_data_table[mixed_site]; + + let macro_body = + macro_body.to_subtree_resolved(CURRENT_API_VERSION, &span_data_table); + let attributes = attributes.map(|it| { + it.to_subtree_resolved(CURRENT_API_VERSION, &span_data_table) + }); + srv.expand( + lib, + env, + current_dir, + macro_name, + macro_body, + attributes, + def_site, + call_site, + mixed_site, + ) + .map(|it| { + ( + msg::FlatTree::new( + tt::SubtreeView::new(&it), + CURRENT_API_VERSION, + &mut span_data_table, + ), + serialize_span_data_index_map(&span_data_table), + ) + }) + .map(|(tree, span_data_table)| msg::ExpandMacroExtended { + tree, + span_data_table, + }) + .map_err(msg::PanicMessage) + }), + } + } + msg::Request::ApiVersionCheck {} => msg::Response::ApiVersionCheck(CURRENT_API_VERSION), + msg::Request::SetConfig(config) => { + span_mode = config.span_mode; + msg::Response::SetConfig(config) + } + }; + write_response(res)? + } + + Ok(()) +} |