Primitive signature help for mbe

This commit is contained in:
kjeremy 2019-10-29 12:16:55 -04:00
parent de16f94ada
commit eb220a081b
2 changed files with 58 additions and 0 deletions

View file

@ -36,6 +36,10 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
let function = analyzer.resolve_method_call(&expr)?; let function = analyzer.resolve_method_call(&expr)?;
(CallInfo::with_fn(db, function), function.data(db).has_self_param()) (CallInfo::with_fn(db, function), function.data(db).has_self_param())
} }
FnCallNode::MacroCallExpr(expr) => {
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 // 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
Some(call_info) Some(call_info)
} }
#[derive(Debug)]
enum FnCallNode { enum FnCallNode {
CallExpr(ast::CallExpr), CallExpr(ast::CallExpr),
MethodCallExpr(ast::MethodCallExpr), MethodCallExpr(ast::MethodCallExpr),
MacroCallExpr(ast::MacroCall),
} }
impl FnCallNode { impl FnCallNode {
@ -89,6 +95,8 @@ impl FnCallNode {
Some(FnCallNode::CallExpr(expr)) Some(FnCallNode::CallExpr(expr))
} else if let Some(expr) = ast::MethodCallExpr::cast(node.clone()) { } else if let Some(expr) = ast::MethodCallExpr::cast(node.clone()) {
Some(FnCallNode::MethodCallExpr(expr)) Some(FnCallNode::MethodCallExpr(expr))
} else if let Some(expr) = ast::MacroCall::cast(node.clone()) {
Some(FnCallNode::MacroCallExpr(expr))
} else { } else {
None None
} }
@ -105,6 +113,8 @@ impl FnCallNode {
FnCallNode::MethodCallExpr(call_expr) => { FnCallNode::MethodCallExpr(call_expr) => {
call_expr.syntax().children().filter_map(ast::NameRef::cast).nth(0) 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 { match self {
FnCallNode::CallExpr(expr) => expr.arg_list(), FnCallNode::CallExpr(expr) => expr.arg_list(),
FnCallNode::MethodCallExpr(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 }) Some(CallInfo { signature, active_parameter: None })
} }
fn with_macro(db: &RootDatabase, macro_def: hir::MacroDef) -> Option<Self> {
let signature = FunctionSignature::from_macro(db, macro_def)?;
Some(CallInfo { signature, active_parameter: None })
}
fn parameters(&self) -> &[String] { fn parameters(&self) -> &[String] {
&self.signature.parameters &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()));
}
} }

View file

@ -17,6 +17,7 @@ pub enum CallableKind {
Function, Function,
StructConstructor, StructConstructor,
VariantConstructor, VariantConstructor,
Macro,
} }
/// Contains information about a function signature /// Contains information about a function signature
@ -123,6 +124,26 @@ impl FunctionSignature {
.with_doc_opt(variant.docs(db)), .with_doc_opt(variant.docs(db)),
) )
} }
pub(crate) fn from_macro(db: &db::RootDatabase, macro_def: hir::MacroDef) -> Option<Self> {
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 { impl From<&'_ ast::FnDef> for FunctionSignature {
@ -167,6 +188,7 @@ impl Display for FunctionSignature {
CallableKind::Function => write!(f, "fn {}", name)?, CallableKind::Function => write!(f, "fn {}", name)?,
CallableKind::StructConstructor => write!(f, "struct {}", name)?, CallableKind::StructConstructor => write!(f, "struct {}", name)?,
CallableKind::VariantConstructor => write!(f, "{}", name)?, CallableKind::VariantConstructor => write!(f, "{}", name)?,
CallableKind::Macro => write!(f, "{}!", name)?,
} }
} }