diff options
| author | kjeremy <[email protected]> | 2019-10-29 16:16:55 +0000 |
|---|---|---|
| committer | kjeremy <[email protected]> | 2019-10-29 16:16:55 +0000 |
| commit | eb220a081b5e5867a1c063b42c02ec35535a19e5 (patch) | |
| tree | 037c39ac54a4c0943960756f46e314a85c118c82 /crates | |
| parent | de16f94ada933cfd394ddab34c31410cf05268f1 (diff) | |
Primitive signature help for mbe
Diffstat (limited to 'crates')
| -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 | ||
