aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api
diff options
context:
space:
mode:
authorkjeremy <[email protected]>2019-10-29 16:16:55 +0000
committerkjeremy <[email protected]>2019-10-29 16:16:55 +0000
commiteb220a081b5e5867a1c063b42c02ec35535a19e5 (patch)
tree037c39ac54a4c0943960756f46e314a85c118c82 /crates/ra_ide_api
parentde16f94ada933cfd394ddab34c31410cf05268f1 (diff)
Primitive signature help for mbe
Diffstat (limited to 'crates/ra_ide_api')
-rw-r--r--crates/ra_ide_api/src/call_info.rs36
-rw-r--r--crates/ra_ide_api/src/display/function_signature.rs22
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)]
80enum FnCallNode { 85enum 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
85impl FnCallNode { 91impl 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
575macro_rules! foo {
576 () => {}
577}
578
579fn 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
128impl From<&'_ ast::FnDef> for FunctionSignature { 149impl 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