Remove FunctionSignature

This commit is contained in:
Aleksey Kladov 2020-07-16 22:05:43 +02:00
parent a5ae8b8b92
commit 3823c2dc19
4 changed files with 8 additions and 181 deletions

View file

@ -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,

View file

@ -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));

View file

@ -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<N: TypeParamsOwner>(node: &N) -> Vec<String> {
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<N: TypeParamsOwner>(node: &N) -> Vec<String> {
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 { "" };

View file

@ -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<String>,
/// Qualifiers like `async`, `unsafe`, ...
pub(crate) qualifier: FunctionQualifier,
/// Name of the function
pub(crate) name: Option<String>,
/// Documentation for the function
pub(crate) doc: Option<Documentation>,
/// Generic parameters
pub(crate) generic_parameters: Vec<String>,
/// Parameters of the function
pub(crate) parameters: Vec<String>,
/// Parameter names of the function
pub(crate) parameter_names: Vec<String>,
/// Parameter types of the function
pub(crate) parameter_types: Vec<String>,
/// Optional return type
pub(crate) ret_type: Option<String>,
/// Where predicates
pub(crate) where_predicates: Vec<String>,
/// 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<String>,
}
impl From<&'_ ast::FnDef> for FunctionSignature {
fn from(node: &ast::FnDef) -> FunctionSignature {
fn param_list(node: &ast::FnDef) -> (bool, Vec<String>, Vec<String>) {
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<String> {
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,
}
}
}