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.rs256
1 files changed, 244 insertions, 12 deletions
diff --git a/crates/ra_ide/src/completion/complete_postfix.rs b/crates/ra_ide/src/completion/complete_postfix.rs
index 6a0f0c72e..f2a52a407 100644
--- a/crates/ra_ide/src/completion/complete_postfix.rs
+++ b/crates/ra_ide/src/completion/complete_postfix.rs
@@ -14,6 +14,7 @@ use crate::{
14 }, 14 },
15 CompletionItem, 15 CompletionItem,
16}; 16};
17use ra_assists::utils::TryEnum;
17 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 {
@@ -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);
40 54
41 if receiver_ty.is_bool() || receiver_ty.is_unknown() { 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);
75
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,16 +125,45 @@ 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);
83 128 match try_enum {
84 postfix_snippet( 129 Some(try_enum) => {
85 ctx, 130 match try_enum {
86 cap, 131 TryEnum::Result => {
87 &dot_receiver, 132 postfix_snippet(
88 "match", 133 ctx,
89 "match expr {}", 134 cap,
90 &format!("match {} {{\n ${{1:_}} => {{$0\\}},\n}}", receiver_text), 135 &dot_receiver,
91 ) 136 "match",
92 .add_to(acc); 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 }
93 167
94 postfix_snippet( 168 postfix_snippet(
95 ctx, 169 ctx,
@@ -236,6 +310,164 @@ mod tests {
236 } 310 }
237 311
238 #[test] 312 #[test]
313 fn postfix_completion_works_for_option() {
314 assert_debug_snapshot!(
315 do_postfix_completion(
316 r#"
317 enum Option<T> {
318 Some(T),
319 None,
320 }
321
322 fn main() {
323 let bar = Option::Some(true);
324 bar.<|>
325 }
326 "#,
327 ),
328 @r###"
329 [
330 CompletionItem {
331 label: "box",
332 source_range: 210..210,
333 delete: 206..210,
334 insert: "Box::new(bar)",
335 detail: "Box::new(expr)",
336 },
337 CompletionItem {
338 label: "dbg",
339 source_range: 210..210,
340 delete: 206..210,
341 insert: "dbg!(bar)",
342 detail: "dbg!(expr)",
343 },
344 CompletionItem {
345 label: "ifl",
346 source_range: 210..210,
347 delete: 206..210,
348 insert: "if let Some($1) = bar {\n $0\n}",
349 detail: "if let Some {}",
350 },
351 CompletionItem {
352 label: "match",
353 source_range: 210..210,
354 delete: 206..210,
355 insert: "match bar {\n Some(${1:_}) => {$2\\},\n None => {$0\\},\n}",
356 detail: "match expr {}",
357 },
358 CompletionItem {
359 label: "not",
360 source_range: 210..210,
361 delete: 206..210,
362 insert: "!bar",
363 detail: "!expr",
364 },
365 CompletionItem {
366 label: "ref",
367 source_range: 210..210,
368 delete: 206..210,
369 insert: "&bar",
370 detail: "&expr",
371 },
372 CompletionItem {
373 label: "refm",
374 source_range: 210..210,
375 delete: 206..210,
376 insert: "&mut bar",
377 detail: "&mut expr",
378 },
379 CompletionItem {
380 label: "while",
381 source_range: 210..210,
382 delete: 206..210,
383 insert: "while let Some($1) = bar {\n $0\n}",
384 detail: "while let Some {}",
385 },
386 ]
387 "###
388 );
389 }
390
391 #[test]
392 fn postfix_completion_works_for_result() {
393 assert_debug_snapshot!(
394 do_postfix_completion(
395 r#"
396 enum Result<T, E> {
397 Ok(T),
398 Err(E),
399 }
400
401 fn main() {
402 let bar = Result::Ok(true);
403 bar.<|>
404 }
405 "#,
406 ),
407 @r###"
408 [
409 CompletionItem {
410 label: "box",
411 source_range: 211..211,
412 delete: 207..211,
413 insert: "Box::new(bar)",
414 detail: "Box::new(expr)",
415 },
416 CompletionItem {
417 label: "dbg",
418 source_range: 211..211,
419 delete: 207..211,
420 insert: "dbg!(bar)",
421 detail: "dbg!(expr)",
422 },
423 CompletionItem {
424 label: "ifl",
425 source_range: 211..211,
426 delete: 207..211,
427 insert: "if let Ok($1) = bar {\n $0\n}",
428 detail: "if let Ok {}",
429 },
430 CompletionItem {
431 label: "match",
432 source_range: 211..211,
433 delete: 207..211,
434 insert: "match bar {\n Ok(${1:_}) => {$2\\},\n Err(${3:_}) => {$0\\},\n}",
435 detail: "match expr {}",
436 },
437 CompletionItem {
438 label: "not",
439 source_range: 211..211,
440 delete: 207..211,
441 insert: "!bar",
442 detail: "!expr",
443 },
444 CompletionItem {
445 label: "ref",
446 source_range: 211..211,
447 delete: 207..211,
448 insert: "&bar",
449 detail: "&expr",
450 },
451 CompletionItem {
452 label: "refm",
453 source_range: 211..211,
454 delete: 207..211,
455 insert: "&mut bar",
456 detail: "&mut expr",
457 },
458 CompletionItem {
459 label: "while",
460 source_range: 211..211,
461 delete: 207..211,
462 insert: "while let Ok($1) = bar {\n $0\n}",
463 detail: "while let Ok {}",
464 },
465 ]
466 "###
467 );
468 }
469
470 #[test]
239 fn some_postfix_completions_ignored() { 471 fn some_postfix_completions_ignored() {
240 assert_debug_snapshot!( 472 assert_debug_snapshot!(
241 do_postfix_completion( 473 do_postfix_completion(