aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-12-01 10:53:12 +0000
committerAleksey Kladov <[email protected]>2020-12-01 10:53:39 +0000
commit6f51f728a114078a0c3a029fc66cfb8c4daf9a28 (patch)
tree21a6ec1454180e7cec86a3a2efae000d70a07096 /crates
parent455a0cfda2121596deb13ca3f40a83c98b32863c (diff)
Type-safer API for dealing with parameter lists with optional self
Diffstat (limited to 'crates')
-rw-r--r--crates/completion/src/completions/trait_impl.rs2
-rw-r--r--crates/completion/src/render/function.rs16
-rw-r--r--crates/hir/src/code_model.rs11
-rw-r--r--crates/ide/src/references/rename.rs2
4 files changed, 21 insertions, 10 deletions
diff --git a/crates/completion/src/completions/trait_impl.rs b/crates/completion/src/completions/trait_impl.rs
index a14be9c73..e2fe44aff 100644
--- a/crates/completion/src/completions/trait_impl.rs
+++ b/crates/completion/src/completions/trait_impl.rs
@@ -139,7 +139,7 @@ fn add_function_impl(
139) { 139) {
140 let fn_name = func.name(ctx.db).to_string(); 140 let fn_name = func.name(ctx.db).to_string();
141 141
142 let label = if func.params(ctx.db).is_empty() { 142 let label = if func.assoc_fn_params(ctx.db).is_empty() {
143 format!("fn {}()", fn_name) 143 format!("fn {}()", fn_name)
144 } else { 144 } else {
145 format!("fn {}(..)", fn_name) 145 format!("fn {}(..)", fn_name)
diff --git a/crates/completion/src/render/function.rs b/crates/completion/src/render/function.rs
index 542383d7e..09d9f85bc 100644
--- a/crates/completion/src/render/function.rs
+++ b/crates/completion/src/render/function.rs
@@ -22,7 +22,7 @@ pub(crate) fn render_fn<'a>(
22struct FunctionRender<'a> { 22struct FunctionRender<'a> {
23 ctx: RenderContext<'a>, 23 ctx: RenderContext<'a>,
24 name: String, 24 name: String,
25 fn_: hir::Function, 25 func: hir::Function,
26 ast_node: Fn, 26 ast_node: Fn,
27} 27}
28 28
@@ -35,15 +35,15 @@ impl<'a> FunctionRender<'a> {
35 let name = local_name.unwrap_or_else(|| fn_.name(ctx.db()).to_string()); 35 let name = local_name.unwrap_or_else(|| fn_.name(ctx.db()).to_string());
36 let ast_node = fn_.source(ctx.db()).value; 36 let ast_node = fn_.source(ctx.db()).value;
37 37
38 FunctionRender { ctx, name, fn_, ast_node } 38 FunctionRender { ctx, name, func: fn_, ast_node }
39 } 39 }
40 40
41 fn render(self, import_to_add: Option<ImportToAdd>) -> CompletionItem { 41 fn render(self, import_to_add: Option<ImportToAdd>) -> CompletionItem {
42 let params = self.params(); 42 let params = self.params();
43 CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), self.name.clone()) 43 CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), self.name.clone())
44 .kind(self.kind()) 44 .kind(self.kind())
45 .set_documentation(self.ctx.docs(self.fn_)) 45 .set_documentation(self.ctx.docs(self.func))
46 .set_deprecated(self.ctx.is_deprecated(self.fn_)) 46 .set_deprecated(self.ctx.is_deprecated(self.func))
47 .detail(self.detail()) 47 .detail(self.detail())
48 .add_call_parens(self.ctx.completion, self.name, params) 48 .add_call_parens(self.ctx.completion, self.name, params)
49 .add_import(import_to_add) 49 .add_import(import_to_add)
@@ -67,7 +67,11 @@ impl<'a> FunctionRender<'a> {
67 } 67 }
68 68
69 fn params(&self) -> Params { 69 fn params(&self) -> Params {
70 let params_ty = self.fn_.params(self.ctx.db()); 70 let params_ty = if self.ctx.completion.dot_receiver.is_some() {
71 self.func.method_params(self.ctx.db()).unwrap_or_default()
72 } else {
73 self.func.assoc_fn_params(self.ctx.db())
74 };
71 let params = self 75 let params = self
72 .ast_node 76 .ast_node
73 .param_list() 77 .param_list()
@@ -87,7 +91,7 @@ impl<'a> FunctionRender<'a> {
87 } 91 }
88 92
89 fn kind(&self) -> CompletionItemKind { 93 fn kind(&self) -> CompletionItemKind {
90 if self.fn_.self_param(self.ctx.db()).is_some() { 94 if self.func.self_param(self.ctx.db()).is_some() {
91 CompletionItemKind::Method 95 CompletionItemKind::Method
92 } else { 96 } else {
93 CompletionItemKind::Function 97 CompletionItemKind::Function
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index f06b5cd9f..ba121104b 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -744,14 +744,13 @@ impl Function {
744 Some(SelfParam { func: self.id }) 744 Some(SelfParam { func: self.id })
745 } 745 }
746 746
747 pub fn params(self, db: &dyn HirDatabase) -> Vec<Param> { 747 pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param> {
748 let resolver = self.id.resolver(db.upcast()); 748 let resolver = self.id.resolver(db.upcast());
749 let ctx = hir_ty::TyLoweringContext::new(db, &resolver); 749 let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
750 let environment = TraitEnvironment::lower(db, &resolver); 750 let environment = TraitEnvironment::lower(db, &resolver);
751 db.function_data(self.id) 751 db.function_data(self.id)
752 .params 752 .params
753 .iter() 753 .iter()
754 .skip(if self.self_param(db).is_some() { 1 } else { 0 })
755 .map(|type_ref| { 754 .map(|type_ref| {
756 let ty = Type { 755 let ty = Type {
757 krate: self.id.lookup(db.upcast()).container.module(db.upcast()).krate, 756 krate: self.id.lookup(db.upcast()).container.module(db.upcast()).krate,
@@ -764,6 +763,14 @@ impl Function {
764 }) 763 })
765 .collect() 764 .collect()
766 } 765 }
766 pub fn method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param>> {
767 if self.self_param(db).is_none() {
768 return None;
769 }
770 let mut res = self.assoc_fn_params(db);
771 res.remove(0);
772 Some(res)
773 }
767 774
768 pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { 775 pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool {
769 db.function_data(self.id).is_unsafe 776 db.function_data(self.id).is_unsafe
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs
index 731457696..64fe8bd65 100644
--- a/crates/ide/src/references/rename.rs
+++ b/crates/ide/src/references/rename.rs
@@ -241,7 +241,7 @@ fn rename_to_self(
241 return Err(RenameError("Method already has a self parameter".to_string())); 241 return Err(RenameError("Method already has a self parameter".to_string()));
242 } 242 }
243 243
244 let params = fn_def.params(sema.db); 244 let params = fn_def.assoc_fn_params(sema.db);
245 let first_param = 245 let first_param =
246 params.first().ok_or_else(|| RenameError("Method has no parameters".into()))?; 246 params.first().ok_or_else(|| RenameError("Method has no parameters".into()))?;
247 let first_param_ty = first_param.ty(); 247 let first_param_ty = first_param.ty();