diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs index 900032b4cba..27be3746b71 100644 --- a/crates/base_db/src/fixture.rs +++ b/crates/base_db/src/fixture.rs @@ -262,6 +262,10 @@ pub fn identity(_attr: TokenStream, item: TokenStream) -> TokenStream { pub fn input_replace(attr: TokenStream, _item: TokenStream) -> TokenStream { attr } +#[proc_macro] +pub fn mirror(input: TokenStream) -> TokenStream { + input +} "#; let proc_macros = std::array::IntoIter::new([ ProcMacro { @@ -274,6 +278,11 @@ pub fn input_replace(attr: TokenStream, _item: TokenStream) -> TokenStream { kind: crate::ProcMacroKind::Attr, expander: Arc::new(AttributeInputReplaceProcMacroExpander), }, + ProcMacro { + name: "mirror".into(), + kind: crate::ProcMacroKind::FuncLike, + expander: Arc::new(MirrorProcMacroExpander), + }, ]) .filter(|pm| proc_macros.iter().any(|name| name == pm.name)) .collect(); @@ -348,3 +357,28 @@ fn expand( .ok_or_else(|| ProcMacroExpansionError::Panic("Expected attribute input".into())) } } + +#[derive(Debug)] +struct MirrorProcMacroExpander; +impl ProcMacroExpander for MirrorProcMacroExpander { + fn expand( + &self, + input: &Subtree, + _: Option<&Subtree>, + _: &Env, + ) -> Result { + fn traverse(input: &Subtree) -> Subtree { + let mut res = Subtree::default(); + res.delimiter = input.delimiter; + for tt in input.token_trees.iter().rev() { + let tt = match tt { + tt::TokenTree::Leaf(leaf) => tt::TokenTree::Leaf(leaf.clone()), + tt::TokenTree::Subtree(sub) => tt::TokenTree::Subtree(traverse(sub)), + }; + res.token_trees.push(tt); + } + res + } + Ok(traverse(input)) + } +} diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index ae5016b8d83..16760c24deb 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html @@ -64,10 +64,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd pub trait Fn<Args>: FnMut<Args> {} } - -struct Foo { - pub x: i32, - pub y: i32, +proc_macros::mirror! { + { + ,i32 :x pub + ,i32 :y pub + } Foo struct } trait Bar where Self: { diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index dbb8de24277..9fc730e0077 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -10,7 +10,7 @@ fn test_highlighting() { check_highlighting( r#" -//- proc_macros: identity +//- proc_macros: identity, mirror //- /main.rs crate:main deps:foo use inner::{self as inner_mod}; mod inner {} @@ -36,10 +36,11 @@ pub trait FnMut: FnOnce {} pub trait Fn: FnMut {} } - -struct Foo { - pub x: i32, - pub y: i32, +proc_macros::mirror! { + { + ,i32 :x pub + ,i32 :y pub + } Foo struct } trait Bar where Self: { diff --git a/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs b/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs index 07d4acb1522..aef03e3238e 100644 --- a/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs +++ b/crates/ide_assists/src/handlers/convert_iter_for_each_to_for.rs @@ -32,7 +32,6 @@ // } // } // ``` - pub(crate) fn convert_iter_for_each_to_for(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { let method = ctx.find_node_at_offset::()?;