Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/proc_macro_api/src/rpc.rs')
| -rw-r--r-- | crates/proc_macro_api/src/rpc.rs | 234 |
1 files changed, 26 insertions, 208 deletions
diff --git a/crates/proc_macro_api/src/rpc.rs b/crates/proc_macro_api/src/rpc.rs index 9fc220cf3f..9fdbf04576 100644 --- a/crates/proc_macro_api/src/rpc.rs +++ b/crates/proc_macro_api/src/rpc.rs @@ -5,17 +5,17 @@ //! Although adding `Serialize` and `Deserialize` traits to `tt` directly seems //! to be much easier, we deliberately duplicate `tt` structs with `#[serde(with = "XXDef")]` //! for separation of code responsibility. +pub(crate) mod flat; + +use std::path::PathBuf; -use paths::AbsPathBuf; use serde::{Deserialize, Serialize}; -use tt::{ - Delimiter, DelimiterKind, Ident, Leaf, Literal, Punct, SmolStr, Spacing, Subtree, TokenId, - TokenTree, -}; + +use crate::rpc::flat::FlatTree; #[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] pub struct ListMacrosTask { - pub lib: AbsPathBuf, + pub lib: PathBuf, } #[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] @@ -30,14 +30,13 @@ pub struct ListMacrosResult { pub macros: Vec<(String, ProcMacroKind)>, } -#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct ExpansionTask { /// 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. - #[serde(with = "SubtreeDef")] - pub macro_body: Subtree, + pub macro_body: FlatTree, /// Name of macro to expand. /// @@ -46,208 +45,23 @@ pub struct ExpansionTask { pub macro_name: String, /// Possible attributes for the attribute-like macros. - #[serde(with = "opt_subtree_def")] - pub attributes: Option<Subtree>, + pub attributes: Option<FlatTree>, - pub lib: AbsPathBuf, + pub lib: PathBuf, /// Environment variables to set during macro expansion. pub env: Vec<(String, String)>, } -#[derive(Clone, Eq, PartialEq, Debug, Default, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct ExpansionResult { - #[serde(with = "SubtreeDef")] - pub expansion: Subtree, -} - -#[derive(Serialize, Deserialize)] -#[serde(remote = "DelimiterKind")] -enum DelimiterKindDef { - Parenthesis, - Brace, - Bracket, -} - -#[derive(Serialize, Deserialize)] -#[serde(remote = "TokenId")] -struct TokenIdDef(u32); - -#[derive(Serialize, Deserialize)] -#[serde(remote = "Delimiter")] -struct DelimiterDef { - #[serde( - with = "TokenIdDef", - default = "tt::TokenId::unspecified", - skip_serializing_if = "token_id_def::skip_if" - )] - id: TokenId, - #[serde(with = "DelimiterKindDef")] - kind: DelimiterKind, -} - -#[derive(Serialize, Deserialize)] -#[serde(remote = "Subtree")] -struct SubtreeDef { - #[serde(default, with = "opt_delimiter_def")] - delimiter: Option<Delimiter>, - #[serde(with = "vec_token_tree")] - token_trees: Vec<TokenTree>, -} - -#[derive(Serialize, Deserialize)] -#[serde(remote = "TokenTree")] -enum TokenTreeDef { - #[serde(with = "LeafDef")] - Leaf(Leaf), - #[serde(with = "SubtreeDef")] - Subtree(Subtree), -} - -#[derive(Serialize, Deserialize)] -#[serde(remote = "Leaf")] -enum LeafDef { - #[serde(with = "LiteralDef")] - Literal(Literal), - #[serde(with = "PunctDef")] - Punct(Punct), - #[serde(with = "IdentDef")] - Ident(Ident), -} - -#[derive(Serialize, Deserialize)] -#[serde(remote = "Literal")] -struct LiteralDef { - text: SmolStr, - #[serde( - with = "TokenIdDef", - default = "tt::TokenId::unspecified", - skip_serializing_if = "token_id_def::skip_if" - )] - id: TokenId, -} - -#[derive(Serialize, Deserialize)] -#[serde(remote = "Punct")] -struct PunctDef { - char: char, - #[serde(with = "SpacingDef")] - spacing: Spacing, - #[serde( - with = "TokenIdDef", - default = "tt::TokenId::unspecified", - skip_serializing_if = "token_id_def::skip_if" - )] - id: TokenId, -} - -#[derive(Serialize, Deserialize)] -#[serde(remote = "Spacing")] -enum SpacingDef { - Alone, - Joint, -} - -#[derive(Serialize, Deserialize)] -#[serde(remote = "Ident")] -struct IdentDef { - text: SmolStr, - #[serde( - with = "TokenIdDef", - default = "tt::TokenId::unspecified", - skip_serializing_if = "token_id_def::skip_if" - )] - id: TokenId, -} - -mod token_id_def { - pub(super) fn skip_if(value: &tt::TokenId) -> bool { - *value == tt::TokenId::unspecified() - } -} - -mod opt_delimiter_def { - use super::{Delimiter, DelimiterDef}; - use serde::{Deserialize, Deserializer, Serialize, Serializer}; - - pub(super) fn serialize<S>(value: &Option<Delimiter>, serializer: S) -> Result<S::Ok, S::Error> - where - S: Serializer, - { - #[derive(Serialize)] - struct Helper<'a>(#[serde(with = "DelimiterDef")] &'a Delimiter); - value.as_ref().map(Helper).serialize(serializer) - } - - pub(super) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Delimiter>, D::Error> - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - struct Helper(#[serde(with = "DelimiterDef")] Delimiter); - let helper = Option::deserialize(deserializer)?; - Ok(helper.map(|Helper(external)| external)) - } -} - -mod opt_subtree_def { - use super::{Subtree, SubtreeDef}; - use serde::{Deserialize, Deserializer, Serialize, Serializer}; - - pub(super) fn serialize<S>(value: &Option<Subtree>, serializer: S) -> Result<S::Ok, S::Error> - where - S: Serializer, - { - #[derive(Serialize)] - struct Helper<'a>(#[serde(with = "SubtreeDef")] &'a Subtree); - value.as_ref().map(Helper).serialize(serializer) - } - - pub(super) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Subtree>, D::Error> - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - struct Helper(#[serde(with = "SubtreeDef")] Subtree); - let helper = Option::deserialize(deserializer)?; - Ok(helper.map(|Helper(external)| external)) - } -} - -mod vec_token_tree { - use super::{TokenTree, TokenTreeDef}; - use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer}; - - pub(super) fn serialize<S>(value: &[TokenTree], serializer: S) -> Result<S::Ok, S::Error> - where - S: Serializer, - { - #[derive(Serialize)] - struct Helper<'a>(#[serde(with = "TokenTreeDef")] &'a TokenTree); - - let items: Vec<_> = value.iter().map(Helper).collect(); - let mut seq = serializer.serialize_seq(Some(items.len()))?; - for element in items { - seq.serialize_element(&element)?; - } - seq.end() - } - - pub(super) fn deserialize<'de, D>(deserializer: D) -> Result<Vec<TokenTree>, D::Error> - where - D: Deserializer<'de>, - { - #[derive(Deserialize)] - struct Helper(#[serde(with = "TokenTreeDef")] TokenTree); - - let helper = Vec::deserialize(deserializer)?; - Ok(helper.into_iter().map(|Helper(external)| external).collect()) - } + pub expansion: FlatTree, } #[cfg(test)] mod tests { use super::*; + use tt::*; fn fixture_token_tree() -> Subtree { let mut subtree = Subtree::default(); @@ -257,6 +71,15 @@ mod tests { 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![], @@ -268,22 +91,17 @@ mod tests { fn test_proc_macro_rpc_works() { let tt = fixture_token_tree(); let task = ExpansionTask { - macro_body: tt.clone(), + macro_body: FlatTree::new(&tt), macro_name: Default::default(), attributes: None, - lib: AbsPathBuf::assert(std::env::current_dir().unwrap()), + lib: std::env::current_dir().unwrap(), env: Default::default(), }; let json = serde_json::to_string(&task).unwrap(); + println!("{}", json); let back: ExpansionTask = serde_json::from_str(&json).unwrap(); - assert_eq!(task.macro_body, back.macro_body); - - let result = ExpansionResult { expansion: tt }; - let json = serde_json::to_string(&result).unwrap(); - let back: ExpansionResult = serde_json::from_str(&json).unwrap(); - - assert_eq!(result, back); + assert_eq!(tt, back.macro_body.to_subtree()); } } |