about summary refs log tree commit diff
path: root/crates/ide/src
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2021-08-24 16:33:52 +0200
committerLukas Wirth <lukastw97@gmail.com>2021-08-24 16:33:52 +0200
commitd99b81f839ec2b7e4a0eb37c96b40e6c5b050b72 (patch)
treedf61391bfd3aa535b401f2fb0efcd123ad86e8ed /crates/ide/src
parent6287d388c0d9a1d89f333cad23b8fbb87607d0f6 (diff)
downloadrust-d99b81f839ec2b7e4a0eb37c96b40e6c5b050b72.tar.gz
rust-d99b81f839ec2b7e4a0eb37c96b40e6c5b050b72.zip
Expand derive macros under cursor in `Expand Macro Recursively`
Diffstat (limited to 'crates/ide/src')
-rw-r--r--crates/ide/src/expand_macro.rs31
1 files changed, 31 insertions, 0 deletions
diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs
index 814d28e7b6c..363b77967c3 100644
--- a/crates/ide/src/expand_macro.rs
+++ b/crates/ide/src/expand_macro.rs
@@ -2,6 +2,7 @@ use std::iter;
 
 use hir::Semantics;
 use ide_db::{helpers::pick_best_token, RootDatabase};
+use itertools::Itertools;
 use syntax::{ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxKind::*, SyntaxNode, WalkEvent, T};
 
 use crate::FilePosition;
@@ -33,6 +34,18 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<
     let mut expanded = None;
     let mut name = None;
     for node in tok.ancestors() {
+        if let Some(attr) = ast::Attr::cast(node.clone()) {
+            if let Some((path, tt)) = attr.as_simple_call() {
+                if path == "derive" {
+                    let mut tt = tt.syntax().children_with_tokens().skip(1).join("");
+                    tt.pop();
+                    name = Some(tt);
+                    expanded = sema.expand_derive_macro(&attr);
+                    break;
+                }
+            }
+        }
+
         if let Some(item) = ast::Item::cast(node.clone()) {
             if let Some(def) = sema.resolve_attr_macro_call(&item) {
                 name = def.name(db).map(|name| name.to_string());
@@ -325,4 +338,22 @@ fn main() {
                 0 "#]],
         );
     }
+
+    #[test]
+    fn macro_expand_derive() {
+        check(
+            r#"
+
+#[rustc_builtin_macro]
+pub macro Clone {}
+
+#[derive(C$0lone)]
+struct Foo {}
+"#,
+            expect![[r#"
+                Clone
+                impl< >crate::clone::Clone for Foo< >{}
+            "#]],
+        );
+    }
 }