From c27fdc75fad67381e43cd7ce7e92a59f5e8fe087 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 25 Jun 2021 10:32:13 +0300 Subject: [PATCH] internal: add cloning macro fixture Macro that deep clone the tokens but otherwise preserves source locations and hygiene info is an interesting case for IDE support. Lets have this, although we don't actively use it at the moment. --- crates/proc_macro_srv/src/tests/mod.rs | 14 +++++++++++++ crates/proc_macro_test/imp/src/lib.rs | 28 +++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/crates/proc_macro_srv/src/tests/mod.rs b/crates/proc_macro_srv/src/tests/mod.rs index 5ca2b8a7505..d9037ee57f5 100644 --- a/crates/proc_macro_srv/src/tests/mod.rs +++ b/crates/proc_macro_srv/src/tests/mod.rs @@ -42,6 +42,19 @@ fn test_fn_like_macro() { ); } +#[test] +fn test_fn_like_macro2() { + assert_expand( + "fn_like_clone_tokens", + r#"ident, []"#, + expect![[r#" + SUBTREE $ + IDENT ident 4294967295 + PUNCH , [alone] 4294967295 + SUBTREE [] 4294967295"#]], + ); +} + #[test] fn test_attr_macro() { // Corresponds to @@ -70,6 +83,7 @@ fn list_test_macros() { fn_like_noop [FuncLike] fn_like_panic [FuncLike] fn_like_error [FuncLike] + fn_like_clone_tokens [FuncLike] attr_noop [Attr] attr_panic [Attr] attr_error [Attr] diff --git a/crates/proc_macro_test/imp/src/lib.rs b/crates/proc_macro_test/imp/src/lib.rs index 4b26d247211..980187a902f 100644 --- a/crates/proc_macro_test/imp/src/lib.rs +++ b/crates/proc_macro_test/imp/src/lib.rs @@ -1,6 +1,6 @@ //! Exports a few trivial procedural macros for testing. -use proc_macro::TokenStream; +use proc_macro::{Group, Ident, Punct, TokenStream, TokenTree}; #[proc_macro] pub fn fn_like_noop(args: TokenStream) -> TokenStream { @@ -17,6 +17,11 @@ pub fn fn_like_error(args: TokenStream) -> TokenStream { format!("compile_error!(\"fn_like_error!({})\");", args).parse().unwrap() } +#[proc_macro] +pub fn fn_like_clone_tokens(args: TokenStream) -> TokenStream { + clone_stream(args) +} + #[proc_macro_attribute] pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream { item @@ -46,3 +51,24 @@ pub fn derive_panic(item: TokenStream) -> TokenStream { pub fn derive_error(item: TokenStream) -> TokenStream { format!("compile_error!(\"#[derive(DeriveError)] {}\");", item).parse().unwrap() } + +fn clone_stream(ts: TokenStream) -> TokenStream { + ts.into_iter().map(clone_tree).collect() +} + +fn clone_tree(t: TokenTree) -> TokenTree { + match t { + TokenTree::Group(orig) => { + let mut new = Group::new(orig.delimiter(), clone_stream(orig.stream())); + new.set_span(orig.span()); + TokenTree::Group(new) + } + TokenTree::Ident(orig) => TokenTree::Ident(Ident::new(&orig.to_string(), orig.span())), + TokenTree::Punct(orig) => { + let mut new = Punct::new(orig.as_char(), orig.spacing()); + new.set_span(orig.span()); + TokenTree::Punct(new) + } + TokenTree::Literal(_orig) => unimplemented!(), + } +}