diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 6cbcc3850e..0f6953158a 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -1553,7 +1553,7 @@ impl Callable { param_list.self_param() } pub fn n_params(&self) -> usize { - self.sig.params().len() + self.sig.params().len() - if self.is_bound_method { 1 } else { 0 } } pub fn params( &self, diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 6aab93e17f..c7b74e6355 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -11,10 +11,7 @@ use crate::{ completion_item::Builder, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, }, - display::{ - const_label, function_declaration, function_signature::FunctionSignature, macro_label, - type_label, - }, + display::{const_label, function_declaration, macro_label, type_label}, CompletionScore, RootDatabase, }; @@ -198,7 +195,6 @@ impl Completions { let name = local_name.unwrap_or_else(|| func.name(ctx.db).to_string()); let ast_node = func.source(ctx.db).value; - let function_signature = FunctionSignature::from(&ast_node); let mut builder = CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.clone()) @@ -211,11 +207,12 @@ impl Completions { .set_deprecated(is_deprecated(func, ctx.db)) .detail(function_declaration(&ast_node)); - let params = function_signature - .parameter_names - .iter() - .skip(if function_signature.has_self_param { 1 } else { 0 }) - .map(|name| name.trim_start_matches('_').into()) + let params = ast_node + .param_list() + .into_iter() + .flat_map(|it| it.params()) + .flat_map(|it| it.pat()) + .map(|pat| pat.to_string().trim_start_matches('_').into()) .collect(); builder = builder.add_call_parens(ctx, name, Params::Named(params)); diff --git a/crates/ra_ide/src/display.rs b/crates/ra_ide/src/display.rs index 34ce32e81c..6d4151dd85 100644 --- a/crates/ra_ide/src/display.rs +++ b/crates/ra_ide/src/display.rs @@ -1,7 +1,6 @@ //! This module contains utilities for turning SyntaxNodes and HIR types //! into types that may be used to render in a UI. -pub(crate) mod function_signature; mod navigation_target; mod short_label; @@ -77,23 +76,6 @@ pub(crate) fn type_label(node: &ast::TypeAliasDef) -> String { label.trim().to_owned() } -pub(crate) fn generic_parameters(node: &N) -> Vec { - let mut res = vec![]; - if let Some(type_params) = node.type_param_list() { - res.extend(type_params.lifetime_params().map(|p| p.syntax().text().to_string())); - res.extend(type_params.type_params().map(|p| p.syntax().text().to_string())); - } - res -} - -pub(crate) fn where_predicates(node: &N) -> Vec { - let mut res = vec![]; - if let Some(clause) = node.where_clause() { - res.extend(clause.predicates().map(|p| p.syntax().text().to_string())); - } - res -} - pub(crate) fn macro_label(node: &ast::MacroCall) -> String { let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default(); let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" }; diff --git a/crates/ra_ide/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs deleted file mode 100644 index f6e11357f8..0000000000 --- a/crates/ra_ide/src/display/function_signature.rs +++ /dev/null @@ -1,152 +0,0 @@ -//! FIXME: write short doc here - -// FIXME: this modules relies on strings and AST way too much, and it should be -// rewritten (matklad 2020-05-07) -use std::convert::From; - -use hir::Documentation; -use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner}; -use stdx::split_delim; - -use crate::display::{generic_parameters, where_predicates}; - -#[derive(Debug)] -pub(crate) enum CallableKind { - Function, -} - -/// Contains information about a function signature -#[derive(Debug)] -pub(crate) struct FunctionSignature { - pub(crate) kind: CallableKind, - /// Optional visibility - pub(crate) visibility: Option, - /// Qualifiers like `async`, `unsafe`, ... - pub(crate) qualifier: FunctionQualifier, - /// Name of the function - pub(crate) name: Option, - /// Documentation for the function - pub(crate) doc: Option, - /// Generic parameters - pub(crate) generic_parameters: Vec, - /// Parameters of the function - pub(crate) parameters: Vec, - /// Parameter names of the function - pub(crate) parameter_names: Vec, - /// Parameter types of the function - pub(crate) parameter_types: Vec, - /// Optional return type - pub(crate) ret_type: Option, - /// Where predicates - pub(crate) where_predicates: Vec, - /// Self param presence - pub(crate) has_self_param: bool, -} - -#[derive(Debug, Default)] -pub(crate) struct FunctionQualifier { - // `async` and `const` are mutually exclusive. Do we need to enforcing it here? - pub(crate) is_async: bool, - pub(crate) is_const: bool, - pub(crate) is_unsafe: bool, - /// The string `extern ".."` - pub(crate) extern_abi: Option, -} - -impl From<&'_ ast::FnDef> for FunctionSignature { - fn from(node: &ast::FnDef) -> FunctionSignature { - fn param_list(node: &ast::FnDef) -> (bool, Vec, Vec) { - let mut res = vec![]; - let mut res_types = vec![]; - let mut has_self_param = false; - if let Some(param_list) = node.param_list() { - if let Some(self_param) = param_list.self_param() { - has_self_param = true; - let raw_param = self_param.syntax().text().to_string(); - - res_types.push( - raw_param - .split(':') - .nth(1) - .and_then(|it| it.get(1..)) - .unwrap_or_else(|| "Self") - .to_string(), - ); - res.push(raw_param); - } - - // macro-generated functions are missing whitespace - fn fmt_param(param: ast::Param) -> String { - let text = param.syntax().text().to_string(); - match split_delim(&text, ':') { - Some((left, right)) => format!("{}: {}", left.trim(), right.trim()), - _ => text, - } - } - - res.extend(param_list.params().map(fmt_param)); - res_types.extend(param_list.params().map(|param| { - let param_text = param.syntax().text().to_string(); - match param_text.split(':').nth(1).and_then(|it| it.get(1..)) { - Some(it) => it.to_string(), - None => param_text, - } - })); - } - (has_self_param, res, res_types) - } - - fn param_name_list(node: &ast::FnDef) -> Vec { - let mut res = vec![]; - if let Some(param_list) = node.param_list() { - if let Some(self_param) = param_list.self_param() { - res.push(self_param.syntax().text().to_string()) - } - - res.extend( - param_list - .params() - .map(|param| { - Some( - param - .pat()? - .syntax() - .descendants() - .find_map(ast::Name::cast)? - .text() - .to_string(), - ) - }) - .map(|param| param.unwrap_or_default()), - ); - } - res - } - - let (has_self_param, parameters, parameter_types) = param_list(node); - - FunctionSignature { - kind: CallableKind::Function, - visibility: node.visibility().map(|n| n.syntax().text().to_string()), - qualifier: FunctionQualifier { - is_async: node.async_token().is_some(), - is_const: node.const_token().is_some(), - is_unsafe: node.unsafe_token().is_some(), - extern_abi: node.abi().map(|n| n.to_string()), - }, - name: node.name().map(|n| n.text().to_string()), - ret_type: node - .ret_type() - .and_then(|r| r.type_ref()) - .map(|n| n.syntax().text().to_string()), - parameters, - parameter_names: param_name_list(node), - parameter_types, - generic_parameters: generic_parameters(node), - where_predicates: where_predicates(node), - // docs are processed separately - doc: None, - has_self_param, - } - } -}