aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion')
-rw-r--r--crates/ide_completion/src/context.rs65
-rw-r--r--crates/ide_completion/src/render.rs75
2 files changed, 72 insertions, 68 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 4814bd64d..f0da98739 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -388,14 +388,19 @@ impl<'a> CompletionContext<'a> {
388 (ty, name) 388 (ty, name)
389 }, 389 },
390 ast::ArgList(_it) => { 390 ast::ArgList(_it) => {
391 cov_mark::hit!(expected_type_fn_param_with_leading_char); 391 cov_mark::hit!(expected_type_fn_param);
392 cov_mark::hit!(expected_type_fn_param_without_leading_char);
393 ActiveParameter::at_token( 392 ActiveParameter::at_token(
394 &self.sema, 393 &self.sema,
395 self.token.clone(), 394 self.token.clone(),
396 ).map(|ap| { 395 ).map(|ap| {
397 let name = ap.ident().map(NameOrNameRef::Name); 396 let name = ap.ident().map(NameOrNameRef::Name);
398 (Some(ap.ty), name) 397 let ty = if has_ref(&self.token) {
398 cov_mark::hit!(expected_type_fn_param_ref);
399 ap.ty.remove_ref()
400 } else {
401 Some(ap.ty)
402 };
403 (ty, name)
399 }) 404 })
400 .unwrap_or((None, None)) 405 .unwrap_or((None, None))
401 }, 406 },
@@ -700,6 +705,19 @@ fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<(ast::Path, bool)> {
700 use_tree.path().zip(Some(true)) 705 use_tree.path().zip(Some(true))
701} 706}
702 707
708fn has_ref(token: &SyntaxToken) -> bool {
709 let mut token = token.clone();
710 for skip in [WHITESPACE, IDENT, T![mut]] {
711 if token.kind() == skip {
712 token = match token.prev_token() {
713 Some(it) => it,
714 None => return false,
715 }
716 }
717 }
718 token.kind() == T![&]
719}
720
703#[cfg(test)] 721#[cfg(test)]
704mod tests { 722mod tests {
705 use expect_test::{expect, Expect}; 723 use expect_test::{expect, Expect};
@@ -772,14 +790,18 @@ fn foo() {
772 } 790 }
773 791
774 #[test] 792 #[test]
775 fn expected_type_fn_param_without_leading_char() { 793 fn expected_type_fn_param() {
776 cov_mark::check!(expected_type_fn_param_without_leading_char); 794 cov_mark::check!(expected_type_fn_param);
777 check_expected_type_and_name( 795 check_expected_type_and_name(
778 r#" 796 r#"
779fn foo() { 797fn foo() { bar($0); }
780 bar($0); 798fn bar(x: u32) {}
781} 799"#,
782 800 expect![[r#"ty: u32, name: x"#]],
801 );
802 check_expected_type_and_name(
803 r#"
804fn foo() { bar(c$0); }
783fn bar(x: u32) {} 805fn bar(x: u32) {}
784"#, 806"#,
785 expect![[r#"ty: u32, name: x"#]], 807 expect![[r#"ty: u32, name: x"#]],
@@ -787,18 +809,29 @@ fn bar(x: u32) {}
787 } 809 }
788 810
789 #[test] 811 #[test]
790 fn expected_type_fn_param_with_leading_char() { 812 fn expected_type_fn_param_ref() {
791 cov_mark::check!(expected_type_fn_param_with_leading_char); 813 cov_mark::check!(expected_type_fn_param_ref);
792 check_expected_type_and_name( 814 check_expected_type_and_name(
793 r#" 815 r#"
794fn foo() { 816fn foo() { bar(&$0); }
795 bar(c$0); 817fn bar(x: &u32) {}
796}
797
798fn bar(x: u32) {}
799"#, 818"#,
800 expect![[r#"ty: u32, name: x"#]], 819 expect![[r#"ty: u32, name: x"#]],
801 ); 820 );
821 check_expected_type_and_name(
822 r#"
823fn foo() { bar(&mut $0); }
824fn bar(x: &mut u32) {}
825"#,
826 expect![[r#"ty: u32, name: x"#]],
827 );
828 check_expected_type_and_name(
829 r#"
830fn foo() { bar(&c$0); }
831fn bar(x: &u32) {}
832 "#,
833 expect![[r#"ty: u32, name: x"#]],
834 );
802 } 835 }
803 836
804 #[test] 837 #[test]
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 9bec03e17..1a9b6212a 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -1057,7 +1057,7 @@ fn f() {
1057 #[test] 1057 #[test]
1058 fn suggest_ref_mut() { 1058 fn suggest_ref_mut() {
1059 cov_mark::check!(suggest_ref); 1059 cov_mark::check!(suggest_ref);
1060 check( 1060 check_relevance(
1061 r#" 1061 r#"
1062struct S; 1062struct S;
1063fn foo(s: &mut S) {} 1063fn foo(s: &mut S) {}
@@ -1067,58 +1067,29 @@ fn main() {
1067} 1067}
1068 "#, 1068 "#,
1069 expect![[r#" 1069 expect![[r#"
1070 [ 1070 lc s [name+local]
1071 CompletionItem { 1071 lc &mut s [type+name+local]
1072 label: "S", 1072 st S []
1073 source_range: 70..70, 1073 fn main() []
1074 delete: 70..70, 1074 fn foo(…) []
1075 insert: "S",
1076 kind: SymbolKind(
1077 Struct,
1078 ),
1079 },
1080 CompletionItem {
1081 label: "foo(…)",
1082 source_range: 70..70,
1083 delete: 70..70,
1084 insert: "foo(${1:&mut s})$0",
1085 kind: SymbolKind(
1086 Function,
1087 ),
1088 lookup: "foo",
1089 detail: "fn(&mut S)",
1090 trigger_call_info: true,
1091 },
1092 CompletionItem {
1093 label: "main()",
1094 source_range: 70..70,
1095 delete: 70..70,
1096 insert: "main()$0",
1097 kind: SymbolKind(
1098 Function,
1099 ),
1100 lookup: "main",
1101 detail: "fn()",
1102 },
1103 CompletionItem {
1104 label: "s",
1105 source_range: 70..70,
1106 delete: 70..70,
1107 insert: "s",
1108 kind: SymbolKind(
1109 Local,
1110 ),
1111 detail: "S",
1112 relevance: CompletionRelevance {
1113 exact_name_match: true,
1114 type_match: None,
1115 is_local: true,
1116 },
1117 ref_match: "&mut ",
1118 },
1119 ]
1120 "#]], 1075 "#]],
1121 ) 1076 );
1077 check_relevance(
1078 r#"
1079struct S;
1080fn foo(s: &mut S) {}
1081fn main() {
1082 let mut s = S;
1083 foo(&mut $0);
1084}
1085 "#,
1086 expect![[r#"
1087 lc s [type+name+local]
1088 st S []
1089 fn main() []
1090 fn foo(…) []
1091 "#]],
1092 );
1122 } 1093 }
1123 1094
1124 #[test] 1095 #[test]