Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/proc_macro_api/src/msg.rs')
-rw-r--r--crates/proc_macro_api/src/msg.rs116
1 files changed, 80 insertions, 36 deletions
diff --git a/crates/proc_macro_api/src/msg.rs b/crates/proc_macro_api/src/msg.rs
index 04248e0447..e9764a7dc6 100644
--- a/crates/proc_macro_api/src/msg.rs
+++ b/crates/proc_macro_api/src/msg.rs
@@ -1,57 +1,53 @@
//! Defines messages for cross-process message passing based on `ndjson` wire protocol
+pub(crate) mod flat;
use std::{
- convert::TryFrom,
io::{self, BufRead, Write},
+ path::PathBuf,
};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
-use crate::{
- rpc::{ListMacrosResult, ListMacrosTask},
- ExpansionResult, ExpansionTask,
-};
+use crate::ProcMacroKind;
+
+pub use crate::msg::flat::FlatTree;
#[derive(Debug, Serialize, Deserialize)]
pub enum Request {
- ListMacro(ListMacrosTask),
- ExpansionMacro(ExpansionTask),
+ ListMacros { dylib_path: PathBuf },
+ ExpandMacro(ExpandMacro),
}
#[derive(Debug, Serialize, Deserialize)]
pub enum Response {
- Error(ResponseError),
- ListMacro(ListMacrosResult),
- ExpansionMacro(ExpansionResult),
-}
-
-macro_rules! impl_try_from_response {
- ($ty:ty, $tag:ident) => {
- impl TryFrom<Response> for $ty {
- type Error = &'static str;
- fn try_from(value: Response) -> Result<Self, Self::Error> {
- match value {
- Response::$tag(res) => Ok(res),
- _ => Err(concat!("Failed to convert response to ", stringify!($tag))),
- }
- }
- }
- };
+ ListMacros(Result<Vec<(String, ProcMacroKind)>, String>),
+ ExpandMacro(Result<FlatTree, PanicMessage>),
}
-impl_try_from_response!(ListMacrosResult, ListMacro);
-impl_try_from_response!(ExpansionResult, ExpansionMacro);
-
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct ResponseError {
- pub code: ErrorCode,
- pub message: String,
-}
+#[derive(Debug, Serialize, Deserialize)]
+pub struct PanicMessage(pub String);
-#[derive(Debug, Serialize, Deserialize, Clone)]
-pub enum ErrorCode {
- ServerErrorEnd,
- ExpansionError,
+#[derive(Debug, Serialize, Deserialize)]
+pub struct ExpandMacro {
+ /// Argument of macro call.
+ ///
+ /// In custom derive this will be a struct or enum; in attribute-like macro - underlying
+ /// item; in function-like macro - the macro body.
+ pub macro_body: FlatTree,
+
+ /// Name of macro to expand.
+ ///
+ /// In custom derive this is the name of the derived trait (`Serialize`, `Getters`, etc.).
+ /// In attribute-like and function-like macros - single name of macro itself (`show_streams`).
+ pub macro_name: String,
+
+ /// Possible attributes for the attribute-like macros.
+ pub attributes: Option<FlatTree>,
+
+ pub lib: PathBuf,
+
+ /// Environment variables to set during macro expansion.
+ pub env: Vec<(String, String)>,
}
pub trait Message: Serialize + DeserializeOwned {
@@ -108,3 +104,51 @@ fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> {
out.flush()?;
Ok(())
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use tt::*;
+
+ fn fixture_token_tree() -> Subtree {
+ let mut subtree = Subtree::default();
+ subtree
+ .token_trees
+ .push(TokenTree::Leaf(Ident { text: "struct".into(), id: TokenId(0) }.into()));
+ subtree
+ .token_trees
+ .push(TokenTree::Leaf(Ident { text: "Foo".into(), id: TokenId(1) }.into()));
+ subtree.token_trees.push(TokenTree::Leaf(Leaf::Literal(Literal {
+ text: "Foo".into(),
+ id: TokenId::unspecified(),
+ })));
+ subtree.token_trees.push(TokenTree::Leaf(Leaf::Punct(Punct {
+ char: '@',
+ id: TokenId::unspecified(),
+ spacing: Spacing::Joint,
+ })));
+ subtree.token_trees.push(TokenTree::Subtree(Subtree {
+ delimiter: Some(Delimiter { id: TokenId(2), kind: DelimiterKind::Brace }),
+ token_trees: vec![],
+ }));
+ subtree
+ }
+
+ #[test]
+ fn test_proc_macro_rpc_works() {
+ let tt = fixture_token_tree();
+ let task = ExpandMacro {
+ macro_body: FlatTree::new(&tt),
+ macro_name: Default::default(),
+ attributes: None,
+ lib: std::env::current_dir().unwrap(),
+ env: Default::default(),
+ };
+
+ let json = serde_json::to_string(&task).unwrap();
+ // println!("{}", json);
+ let back: ExpandMacro = serde_json::from_str(&json).unwrap();
+
+ assert_eq!(tt, back.macro_body.to_subtree());
+ }
+}