aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/completion/presentation.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/completion/presentation.rs')
-rw-r--r--crates/ra_ide/src/completion/presentation.rs86
1 files changed, 66 insertions, 20 deletions
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs
index aada4d025..253848602 100644
--- a/crates/ra_ide/src/completion/presentation.rs
+++ b/crates/ra_ide/src/completion/presentation.rs
@@ -1,6 +1,6 @@
1//! This modules takes care of rendering various definitions as completion items. 1//! This modules takes care of rendering various definitions as completion items.
2 2
3use hir::{db::HirDatabase, Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, StructKind, Type}; 3use hir::{Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, StructKind, Type};
4use join_to_string::join; 4use join_to_string::join;
5use ra_syntax::ast::NameOwner; 5use ra_syntax::ast::NameOwner;
6use test_utils::tested_by; 6use test_utils::tested_by;
@@ -9,7 +9,10 @@ use crate::completion::{
9 CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, 9 CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions,
10}; 10};
11 11
12use crate::display::{const_label, macro_label, type_label, FunctionSignature}; 12use crate::{
13 display::{const_label, macro_label, type_label, FunctionSignature},
14 RootDatabase,
15};
13 16
14impl Completions { 17impl Completions {
15 pub(crate) fn add_field( 18 pub(crate) fn add_field(
@@ -104,10 +107,7 @@ impl Completions {
104 }; 107 };
105 108
106 // Add `<>` for generic types 109 // Add `<>` for generic types
107 if ctx.is_path_type 110 if ctx.is_path_type && !ctx.has_type_args && ctx.options.add_call_parenthesis {
108 && !ctx.has_type_args
109 && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
110 {
111 let has_non_default_type_params = match resolution { 111 let has_non_default_type_params = match resolution {
112 ScopeDef::ModuleDef(Adt(it)) => it.has_non_default_type_params(ctx.db), 112 ScopeDef::ModuleDef(Adt(it)) => it.has_non_default_type_params(ctx.db),
113 ScopeDef::ModuleDef(TypeAlias(it)) => it.has_non_default_type_params(ctx.db), 113 ScopeDef::ModuleDef(TypeAlias(it)) => it.has_non_default_type_params(ctx.db),
@@ -212,21 +212,14 @@ impl Completions {
212 .detail(function_signature.to_string()); 212 .detail(function_signature.to_string());
213 213
214 // If not an import, add parenthesis automatically. 214 // If not an import, add parenthesis automatically.
215 if ctx.use_item_syntax.is_none() 215 if ctx.use_item_syntax.is_none() && !ctx.is_call && ctx.options.add_call_parenthesis {
216 && !ctx.is_call
217 && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
218 {
219 tested_by!(inserts_parens_for_function_calls); 216 tested_by!(inserts_parens_for_function_calls);
220 217
221 let (snippet, label) = if params.is_empty() || has_self_param && params.len() == 1 { 218 let (snippet, label) = if params.is_empty() || has_self_param && params.len() == 1 {
222 (format!("{}()$0", name), format!("{}()", name)) 219 (format!("{}()$0", name), format!("{}()", name))
223 } else { 220 } else {
224 builder = builder.trigger_call_info(); 221 builder = builder.trigger_call_info();
225 let snippet = if ctx 222 let snippet = if ctx.options.add_call_argument_snippets {
226 .db
227 .feature_flags
228 .get("completion.insertion.add-argument-snippets")
229 {
230 let to_skip = if has_self_param { 1 } else { 0 }; 223 let to_skip = if has_self_param { 1 } else { 0 };
231 let function_params_snippet = join( 224 let function_params_snippet = join(
232 function_signature.parameter_names.iter().skip(to_skip).enumerate().map( 225 function_signature.parameter_names.iter().skip(to_skip).enumerate().map(
@@ -283,8 +276,10 @@ impl Completions {
283 pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) { 276 pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) {
284 let is_deprecated = is_deprecated(variant, ctx.db); 277 let is_deprecated = is_deprecated(variant, ctx.db);
285 let name = variant.name(ctx.db); 278 let name = variant.name(ctx.db);
286 let detail_types = 279 let detail_types = variant
287 variant.fields(ctx.db).into_iter().map(|field| (field.name(ctx.db), field.ty(ctx.db))); 280 .fields(ctx.db)
281 .into_iter()
282 .map(|field| (field.name(ctx.db), field.signature_ty(ctx.db)));
288 let detail = match variant.kind(ctx.db) { 283 let detail = match variant.kind(ctx.db) {
289 StructKind::Tuple | StructKind::Unit => { 284 StructKind::Tuple | StructKind::Unit => {
290 join(detail_types.map(|(_, t)| t.display(ctx.db).to_string())) 285 join(detail_types.map(|(_, t)| t.display(ctx.db).to_string()))
@@ -308,7 +303,7 @@ impl Completions {
308 } 303 }
309} 304}
310 305
311fn is_deprecated(node: impl HasAttrs, db: &impl HirDatabase) -> bool { 306fn is_deprecated(node: impl HasAttrs, db: &RootDatabase) -> bool {
312 node.attrs(db).by_key("deprecated").exists() 307 node.attrs(db).by_key("deprecated").exists()
313} 308}
314 309
@@ -317,12 +312,22 @@ mod tests {
317 use insta::assert_debug_snapshot; 312 use insta::assert_debug_snapshot;
318 use test_utils::covers; 313 use test_utils::covers;
319 314
320 use crate::completion::{do_completion, CompletionItem, CompletionKind}; 315 use crate::completion::{
316 test_utils::{do_completion, do_completion_with_options},
317 CompletionItem, CompletionKind, CompletionOptions,
318 };
321 319
322 fn do_reference_completion(ra_fixture: &str) -> Vec<CompletionItem> { 320 fn do_reference_completion(ra_fixture: &str) -> Vec<CompletionItem> {
323 do_completion(ra_fixture, CompletionKind::Reference) 321 do_completion(ra_fixture, CompletionKind::Reference)
324 } 322 }
325 323
324 fn do_reference_completion_with_options(
325 ra_fixture: &str,
326 options: CompletionOptions,
327 ) -> Vec<CompletionItem> {
328 do_completion_with_options(ra_fixture, CompletionKind::Reference, &options)
329 }
330
326 #[test] 331 #[test]
327 fn enum_detail_includes_names_for_record() { 332 fn enum_detail_includes_names_for_record() {
328 assert_debug_snapshot!( 333 assert_debug_snapshot!(
@@ -510,6 +515,7 @@ mod tests {
510 kind: Function, 515 kind: Function,
511 lookup: "with_args", 516 lookup: "with_args",
512 detail: "fn with_args(x: i32, y: String)", 517 detail: "fn with_args(x: i32, y: String)",
518 trigger_call_info: true,
513 }, 519 },
514 ] 520 ]
515 "### 521 "###
@@ -543,7 +549,7 @@ mod tests {
543 } 549 }
544 550
545 #[test] 551 #[test]
546 fn parens_for_method_call() { 552 fn arg_snippets_for_method_call() {
547 assert_debug_snapshot!( 553 assert_debug_snapshot!(
548 do_reference_completion( 554 do_reference_completion(
549 r" 555 r"
@@ -566,6 +572,42 @@ mod tests {
566 kind: Method, 572 kind: Method,
567 lookup: "foo", 573 lookup: "foo",
568 detail: "fn foo(&self, x: i32)", 574 detail: "fn foo(&self, x: i32)",
575 trigger_call_info: true,
576 },
577 ]
578 "###
579 )
580 }
581
582 #[test]
583 fn no_arg_snippets_for_method_call() {
584 assert_debug_snapshot!(
585 do_reference_completion_with_options(
586 r"
587 struct S {}
588 impl S {
589 fn foo(&self, x: i32) {}
590 }
591 fn bar(s: &S) {
592 s.f<|>
593 }
594 ",
595 CompletionOptions {
596 add_call_argument_snippets: false,
597 .. Default::default()
598 }
599 ),
600 @r###"
601 [
602 CompletionItem {
603 label: "foo(…)",
604 source_range: [171; 172),
605 delete: [171; 172),
606 insert: "foo($0)",
607 kind: Method,
608 lookup: "foo",
609 detail: "fn foo(&self, x: i32)",
610 trigger_call_info: true,
569 }, 611 },
570 ] 612 ]
571 "### 613 "###
@@ -684,6 +726,7 @@ mod tests {
684 kind: Function, 726 kind: Function,
685 lookup: "foo", 727 lookup: "foo",
686 detail: "fn foo(xs: Ve)", 728 detail: "fn foo(xs: Ve)",
729 trigger_call_info: true,
687 }, 730 },
688 ] 731 ]
689 "### 732 "###
@@ -713,6 +756,7 @@ mod tests {
713 kind: Function, 756 kind: Function,
714 lookup: "foo", 757 lookup: "foo",
715 detail: "fn foo(xs: Ve)", 758 detail: "fn foo(xs: Ve)",
759 trigger_call_info: true,
716 }, 760 },
717 ] 761 ]
718 "### 762 "###
@@ -741,6 +785,7 @@ mod tests {
741 kind: Function, 785 kind: Function,
742 lookup: "foo", 786 lookup: "foo",
743 detail: "fn foo(xs: Ve)", 787 detail: "fn foo(xs: Ve)",
788 trigger_call_info: true,
744 }, 789 },
745 ] 790 ]
746 "### 791 "###
@@ -769,6 +814,7 @@ mod tests {
769 kind: Function, 814 kind: Function,
770 lookup: "foo", 815 lookup: "foo",
771 detail: "fn foo(xs: Ve<i128>)", 816 detail: "fn foo(xs: Ve<i128>)",
817 trigger_call_info: true,
772 }, 818 },
773 ] 819 ]
774 "### 820 "###