From eb220a081b5e5867a1c063b42c02ec35535a19e5 Mon Sep 17 00:00:00 2001 From: kjeremy Date: Tue, 29 Oct 2019 12:16:55 -0400 Subject: [PATCH] Primitive signature help for mbe --- crates/ra_ide_api/src/call_info.rs | 36 +++++++++++++++++++ .../src/display/function_signature.rs | 22 ++++++++++++ 2 files changed, 58 insertions(+) diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index d947ac50c2f..729f4c2fff4 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 { + let macro_def = analyzer.resolve_macro_call(db, &expr)?; + (CallInfo::with_macro(db, macro_def)?, false) + } }; // 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 { call_expr.syntax().children().filter_map(ast::NameRef::cast).nth(0) } + + FnCallNode::MacroCallExpr(call_expr) => call_expr.path()?.segment()?.name_ref(), } } @@ -112,6 +122,7 @@ impl FnCallNode { match self { FnCallNode::CallExpr(expr) => expr.arg_list(), FnCallNode::MethodCallExpr(expr) => expr.arg_list(), + FnCallNode::MacroCallExpr(_) => None, } } } @@ -135,6 +146,12 @@ impl CallInfo { Some(CallInfo { signature, active_parameter: None }) } + fn with_macro(db: &RootDatabase, macro_def: hir::MacroDef) -> Option { + let signature = FunctionSignature::from_macro(db, macro_def)?; + + Some(CallInfo { signature, active_parameter: None }) + } + fn parameters(&self) -> &[String] { &self.signature.parameters } @@ -549,4 +566,23 @@ fn main() { "#, ); } + + #[test] + fn fn_signature_for_macro() { + let info = call_info( + r#" +/// empty macro +macro_rules! foo { + () => {} +} + +fn f() { + foo!(<|>); +} + "#, + ); + + assert_eq!(info.label(), "foo!()"); + assert_eq!(info.doc().map(|it| it.into()), Some("empty macro".to_string())); + } } diff --git a/crates/ra_ide_api/src/display/function_signature.rs b/crates/ra_ide_api/src/display/function_signature.rs index e21f8378d86..9075ca443c3 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 { Function, StructConstructor, VariantConstructor, + Macro, } /// Contains information about a function signature @@ -123,6 +124,26 @@ impl FunctionSignature { .with_doc_opt(variant.docs(db)), ) } + + pub(crate) fn from_macro(db: &db::RootDatabase, macro_def: hir::MacroDef) -> Option { + let node: ast::MacroCall = macro_def.source(db).ast; + + let params = vec![]; + + Some( + FunctionSignature { + kind: CallableKind::Macro, + visibility: None, + name: node.name().map(|n| n.text().to_string()), + ret_type: None, + parameters: params, + generic_parameters: vec![], + where_predicates: vec![], + doc: None, + } + .with_doc_opt(macro_def.docs(db)), + ) + } } impl From<&'_ ast::FnDef> for FunctionSignature { @@ -167,6 +188,7 @@ impl Display for FunctionSignature { CallableKind::Function => write!(f, "fn {}", name)?, CallableKind::StructConstructor => write!(f, "struct {}", name)?, CallableKind::VariantConstructor => write!(f, "{}", name)?, + CallableKind::Macro => write!(f, "{}!", name)?, } }