From 9a3eae8755f99f4cfb8c2abb0885ec500b946218 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 20 Jun 2021 19:32:45 +0300 Subject: fix: don't add duplicate `&` during completion --- crates/ide_completion/src/context.rs | 65 +++++++++++++++++++++++-------- crates/ide_completion/src/render.rs | 75 +++++++++++------------------------- 2 files changed, 72 insertions(+), 68 deletions(-) (limited to 'crates/ide_completion/src') diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index e49e434fa..7b76600df 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs @@ -385,14 +385,19 @@ impl<'a> CompletionContext<'a> { (ty, name) }, ast::ArgList(_it) => { - cov_mark::hit!(expected_type_fn_param_with_leading_char); - cov_mark::hit!(expected_type_fn_param_without_leading_char); + cov_mark::hit!(expected_type_fn_param); ActiveParameter::at_token( &self.sema, self.token.clone(), ).map(|ap| { let name = ap.ident().map(NameOrNameRef::Name); - (Some(ap.ty), name) + let ty = if has_ref(&self.token) { + cov_mark::hit!(expected_type_fn_param_ref); + ap.ty.remove_ref() + } else { + Some(ap.ty) + }; + (ty, name) }) .unwrap_or((None, None)) }, @@ -697,6 +702,19 @@ fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<(ast::Path, bool)> { use_tree.path().zip(Some(true)) } +fn has_ref(token: &SyntaxToken) -> bool { + let mut token = token.clone(); + for skip in [WHITESPACE, IDENT, T![mut]] { + if token.kind() == skip { + token = match token.prev_token() { + Some(it) => it, + None => return false, + } + } + } + token.kind() == T![&] +} + #[cfg(test)] mod tests { use expect_test::{expect, Expect}; @@ -769,14 +787,18 @@ fn foo() { } #[test] - fn expected_type_fn_param_without_leading_char() { - cov_mark::check!(expected_type_fn_param_without_leading_char); + fn expected_type_fn_param() { + cov_mark::check!(expected_type_fn_param); check_expected_type_and_name( r#" -fn foo() { - bar($0); -} - +fn foo() { bar($0); } +fn bar(x: u32) {} +"#, + expect![[r#"ty: u32, name: x"#]], + ); + check_expected_type_and_name( + r#" +fn foo() { bar(c$0); } fn bar(x: u32) {} "#, expect![[r#"ty: u32, name: x"#]], @@ -784,18 +806,29 @@ fn bar(x: u32) {} } #[test] - fn expected_type_fn_param_with_leading_char() { - cov_mark::check!(expected_type_fn_param_with_leading_char); + fn expected_type_fn_param_ref() { + cov_mark::check!(expected_type_fn_param_ref); check_expected_type_and_name( r#" -fn foo() { - bar(c$0); -} - -fn bar(x: u32) {} +fn foo() { bar(&$0); } +fn bar(x: &u32) {} "#, expect![[r#"ty: u32, name: x"#]], ); + check_expected_type_and_name( + r#" +fn foo() { bar(&mut $0); } +fn bar(x: &mut u32) {} +"#, + expect![[r#"ty: u32, name: x"#]], + ); + check_expected_type_and_name( + r#" +fn foo() { bar(&c$0); } +fn bar(x: &u32) {} + "#, + expect![[r#"ty: u32, name: x"#]], + ); } #[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() { #[test] fn suggest_ref_mut() { cov_mark::check!(suggest_ref); - check( + check_relevance( r#" struct S; fn foo(s: &mut S) {} @@ -1067,58 +1067,29 @@ fn main() { } "#, expect![[r#" - [ - CompletionItem { - label: "S", - source_range: 70..70, - delete: 70..70, - insert: "S", - kind: SymbolKind( - Struct, - ), - }, - CompletionItem { - label: "foo(…)", - source_range: 70..70, - delete: 70..70, - insert: "foo(${1:&mut s})$0", - kind: SymbolKind( - Function, - ), - lookup: "foo", - detail: "fn(&mut S)", - trigger_call_info: true, - }, - CompletionItem { - label: "main()", - source_range: 70..70, - delete: 70..70, - insert: "main()$0", - kind: SymbolKind( - Function, - ), - lookup: "main", - detail: "fn()", - }, - CompletionItem { - label: "s", - source_range: 70..70, - delete: 70..70, - insert: "s", - kind: SymbolKind( - Local, - ), - detail: "S", - relevance: CompletionRelevance { - exact_name_match: true, - type_match: None, - is_local: true, - }, - ref_match: "&mut ", - }, - ] + lc s [name+local] + lc &mut s [type+name+local] + st S [] + fn main() [] + fn foo(…) [] "#]], - ) + ); + check_relevance( + r#" +struct S; +fn foo(s: &mut S) {} +fn main() { + let mut s = S; + foo(&mut $0); +} + "#, + expect![[r#" + lc s [type+name+local] + st S [] + fn main() [] + fn foo(…) [] + "#]], + ); } #[test] -- cgit v1.2.3