diff options
-rw-r--r-- | crates/ra_ide_api/src/call_info.rs | 36 | ||||
-rw-r--r-- | crates/ra_ide_api/src/display/function_signature.rs | 22 |
2 files changed, 58 insertions, 0 deletions
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index d947ac50c..729f4c2ff 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs | |||
@@ -36,6 +36,10 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
36 | let function = analyzer.resolve_method_call(&expr)?; | 36 | let function = analyzer.resolve_method_call(&expr)?; |
37 | (CallInfo::with_fn(db, function), function.data(db).has_self_param()) | 37 | (CallInfo::with_fn(db, function), function.data(db).has_self_param()) |
38 | } | 38 | } |
39 | FnCallNode::MacroCallExpr(expr) => { | ||
40 | let macro_def = analyzer.resolve_macro_call(db, &expr)?; | ||
41 | (CallInfo::with_macro(db, macro_def)?, false) | ||
42 | } | ||
39 | }; | 43 | }; |
40 | 44 | ||
41 | // If we have a calling expression let's find which argument we are on | 45 | // If we have a calling expression let's find which argument we are on |
@@ -77,9 +81,11 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
77 | Some(call_info) | 81 | Some(call_info) |
78 | } | 82 | } |
79 | 83 | ||
84 | #[derive(Debug)] | ||
80 | enum FnCallNode { | 85 | enum FnCallNode { |
81 | CallExpr(ast::CallExpr), | 86 | CallExpr(ast::CallExpr), |
82 | MethodCallExpr(ast::MethodCallExpr), | 87 | MethodCallExpr(ast::MethodCallExpr), |
88 | MacroCallExpr(ast::MacroCall), | ||
83 | } | 89 | } |
84 | 90 | ||
85 | impl FnCallNode { | 91 | impl FnCallNode { |
@@ -89,6 +95,8 @@ impl FnCallNode { | |||
89 | Some(FnCallNode::CallExpr(expr)) | 95 | Some(FnCallNode::CallExpr(expr)) |
90 | } else if let Some(expr) = ast::MethodCallExpr::cast(node.clone()) { | 96 | } else if let Some(expr) = ast::MethodCallExpr::cast(node.clone()) { |
91 | Some(FnCallNode::MethodCallExpr(expr)) | 97 | Some(FnCallNode::MethodCallExpr(expr)) |
98 | } else if let Some(expr) = ast::MacroCall::cast(node.clone()) { | ||
99 | Some(FnCallNode::MacroCallExpr(expr)) | ||
92 | } else { | 100 | } else { |
93 | None | 101 | None |
94 | } | 102 | } |
@@ -105,6 +113,8 @@ impl FnCallNode { | |||
105 | FnCallNode::MethodCallExpr(call_expr) => { | 113 | FnCallNode::MethodCallExpr(call_expr) => { |
106 | call_expr.syntax().children().filter_map(ast::NameRef::cast).nth(0) | 114 | call_expr.syntax().children().filter_map(ast::NameRef::cast).nth(0) |
107 | } | 115 | } |
116 | |||
117 | FnCallNode::MacroCallExpr(call_expr) => call_expr.path()?.segment()?.name_ref(), | ||
108 | } | 118 | } |
109 | } | 119 | } |
110 | 120 | ||
@@ -112,6 +122,7 @@ impl FnCallNode { | |||
112 | match self { | 122 | match self { |
113 | FnCallNode::CallExpr(expr) => expr.arg_list(), | 123 | FnCallNode::CallExpr(expr) => expr.arg_list(), |
114 | FnCallNode::MethodCallExpr(expr) => expr.arg_list(), | 124 | FnCallNode::MethodCallExpr(expr) => expr.arg_list(), |
125 | FnCallNode::MacroCallExpr(_) => None, | ||
115 | } | 126 | } |
116 | } | 127 | } |
117 | } | 128 | } |
@@ -135,6 +146,12 @@ impl CallInfo { | |||
135 | Some(CallInfo { signature, active_parameter: None }) | 146 | Some(CallInfo { signature, active_parameter: None }) |
136 | } | 147 | } |
137 | 148 | ||
149 | fn with_macro(db: &RootDatabase, macro_def: hir::MacroDef) -> Option<Self> { | ||
150 | let signature = FunctionSignature::from_macro(db, macro_def)?; | ||
151 | |||
152 | Some(CallInfo { signature, active_parameter: None }) | ||
153 | } | ||
154 | |||
138 | fn parameters(&self) -> &[String] { | 155 | fn parameters(&self) -> &[String] { |
139 | &self.signature.parameters | 156 | &self.signature.parameters |
140 | } | 157 | } |
@@ -549,4 +566,23 @@ fn main() { | |||
549 | "#, | 566 | "#, |
550 | ); | 567 | ); |
551 | } | 568 | } |
569 | |||
570 | #[test] | ||
571 | fn fn_signature_for_macro() { | ||
572 | let info = call_info( | ||
573 | r#" | ||
574 | /// empty macro | ||
575 | macro_rules! foo { | ||
576 | () => {} | ||
577 | } | ||
578 | |||
579 | fn f() { | ||
580 | foo!(<|>); | ||
581 | } | ||
582 | "#, | ||
583 | ); | ||
584 | |||
585 | assert_eq!(info.label(), "foo!()"); | ||
586 | assert_eq!(info.doc().map(|it| it.into()), Some("empty macro".to_string())); | ||
587 | } | ||
552 | } | 588 | } |
diff --git a/crates/ra_ide_api/src/display/function_signature.rs b/crates/ra_ide_api/src/display/function_signature.rs index e21f8378d..9075ca443 100644 --- a/crates/ra_ide_api/src/display/function_signature.rs +++ b/crates/ra_ide_api/src/display/function_signature.rs | |||
@@ -17,6 +17,7 @@ pub enum CallableKind { | |||
17 | Function, | 17 | Function, |
18 | StructConstructor, | 18 | StructConstructor, |
19 | VariantConstructor, | 19 | VariantConstructor, |
20 | Macro, | ||
20 | } | 21 | } |
21 | 22 | ||
22 | /// Contains information about a function signature | 23 | /// Contains information about a function signature |
@@ -123,6 +124,26 @@ impl FunctionSignature { | |||
123 | .with_doc_opt(variant.docs(db)), | 124 | .with_doc_opt(variant.docs(db)), |
124 | ) | 125 | ) |
125 | } | 126 | } |
127 | |||
128 | pub(crate) fn from_macro(db: &db::RootDatabase, macro_def: hir::MacroDef) -> Option<Self> { | ||
129 | let node: ast::MacroCall = macro_def.source(db).ast; | ||
130 | |||
131 | let params = vec![]; | ||
132 | |||
133 | Some( | ||
134 | FunctionSignature { | ||
135 | kind: CallableKind::Macro, | ||
136 | visibility: None, | ||
137 | name: node.name().map(|n| n.text().to_string()), | ||
138 | ret_type: None, | ||
139 | parameters: params, | ||
140 | generic_parameters: vec![], | ||
141 | where_predicates: vec![], | ||
142 | doc: None, | ||
143 | } | ||
144 | .with_doc_opt(macro_def.docs(db)), | ||
145 | ) | ||
146 | } | ||
126 | } | 147 | } |
127 | 148 | ||
128 | impl From<&'_ ast::FnDef> for FunctionSignature { | 149 | impl From<&'_ ast::FnDef> for FunctionSignature { |
@@ -167,6 +188,7 @@ impl Display for FunctionSignature { | |||
167 | CallableKind::Function => write!(f, "fn {}", name)?, | 188 | CallableKind::Function => write!(f, "fn {}", name)?, |
168 | CallableKind::StructConstructor => write!(f, "struct {}", name)?, | 189 | CallableKind::StructConstructor => write!(f, "struct {}", name)?, |
169 | CallableKind::VariantConstructor => write!(f, "{}", name)?, | 190 | CallableKind::VariantConstructor => write!(f, "{}", name)?, |
191 | CallableKind::Macro => write!(f, "{}!", name)?, | ||
170 | } | 192 | } |
171 | } | 193 | } |
172 | 194 | ||