aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/completion/complete_postfix.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/completion/complete_postfix.rs')
-rw-r--r--crates/ra_ide/src/completion/complete_postfix.rs317
1 files changed, 304 insertions, 13 deletions
diff --git a/crates/ra_ide/src/completion/complete_postfix.rs b/crates/ra_ide/src/completion/complete_postfix.rs
index 6a0f0c72e..59b58bf98 100644
--- a/crates/ra_ide/src/completion/complete_postfix.rs
+++ b/crates/ra_ide/src/completion/complete_postfix.rs
@@ -1,12 +1,11 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2use ra_assists::utils::TryEnum;
3use ra_syntax::{ 3use ra_syntax::{
4 ast::{self, AstNode}, 4 ast::{self, AstNode},
5 TextRange, TextSize, 5 TextRange, TextSize,
6}; 6};
7use ra_text_edit::TextEdit; 7use ra_text_edit::TextEdit;
8 8
9use super::completion_config::SnippetCap;
10use crate::{ 9use crate::{
11 completion::{ 10 completion::{
12 completion_context::CompletionContext, 11 completion_context::CompletionContext,
@@ -15,6 +14,8 @@ use crate::{
15 CompletionItem, 14 CompletionItem,
16}; 15};
17 16
17use super::completion_config::SnippetCap;
18
18pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { 19pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
19 if !ctx.config.enable_postfix_completions { 20 if !ctx.config.enable_postfix_completions {
20 return; 21 return;
@@ -37,8 +38,53 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
37 Some(it) => it, 38 Some(it) => it,
38 None => return, 39 None => return,
39 }; 40 };
41 let try_enum = TryEnum::from_ty(&ctx.sema, &receiver_ty);
42 if let Some(try_enum) = &try_enum {
43 match try_enum {
44 TryEnum::Result => {
45 postfix_snippet(
46 ctx,
47 cap,
48 &dot_receiver,
49 "ifl",
50 "if let Ok {}",
51 &format!("if let Ok($1) = {} {{\n $0\n}}", receiver_text),
52 )
53 .add_to(acc);
54
55 postfix_snippet(
56 ctx,
57 cap,
58 &dot_receiver,
59 "while",
60 "while let Ok {}",
61 &format!("while let Ok($1) = {} {{\n $0\n}}", receiver_text),
62 )
63 .add_to(acc);
64 }
65 TryEnum::Option => {
66 postfix_snippet(
67 ctx,
68 cap,
69 &dot_receiver,
70 "ifl",
71 "if let Some {}",
72 &format!("if let Some($1) = {} {{\n $0\n}}", receiver_text),
73 )
74 .add_to(acc);
40 75
41 if receiver_ty.is_bool() || receiver_ty.is_unknown() { 76 postfix_snippet(
77 ctx,
78 cap,
79 &dot_receiver,
80 "while",
81 "while let Some {}",
82 &format!("while let Some($1) = {} {{\n $0\n}}", receiver_text),
83 )
84 .add_to(acc);
85 }
86 }
87 } else if receiver_ty.is_bool() || receiver_ty.is_unknown() {
42 postfix_snippet( 88 postfix_snippet(
43 ctx, 89 ctx,
44 cap, 90 cap,
@@ -58,7 +104,6 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
58 ) 104 )
59 .add_to(acc); 105 .add_to(acc);
60 } 106 }
61
62 // !&&&42 is a compiler error, ergo process it before considering the references 107 // !&&&42 is a compiler error, ergo process it before considering the references
63 postfix_snippet(ctx, cap, &dot_receiver, "not", "!expr", &format!("!{}", receiver_text)) 108 postfix_snippet(ctx, cap, &dot_receiver, "not", "!expr", &format!("!{}", receiver_text))
64 .add_to(acc); 109 .add_to(acc);
@@ -80,14 +125,53 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
80 let dot_receiver = include_references(dot_receiver); 125 let dot_receiver = include_references(dot_receiver);
81 let receiver_text = 126 let receiver_text =
82 get_receiver_text(&dot_receiver, ctx.dot_receiver_is_ambiguous_float_literal); 127 get_receiver_text(&dot_receiver, ctx.dot_receiver_is_ambiguous_float_literal);
128 match try_enum {
129 Some(try_enum) => {
130 match try_enum {
131 TryEnum::Result => {
132 postfix_snippet(
133 ctx,
134 cap,
135 &dot_receiver,
136 "match",
137 "match expr {}",
138 &format!("match {} {{\n Ok(${{1:_}}) => {{$2\\}},\n Err(${{3:_}}) => {{$0\\}},\n}}", receiver_text),
139 )
140 .add_to(acc);
141 }
142 TryEnum::Option => {
143 postfix_snippet(
144 ctx,
145 cap,
146 &dot_receiver,
147 "match",
148 "match expr {}",
149 &format!("match {} {{\n Some(${{1:_}}) => {{$2\\}},\n None => {{$0\\}},\n}}", receiver_text),
150 )
151 .add_to(acc);
152 }
153 }
154 }
155 None => {
156 postfix_snippet(
157 ctx,
158 cap,
159 &dot_receiver,
160 "match",
161 "match expr {}",
162 &format!("match {} {{\n ${{1:_}} => {{$0\\}},\n}}", receiver_text),
163 )
164 .add_to(acc);
165 }
166 }
83 167
84 postfix_snippet( 168 postfix_snippet(
85 ctx, 169 ctx,
86 cap, 170 cap,
87 &dot_receiver, 171 &dot_receiver,
88 "match", 172 "box",
89 "match expr {}", 173 "Box::new(expr)",
90 &format!("match {} {{\n ${{1:_}} => {{$0\\}},\n}}", receiver_text), 174 &format!("Box::new({})", receiver_text),
91 ) 175 )
92 .add_to(acc); 176 .add_to(acc);
93 177
@@ -95,9 +179,9 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
95 ctx, 179 ctx,
96 cap, 180 cap,
97 &dot_receiver, 181 &dot_receiver,
98 "box", 182 "dbg",
99 "Box::new(expr)", 183 "dbg!(expr)",
100 &format!("Box::new({})", receiver_text), 184 &format!("dbg!({})", receiver_text),
101 ) 185 )
102 .add_to(acc); 186 .add_to(acc);
103 187
@@ -105,9 +189,9 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
105 ctx, 189 ctx,
106 cap, 190 cap,
107 &dot_receiver, 191 &dot_receiver,
108 "dbg", 192 "call",
109 "dbg!(expr)", 193 "function(expr)",
110 &format!("dbg!({})", receiver_text), 194 &format!("${{1}}({})", receiver_text),
111 ) 195 )
112 .add_to(acc); 196 .add_to(acc);
113} 197}
@@ -182,6 +266,13 @@ mod tests {
182 detail: "Box::new(expr)", 266 detail: "Box::new(expr)",
183 }, 267 },
184 CompletionItem { 268 CompletionItem {
269 label: "call",
270 source_range: 89..89,
271 delete: 85..89,
272 insert: "${1}(bar)",
273 detail: "function(expr)",
274 },
275 CompletionItem {
185 label: "dbg", 276 label: "dbg",
186 source_range: 89..89, 277 source_range: 89..89,
187 delete: 85..89, 278 delete: 85..89,
@@ -236,6 +327,178 @@ mod tests {
236 } 327 }
237 328
238 #[test] 329 #[test]
330 fn postfix_completion_works_for_option() {
331 assert_debug_snapshot!(
332 do_postfix_completion(
333 r#"
334 enum Option<T> {
335 Some(T),
336 None,
337 }
338
339 fn main() {
340 let bar = Option::Some(true);
341 bar.<|>
342 }
343 "#,
344 ),
345 @r###"
346 [
347 CompletionItem {
348 label: "box",
349 source_range: 210..210,
350 delete: 206..210,
351 insert: "Box::new(bar)",
352 detail: "Box::new(expr)",
353 },
354 CompletionItem {
355 label: "call",
356 source_range: 210..210,
357 delete: 206..210,
358 insert: "${1}(bar)",
359 detail: "function(expr)",
360 },
361 CompletionItem {
362 label: "dbg",
363 source_range: 210..210,
364 delete: 206..210,
365 insert: "dbg!(bar)",
366 detail: "dbg!(expr)",
367 },
368 CompletionItem {
369 label: "ifl",
370 source_range: 210..210,
371 delete: 206..210,
372 insert: "if let Some($1) = bar {\n $0\n}",
373 detail: "if let Some {}",
374 },
375 CompletionItem {
376 label: "match",
377 source_range: 210..210,
378 delete: 206..210,
379 insert: "match bar {\n Some(${1:_}) => {$2\\},\n None => {$0\\},\n}",
380 detail: "match expr {}",
381 },
382 CompletionItem {
383 label: "not",
384 source_range: 210..210,
385 delete: 206..210,
386 insert: "!bar",
387 detail: "!expr",
388 },
389 CompletionItem {
390 label: "ref",
391 source_range: 210..210,
392 delete: 206..210,
393 insert: "&bar",
394 detail: "&expr",
395 },
396 CompletionItem {
397 label: "refm",
398 source_range: 210..210,
399 delete: 206..210,
400 insert: "&mut bar",
401 detail: "&mut expr",
402 },
403 CompletionItem {
404 label: "while",
405 source_range: 210..210,
406 delete: 206..210,
407 insert: "while let Some($1) = bar {\n $0\n}",
408 detail: "while let Some {}",
409 },
410 ]
411 "###
412 );
413 }
414
415 #[test]
416 fn postfix_completion_works_for_result() {
417 assert_debug_snapshot!(
418 do_postfix_completion(
419 r#"
420 enum Result<T, E> {
421 Ok(T),
422 Err(E),
423 }
424
425 fn main() {
426 let bar = Result::Ok(true);
427 bar.<|>
428 }
429 "#,
430 ),
431 @r###"
432 [
433 CompletionItem {
434 label: "box",
435 source_range: 211..211,
436 delete: 207..211,
437 insert: "Box::new(bar)",
438 detail: "Box::new(expr)",
439 },
440 CompletionItem {
441 label: "call",
442 source_range: 211..211,
443 delete: 207..211,
444 insert: "${1}(bar)",
445 detail: "function(expr)",
446 },
447 CompletionItem {
448 label: "dbg",
449 source_range: 211..211,
450 delete: 207..211,
451 insert: "dbg!(bar)",
452 detail: "dbg!(expr)",
453 },
454 CompletionItem {
455 label: "ifl",
456 source_range: 211..211,
457 delete: 207..211,
458 insert: "if let Ok($1) = bar {\n $0\n}",
459 detail: "if let Ok {}",
460 },
461 CompletionItem {
462 label: "match",
463 source_range: 211..211,
464 delete: 207..211,
465 insert: "match bar {\n Ok(${1:_}) => {$2\\},\n Err(${3:_}) => {$0\\},\n}",
466 detail: "match expr {}",
467 },
468 CompletionItem {
469 label: "not",
470 source_range: 211..211,
471 delete: 207..211,
472 insert: "!bar",
473 detail: "!expr",
474 },
475 CompletionItem {
476 label: "ref",
477 source_range: 211..211,
478 delete: 207..211,
479 insert: "&bar",
480 detail: "&expr",
481 },
482 CompletionItem {
483 label: "refm",
484 source_range: 211..211,
485 delete: 207..211,
486 insert: "&mut bar",
487 detail: "&mut expr",
488 },
489 CompletionItem {
490 label: "while",
491 source_range: 211..211,
492 delete: 207..211,
493 insert: "while let Ok($1) = bar {\n $0\n}",
494 detail: "while let Ok {}",
495 },
496 ]
497 "###
498 );
499 }
500
501 #[test]
239 fn some_postfix_completions_ignored() { 502 fn some_postfix_completions_ignored() {
240 assert_debug_snapshot!( 503 assert_debug_snapshot!(
241 do_postfix_completion( 504 do_postfix_completion(
@@ -256,6 +519,13 @@ mod tests {
256 detail: "Box::new(expr)", 519 detail: "Box::new(expr)",
257 }, 520 },
258 CompletionItem { 521 CompletionItem {
522 label: "call",
523 source_range: 91..91,
524 delete: 87..91,
525 insert: "${1}(bar)",
526 detail: "function(expr)",
527 },
528 CompletionItem {
259 label: "dbg", 529 label: "dbg",
260 source_range: 91..91, 530 source_range: 91..91,
261 delete: 87..91, 531 delete: 87..91,
@@ -315,6 +585,13 @@ mod tests {
315 detail: "Box::new(expr)", 585 detail: "Box::new(expr)",
316 }, 586 },
317 CompletionItem { 587 CompletionItem {
588 label: "call",
589 source_range: 52..52,
590 delete: 49..52,
591 insert: "${1}(42)",
592 detail: "function(expr)",
593 },
594 CompletionItem {
318 label: "dbg", 595 label: "dbg",
319 source_range: 52..52, 596 source_range: 52..52,
320 delete: 49..52, 597 delete: 49..52,
@@ -376,6 +653,13 @@ mod tests {
376 detail: "Box::new(expr)", 653 detail: "Box::new(expr)",
377 }, 654 },
378 CompletionItem { 655 CompletionItem {
656 label: "call",
657 source_range: 149..150,
658 delete: 145..150,
659 insert: "${1}(bar)",
660 detail: "function(expr)",
661 },
662 CompletionItem {
379 label: "dbg", 663 label: "dbg",
380 source_range: 149..150, 664 source_range: 149..150,
381 delete: 145..150, 665 delete: 145..150,
@@ -435,6 +719,13 @@ mod tests {
435 detail: "Box::new(expr)", 719 detail: "Box::new(expr)",
436 }, 720 },
437 CompletionItem { 721 CompletionItem {
722 label: "call",
723 source_range: 56..56,
724 delete: 49..56,
725 insert: "${1}(&&&&42)",
726 detail: "function(expr)",
727 },
728 CompletionItem {
438 label: "dbg", 729 label: "dbg",
439 source_range: 56..56, 730 source_range: 56..56,
440 delete: 49..56, 731 delete: 49..56,