From b7aa4898e0841ab8199643f89a0caa967b698ca8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 13 Aug 2020 16:26:29 +0200 Subject: Rename ra_hir_expand -> hir_expand --- crates/ra_hir_expand/src/quote.rs | 282 -------------------------------------- 1 file changed, 282 deletions(-) delete mode 100644 crates/ra_hir_expand/src/quote.rs (limited to 'crates/ra_hir_expand/src/quote.rs') diff --git a/crates/ra_hir_expand/src/quote.rs b/crates/ra_hir_expand/src/quote.rs deleted file mode 100644 index 219bc2097..000000000 --- a/crates/ra_hir_expand/src/quote.rs +++ /dev/null @@ -1,282 +0,0 @@ -//! A simplified version of quote-crate like quasi quote macro - -// A helper macro quote macro -// FIXME: -// 1. Not all puncts are handled -// 2. #()* pattern repetition not supported now -// * But we can do it manually, see `test_quote_derive_copy_hack` -#[doc(hidden)] -#[macro_export] -macro_rules! __quote { - () => { - Vec::::new() - }; - - ( @SUBTREE $delim:ident $($tt:tt)* ) => { - { - let children = $crate::__quote!($($tt)*); - tt::Subtree { - delimiter: Some(tt::Delimiter { - kind: tt::DelimiterKind::$delim, - id: tt::TokenId::unspecified(), - }), - token_trees: $crate::quote::IntoTt::to_tokens(children), - } - } - }; - - ( @PUNCT $first:literal ) => { - { - vec![ - tt::Leaf::Punct(tt::Punct { - char: $first, - spacing: tt::Spacing::Alone, - id: tt::TokenId::unspecified(), - }).into() - ] - } - }; - - ( @PUNCT $first:literal, $sec:literal ) => { - { - vec![ - tt::Leaf::Punct(tt::Punct { - char: $first, - spacing: tt::Spacing::Joint, - id: tt::TokenId::unspecified(), - }).into(), - tt::Leaf::Punct(tt::Punct { - char: $sec, - spacing: tt::Spacing::Alone, - id: tt::TokenId::unspecified(), - }).into() - ] - } - }; - - // hash variable - ( # $first:ident $($tail:tt)* ) => { - { - let token = $crate::quote::ToTokenTree::to_token($first); - let mut tokens = vec![token.into()]; - let mut tail_tokens = $crate::quote::IntoTt::to_tokens($crate::__quote!($($tail)*)); - tokens.append(&mut tail_tokens); - tokens - } - }; - - ( ## $first:ident $($tail:tt)* ) => { - { - let mut tokens = $first.into_iter().map($crate::quote::ToTokenTree::to_token).collect::>(); - let mut tail_tokens = $crate::quote::IntoTt::to_tokens($crate::__quote!($($tail)*)); - tokens.append(&mut tail_tokens); - tokens - } - }; - - // Brace - ( { $($tt:tt)* } ) => { $crate::__quote!(@SUBTREE Brace $($tt)*) }; - // Bracket - ( [ $($tt:tt)* ] ) => { $crate::__quote!(@SUBTREE Bracket $($tt)*) }; - // Parenthesis - ( ( $($tt:tt)* ) ) => { $crate::__quote!(@SUBTREE Parenthesis $($tt)*) }; - - // Literal - ( $tt:literal ) => { vec![$crate::quote::ToTokenTree::to_token($tt).into()] }; - // Ident - ( $tt:ident ) => { - vec![ { - tt::Leaf::Ident(tt::Ident { - text: stringify!($tt).into(), - id: tt::TokenId::unspecified(), - }).into() - }] - }; - - // Puncts - // FIXME: Not all puncts are handled - ( -> ) => {$crate::__quote!(@PUNCT '-', '>')}; - ( & ) => {$crate::__quote!(@PUNCT '&')}; - ( , ) => {$crate::__quote!(@PUNCT ',')}; - ( : ) => {$crate::__quote!(@PUNCT ':')}; - ( ; ) => {$crate::__quote!(@PUNCT ';')}; - ( :: ) => {$crate::__quote!(@PUNCT ':', ':')}; - ( . ) => {$crate::__quote!(@PUNCT '.')}; - ( < ) => {$crate::__quote!(@PUNCT '<')}; - ( > ) => {$crate::__quote!(@PUNCT '>')}; - - ( $first:tt $($tail:tt)+ ) => { - { - let mut tokens = $crate::quote::IntoTt::to_tokens($crate::__quote!($first)); - let mut tail_tokens = $crate::quote::IntoTt::to_tokens($crate::__quote!($($tail)*)); - - tokens.append(&mut tail_tokens); - tokens - } - }; -} - -/// FIXME: -/// It probably should implement in proc-macro -#[macro_export] -macro_rules! quote { - ( $($tt:tt)* ) => { - $crate::quote::IntoTt::to_subtree($crate::__quote!($($tt)*)) - } -} - -pub(crate) trait IntoTt { - fn to_subtree(self) -> tt::Subtree; - fn to_tokens(self) -> Vec; -} - -impl IntoTt for Vec { - fn to_subtree(self) -> tt::Subtree { - tt::Subtree { delimiter: None, token_trees: self } - } - - fn to_tokens(self) -> Vec { - self - } -} - -impl IntoTt for tt::Subtree { - fn to_subtree(self) -> tt::Subtree { - self - } - - fn to_tokens(self) -> Vec { - vec![tt::TokenTree::Subtree(self)] - } -} - -pub(crate) trait ToTokenTree { - fn to_token(self) -> tt::TokenTree; -} - -impl ToTokenTree for tt::TokenTree { - fn to_token(self) -> tt::TokenTree { - self - } -} - -impl ToTokenTree for tt::Subtree { - fn to_token(self) -> tt::TokenTree { - self.into() - } -} - -macro_rules! impl_to_to_tokentrees { - ($($ty:ty => $this:ident $im:block);*) => { - $( - impl ToTokenTree for $ty { - fn to_token($this) -> tt::TokenTree { - let leaf: tt::Leaf = $im.into(); - leaf.into() - } - } - - impl ToTokenTree for &$ty { - fn to_token($this) -> tt::TokenTree { - let leaf: tt::Leaf = $im.clone().into(); - leaf.into() - } - } - )* - } -} - -impl_to_to_tokentrees! { - u32 => self { tt::Literal{text: self.to_string().into(), id: tt::TokenId::unspecified()} }; - usize => self { tt::Literal{text: self.to_string().into(), id: tt::TokenId::unspecified()}}; - i32 => self { tt::Literal{text: self.to_string().into(), id: tt::TokenId::unspecified()}}; - tt::Leaf => self { self }; - tt::Literal => self { self }; - tt::Ident => self { self }; - tt::Punct => self { self }; - &str => self { tt::Literal{text: format!("{:?}", self.escape_default().to_string()).into(), id: tt::TokenId::unspecified()}}; - String => self { tt::Literal{text: format!("{:?}", self.escape_default().to_string()).into(), id: tt::TokenId::unspecified()}} -} - -#[cfg(test)] -mod tests { - #[test] - fn test_quote_delimiters() { - assert_eq!(quote!({}).to_string(), "{}"); - assert_eq!(quote!(()).to_string(), "()"); - assert_eq!(quote!([]).to_string(), "[]"); - } - - #[test] - fn test_quote_idents() { - assert_eq!(quote!(32).to_string(), "32"); - assert_eq!(quote!(struct).to_string(), "struct"); - } - - #[test] - fn test_quote_hash_simple_literal() { - let a = 20; - assert_eq!(quote!(#a).to_string(), "20"); - let s: String = "hello".into(); - assert_eq!(quote!(#s).to_string(), "\"hello\""); - } - - fn mk_ident(name: &str) -> tt::Ident { - tt::Ident { text: name.into(), id: tt::TokenId::unspecified() } - } - - #[test] - fn test_quote_hash_token_tree() { - let a = mk_ident("hello"); - - let quoted = quote!(#a); - assert_eq!(quoted.to_string(), "hello"); - let t = format!("{:?}", quoted); - assert_eq!(t, "SUBTREE $\n IDENT hello 4294967295"); - } - - #[test] - fn test_quote_simple_derive_copy() { - let name = mk_ident("Foo"); - - let quoted = quote! { - impl Clone for #name { - fn clone(&self) -> Self { - Self {} - } - } - }; - - assert_eq!(quoted.to_string(), "impl Clone for Foo {fn clone (& self) -> Self {Self {}}}"); - } - - #[test] - fn test_quote_derive_copy_hack() { - // Assume the given struct is: - // struct Foo { - // name: String, - // id: u32, - // } - let struct_name = mk_ident("Foo"); - let fields = [mk_ident("name"), mk_ident("id")]; - let fields = fields.iter().map(|it| quote!(#it: self.#it.clone(), ).token_trees).flatten(); - - let list = tt::Subtree { - delimiter: Some(tt::Delimiter { - kind: tt::DelimiterKind::Brace, - id: tt::TokenId::unspecified(), - }), - token_trees: fields.collect(), - }; - - let quoted = quote! { - impl Clone for #struct_name { - fn clone(&self) -> Self { - Self #list - } - } - }; - - assert_eq!(quoted.to_string(), "impl Clone for Foo {fn clone (& self) -> Self {Self {name : self . name . clone () , id : self . id . clone () ,}}}"); - } -} -- cgit v1.2.3