diff options
Diffstat (limited to 'crates/ra_ide/src/completion/complete_keyword.rs')
-rw-r--r-- | crates/ra_ide/src/completion/complete_keyword.rs | 562 |
1 files changed, 320 insertions, 242 deletions
diff --git a/crates/ra_ide/src/completion/complete_keyword.rs b/crates/ra_ide/src/completion/complete_keyword.rs index 3b174f916..b62064797 100644 --- a/crates/ra_ide/src/completion/complete_keyword.rs +++ b/crates/ra_ide/src/completion/complete_keyword.rs | |||
@@ -1,6 +1,7 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use ra_syntax::ast; | 3 | use ra_syntax::{ast, SyntaxKind}; |
4 | use test_utils::mark; | ||
4 | 5 | ||
5 | use crate::completion::{ | 6 | use crate::completion::{ |
6 | CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, | 7 | CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, |
@@ -34,9 +35,27 @@ pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionC | |||
34 | } | 35 | } |
35 | _ => {} | 36 | _ => {} |
36 | } | 37 | } |
38 | |||
39 | // Suggest .await syntax for types that implement Future trait | ||
40 | if let Some(receiver) = &ctx.dot_receiver { | ||
41 | if let Some(ty) = ctx.sema.type_of_expr(receiver) { | ||
42 | if ty.impls_future(ctx.db) { | ||
43 | CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await") | ||
44 | .kind(CompletionItemKind::Keyword) | ||
45 | .detail("expr.await") | ||
46 | .insert_text("await") | ||
47 | .add_to(acc); | ||
48 | } | ||
49 | }; | ||
50 | } | ||
37 | } | 51 | } |
38 | 52 | ||
39 | pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) { | 53 | pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) { |
54 | if ctx.token.kind() == SyntaxKind::COMMENT { | ||
55 | mark::hit!(no_keyword_completion_in_comments); | ||
56 | return; | ||
57 | } | ||
58 | |||
40 | let has_trait_or_impl_parent = ctx.has_impl_parent || ctx.has_trait_parent; | 59 | let has_trait_or_impl_parent = ctx.has_impl_parent || ctx.has_trait_parent; |
41 | if ctx.trait_as_prev_sibling || ctx.impl_as_prev_sibling { | 60 | if ctx.trait_as_prev_sibling || ctx.impl_as_prev_sibling { |
42 | add_keyword(ctx, acc, "where", "where "); | 61 | add_keyword(ctx, acc, "where", "where "); |
@@ -47,73 +66,67 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
47 | add_keyword(ctx, acc, "fn", "fn $0() {}") | 66 | add_keyword(ctx, acc, "fn", "fn $0() {}") |
48 | } | 67 | } |
49 | 68 | ||
50 | if (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) | 69 | if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { |
51 | || ctx.block_expr_parent | ||
52 | { | ||
53 | add_keyword(ctx, acc, "trait", "trait $0 {}"); | 70 | add_keyword(ctx, acc, "trait", "trait $0 {}"); |
54 | add_keyword(ctx, acc, "impl", "impl $0 {}"); | 71 | add_keyword(ctx, acc, "impl", "impl $0 {}"); |
55 | } | 72 | } |
56 | 73 | ||
57 | return; | 74 | return; |
58 | } | 75 | } |
59 | if ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent { | 76 | if ctx.has_item_list_or_source_file_parent || has_trait_or_impl_parent || ctx.block_expr_parent |
77 | { | ||
60 | add_keyword(ctx, acc, "fn", "fn $0() {}"); | 78 | add_keyword(ctx, acc, "fn", "fn $0() {}"); |
61 | } | 79 | } |
62 | if (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) | 80 | if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { |
63 | || ctx.block_expr_parent | ||
64 | { | ||
65 | add_keyword(ctx, acc, "use", "use "); | 81 | add_keyword(ctx, acc, "use", "use "); |
66 | add_keyword(ctx, acc, "impl", "impl $0 {}"); | 82 | add_keyword(ctx, acc, "impl", "impl $0 {}"); |
67 | add_keyword(ctx, acc, "trait", "trait $0 {}"); | 83 | add_keyword(ctx, acc, "trait", "trait $0 {}"); |
68 | } | 84 | } |
69 | 85 | ||
70 | if ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent { | 86 | if ctx.has_item_list_or_source_file_parent { |
71 | add_keyword(ctx, acc, "enum", "enum $0 {}"); | 87 | add_keyword(ctx, acc, "enum", "enum $0 {}"); |
72 | add_keyword(ctx, acc, "struct", "struct $0 {}"); | 88 | add_keyword(ctx, acc, "struct", "struct $0"); |
73 | add_keyword(ctx, acc, "union", "union $0 {}"); | 89 | add_keyword(ctx, acc, "union", "union $0 {}"); |
74 | } | 90 | } |
75 | 91 | ||
76 | if ctx.block_expr_parent || ctx.is_match_arm { | 92 | if ctx.is_expr { |
77 | add_keyword(ctx, acc, "match", "match $0 {}"); | 93 | add_keyword(ctx, acc, "match", "match $0 {}"); |
78 | add_keyword(ctx, acc, "loop", "loop {$0}"); | ||
79 | } | ||
80 | if ctx.block_expr_parent { | ||
81 | add_keyword(ctx, acc, "while", "while $0 {}"); | 94 | add_keyword(ctx, acc, "while", "while $0 {}"); |
95 | add_keyword(ctx, acc, "loop", "loop {$0}"); | ||
96 | add_keyword(ctx, acc, "if", "if "); | ||
97 | add_keyword(ctx, acc, "if let", "if let "); | ||
82 | } | 98 | } |
99 | |||
83 | if ctx.if_is_prev || ctx.block_expr_parent { | 100 | if ctx.if_is_prev || ctx.block_expr_parent { |
84 | add_keyword(ctx, acc, "let", "let "); | 101 | add_keyword(ctx, acc, "let", "let "); |
85 | } | 102 | } |
86 | if ctx.if_is_prev || ctx.block_expr_parent || ctx.is_match_arm { | 103 | |
87 | add_keyword(ctx, acc, "if", "if "); | ||
88 | add_keyword(ctx, acc, "if let", "if let "); | ||
89 | } | ||
90 | if ctx.after_if { | 104 | if ctx.after_if { |
91 | add_keyword(ctx, acc, "else", "else {$0}"); | 105 | add_keyword(ctx, acc, "else", "else {$0}"); |
92 | add_keyword(ctx, acc, "else if", "else if $0 {}"); | 106 | add_keyword(ctx, acc, "else if", "else if $0 {}"); |
93 | } | 107 | } |
94 | if (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) | 108 | if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { |
95 | || ctx.block_expr_parent | ||
96 | { | ||
97 | add_keyword(ctx, acc, "mod", "mod $0 {}"); | 109 | add_keyword(ctx, acc, "mod", "mod $0 {}"); |
98 | } | 110 | } |
99 | if ctx.bind_pat_parent || ctx.ref_pat_parent { | 111 | if ctx.bind_pat_parent || ctx.ref_pat_parent { |
100 | add_keyword(ctx, acc, "mut", "mut "); | 112 | add_keyword(ctx, acc, "mut", "mut "); |
101 | } | 113 | } |
102 | if ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent { | 114 | if ctx.has_item_list_or_source_file_parent || has_trait_or_impl_parent || ctx.block_expr_parent |
115 | { | ||
103 | add_keyword(ctx, acc, "const", "const "); | 116 | add_keyword(ctx, acc, "const", "const "); |
104 | add_keyword(ctx, acc, "type", "type "); | 117 | add_keyword(ctx, acc, "type", "type "); |
105 | } | 118 | } |
106 | if (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) | 119 | if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { |
107 | || ctx.block_expr_parent | ||
108 | { | ||
109 | add_keyword(ctx, acc, "static", "static "); | 120 | add_keyword(ctx, acc, "static", "static "); |
110 | }; | 121 | }; |
111 | if (ctx.has_item_list_or_source_file_parent && !has_trait_or_impl_parent) | 122 | if (ctx.has_item_list_or_source_file_parent) || ctx.block_expr_parent { |
112 | || ctx.block_expr_parent | ||
113 | { | ||
114 | add_keyword(ctx, acc, "extern", "extern "); | 123 | add_keyword(ctx, acc, "extern", "extern "); |
115 | } | 124 | } |
116 | if ctx.has_item_list_or_source_file_parent || ctx.block_expr_parent || ctx.is_match_arm { | 125 | if ctx.has_item_list_or_source_file_parent |
126 | || has_trait_or_impl_parent | ||
127 | || ctx.block_expr_parent | ||
128 | || ctx.is_match_arm | ||
129 | { | ||
117 | add_keyword(ctx, acc, "unsafe", "unsafe "); | 130 | add_keyword(ctx, acc, "unsafe", "unsafe "); |
118 | } | 131 | } |
119 | if ctx.in_loop_body { | 132 | if ctx.in_loop_body { |
@@ -125,7 +138,7 @@ pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte | |||
125 | add_keyword(ctx, acc, "break", "break"); | 138 | add_keyword(ctx, acc, "break", "break"); |
126 | } | 139 | } |
127 | } | 140 | } |
128 | if ctx.has_item_list_or_source_file_parent && !ctx.has_trait_parent { | 141 | if ctx.has_item_list_or_source_file_parent || ctx.has_impl_parent { |
129 | add_keyword(ctx, acc, "pub", "pub ") | 142 | add_keyword(ctx, acc, "pub", "pub ") |
130 | } | 143 | } |
131 | 144 | ||
@@ -156,7 +169,7 @@ fn add_keyword(ctx: &CompletionContext, acc: &mut Completions, kw: &str, snippet | |||
156 | 169 | ||
157 | fn complete_return( | 170 | fn complete_return( |
158 | ctx: &CompletionContext, | 171 | ctx: &CompletionContext, |
159 | fn_def: &ast::FnDef, | 172 | fn_def: &ast::Fn, |
160 | can_be_stmt: bool, | 173 | can_be_stmt: bool, |
161 | ) -> Option<CompletionItem> { | 174 | ) -> Option<CompletionItem> { |
162 | let snip = match (can_be_stmt, fn_def.ret_type().is_some()) { | 175 | let snip = match (can_be_stmt, fn_def.ret_type().is_some()) { |
@@ -170,289 +183,354 @@ fn complete_return( | |||
170 | 183 | ||
171 | #[cfg(test)] | 184 | #[cfg(test)] |
172 | mod tests { | 185 | mod tests { |
173 | use crate::completion::{test_utils::completion_list, CompletionKind}; | 186 | use expect::{expect, Expect}; |
174 | use insta::assert_snapshot; | 187 | |
188 | use crate::completion::{ | ||
189 | test_utils::{check_edit, completion_list}, | ||
190 | CompletionKind, | ||
191 | }; | ||
192 | use test_utils::mark; | ||
175 | 193 | ||
176 | fn get_keyword_completions(code: &str) -> String { | 194 | fn check(ra_fixture: &str, expect: Expect) { |
177 | completion_list(code, CompletionKind::Keyword) | 195 | let actual = completion_list(ra_fixture, CompletionKind::Keyword); |
196 | expect.assert_eq(&actual) | ||
178 | } | 197 | } |
179 | 198 | ||
180 | #[test] | 199 | #[test] |
181 | fn test_keywords_in_use_stmt() { | 200 | fn test_keywords_in_use_stmt() { |
182 | assert_snapshot!( | 201 | check( |
183 | get_keyword_completions(r"use <|>"), | 202 | r"use <|>", |
184 | @r###" | 203 | expect![[r#" |
185 | kw crate:: | 204 | kw crate:: |
186 | kw self | 205 | kw self |
187 | kw super:: | 206 | kw super:: |
188 | "### | 207 | "#]], |
189 | ); | 208 | ); |
190 | 209 | ||
191 | assert_snapshot!( | 210 | check( |
192 | get_keyword_completions(r"use a::<|>"), | 211 | r"use a::<|>", |
193 | @r###" | 212 | expect![[r#" |
194 | kw self | 213 | kw self |
195 | kw super:: | 214 | kw super:: |
196 | "### | 215 | "#]], |
197 | ); | 216 | ); |
198 | 217 | ||
199 | assert_snapshot!( | 218 | check( |
200 | get_keyword_completions(r"use a::{b, <|>}"), | 219 | r"use a::{b, <|>}", |
201 | @r###" | 220 | expect![[r#" |
202 | kw self | 221 | kw self |
203 | kw super:: | 222 | kw super:: |
204 | "### | 223 | "#]], |
205 | ); | 224 | ); |
206 | } | 225 | } |
207 | 226 | ||
208 | #[test] | 227 | #[test] |
209 | fn test_keywords_at_source_file_level() { | 228 | fn test_keywords_at_source_file_level() { |
210 | assert_snapshot!( | 229 | check( |
211 | get_keyword_completions(r"m<|>"), | 230 | r"m<|>", |
212 | @r###" | 231 | expect![[r#" |
213 | kw const | 232 | kw const |
214 | kw enum | 233 | kw enum |
215 | kw extern | 234 | kw extern |
216 | kw fn | 235 | kw fn |
217 | kw impl | 236 | kw impl |
218 | kw mod | 237 | kw mod |
219 | kw pub | 238 | kw pub |
220 | kw static | 239 | kw static |
221 | kw struct | 240 | kw struct |
222 | kw trait | 241 | kw trait |
223 | kw type | 242 | kw type |
224 | kw union | 243 | kw union |
225 | kw unsafe | 244 | kw unsafe |
226 | kw use | 245 | kw use |
227 | "### | 246 | "#]], |
228 | ); | 247 | ); |
229 | } | 248 | } |
230 | 249 | ||
231 | #[test] | 250 | #[test] |
232 | fn test_keywords_in_function() { | 251 | fn test_keywords_in_function() { |
233 | assert_snapshot!( | 252 | check( |
234 | get_keyword_completions(r"fn quux() { <|> }"), | 253 | r"fn quux() { <|> }", |
235 | @r###" | 254 | expect![[r#" |
236 | kw const | 255 | kw const |
237 | kw extern | 256 | kw extern |
238 | kw fn | 257 | kw fn |
239 | kw if | 258 | kw if |
240 | kw if let | 259 | kw if let |
241 | kw impl | 260 | kw impl |
242 | kw let | 261 | kw let |
243 | kw loop | 262 | kw loop |
244 | kw match | 263 | kw match |
245 | kw mod | 264 | kw mod |
246 | kw return | 265 | kw return |
247 | kw static | 266 | kw static |
248 | kw trait | 267 | kw trait |
249 | kw type | 268 | kw type |
250 | kw unsafe | 269 | kw unsafe |
251 | kw use | 270 | kw use |
252 | kw while | 271 | kw while |
253 | "### | 272 | "#]], |
254 | ); | 273 | ); |
255 | } | 274 | } |
256 | 275 | ||
257 | #[test] | 276 | #[test] |
258 | fn test_keywords_inside_block() { | 277 | fn test_keywords_inside_block() { |
259 | assert_snapshot!( | 278 | check( |
260 | get_keyword_completions(r"fn quux() { if true { <|> } }"), | 279 | r"fn quux() { if true { <|> } }", |
261 | @r###" | 280 | expect![[r#" |
262 | kw const | 281 | kw const |
263 | kw extern | 282 | kw extern |
264 | kw fn | 283 | kw fn |
265 | kw if | 284 | kw if |
266 | kw if let | 285 | kw if let |
267 | kw impl | 286 | kw impl |
268 | kw let | 287 | kw let |
269 | kw loop | 288 | kw loop |
270 | kw match | 289 | kw match |
271 | kw mod | 290 | kw mod |
272 | kw return | 291 | kw return |
273 | kw static | 292 | kw static |
274 | kw trait | 293 | kw trait |
275 | kw type | 294 | kw type |
276 | kw unsafe | 295 | kw unsafe |
277 | kw use | 296 | kw use |
278 | kw while | 297 | kw while |
279 | "### | 298 | "#]], |
280 | ); | 299 | ); |
281 | } | 300 | } |
282 | 301 | ||
283 | #[test] | 302 | #[test] |
284 | fn test_keywords_after_if() { | 303 | fn test_keywords_after_if() { |
285 | assert_snapshot!( | 304 | check( |
286 | get_keyword_completions( | 305 | r#"fn quux() { if true { () } <|> }"#, |
287 | r" | 306 | expect![[r#" |
288 | fn quux() { | 307 | kw const |
289 | if true { | 308 | kw else |
290 | () | 309 | kw else if |
291 | } <|> | 310 | kw extern |
292 | } | 311 | kw fn |
293 | ", | 312 | kw if |
294 | ), | 313 | kw if let |
295 | @r###" | 314 | kw impl |
296 | kw const | 315 | kw let |
297 | kw else | 316 | kw loop |
298 | kw else if | 317 | kw match |
299 | kw extern | 318 | kw mod |
300 | kw fn | 319 | kw return |
301 | kw if | 320 | kw static |
302 | kw if let | 321 | kw trait |
303 | kw impl | 322 | kw type |
304 | kw let | 323 | kw unsafe |
305 | kw loop | 324 | kw use |
306 | kw match | 325 | kw while |
307 | kw mod | 326 | "#]], |
308 | kw return | 327 | ); |
309 | kw static | 328 | check_edit( |
310 | kw trait | 329 | "else", |
311 | kw type | 330 | r#"fn quux() { if true { () } <|> }"#, |
312 | kw unsafe | 331 | r#"fn quux() { if true { () } else {$0} }"#, |
313 | kw use | ||
314 | kw while | ||
315 | "### | ||
316 | ); | 332 | ); |
317 | } | 333 | } |
318 | 334 | ||
319 | #[test] | 335 | #[test] |
320 | fn test_keywords_in_match_arm() { | 336 | fn test_keywords_in_match_arm() { |
321 | assert_snapshot!( | 337 | check( |
322 | get_keyword_completions( | 338 | r#" |
323 | r" | 339 | fn quux() -> i32 { |
324 | fn quux() -> i32 { | 340 | match () { () => <|> } |
325 | match () { | 341 | } |
326 | () => <|> | 342 | "#, |
327 | } | 343 | expect![[r#" |
328 | } | 344 | kw if |
329 | ", | 345 | kw if let |
330 | ), | 346 | kw loop |
331 | @r###" | 347 | kw match |
332 | kw if | 348 | kw return |
333 | kw if let | 349 | kw unsafe |
334 | kw loop | 350 | kw while |
335 | kw match | 351 | "#]], |
336 | kw return | ||
337 | kw unsafe | ||
338 | "### | ||
339 | ); | 352 | ); |
340 | } | 353 | } |
341 | 354 | ||
342 | #[test] | 355 | #[test] |
343 | fn test_keywords_in_trait_def() { | 356 | fn test_keywords_in_trait_def() { |
344 | assert_snapshot!( | 357 | check( |
345 | get_keyword_completions(r"trait My { <|> }"), | 358 | r"trait My { <|> }", |
346 | @r###" | 359 | expect![[r#" |
347 | kw const | 360 | kw const |
348 | kw fn | 361 | kw fn |
349 | kw type | 362 | kw type |
350 | kw unsafe | 363 | kw unsafe |
351 | "### | 364 | "#]], |
352 | ); | 365 | ); |
353 | } | 366 | } |
354 | 367 | ||
355 | #[test] | 368 | #[test] |
356 | fn test_keywords_in_impl_def() { | 369 | fn test_keywords_in_impl_def() { |
357 | assert_snapshot!( | 370 | check( |
358 | get_keyword_completions(r"impl My { <|> }"), | 371 | r"impl My { <|> }", |
359 | @r###" | 372 | expect![[r#" |
360 | kw const | 373 | kw const |
361 | kw fn | 374 | kw fn |
362 | kw pub | 375 | kw pub |
363 | kw type | 376 | kw type |
364 | kw unsafe | 377 | kw unsafe |
365 | "### | 378 | "#]], |
366 | ); | 379 | ); |
367 | } | 380 | } |
368 | 381 | ||
369 | #[test] | 382 | #[test] |
370 | fn test_keywords_in_loop() { | 383 | fn test_keywords_in_loop() { |
371 | assert_snapshot!( | 384 | check( |
372 | get_keyword_completions(r"fn my() { loop { <|> } }"), | 385 | r"fn my() { loop { <|> } }", |
373 | @r###" | 386 | expect![[r#" |
374 | kw break | 387 | kw break |
375 | kw const | 388 | kw const |
376 | kw continue | 389 | kw continue |
377 | kw extern | 390 | kw extern |
378 | kw fn | 391 | kw fn |
379 | kw if | 392 | kw if |
380 | kw if let | 393 | kw if let |
381 | kw impl | 394 | kw impl |
382 | kw let | 395 | kw let |
383 | kw loop | 396 | kw loop |
384 | kw match | 397 | kw match |
385 | kw mod | 398 | kw mod |
386 | kw return | 399 | kw return |
387 | kw static | 400 | kw static |
388 | kw trait | 401 | kw trait |
389 | kw type | 402 | kw type |
390 | kw unsafe | 403 | kw unsafe |
391 | kw use | 404 | kw use |
392 | kw while | 405 | kw while |
393 | "### | 406 | "#]], |
394 | ); | 407 | ); |
395 | } | 408 | } |
396 | 409 | ||
397 | #[test] | 410 | #[test] |
398 | fn test_keywords_after_unsafe_in_item_list() { | 411 | fn test_keywords_after_unsafe_in_item_list() { |
399 | assert_snapshot!( | 412 | check( |
400 | get_keyword_completions(r"unsafe <|>"), | 413 | r"unsafe <|>", |
401 | @r###" | 414 | expect![[r#" |
402 | kw fn | 415 | kw fn |
403 | kw impl | 416 | kw impl |
404 | kw trait | 417 | kw trait |
405 | "### | 418 | "#]], |
406 | ); | 419 | ); |
407 | } | 420 | } |
408 | 421 | ||
409 | #[test] | 422 | #[test] |
410 | fn test_keywords_after_unsafe_in_block_expr() { | 423 | fn test_keywords_after_unsafe_in_block_expr() { |
411 | assert_snapshot!( | 424 | check( |
412 | get_keyword_completions(r"fn my_fn() { unsafe <|> }"), | 425 | r"fn my_fn() { unsafe <|> }", |
413 | @r###" | 426 | expect![[r#" |
414 | kw fn | 427 | kw fn |
415 | kw impl | 428 | kw impl |
416 | kw trait | 429 | kw trait |
417 | "### | 430 | "#]], |
418 | ); | 431 | ); |
419 | } | 432 | } |
420 | 433 | ||
421 | #[test] | 434 | #[test] |
422 | fn test_mut_in_ref_and_in_fn_parameters_list() { | 435 | fn test_mut_in_ref_and_in_fn_parameters_list() { |
423 | assert_snapshot!( | 436 | check( |
424 | get_keyword_completions(r"fn my_fn(&<|>) {}"), | 437 | r"fn my_fn(&<|>) {}", |
425 | @r###" | 438 | expect![[r#" |
426 | kw mut | 439 | kw mut |
427 | "### | 440 | "#]], |
428 | ); | 441 | ); |
429 | assert_snapshot!( | 442 | check( |
430 | get_keyword_completions(r"fn my_fn(<|>) {}"), | 443 | r"fn my_fn(<|>) {}", |
431 | @r###" | 444 | expect![[r#" |
432 | kw mut | 445 | kw mut |
433 | "### | 446 | "#]], |
434 | ); | 447 | ); |
435 | assert_snapshot!( | 448 | check( |
436 | get_keyword_completions(r"fn my_fn() { let &<|> }"), | 449 | r"fn my_fn() { let &<|> }", |
437 | @r###" | 450 | expect![[r#" |
438 | kw mut | 451 | kw mut |
439 | "### | 452 | "#]], |
440 | ); | 453 | ); |
441 | } | 454 | } |
442 | 455 | ||
443 | #[test] | 456 | #[test] |
444 | fn test_where_keyword() { | 457 | fn test_where_keyword() { |
445 | assert_snapshot!( | 458 | check( |
446 | get_keyword_completions(r"trait A <|>"), | 459 | r"trait A <|>", |
447 | @r###" | 460 | expect![[r#" |
448 | kw where | 461 | kw where |
449 | "### | 462 | "#]], |
450 | ); | 463 | ); |
451 | assert_snapshot!( | 464 | check( |
452 | get_keyword_completions(r"impl A <|>"), | 465 | r"impl A <|>", |
453 | @r###" | 466 | expect![[r#" |
454 | kw where | 467 | kw where |
455 | "### | 468 | "#]], |
456 | ); | 469 | ); |
457 | } | 470 | } |
471 | |||
472 | #[test] | ||
473 | fn no_keyword_completion_in_comments() { | ||
474 | mark::check!(no_keyword_completion_in_comments); | ||
475 | check( | ||
476 | r#" | ||
477 | fn test() { | ||
478 | let x = 2; // A comment<|> | ||
479 | } | ||
480 | "#, | ||
481 | expect![[""]], | ||
482 | ); | ||
483 | check( | ||
484 | r#" | ||
485 | /* | ||
486 | Some multi-line comment<|> | ||
487 | */ | ||
488 | "#, | ||
489 | expect![[""]], | ||
490 | ); | ||
491 | check( | ||
492 | r#" | ||
493 | /// Some doc comment | ||
494 | /// let test<|> = 1 | ||
495 | "#, | ||
496 | expect![[""]], | ||
497 | ); | ||
498 | } | ||
499 | |||
500 | #[test] | ||
501 | fn test_completion_await_impls_future() { | ||
502 | check( | ||
503 | r#" | ||
504 | //- /main.rs | ||
505 | use std::future::*; | ||
506 | struct A {} | ||
507 | impl Future for A {} | ||
508 | fn foo(a: A) { a.<|> } | ||
509 | |||
510 | //- /std/lib.rs | ||
511 | pub mod future { | ||
512 | #[lang = "future_trait"] | ||
513 | pub trait Future {} | ||
514 | } | ||
515 | "#, | ||
516 | expect![[r#" | ||
517 | kw await expr.await | ||
518 | "#]], | ||
519 | ) | ||
520 | } | ||
521 | |||
522 | #[test] | ||
523 | fn after_let() { | ||
524 | check( | ||
525 | r#"fn main() { let _ = <|> }"#, | ||
526 | expect![[r#" | ||
527 | kw if | ||
528 | kw if let | ||
529 | kw loop | ||
530 | kw match | ||
531 | kw return | ||
532 | kw while | ||
533 | "#]], | ||
534 | ) | ||
535 | } | ||
458 | } | 536 | } |