From d1608538de6fe8724b24c4f4988ea8a9d3ca93bd Mon Sep 17 00:00:00 2001 From: Marco Groppo Date: Tue, 16 Jul 2019 15:06:15 +0200 Subject: Restrict some postfix completions to bool and unknown expr. Restrict `if` and `while` postfix completions to boolean expressions and expressions of an unknown type. --- .../ra_ide_api/src/completion/complete_postfix.rs | 129 ++++++++++++++++----- 1 file changed, 103 insertions(+), 26 deletions(-) diff --git a/crates/ra_ide_api/src/completion/complete_postfix.rs b/crates/ra_ide_api/src/completion/complete_postfix.rs index a25e517f5..4f5062214 100644 --- a/crates/ra_ide_api/src/completion/complete_postfix.rs +++ b/crates/ra_ide_api/src/completion/complete_postfix.rs @@ -5,6 +5,7 @@ use crate::{ }, CompletionItem, }; +use hir::{Ty, TypeCtor}; use ra_syntax::{ast::AstNode, TextRange}; use ra_text_edit::TextEditBuilder; @@ -21,14 +22,39 @@ fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet: .snippet_edit(edit) } +fn is_bool_or_unknown(ty: Option) -> bool { + if let Some(ty) = ty { + match ty { + Ty::Apply(at) => match at.ctor { + TypeCtor::Bool => true, + _ => false, + }, + Ty::Unknown => true, + _ => false, + } + } else { + true + } +} + pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { if let Some(dot_receiver) = ctx.dot_receiver { let receiver_text = dot_receiver.syntax().text().to_string(); + let receiver_ty = ctx.analyzer.type_of(ctx.db, dot_receiver); + if is_bool_or_unknown(receiver_ty) { + postfix_snippet(ctx, "if", "if expr {}", &format!("if {} {{$0}}", receiver_text)) + .add_to(acc); + postfix_snippet( + ctx, + "while", + "while expr {}", + &format!("while {} {{\n$0\n}}", receiver_text), + ) + .add_to(acc); + } postfix_snippet(ctx, "not", "!expr", &format!("!{}", receiver_text)).add_to(acc); postfix_snippet(ctx, "ref", "&expr", &format!("&{}", receiver_text)).add_to(acc); postfix_snippet(ctx, "refm", "&mut expr", &format!("&mut {}", receiver_text)).add_to(acc); - postfix_snippet(ctx, "if", "if expr {}", &format!("if {} {{$0}}", receiver_text)) - .add_to(acc); postfix_snippet( ctx, "match", @@ -36,13 +62,6 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { &format!("match {} {{\n ${{1:_}} => {{$0\\}},\n}}", receiver_text), ) .add_to(acc); - postfix_snippet( - ctx, - "while", - "while expr {}", - &format!("while {} {{\n$0\n}}", receiver_text), - ) - .add_to(acc); postfix_snippet(ctx, "dbg", "dbg!(expr)", &format!("dbg!({})", receiver_text)).add_to(acc); postfix_snippet(ctx, "box", "Box::new(expr)", &format!("Box::new({})", receiver_text)) .add_to(acc); @@ -64,7 +83,7 @@ mod tests { do_postfix_completion( r#" fn main() { - let bar = "a"; + let bar = true; bar.<|> } "#, @@ -72,60 +91,118 @@ mod tests { @r###"[ CompletionItem { label: "box", - source_range: [88; 88), - delete: [84; 88), + source_range: [89; 89), + delete: [85; 89), insert: "Box::new(bar)", detail: "Box::new(expr)", }, CompletionItem { label: "dbg", - source_range: [88; 88), - delete: [84; 88), + source_range: [89; 89), + delete: [85; 89), insert: "dbg!(bar)", detail: "dbg!(expr)", }, CompletionItem { label: "if", - source_range: [88; 88), - delete: [84; 88), + source_range: [89; 89), + delete: [85; 89), insert: "if bar {$0}", detail: "if expr {}", }, CompletionItem { label: "match", - source_range: [88; 88), - delete: [84; 88), + source_range: [89; 89), + delete: [85; 89), insert: "match bar {\n ${1:_} => {$0\\},\n}", detail: "match expr {}", }, CompletionItem { label: "not", - source_range: [88; 88), - delete: [84; 88), + source_range: [89; 89), + delete: [85; 89), insert: "!bar", detail: "!expr", }, CompletionItem { label: "ref", - source_range: [88; 88), - delete: [84; 88), + source_range: [89; 89), + delete: [85; 89), insert: "&bar", detail: "&expr", }, CompletionItem { label: "refm", - source_range: [88; 88), - delete: [84; 88), + source_range: [89; 89), + delete: [85; 89), insert: "&mut bar", detail: "&mut expr", }, CompletionItem { label: "while", - source_range: [88; 88), - delete: [84; 88), + source_range: [89; 89), + delete: [85; 89), insert: "while bar {\n$0\n}", detail: "while expr {}", }, +]"### + ); + } + + #[test] + fn some_postfix_completions_ignored() { + assert_debug_snapshot_matches!( + do_postfix_completion( + r#" + fn main() { + let bar: u8 = 12; + bar.<|> + } + "#, + ), + @r###"[ + CompletionItem { + label: "box", + source_range: [91; 91), + delete: [87; 91), + insert: "Box::new(bar)", + detail: "Box::new(expr)", + }, + CompletionItem { + label: "dbg", + source_range: [91; 91), + delete: [87; 91), + insert: "dbg!(bar)", + detail: "dbg!(expr)", + }, + CompletionItem { + label: "match", + source_range: [91; 91), + delete: [87; 91), + insert: "match bar {\n ${1:_} => {$0\\},\n}", + detail: "match expr {}", + }, + CompletionItem { + label: "not", + source_range: [91; 91), + delete: [87; 91), + insert: "!bar", + detail: "!expr", + }, + CompletionItem { + label: "ref", + source_range: [91; 91), + delete: [87; 91), + insert: "&bar", + detail: "&expr", + }, + CompletionItem { + label: "refm", + source_range: [91; 91), + delete: [87; 91), + insert: "&mut bar", + detail: "&mut expr", + }, ]"### ); } -- cgit v1.2.3