From f609efff8762abe66a8418d926a157b5299e457c Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 20 Dec 2021 14:38:22 +0100 Subject: [PATCH] Simplify --- .../ide_completion/src/render/builder_ext.rs | 77 ++++++++++--------- crates/ide_completion/src/render/function.rs | 33 ++++---- 2 files changed, 58 insertions(+), 52 deletions(-) diff --git a/crates/ide_completion/src/render/builder_ext.rs b/crates/ide_completion/src/render/builder_ext.rs index 4d040544454..0c6cbf7cb2d 100644 --- a/crates/ide_completion/src/render/builder_ext.rs +++ b/crates/ide_completion/src/render/builder_ext.rs @@ -1,6 +1,5 @@ //! Extensions for `Builder` structure required for item rendering. -use either::Either; use itertools::Itertools; use syntax::ast::{self, HasName}; @@ -8,14 +7,14 @@ #[derive(Debug)] pub(super) enum Params { - Named(Vec<(Either, hir::Param)>), + Named(Option, Vec<(ast::Param, hir::Param)>), Anonymous(usize), } impl Params { pub(super) fn len(&self) -> usize { match self { - Params::Named(xs) => xs.len(), + Params::Named(selv, params) => params.len() + if selv.is_some() { 1 } else { 0 }, Params::Anonymous(len) => *len, } } @@ -77,48 +76,56 @@ pub(super) fn add_call_parens( } else { self.trigger_call_info(); let snippet = match (ctx.config.add_call_argument_snippets, params) { - (true, Params::Named(params)) => { + (true, Params::Named(self_param, params)) => { + let offset = if self_param.is_some() { 2 } else { 1 }; let function_params_snippet = params.iter().enumerate().format_with( ", ", |(index, (param_source, param)), f| { let name; let text; - let (ref_, name) = match param_source { - Either::Left(self_param) => ( - match self_param.kind() { - ast::SelfParamKind::Owned => "", - ast::SelfParamKind::Ref => "&", - ast::SelfParamKind::MutRef => "&mut ", - }, - "self", - ), - Either::Right(it) => { - let n = (|| { - let mut pat = it.pat()?; - loop { - match pat { - ast::Pat::IdentPat(pat) => break pat.name(), - ast::Pat::RefPat(it) => pat = it.pat()?, - _ => return None, - } - } - })(); - match n { - Some(n) => { - name = n; - text = name.text(); - let text = text.as_str().trim_start_matches('_'); - let ref_ = ref_of_param(ctx, text, param.ty()); - (ref_, text) - } - None => ("", "_"), + let n = (|| { + let mut pat = param_source.pat()?; + loop { + match pat { + ast::Pat::IdentPat(pat) => break pat.name(), + ast::Pat::RefPat(it) => pat = it.pat()?, + _ => return None, } } + })(); + let (ref_, name) = match n { + Some(n) => { + name = n; + text = name.text(); + let text = text.as_str().trim_start_matches('_'); + let ref_ = ref_of_param(ctx, text, param.ty()); + (ref_, text) + } + None => ("", "_"), }; - f(&format_args!("${{{}:{}{}}}", index + 1, ref_, name)) + + f(&format_args!("${{{}:{}{}}}", index + offset, ref_, name)) }, ); - format!("{}({})$0", name, function_params_snippet) + match self_param { + Some(self_param) => { + let prefix = match self_param.kind() { + ast::SelfParamKind::Owned => "", + ast::SelfParamKind::Ref => "&", + ast::SelfParamKind::MutRef => "&mut ", + }; + format!( + "{}(${{1:{}self}}{}{})$0", + name, + prefix, + if params.is_empty() { "" } else { ", " }, + function_params_snippet + ) + } + None => { + format!("{}({})$0", name, function_params_snippet) + } + } } _ => { cov_mark::hit!(suppress_arg_snippets); diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs index 86dfbf7fc8f..5a243cbdd32 100644 --- a/crates/ide_completion/src/render/function.rs +++ b/crates/ide_completion/src/render/function.rs @@ -1,6 +1,5 @@ //! Renderer for function calls. -use either::Either; use hir::{AsAssocItem, HasSource, HirDisplay}; use ide_db::SymbolKind; use itertools::Itertools; @@ -56,7 +55,7 @@ struct FunctionRender<'a> { /// /// It seems that just using `ast` is the best choice -- most of parses /// should be cached anyway. - ast_node: ast::Fn, + param_list: Option, is_method: bool, } @@ -69,9 +68,9 @@ fn new( is_method: bool, ) -> Option> { let name = local_name.unwrap_or_else(|| fn_.name(ctx.db())); - let ast_node = fn_.source(ctx.db())?.value; + let param_list = fn_.source(ctx.db())?.value.param_list(); - Some(FunctionRender { ctx, name, receiver, func: fn_, ast_node, is_method }) + Some(FunctionRender { ctx, name, receiver, func: fn_, param_list, is_method }) } fn render(self, import_to_add: Option) -> CompletionItem { @@ -152,25 +151,25 @@ fn params_display(&self) -> String { } fn params(&self) -> Params { - let ast_params = match self.ast_node.param_list() { + let ast_params = match &self.param_list { Some(it) => it, - None => return Params::Named(Vec::new()), + None => return Params::Named(None, Vec::new()), }; - let params = ast_params.params().map(Either::Right); + let params = ast_params.params(); - let params = if self.ctx.completion.has_dot_receiver() || self.receiver.is_some() { - params.zip(self.func.method_params(self.ctx.db()).unwrap_or_default()).collect() + let (params, self_param) = if self.ctx.completion.has_dot_receiver() + || self.receiver.is_some() + { + (params.zip(self.func.method_params(self.ctx.db()).unwrap_or_default()).collect(), None) } else { - ast_params - .self_param() - .map(Either::Left) - .into_iter() - .chain(params) - .zip(self.func.assoc_fn_params(self.ctx.db())) - .collect() + let mut assoc_params = self.func.assoc_fn_params(self.ctx.db()); + if self.func.self_param(self.ctx.db()).is_some() { + assoc_params.remove(0); + } + (params.zip(assoc_params).collect(), ast_params.self_param()) }; - Params::Named(params) + Params::Named(self_param, params) } fn kind(&self) -> CompletionItemKind { -- 2.44.0