diff options
Diffstat (limited to 'crates/ra_ide/src/completion')
-rw-r--r-- | crates/ra_ide/src/completion/completion_context.rs | 5 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/presentation.rs | 35 |
2 files changed, 39 insertions, 1 deletions
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index 3d93f7067..9e82d6854 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs | |||
@@ -63,6 +63,8 @@ pub(crate) struct CompletionContext<'a> { | |||
63 | pub(super) dot_receiver_is_ambiguous_float_literal: bool, | 63 | pub(super) dot_receiver_is_ambiguous_float_literal: bool, |
64 | /// If this is a call (method or function) in particular, i.e. the () are already there. | 64 | /// If this is a call (method or function) in particular, i.e. the () are already there. |
65 | pub(super) is_call: bool, | 65 | pub(super) is_call: bool, |
66 | /// Like `is_call`, but for tuple patterns. | ||
67 | pub(super) is_pattern_call: bool, | ||
66 | /// If this is a macro call, i.e. the () are already there. | 68 | /// If this is a macro call, i.e. the () are already there. |
67 | pub(super) is_macro_call: bool, | 69 | pub(super) is_macro_call: bool, |
68 | pub(super) is_path_type: bool, | 70 | pub(super) is_path_type: bool, |
@@ -136,6 +138,7 @@ impl<'a> CompletionContext<'a> { | |||
136 | is_new_item: false, | 138 | is_new_item: false, |
137 | dot_receiver: None, | 139 | dot_receiver: None, |
138 | is_call: false, | 140 | is_call: false, |
141 | is_pattern_call: false, | ||
139 | is_macro_call: false, | 142 | is_macro_call: false, |
140 | is_path_type: false, | 143 | is_path_type: false, |
141 | has_type_args: false, | 144 | has_type_args: false, |
@@ -370,6 +373,8 @@ impl<'a> CompletionContext<'a> { | |||
370 | .and_then(|it| it.syntax().parent().and_then(ast::CallExpr::cast)) | 373 | .and_then(|it| it.syntax().parent().and_then(ast::CallExpr::cast)) |
371 | .is_some(); | 374 | .is_some(); |
372 | self.is_macro_call = path.syntax().parent().and_then(ast::MacroCall::cast).is_some(); | 375 | self.is_macro_call = path.syntax().parent().and_then(ast::MacroCall::cast).is_some(); |
376 | self.is_pattern_call = | ||
377 | path.syntax().parent().and_then(ast::TupleStructPat::cast).is_some(); | ||
373 | 378 | ||
374 | self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some(); | 379 | self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some(); |
375 | self.has_type_args = segment.type_arg_list().is_some(); | 380 | self.has_type_args = segment.type_arg_list().is_some(); |
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 48afee5fb..64349dcb8 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs | |||
@@ -315,6 +315,7 @@ impl Completions { | |||
315 | } | 315 | } |
316 | 316 | ||
317 | if variant_kind == StructKind::Tuple { | 317 | if variant_kind == StructKind::Tuple { |
318 | mark::hit!(inserts_parens_for_tuple_enums); | ||
318 | let params = Params::Anonymous(variant.fields(ctx.db).len()); | 319 | let params = Params::Anonymous(variant.fields(ctx.db).len()); |
319 | res = res.add_call_parens(ctx, qualified_name, params) | 320 | res = res.add_call_parens(ctx, qualified_name, params) |
320 | } | 321 | } |
@@ -383,10 +384,17 @@ impl Builder { | |||
383 | if !ctx.config.add_call_parenthesis { | 384 | if !ctx.config.add_call_parenthesis { |
384 | return self; | 385 | return self; |
385 | } | 386 | } |
386 | if ctx.use_item_syntax.is_some() || ctx.is_call { | 387 | if ctx.use_item_syntax.is_some() { |
387 | mark::hit!(no_parens_in_use_item); | 388 | mark::hit!(no_parens_in_use_item); |
388 | return self; | 389 | return self; |
389 | } | 390 | } |
391 | if ctx.is_pattern_call { | ||
392 | mark::hit!(dont_duplicate_pattern_parens); | ||
393 | return self; | ||
394 | } | ||
395 | if ctx.is_call { | ||
396 | return self; | ||
397 | } | ||
390 | 398 | ||
391 | // Don't add parentheses if the expected type is some function reference. | 399 | // Don't add parentheses if the expected type is some function reference. |
392 | if let Some(ty) = &ctx.expected_type { | 400 | if let Some(ty) = &ctx.expected_type { |
@@ -865,6 +873,7 @@ fn main() { foo(${1:foo}, ${2:bar}, ${3:ho_ge_})$0 } | |||
865 | 873 | ||
866 | #[test] | 874 | #[test] |
867 | fn inserts_parens_for_tuple_enums() { | 875 | fn inserts_parens_for_tuple_enums() { |
876 | mark::check!(inserts_parens_for_tuple_enums); | ||
868 | check_edit( | 877 | check_edit( |
869 | "Some", | 878 | "Some", |
870 | r#" | 879 | r#" |
@@ -906,6 +915,30 @@ fn main(value: Option<i32>) { | |||
906 | } | 915 | } |
907 | 916 | ||
908 | #[test] | 917 | #[test] |
918 | fn dont_duplicate_pattern_parens() { | ||
919 | mark::check!(dont_duplicate_pattern_parens); | ||
920 | check_edit( | ||
921 | "Var", | ||
922 | r#" | ||
923 | enum E { Var(i32) } | ||
924 | fn main() { | ||
925 | match E::Var(92) { | ||
926 | E::<|>(92) => (), | ||
927 | } | ||
928 | } | ||
929 | "#, | ||
930 | r#" | ||
931 | enum E { Var(i32) } | ||
932 | fn main() { | ||
933 | match E::Var(92) { | ||
934 | E::Var(92) => (), | ||
935 | } | ||
936 | } | ||
937 | "#, | ||
938 | ); | ||
939 | } | ||
940 | |||
941 | #[test] | ||
909 | fn no_call_parens_if_fn_ptr_needed() { | 942 | fn no_call_parens_if_fn_ptr_needed() { |
910 | mark::check!(no_call_parens_if_fn_ptr_needed); | 943 | mark::check!(no_call_parens_if_fn_ptr_needed); |
911 | check_edit( | 944 | check_edit( |