From 5a59bc9fcbbacb3d214e5bb9490f66ccb0abf5cb Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Sun, 27 Oct 2019 19:12:21 -0400 Subject: WIP: Expand signature help This is hacky but works for tuple structs. Proof of concept. --- crates/ra_ide_api/src/call_info.rs | 39 ++++++++++++++++++---- .../ra_ide_api/src/display/function_signature.rs | 29 +++++++++++++++- 2 files changed, 60 insertions(+), 8 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index c95133343..dfd6e69c5 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -20,24 +20,27 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option { //FIXME: apply subst let (callable_def, _subst) = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; match callable_def { - hir::CallableDef::Function(it) => it, + hir::CallableDef::Function(it) => { + (CallInfo::with_fn(db, it), it.data(db).has_self_param()) + } + hir::CallableDef::Struct(it) => (CallInfo::with_struct(db, it), false), //FIXME: handle other callables _ => return None, } } - FnCallNode::MethodCallExpr(expr) => analyzer.resolve_method_call(&expr)?, + FnCallNode::MethodCallExpr(expr) => { + let function = analyzer.resolve_method_call(&expr)?; + (CallInfo::with_fn(db, function), function.data(db).has_self_param()) + } }; - let mut call_info = CallInfo::new(db, function); - // If we have a calling expression let's find which argument we are on let num_params = call_info.parameters().len(); - let has_self = function.data(db).has_self_param(); if num_params == 1 { if !has_self { @@ -115,12 +118,18 @@ impl FnCallNode { } impl CallInfo { - fn new(db: &RootDatabase, function: hir::Function) -> Self { + fn with_fn(db: &RootDatabase, function: hir::Function) -> Self { let signature = FunctionSignature::from_hir(db, function); CallInfo { signature, active_parameter: None } } + fn with_struct(db: &RootDatabase, st: hir::Struct) -> Self { + let signature = FunctionSignature::from_struct(db, st); + + CallInfo { signature, active_parameter: None } + } + fn parameters(&self) -> &[String] { &self.signature.parameters } @@ -462,4 +471,20 @@ fn main() { assert_eq!(info.active_parameter, Some(1)); assert_eq!(info.label(), "fn bar(&self, _: u32)"); } + + fn works_for_tuple_structs() { + let info = call_info( + r#" +/// A cool tuple struct +struct TS(String, i32); +fn main() { + let s = TS("".into(), <|>); +}"#, + ); + + //assert_eq!(info.label(), "struct TS(String, i32)"); + assert_eq!(info.label(), "fn TS(0: {unknown}, 1: i32) -> TS"); + assert_eq!(info.doc().map(|it| it.into()), Some("A cool tuple struct".to_string())); + assert_eq!(info.active_parameter, Some(1)); + } } diff --git a/crates/ra_ide_api/src/display/function_signature.rs b/crates/ra_ide_api/src/display/function_signature.rs index 43f022ccd..0697a0727 100644 --- a/crates/ra_ide_api/src/display/function_signature.rs +++ b/crates/ra_ide_api/src/display/function_signature.rs @@ -2,7 +2,7 @@ use std::fmt::{self, Display}; -use hir::{Docs, Documentation, HasSource}; +use hir::{Docs, Documentation, HasSource, HirDisplay}; use join_to_string::join; use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner}; use std::convert::From; @@ -42,6 +42,33 @@ impl FunctionSignature { let ast_node = function.source(db).ast; FunctionSignature::from(&ast_node).with_doc_opt(doc) } + + pub(crate) fn from_struct(db: &db::RootDatabase, st: hir::Struct) -> Self { + let doc = st.docs(db); + + let node: ast::StructDef = st.source(db).ast; + + let params = st + .fields(db) + .into_iter() + .map(|field: hir::StructField| { + let name = field.name(db); + let ty = field.ty(db); + format!("{}: {}", name, ty.display(db)) + }) + .collect(); + + FunctionSignature { + visibility: node.visibility().map(|n| n.syntax().text().to_string()), + name: node.name().map(|n| n.text().to_string()), + ret_type: node.name().map(|n| n.text().to_string()), + parameters: /*param_list(node)*/ params, + generic_parameters: generic_parameters(&node), + where_predicates: where_predicates(&node), + doc: None, + } + .with_doc_opt(doc) + } } impl From<&'_ ast::FnDef> for FunctionSignature { -- cgit v1.2.3