aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model.rs22
-rw-r--r--crates/ra_ide/src/completion/complete_postfix.rs200
2 files changed, 221 insertions, 1 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 5f480c304..7e840add5 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -1083,6 +1083,28 @@ impl Type {
1083 matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })) 1083 matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }))
1084 } 1084 }
1085 1085
1086 pub fn is_option(&self, db: &dyn HirDatabase) -> bool {
1087 if let Some(adt_ty) = self.as_adt() {
1088 if let Adt::Enum(_) = adt_ty {
1089 if self.display(db).to_string().starts_with("Option<") {
1090 return true;
1091 }
1092 }
1093 }
1094 false
1095 }
1096
1097 pub fn is_result(&self, db: &dyn HirDatabase) -> bool {
1098 if let Some(adt_ty) = self.as_adt() {
1099 if let Adt::Enum(_) = adt_ty {
1100 if self.display(db).to_string().starts_with("Result<") {
1101 return true;
1102 }
1103 }
1104 }
1105 false
1106 }
1107
1086 pub fn is_mutable_reference(&self) -> bool { 1108 pub fn is_mutable_reference(&self) -> bool {
1087 matches!( 1109 matches!(
1088 self.ty.value, 1110 self.ty.value,
diff --git a/crates/ra_ide/src/completion/complete_postfix.rs b/crates/ra_ide/src/completion/complete_postfix.rs
index 6a0f0c72e..dc32bbee2 100644
--- a/crates/ra_ide/src/completion/complete_postfix.rs
+++ b/crates/ra_ide/src/completion/complete_postfix.rs
@@ -38,7 +38,47 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
38 None => return, 38 None => return,
39 }; 39 };
40 40
41 if receiver_ty.is_bool() || receiver_ty.is_unknown() { 41 if receiver_ty.is_option(ctx.db) {
42 postfix_snippet(
43 ctx,
44 cap,
45 &dot_receiver,
46 "ifl",
47 "if let Some {}",
48 &format!("if let Some($1) = {} {{\n $0\n}}", receiver_text),
49 )
50 .add_to(acc);
51
52 postfix_snippet(
53 ctx,
54 cap,
55 &dot_receiver,
56 "while",
57 "while let Some {}",
58 &format!("while let Some($1) = {} {{\n $0\n}}", receiver_text),
59 )
60 .add_to(acc);
61 } else if receiver_ty.is_result(ctx.db) {
62 postfix_snippet(
63 ctx,
64 cap,
65 &dot_receiver,
66 "ifl",
67 "if let Ok {}",
68 &format!("if let Ok($1) = {} {{\n $0\n}}", receiver_text),
69 )
70 .add_to(acc);
71
72 postfix_snippet(
73 ctx,
74 cap,
75 &dot_receiver,
76 "while",
77 "while let Ok {}",
78 &format!("while let Ok($1) = {} {{\n $0\n}}", receiver_text),
79 )
80 .add_to(acc);
81 } else if receiver_ty.is_bool() || receiver_ty.is_unknown() {
42 postfix_snippet( 82 postfix_snippet(
43 ctx, 83 ctx,
44 cap, 84 cap,
@@ -236,6 +276,164 @@ mod tests {
236 } 276 }
237 277
238 #[test] 278 #[test]
279 fn postfix_completion_works_for_option() {
280 assert_debug_snapshot!(
281 do_postfix_completion(
282 r#"
283 enum Option<T> {
284 Some(T),
285 None,
286 }
287
288 fn main() {
289 let bar = Option::Some(true);
290 bar.<|>
291 }
292 "#,
293 ),
294 @r###"
295 [
296 CompletionItem {
297 label: "box",
298 source_range: 210..210,
299 delete: 206..210,
300 insert: "Box::new(bar)",
301 detail: "Box::new(expr)",
302 },
303 CompletionItem {
304 label: "dbg",
305 source_range: 210..210,
306 delete: 206..210,
307 insert: "dbg!(bar)",
308 detail: "dbg!(expr)",
309 },
310 CompletionItem {
311 label: "ifl",
312 source_range: 210..210,
313 delete: 206..210,
314 insert: "if let Some($1) = bar {\n $0\n}",
315 detail: "if let Some {}",
316 },
317 CompletionItem {
318 label: "match",
319 source_range: 210..210,
320 delete: 206..210,
321 insert: "match bar {\n ${1:_} => {$0\\},\n}",
322 detail: "match expr {}",
323 },
324 CompletionItem {
325 label: "not",
326 source_range: 210..210,
327 delete: 206..210,
328 insert: "!bar",
329 detail: "!expr",
330 },
331 CompletionItem {
332 label: "ref",
333 source_range: 210..210,
334 delete: 206..210,
335 insert: "&bar",
336 detail: "&expr",
337 },
338 CompletionItem {
339 label: "refm",
340 source_range: 210..210,
341 delete: 206..210,
342 insert: "&mut bar",
343 detail: "&mut expr",
344 },
345 CompletionItem {
346 label: "while",
347 source_range: 210..210,
348 delete: 206..210,
349 insert: "while let Some($1) = bar {\n $0\n}",
350 detail: "while let Some {}",
351 },
352 ]
353 "###
354 );
355 }
356
357 #[test]
358 fn postfix_completion_works_for_result() {
359 assert_debug_snapshot!(
360 do_postfix_completion(
361 r#"
362 enum Result<T, E> {
363 Ok(T),
364 Err(E),
365 }
366
367 fn main() {
368 let bar = Result::Ok(true);
369 bar.<|>
370 }
371 "#,
372 ),
373 @r###"
374 [
375 CompletionItem {
376 label: "box",
377 source_range: 211..211,
378 delete: 207..211,
379 insert: "Box::new(bar)",
380 detail: "Box::new(expr)",
381 },
382 CompletionItem {
383 label: "dbg",
384 source_range: 211..211,
385 delete: 207..211,
386 insert: "dbg!(bar)",
387 detail: "dbg!(expr)",
388 },
389 CompletionItem {
390 label: "ifl",
391 source_range: 211..211,
392 delete: 207..211,
393 insert: "if let Ok($1) = bar {\n $0\n}",
394 detail: "if let Ok {}",
395 },
396 CompletionItem {
397 label: "match",
398 source_range: 211..211,
399 delete: 207..211,
400 insert: "match bar {\n ${1:_} => {$0\\},\n}",
401 detail: "match expr {}",
402 },
403 CompletionItem {
404 label: "not",
405 source_range: 211..211,
406 delete: 207..211,
407 insert: "!bar",
408 detail: "!expr",
409 },
410 CompletionItem {
411 label: "ref",
412 source_range: 211..211,
413 delete: 207..211,
414 insert: "&bar",
415 detail: "&expr",
416 },
417 CompletionItem {
418 label: "refm",
419 source_range: 211..211,
420 delete: 207..211,
421 insert: "&mut bar",
422 detail: "&mut expr",
423 },
424 CompletionItem {
425 label: "while",
426 source_range: 211..211,
427 delete: 207..211,
428 insert: "while let Ok($1) = bar {\n $0\n}",
429 detail: "while let Ok {}",
430 },
431 ]
432 "###
433 );
434 }
435
436 #[test]
239 fn some_postfix_completions_ignored() { 437 fn some_postfix_completions_ignored() {
240 assert_debug_snapshot!( 438 assert_debug_snapshot!(
241 do_postfix_completion( 439 do_postfix_completion(