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.
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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!(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user