aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-07-18 17:30:19 +0100
committerbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-07-18 17:30:19 +0100
commit8a6d270ecc26b59ad7ab0a207a963dc14f7bf81b (patch)
treebad977e2b6e111efb74496f6c0ced2f695a66c15 /crates/ra_ide_api/src
parent7b2ab597bd2d500a68e08d0546d8f72f6a013248 (diff)
parentd1608538de6fe8724b24c4f4988ea8a9d3ca93bd (diff)
Merge #1537
1537: Less magic completions r=matklad a=marcogroppo Restrict `if`, `not` and `while` postfix magic completions to boolean expressions and expressions of an unknown type. (this may be controversial, marking as draft for this reason) See the discussion in #1526. Co-authored-by: Marco Groppo <[email protected]>
Diffstat (limited to 'crates/ra_ide_api/src')
-rw-r--r--crates/ra_ide_api/src/completion/complete_postfix.rs129
1 files 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::{
5 }, 5 },
6 CompletionItem, 6 CompletionItem,
7}; 7};
8use hir::{Ty, TypeCtor};
8use ra_syntax::{ast::AstNode, TextRange}; 9use ra_syntax::{ast::AstNode, TextRange};
9use ra_text_edit::TextEditBuilder; 10use ra_text_edit::TextEditBuilder;
10 11
@@ -21,14 +22,39 @@ fn postfix_snippet(ctx: &CompletionContext, label: &str, detail: &str, snippet:
21 .snippet_edit(edit) 22 .snippet_edit(edit)
22} 23}
23 24
25fn is_bool_or_unknown(ty: Option<Ty>) -> bool {
26 if let Some(ty) = ty {
27 match ty {
28 Ty::Apply(at) => match at.ctor {
29 TypeCtor::Bool => true,
30 _ => false,
31 },
32 Ty::Unknown => true,
33 _ => false,
34 }
35 } else {
36 true
37 }
38}
39
24pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { 40pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
25 if let Some(dot_receiver) = ctx.dot_receiver { 41 if let Some(dot_receiver) = ctx.dot_receiver {
26 let receiver_text = dot_receiver.syntax().text().to_string(); 42 let receiver_text = dot_receiver.syntax().text().to_string();
43 let receiver_ty = ctx.analyzer.type_of(ctx.db, dot_receiver);
44 if is_bool_or_unknown(receiver_ty) {
45 postfix_snippet(ctx, "if", "if expr {}", &format!("if {} {{$0}}", receiver_text))
46 .add_to(acc);
47 postfix_snippet(
48 ctx,
49 "while",
50 "while expr {}",
51 &format!("while {} {{\n$0\n}}", receiver_text),
52 )
53 .add_to(acc);
54 }
27 postfix_snippet(ctx, "not", "!expr", &format!("!{}", receiver_text)).add_to(acc); 55 postfix_snippet(ctx, "not", "!expr", &format!("!{}", receiver_text)).add_to(acc);
28 postfix_snippet(ctx, "ref", "&expr", &format!("&{}", receiver_text)).add_to(acc); 56 postfix_snippet(ctx, "ref", "&expr", &format!("&{}", receiver_text)).add_to(acc);
29 postfix_snippet(ctx, "refm", "&mut expr", &format!("&mut {}", receiver_text)).add_to(acc); 57 postfix_snippet(ctx, "refm", "&mut expr", &format!("&mut {}", receiver_text)).add_to(acc);
30 postfix_snippet(ctx, "if", "if expr {}", &format!("if {} {{$0}}", receiver_text))
31 .add_to(acc);
32 postfix_snippet( 58 postfix_snippet(
33 ctx, 59 ctx,
34 "match", 60 "match",
@@ -36,13 +62,6 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
36 &format!("match {} {{\n ${{1:_}} => {{$0\\}},\n}}", receiver_text), 62 &format!("match {} {{\n ${{1:_}} => {{$0\\}},\n}}", receiver_text),
37 ) 63 )
38 .add_to(acc); 64 .add_to(acc);
39 postfix_snippet(
40 ctx,
41 "while",
42 "while expr {}",
43 &format!("while {} {{\n$0\n}}", receiver_text),
44 )
45 .add_to(acc);
46 postfix_snippet(ctx, "dbg", "dbg!(expr)", &format!("dbg!({})", receiver_text)).add_to(acc); 65 postfix_snippet(ctx, "dbg", "dbg!(expr)", &format!("dbg!({})", receiver_text)).add_to(acc);
47 postfix_snippet(ctx, "box", "Box::new(expr)", &format!("Box::new({})", receiver_text)) 66 postfix_snippet(ctx, "box", "Box::new(expr)", &format!("Box::new({})", receiver_text))
48 .add_to(acc); 67 .add_to(acc);
@@ -64,7 +83,7 @@ mod tests {
64 do_postfix_completion( 83 do_postfix_completion(
65 r#" 84 r#"
66 fn main() { 85 fn main() {
67 let bar = "a"; 86 let bar = true;
68 bar.<|> 87 bar.<|>
69 } 88 }
70 "#, 89 "#,
@@ -72,61 +91,119 @@ mod tests {
72 @r###"[ 91 @r###"[
73 CompletionItem { 92 CompletionItem {
74 label: "box", 93 label: "box",
75 source_range: [88; 88), 94 source_range: [89; 89),
76 delete: [84; 88), 95 delete: [85; 89),
77 insert: "Box::new(bar)", 96 insert: "Box::new(bar)",
78 detail: "Box::new(expr)", 97 detail: "Box::new(expr)",
79 }, 98 },
80 CompletionItem { 99 CompletionItem {
81 label: "dbg", 100 label: "dbg",
82 source_range: [88; 88), 101 source_range: [89; 89),
83 delete: [84; 88), 102 delete: [85; 89),
84 insert: "dbg!(bar)", 103 insert: "dbg!(bar)",
85 detail: "dbg!(expr)", 104 detail: "dbg!(expr)",
86 }, 105 },
87 CompletionItem { 106 CompletionItem {
88 label: "if", 107 label: "if",
89 source_range: [88; 88), 108 source_range: [89; 89),
90 delete: [84; 88), 109 delete: [85; 89),
91 insert: "if bar {$0}", 110 insert: "if bar {$0}",
92 detail: "if expr {}", 111 detail: "if expr {}",
93 }, 112 },
94 CompletionItem { 113 CompletionItem {
95 label: "match", 114 label: "match",
96 source_range: [88; 88), 115 source_range: [89; 89),
97 delete: [84; 88), 116 delete: [85; 89),
98 insert: "match bar {\n ${1:_} => {$0\\},\n}", 117 insert: "match bar {\n ${1:_} => {$0\\},\n}",
99 detail: "match expr {}", 118 detail: "match expr {}",
100 }, 119 },
101 CompletionItem { 120 CompletionItem {
102 label: "not", 121 label: "not",
103 source_range: [88; 88), 122 source_range: [89; 89),
104 delete: [84; 88), 123 delete: [85; 89),
105 insert: "!bar", 124 insert: "!bar",
106 detail: "!expr", 125 detail: "!expr",
107 }, 126 },
108 CompletionItem { 127 CompletionItem {
109 label: "ref", 128 label: "ref",
110 source_range: [88; 88), 129 source_range: [89; 89),
111 delete: [84; 88), 130 delete: [85; 89),
112 insert: "&bar", 131 insert: "&bar",
113 detail: "&expr", 132 detail: "&expr",
114 }, 133 },
115 CompletionItem { 134 CompletionItem {
116 label: "refm", 135 label: "refm",
117 source_range: [88; 88), 136 source_range: [89; 89),
118 delete: [84; 88), 137 delete: [85; 89),
119 insert: "&mut bar", 138 insert: "&mut bar",
120 detail: "&mut expr", 139 detail: "&mut expr",
121 }, 140 },
122 CompletionItem { 141 CompletionItem {
123 label: "while", 142 label: "while",
124 source_range: [88; 88), 143 source_range: [89; 89),
125 delete: [84; 88), 144 delete: [85; 89),
126 insert: "while bar {\n$0\n}", 145 insert: "while bar {\n$0\n}",
127 detail: "while expr {}", 146 detail: "while expr {}",
128 }, 147 },
129]"### 148]"###
130 ); 149 );
131 } 150 }
151
152 #[test]
153 fn some_postfix_completions_ignored() {
154 assert_debug_snapshot_matches!(
155 do_postfix_completion(
156 r#"
157 fn main() {
158 let bar: u8 = 12;
159 bar.<|>
160 }
161 "#,
162 ),
163 @r###"[
164 CompletionItem {
165 label: "box",
166 source_range: [91; 91),
167 delete: [87; 91),
168 insert: "Box::new(bar)",
169 detail: "Box::new(expr)",
170 },
171 CompletionItem {
172 label: "dbg",
173 source_range: [91; 91),
174 delete: [87; 91),
175 insert: "dbg!(bar)",
176 detail: "dbg!(expr)",
177 },
178 CompletionItem {
179 label: "match",
180 source_range: [91; 91),
181 delete: [87; 91),
182 insert: "match bar {\n ${1:_} => {$0\\},\n}",
183 detail: "match expr {}",
184 },
185 CompletionItem {
186 label: "not",
187 source_range: [91; 91),
188 delete: [87; 91),
189 insert: "!bar",
190 detail: "!expr",
191 },
192 CompletionItem {
193 label: "ref",
194 source_range: [91; 91),
195 delete: [87; 91),
196 insert: "&bar",
197 detail: "&expr",
198 },
199 CompletionItem {
200 label: "refm",
201 source_range: [91; 91),
202 delete: [87; 91),
203 insert: "&mut bar",
204 detail: "&mut expr",
205 },
206]"###
207 );
208 }
132} 209}