|
1 | 1 | //! Renderer for function calls.
|
2 | 2 |
|
3 |
| -use std::ops::ControlFlow; |
4 |
| - |
5 | 3 | use hir::{db::HirDatabase, AsAssocItem, HirDisplay};
|
6 | 4 | use ide_db::{SnippetCap, SymbolKind};
|
7 | 5 | use itertools::Itertools;
|
8 | 6 | use stdx::{format_to, to_lower_snake_case};
|
9 |
| -use syntax::{ast, format_smolstr, AstNode, Edition, SmolStr, SyntaxKind, ToSmolStr, T}; |
| 7 | +use syntax::{format_smolstr, AstNode, Edition, SmolStr, ToSmolStr}; |
10 | 8 |
|
11 | 9 | use crate::{
|
12 |
| - context::{CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind}, |
| 10 | + context::{ |
| 11 | + CompleteSemicolon, CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind, |
| 12 | + }, |
13 | 13 | item::{
|
14 | 14 | Builder, CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevanceFn,
|
15 | 15 | CompletionRelevanceReturnType, CompletionRelevanceTraitInfo,
|
@@ -277,32 +277,21 @@ pub(super) fn add_call_parens<'b>(
|
277 | 277 |
|
278 | 278 | (snippet, "(…)")
|
279 | 279 | };
|
280 |
| - if ret_type.is_unit() && ctx.config.add_semicolon_to_unit { |
281 |
| - let next_non_trivia_token = |
282 |
| - std::iter::successors(ctx.token.next_token(), |it| it.next_token()) |
283 |
| - .find(|it| !it.kind().is_trivia()); |
284 |
| - let in_match_arm = ctx.token.parent_ancestors().try_for_each(|ancestor| { |
285 |
| - if ast::MatchArm::can_cast(ancestor.kind()) { |
286 |
| - ControlFlow::Break(true) |
287 |
| - } else if matches!(ancestor.kind(), SyntaxKind::EXPR_STMT | SyntaxKind::BLOCK_EXPR) { |
288 |
| - ControlFlow::Break(false) |
289 |
| - } else { |
290 |
| - ControlFlow::Continue(()) |
291 |
| - } |
292 |
| - }); |
293 |
| - // FIXME: This will assume expr macros are not inside match, we need to somehow go to the "parent" of the root node. |
294 |
| - let in_match_arm = match in_match_arm { |
295 |
| - ControlFlow::Continue(()) => false, |
296 |
| - ControlFlow::Break(it) => it, |
297 |
| - }; |
298 |
| - let complete_token = if in_match_arm { T![,] } else { T![;] }; |
299 |
| - if next_non_trivia_token.map(|it| it.kind()) != Some(complete_token) { |
300 |
| - cov_mark::hit!(complete_semicolon); |
301 |
| - let ch = if in_match_arm { ',' } else { ';' }; |
302 |
| - if snippet.ends_with("$0") { |
303 |
| - snippet.insert(snippet.len() - "$0".len(), ch); |
304 |
| - } else { |
305 |
| - snippet.push(ch); |
| 280 | + if ret_type.is_unit() { |
| 281 | + match ctx.complete_semicolon { |
| 282 | + CompleteSemicolon::DoNotComplete => {} |
| 283 | + CompleteSemicolon::CompleteSemi | CompleteSemicolon::CompleteComma => { |
| 284 | + cov_mark::hit!(complete_semicolon); |
| 285 | + let ch = if matches!(ctx.complete_semicolon, CompleteSemicolon::CompleteComma) { |
| 286 | + ',' |
| 287 | + } else { |
| 288 | + ';' |
| 289 | + }; |
| 290 | + if snippet.ends_with("$0") { |
| 291 | + snippet.insert(snippet.len() - "$0".len(), ch); |
| 292 | + } else { |
| 293 | + snippet.push(ch); |
| 294 | + } |
306 | 295 | }
|
307 | 296 | }
|
308 | 297 | }
|
@@ -886,6 +875,27 @@ fn bar() {
|
886 | 875 | v => foo()$0,
|
887 | 876 | }
|
888 | 877 | }
|
| 878 | +"#, |
| 879 | + ); |
| 880 | + } |
| 881 | + |
| 882 | + #[test] |
| 883 | + fn no_semicolon_in_closure_ret() { |
| 884 | + check_edit( |
| 885 | + r#"foo"#, |
| 886 | + r#" |
| 887 | +fn foo() {} |
| 888 | +fn baz(_: impl FnOnce()) {} |
| 889 | +fn bar() { |
| 890 | + baz(|| fo$0); |
| 891 | +} |
| 892 | +"#, |
| 893 | + r#" |
| 894 | +fn foo() {} |
| 895 | +fn baz(_: impl FnOnce()) {} |
| 896 | +fn bar() { |
| 897 | + baz(|| foo()$0); |
| 898 | +} |
889 | 899 | "#,
|
890 | 900 | );
|
891 | 901 | }
|
|
0 commit comments