diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-20 18:27:23 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-01-20 18:27:23 +0000 |
commit | f133702f723203a60a1b4dade51418261cdbc133 (patch) | |
tree | 4d6d38d2e6185bb39b08ccfd5b89cdb5740d5ef8 /crates/ra_ide_api/src/completion/complete_keyword.rs | |
parent | b89f8b6b4929ec09be4f9b13f87ad56b3235bd39 (diff) | |
parent | fd8db14c2fcec7801edbdbb8e7f4d4c982a3da09 (diff) |
Merge #574
574: refactor completions to use TextEdit instead of InsertText r=matklad a=gfreezy
1. migrate from `insertText` to `TextEdit` from `CompleteItem`
2. use `insta` to test completions
Co-authored-by: gfreezy <[email protected]>
Diffstat (limited to 'crates/ra_ide_api/src/completion/complete_keyword.rs')
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_keyword.rs | 165 |
1 files changed, 47 insertions, 118 deletions
diff --git a/crates/ra_ide_api/src/completion/complete_keyword.rs b/crates/ra_ide_api/src/completion/complete_keyword.rs index d350f06ce..10ae01bc5 100644 --- a/crates/ra_ide_api/src/completion/complete_keyword.rs +++ b/crates/ra_ide_api/src/completion/complete_keyword.rs | |||
@@ -9,38 +9,36 @@ use crate::completion::{CompletionContext, CompletionItem, Completions, Completi | |||
9 | 9 | ||
10 | pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) { | 10 | pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) { |
11 | // complete keyword "crate" in use stmt | 11 | // complete keyword "crate" in use stmt |
12 | let source_range = ctx.source_range(); | ||
12 | match (ctx.use_item_syntax.as_ref(), ctx.path_prefix.as_ref()) { | 13 | match (ctx.use_item_syntax.as_ref(), ctx.path_prefix.as_ref()) { |
13 | (Some(_), None) => { | 14 | (Some(_), None) => { |
14 | CompletionItem::new(CompletionKind::Keyword, "crate") | 15 | CompletionItem::new(CompletionKind::Keyword, source_range, "crate") |
15 | .kind(CompletionItemKind::Keyword) | 16 | .kind(CompletionItemKind::Keyword) |
16 | .lookup_by("crate") | 17 | .insert_text("crate::") |
17 | .snippet("crate::") | ||
18 | .add_to(acc); | 18 | .add_to(acc); |
19 | CompletionItem::new(CompletionKind::Keyword, "self") | 19 | CompletionItem::new(CompletionKind::Keyword, source_range, "self") |
20 | .kind(CompletionItemKind::Keyword) | 20 | .kind(CompletionItemKind::Keyword) |
21 | .lookup_by("self") | ||
22 | .add_to(acc); | 21 | .add_to(acc); |
23 | CompletionItem::new(CompletionKind::Keyword, "super") | 22 | CompletionItem::new(CompletionKind::Keyword, source_range, "super") |
24 | .kind(CompletionItemKind::Keyword) | 23 | .kind(CompletionItemKind::Keyword) |
25 | .lookup_by("super") | 24 | .insert_text("super::") |
26 | .add_to(acc); | 25 | .add_to(acc); |
27 | } | 26 | } |
28 | (Some(_), Some(_)) => { | 27 | (Some(_), Some(_)) => { |
29 | CompletionItem::new(CompletionKind::Keyword, "self") | 28 | CompletionItem::new(CompletionKind::Keyword, source_range, "self") |
30 | .kind(CompletionItemKind::Keyword) | 29 | .kind(CompletionItemKind::Keyword) |
31 | .lookup_by("self") | ||
32 | .add_to(acc); | 30 | .add_to(acc); |
33 | CompletionItem::new(CompletionKind::Keyword, "super") | 31 | CompletionItem::new(CompletionKind::Keyword, source_range, "super") |
34 | .kind(CompletionItemKind::Keyword) | 32 | .kind(CompletionItemKind::Keyword) |
35 | .lookup_by("super") | 33 | .insert_text("super::") |
36 | .add_to(acc); | 34 | .add_to(acc); |
37 | } | 35 | } |
38 | _ => {} | 36 | _ => {} |
39 | } | 37 | } |
40 | } | 38 | } |
41 | 39 | ||
42 | fn keyword(kw: &str, snippet: &str) -> CompletionItem { | 40 | fn keyword(ctx: &CompletionContext, kw: &str, snippet: &str) -> CompletionItem { |
43 | CompletionItem::new(CompletionKind::Keyword, kw) | 41 | CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), kw) |
44 | .kind(CompletionItemKind::Keyword) | 42 | .kind(CompletionItemKind::Keyword) |
45 | .snippet(snippet) | 43 | .snippet(snippet) |
46 | .build() | 44 | .build() |
@@ -55,25 +53,25 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
55 | Some(it) => it, | 53 | Some(it) => it, |
56 | None => return, | 54 | None => return, |
57 | }; | 55 | }; |
58 | acc.add(keyword("if", "if $0 {}")); | 56 | acc.add(keyword(ctx, "if", "if $0 {}")); |
59 | acc.add(keyword("match", "match $0 {}")); | 57 | acc.add(keyword(ctx, "match", "match $0 {}")); |
60 | acc.add(keyword("while", "while $0 {}")); | 58 | acc.add(keyword(ctx, "while", "while $0 {}")); |
61 | acc.add(keyword("loop", "loop {$0}")); | 59 | acc.add(keyword(ctx, "loop", "loop {$0}")); |
62 | 60 | ||
63 | if ctx.after_if { | 61 | if ctx.after_if { |
64 | acc.add(keyword("else", "else {$0}")); | 62 | acc.add(keyword(ctx, "else", "else {$0}")); |
65 | acc.add(keyword("else if", "else if $0 {}")); | 63 | acc.add(keyword(ctx, "else if", "else if $0 {}")); |
66 | } | 64 | } |
67 | if is_in_loop_body(ctx.leaf) { | 65 | if is_in_loop_body(ctx.leaf) { |
68 | if ctx.can_be_stmt { | 66 | if ctx.can_be_stmt { |
69 | acc.add(keyword("continue", "continue;")); | 67 | acc.add(keyword(ctx, "continue", "continue;")); |
70 | acc.add(keyword("break", "break;")); | 68 | acc.add(keyword(ctx, "break", "break;")); |
71 | } else { | 69 | } else { |
72 | acc.add(keyword("continue", "continue")); | 70 | acc.add(keyword(ctx, "continue", "continue")); |
73 | acc.add(keyword("break", "break")); | 71 | acc.add(keyword(ctx, "break", "break")); |
74 | } | 72 | } |
75 | } | 73 | } |
76 | acc.add_all(complete_return(fn_def, ctx.can_be_stmt)); | 74 | acc.add_all(complete_return(ctx, fn_def, ctx.can_be_stmt)); |
77 | } | 75 | } |
78 | 76 | ||
79 | fn is_in_loop_body(leaf: &SyntaxNode) -> bool { | 77 | fn is_in_loop_body(leaf: &SyntaxNode) -> bool { |
@@ -95,78 +93,69 @@ fn is_in_loop_body(leaf: &SyntaxNode) -> bool { | |||
95 | false | 93 | false |
96 | } | 94 | } |
97 | 95 | ||
98 | fn complete_return(fn_def: &ast::FnDef, can_be_stmt: bool) -> Option<CompletionItem> { | 96 | fn complete_return( |
97 | ctx: &CompletionContext, | ||
98 | fn_def: &ast::FnDef, | ||
99 | can_be_stmt: bool, | ||
100 | ) -> Option<CompletionItem> { | ||
99 | let snip = match (can_be_stmt, fn_def.ret_type().is_some()) { | 101 | let snip = match (can_be_stmt, fn_def.ret_type().is_some()) { |
100 | (true, true) => "return $0;", | 102 | (true, true) => "return $0;", |
101 | (true, false) => "return;", | 103 | (true, false) => "return;", |
102 | (false, true) => "return $0", | 104 | (false, true) => "return $0", |
103 | (false, false) => "return", | 105 | (false, false) => "return", |
104 | }; | 106 | }; |
105 | Some(keyword("return", snip)) | 107 | Some(keyword(ctx, "return", snip)) |
106 | } | 108 | } |
107 | 109 | ||
108 | #[cfg(test)] | 110 | #[cfg(test)] |
109 | mod tests { | 111 | mod tests { |
110 | use crate::completion::{CompletionKind, check_completion}; | 112 | use crate::completion::CompletionKind; |
111 | fn check_keyword_completion(code: &str, expected_completions: &str) { | 113 | use crate::completion::completion_item::check_completion; |
112 | check_completion(code, expected_completions, CompletionKind::Keyword); | 114 | |
115 | fn check_keyword_completion(name: &str, code: &str) { | ||
116 | check_completion(name, code, CompletionKind::Keyword); | ||
113 | } | 117 | } |
114 | 118 | ||
115 | #[test] | 119 | #[test] |
116 | fn completes_keywords_in_use_stmt() { | 120 | fn completes_keywords_in_use_stmt() { |
117 | check_keyword_completion( | 121 | check_keyword_completion( |
122 | "keywords_in_use_stmt1", | ||
118 | r" | 123 | r" |
119 | use <|> | 124 | use <|> |
120 | ", | 125 | ", |
121 | r#" | ||
122 | crate "crate" "crate::" | ||
123 | self "self" | ||
124 | super "super" | ||
125 | "#, | ||
126 | ); | 126 | ); |
127 | 127 | ||
128 | check_keyword_completion( | 128 | check_keyword_completion( |
129 | "keywords_in_use_stmt2", | ||
129 | r" | 130 | r" |
130 | use a::<|> | 131 | use a::<|> |
131 | ", | 132 | ", |
132 | r#" | ||
133 | self "self" | ||
134 | super "super" | ||
135 | "#, | ||
136 | ); | 133 | ); |
137 | 134 | ||
138 | check_keyword_completion( | 135 | check_keyword_completion( |
136 | "keywords_in_use_stmt3", | ||
139 | r" | 137 | r" |
140 | use a::{b, <|>} | 138 | use a::{b, <|>} |
141 | ", | 139 | ", |
142 | r#" | ||
143 | self "self" | ||
144 | super "super" | ||
145 | "#, | ||
146 | ); | 140 | ); |
147 | } | 141 | } |
148 | 142 | ||
149 | #[test] | 143 | #[test] |
150 | fn completes_various_keywords_in_function() { | 144 | fn completes_various_keywords_in_function() { |
151 | check_keyword_completion( | 145 | check_keyword_completion( |
146 | "keywords_in_function1", | ||
152 | r" | 147 | r" |
153 | fn quux() { | 148 | fn quux() { |
154 | <|> | 149 | <|> |
155 | } | 150 | } |
156 | ", | 151 | ", |
157 | r#" | ||
158 | if "if $0 {}" | ||
159 | match "match $0 {}" | ||
160 | while "while $0 {}" | ||
161 | loop "loop {$0}" | ||
162 | return "return;" | ||
163 | "#, | ||
164 | ); | 152 | ); |
165 | } | 153 | } |
166 | 154 | ||
167 | #[test] | 155 | #[test] |
168 | fn completes_else_after_if() { | 156 | fn completes_else_after_if() { |
169 | check_keyword_completion( | 157 | check_keyword_completion( |
158 | "keywords_in_function2", | ||
170 | r" | 159 | r" |
171 | fn quux() { | 160 | fn quux() { |
172 | if true { | 161 | if true { |
@@ -174,55 +163,35 @@ mod tests { | |||
174 | } <|> | 163 | } <|> |
175 | } | 164 | } |
176 | ", | 165 | ", |
177 | r#" | ||
178 | if "if $0 {}" | ||
179 | match "match $0 {}" | ||
180 | while "while $0 {}" | ||
181 | loop "loop {$0}" | ||
182 | else "else {$0}" | ||
183 | else if "else if $0 {}" | ||
184 | return "return;" | ||
185 | "#, | ||
186 | ); | 166 | ); |
187 | } | 167 | } |
188 | 168 | ||
189 | #[test] | 169 | #[test] |
190 | fn test_completion_return_value() { | 170 | fn test_completion_return_value() { |
191 | check_keyword_completion( | 171 | check_keyword_completion( |
172 | "keywords_in_function3", | ||
192 | r" | 173 | r" |
193 | fn quux() -> i32 { | 174 | fn quux() -> i32 { |
194 | <|> | 175 | <|> |
195 | 92 | 176 | 92 |
196 | } | 177 | } |
197 | ", | 178 | ", |
198 | r#" | ||
199 | if "if $0 {}" | ||
200 | match "match $0 {}" | ||
201 | while "while $0 {}" | ||
202 | loop "loop {$0}" | ||
203 | return "return $0;" | ||
204 | "#, | ||
205 | ); | 179 | ); |
206 | check_keyword_completion( | 180 | check_keyword_completion( |
181 | "keywords_in_function4", | ||
207 | r" | 182 | r" |
208 | fn quux() { | 183 | fn quux() { |
209 | <|> | 184 | <|> |
210 | 92 | 185 | 92 |
211 | } | 186 | } |
212 | ", | 187 | ", |
213 | r#" | ||
214 | if "if $0 {}" | ||
215 | match "match $0 {}" | ||
216 | while "while $0 {}" | ||
217 | loop "loop {$0}" | ||
218 | return "return;" | ||
219 | "#, | ||
220 | ); | 188 | ); |
221 | } | 189 | } |
222 | 190 | ||
223 | #[test] | 191 | #[test] |
224 | fn dont_add_semi_after_return_if_not_a_statement() { | 192 | fn dont_add_semi_after_return_if_not_a_statement() { |
225 | check_keyword_completion( | 193 | check_keyword_completion( |
194 | "dont_add_semi_after_return_if_not_a_statement", | ||
226 | r" | 195 | r" |
227 | fn quux() -> i32 { | 196 | fn quux() -> i32 { |
228 | match () { | 197 | match () { |
@@ -230,19 +199,13 @@ mod tests { | |||
230 | } | 199 | } |
231 | } | 200 | } |
232 | ", | 201 | ", |
233 | r#" | ||
234 | if "if $0 {}" | ||
235 | match "match $0 {}" | ||
236 | while "while $0 {}" | ||
237 | loop "loop {$0}" | ||
238 | return "return $0" | ||
239 | "#, | ||
240 | ); | 202 | ); |
241 | } | 203 | } |
242 | 204 | ||
243 | #[test] | 205 | #[test] |
244 | fn last_return_in_block_has_semi() { | 206 | fn last_return_in_block_has_semi() { |
245 | check_keyword_completion( | 207 | check_keyword_completion( |
208 | "last_return_in_block_has_semi1", | ||
246 | r" | 209 | r" |
247 | fn quux() -> i32 { | 210 | fn quux() -> i32 { |
248 | if condition { | 211 | if condition { |
@@ -250,15 +213,9 @@ mod tests { | |||
250 | } | 213 | } |
251 | } | 214 | } |
252 | ", | 215 | ", |
253 | r#" | ||
254 | if "if $0 {}" | ||
255 | match "match $0 {}" | ||
256 | while "while $0 {}" | ||
257 | loop "loop {$0}" | ||
258 | return "return $0;" | ||
259 | "#, | ||
260 | ); | 216 | ); |
261 | check_keyword_completion( | 217 | check_keyword_completion( |
218 | "last_return_in_block_has_semi2", | ||
262 | r" | 219 | r" |
263 | fn quux() -> i32 { | 220 | fn quux() -> i32 { |
264 | if condition { | 221 | if condition { |
@@ -268,54 +225,35 @@ mod tests { | |||
268 | x | 225 | x |
269 | } | 226 | } |
270 | ", | 227 | ", |
271 | r#" | ||
272 | if "if $0 {}" | ||
273 | match "match $0 {}" | ||
274 | while "while $0 {}" | ||
275 | loop "loop {$0}" | ||
276 | return "return $0;" | ||
277 | "#, | ||
278 | ); | 228 | ); |
279 | } | 229 | } |
280 | 230 | ||
281 | #[test] | 231 | #[test] |
282 | fn completes_break_and_continue_in_loops() { | 232 | fn completes_break_and_continue_in_loops() { |
283 | check_keyword_completion( | 233 | check_keyword_completion( |
234 | "completes_break_and_continue_in_loops1", | ||
284 | r" | 235 | r" |
285 | fn quux() -> i32 { | 236 | fn quux() -> i32 { |
286 | loop { <|> } | 237 | loop { <|> } |
287 | } | 238 | } |
288 | ", | 239 | ", |
289 | r#" | ||
290 | if "if $0 {}" | ||
291 | match "match $0 {}" | ||
292 | while "while $0 {}" | ||
293 | loop "loop {$0}" | ||
294 | continue "continue;" | ||
295 | break "break;" | ||
296 | return "return $0;" | ||
297 | "#, | ||
298 | ); | 240 | ); |
241 | |||
299 | // No completion: lambda isolates control flow | 242 | // No completion: lambda isolates control flow |
300 | check_keyword_completion( | 243 | check_keyword_completion( |
244 | "completes_break_and_continue_in_loops2", | ||
301 | r" | 245 | r" |
302 | fn quux() -> i32 { | 246 | fn quux() -> i32 { |
303 | loop { || { <|> } } | 247 | loop { || { <|> } } |
304 | } | 248 | } |
305 | ", | 249 | ", |
306 | r#" | ||
307 | if "if $0 {}" | ||
308 | match "match $0 {}" | ||
309 | while "while $0 {}" | ||
310 | loop "loop {$0}" | ||
311 | return "return $0;" | ||
312 | "#, | ||
313 | ); | 250 | ); |
314 | } | 251 | } |
315 | 252 | ||
316 | #[test] | 253 | #[test] |
317 | fn no_semi_after_break_continue_in_expr() { | 254 | fn no_semi_after_break_continue_in_expr() { |
318 | check_keyword_completion( | 255 | check_keyword_completion( |
256 | "no_semi_after_break_continue_in_expr", | ||
319 | r" | 257 | r" |
320 | fn f() { | 258 | fn f() { |
321 | loop { | 259 | loop { |
@@ -325,15 +263,6 @@ mod tests { | |||
325 | } | 263 | } |
326 | } | 264 | } |
327 | ", | 265 | ", |
328 | r#" | ||
329 | if "if $0 {}" | ||
330 | match "match $0 {}" | ||
331 | while "while $0 {}" | ||
332 | loop "loop {$0}" | ||
333 | continue "continue" | ||
334 | break "break" | ||
335 | return "return" | ||
336 | "#, | ||
337 | ) | 266 | ) |
338 | } | 267 | } |
339 | } | 268 | } |