diff options
author | Aleksey Kladov <[email protected]> | 2018-12-21 15:13:21 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-12-21 15:13:21 +0000 |
commit | 45232dfa689bafadf98b92ef30fd32ea9a5e9e7a (patch) | |
tree | 4652bd1f393540f2f5abdaaab367cfb0b46a10d6 /crates/ra_analysis/src/completion/reference_completion.rs | |
parent | d4ef07b2355df891d4f9b7641f0246ebe5bd6a6b (diff) |
organize completion tests better
Diffstat (limited to 'crates/ra_analysis/src/completion/reference_completion.rs')
-rw-r--r-- | crates/ra_analysis/src/completion/reference_completion.rs | 376 |
1 files changed, 368 insertions, 8 deletions
diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs index c578e9e8b..c2a650b6d 100644 --- a/crates/ra_analysis/src/completion/reference_completion.rs +++ b/crates/ra_analysis/src/completion/reference_completion.rs | |||
@@ -13,7 +13,7 @@ use hir::{ | |||
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | db::RootDatabase, | 15 | db::RootDatabase, |
16 | completion::{CompletionItem, Completions}, | 16 | completion::{CompletionItem, Completions, CompletionKind::*}, |
17 | Cancelable | 17 | Cancelable |
18 | }; | 18 | }; |
19 | 19 | ||
@@ -51,7 +51,11 @@ pub(super) fn completions( | |||
51 | } | 51 | } |
52 | } | 52 | } |
53 | }) | 53 | }) |
54 | .for_each(|(name, _res)| CompletionItem::new(name.to_string()).add_to(acc)); | 54 | .for_each(|(name, _res)| { |
55 | CompletionItem::new(name.to_string()) | ||
56 | .kind(Reference) | ||
57 | .add_to(acc) | ||
58 | }); | ||
55 | } | 59 | } |
56 | NameRefKind::Path(path) => complete_path(acc, db, module, path)?, | 60 | NameRefKind::Path(path) => complete_path(acc, db, module, path)?, |
57 | NameRefKind::BareIdentInMod => { | 61 | NameRefKind::BareIdentInMod => { |
@@ -123,9 +127,13 @@ fn complete_fn(name_ref: ast::NameRef, scopes: &FnScopes, acc: &mut Completions) | |||
123 | .scope_chain(name_ref.syntax()) | 127 | .scope_chain(name_ref.syntax()) |
124 | .flat_map(|scope| scopes.entries(scope).iter()) | 128 | .flat_map(|scope| scopes.entries(scope).iter()) |
125 | .filter(|entry| shadowed.insert(entry.name())) | 129 | .filter(|entry| shadowed.insert(entry.name())) |
126 | .for_each(|entry| CompletionItem::new(entry.name().to_string()).add_to(acc)); | 130 | .for_each(|entry| { |
131 | CompletionItem::new(entry.name().to_string()) | ||
132 | .kind(Reference) | ||
133 | .add_to(acc) | ||
134 | }); | ||
127 | if scopes.self_param.is_some() { | 135 | if scopes.self_param.is_some() { |
128 | CompletionItem::new("self").add_to(acc); | 136 | CompletionItem::new("self").kind(Reference).add_to(acc); |
129 | } | 137 | } |
130 | } | 138 | } |
131 | 139 | ||
@@ -148,9 +156,11 @@ fn complete_path( | |||
148 | _ => return Ok(()), | 156 | _ => return Ok(()), |
149 | }; | 157 | }; |
150 | let module_scope = target_module.scope(db)?; | 158 | let module_scope = target_module.scope(db)?; |
151 | module_scope | 159 | module_scope.entries().for_each(|(name, _res)| { |
152 | .entries() | 160 | CompletionItem::new(name.to_string()) |
153 | .for_each(|(name, _res)| CompletionItem::new(name.to_string()).add_to(acc)); | 161 | .kind(Reference) |
162 | .add_to(acc) | ||
163 | }); | ||
154 | Ok(()) | 164 | Ok(()) |
155 | } | 165 | } |
156 | 166 | ||
@@ -164,9 +174,11 @@ fn ${1:feature}() { | |||
164 | $0 | 174 | $0 |
165 | }", | 175 | }", |
166 | ) | 176 | ) |
177 | .kind(Snippet) | ||
167 | .add_to(acc); | 178 | .add_to(acc); |
168 | CompletionItem::new("pub(crate)") | 179 | CompletionItem::new("pub(crate)") |
169 | .snippet("pub(crate) $0") | 180 | .snippet("pub(crate) $0") |
181 | .kind(Snippet) | ||
170 | .add_to(acc); | 182 | .add_to(acc); |
171 | } | 183 | } |
172 | 184 | ||
@@ -249,14 +261,362 @@ fn complete_return(fn_def: ast::FnDef, name_ref: ast::NameRef) -> Option<Complet | |||
249 | } | 261 | } |
250 | 262 | ||
251 | fn keyword(kw: &str, snippet: &str) -> CompletionItem { | 263 | fn keyword(kw: &str, snippet: &str) -> CompletionItem { |
252 | CompletionItem::new(kw).snippet(snippet).build() | 264 | CompletionItem::new(kw) |
265 | .kind(Keyword) | ||
266 | .snippet(snippet) | ||
267 | .build() | ||
253 | } | 268 | } |
254 | 269 | ||
255 | fn complete_expr_snippets(acc: &mut Completions) { | 270 | fn complete_expr_snippets(acc: &mut Completions) { |
256 | CompletionItem::new("pd") | 271 | CompletionItem::new("pd") |
257 | .snippet("eprintln!(\"$0 = {:?}\", $0);") | 272 | .snippet("eprintln!(\"$0 = {:?}\", $0);") |
273 | .kind(Snippet) | ||
258 | .add_to(acc); | 274 | .add_to(acc); |
259 | CompletionItem::new("ppd") | 275 | CompletionItem::new("ppd") |
260 | .snippet("eprintln!(\"$0 = {:#?}\", $0);") | 276 | .snippet("eprintln!(\"$0 = {:#?}\", $0);") |
277 | .kind(Snippet) | ||
261 | .add_to(acc); | 278 | .add_to(acc); |
262 | } | 279 | } |
280 | |||
281 | #[cfg(test)] | ||
282 | mod tests { | ||
283 | use crate::completion::{CompletionKind, check_completion}; | ||
284 | |||
285 | fn check_reference_completion(code: &str, expected_completions: &str) { | ||
286 | check_completion(code, expected_completions, CompletionKind::Reference); | ||
287 | } | ||
288 | |||
289 | fn check_keyword_completion(code: &str, expected_completions: &str) { | ||
290 | check_completion(code, expected_completions, CompletionKind::Keyword); | ||
291 | } | ||
292 | |||
293 | fn check_snippet_completion(code: &str, expected_completions: &str) { | ||
294 | check_completion(code, expected_completions, CompletionKind::Snippet); | ||
295 | } | ||
296 | |||
297 | #[test] | ||
298 | fn test_completion_let_scope() { | ||
299 | check_reference_completion( | ||
300 | r" | ||
301 | fn quux(x: i32) { | ||
302 | let y = 92; | ||
303 | 1 + <|>; | ||
304 | let z = (); | ||
305 | } | ||
306 | ", | ||
307 | "y;x;quux", | ||
308 | ); | ||
309 | } | ||
310 | |||
311 | #[test] | ||
312 | fn test_completion_if_let_scope() { | ||
313 | check_reference_completion( | ||
314 | r" | ||
315 | fn quux() { | ||
316 | if let Some(x) = foo() { | ||
317 | let y = 92; | ||
318 | }; | ||
319 | if let Some(a) = bar() { | ||
320 | let b = 62; | ||
321 | 1 + <|> | ||
322 | } | ||
323 | } | ||
324 | ", | ||
325 | "b;a;quux", | ||
326 | ); | ||
327 | } | ||
328 | |||
329 | #[test] | ||
330 | fn test_completion_for_scope() { | ||
331 | check_reference_completion( | ||
332 | r" | ||
333 | fn quux() { | ||
334 | for x in &[1, 2, 3] { | ||
335 | <|> | ||
336 | } | ||
337 | } | ||
338 | ", | ||
339 | "x;quux", | ||
340 | ); | ||
341 | } | ||
342 | |||
343 | #[test] | ||
344 | fn test_completion_mod_scope() { | ||
345 | check_reference_completion( | ||
346 | r" | ||
347 | struct Foo; | ||
348 | enum Baz {} | ||
349 | fn quux() { | ||
350 | <|> | ||
351 | } | ||
352 | ", | ||
353 | "quux;Foo;Baz", | ||
354 | ); | ||
355 | } | ||
356 | |||
357 | #[test] | ||
358 | fn test_completion_mod_scope_no_self_use() { | ||
359 | check_reference_completion( | ||
360 | r" | ||
361 | use foo<|>; | ||
362 | ", | ||
363 | "", | ||
364 | ); | ||
365 | } | ||
366 | |||
367 | #[test] | ||
368 | fn test_completion_self_path() { | ||
369 | check_reference_completion( | ||
370 | r" | ||
371 | use self::m::<|>; | ||
372 | |||
373 | mod m { | ||
374 | struct Bar; | ||
375 | } | ||
376 | ", | ||
377 | "Bar", | ||
378 | ); | ||
379 | } | ||
380 | |||
381 | #[test] | ||
382 | fn test_completion_mod_scope_nested() { | ||
383 | check_reference_completion( | ||
384 | r" | ||
385 | struct Foo; | ||
386 | mod m { | ||
387 | struct Bar; | ||
388 | fn quux() { <|> } | ||
389 | } | ||
390 | ", | ||
391 | "quux;Bar", | ||
392 | ); | ||
393 | } | ||
394 | |||
395 | #[test] | ||
396 | fn test_complete_type() { | ||
397 | check_reference_completion( | ||
398 | r" | ||
399 | struct Foo; | ||
400 | fn x() -> <|> | ||
401 | ", | ||
402 | "Foo;x", | ||
403 | ) | ||
404 | } | ||
405 | |||
406 | #[test] | ||
407 | fn test_complete_shadowing() { | ||
408 | check_reference_completion( | ||
409 | r" | ||
410 | fn foo() -> { | ||
411 | let bar = 92; | ||
412 | { | ||
413 | let bar = 62; | ||
414 | <|> | ||
415 | } | ||
416 | } | ||
417 | ", | ||
418 | "bar;foo", | ||
419 | ) | ||
420 | } | ||
421 | |||
422 | #[test] | ||
423 | fn test_complete_self() { | ||
424 | check_reference_completion(r"impl S { fn foo(&self) { <|> } }", "self") | ||
425 | } | ||
426 | |||
427 | #[test] | ||
428 | fn test_complete_crate_path() { | ||
429 | check_reference_completion( | ||
430 | " | ||
431 | //- /lib.rs | ||
432 | mod foo; | ||
433 | struct Spam; | ||
434 | //- /foo.rs | ||
435 | use crate::Sp<|> | ||
436 | ", | ||
437 | "Spam;foo", | ||
438 | ); | ||
439 | } | ||
440 | |||
441 | #[test] | ||
442 | fn test_complete_crate_path_with_braces() { | ||
443 | check_reference_completion( | ||
444 | " | ||
445 | //- /lib.rs | ||
446 | mod foo; | ||
447 | struct Spam; | ||
448 | //- /foo.rs | ||
449 | use crate::{Sp<|>}; | ||
450 | ", | ||
451 | "Spam;foo", | ||
452 | ); | ||
453 | } | ||
454 | |||
455 | #[test] | ||
456 | fn test_complete_crate_path_in_nested_tree() { | ||
457 | check_reference_completion( | ||
458 | " | ||
459 | //- /lib.rs | ||
460 | mod foo; | ||
461 | pub mod bar { | ||
462 | pub mod baz { | ||
463 | pub struct Spam; | ||
464 | } | ||
465 | } | ||
466 | //- /foo.rs | ||
467 | use crate::{bar::{baz::Sp<|>}}; | ||
468 | ", | ||
469 | "Spam", | ||
470 | ); | ||
471 | } | ||
472 | |||
473 | #[test] | ||
474 | fn test_completion_kewords() { | ||
475 | check_keyword_completion( | ||
476 | r" | ||
477 | fn quux() { | ||
478 | <|> | ||
479 | } | ||
480 | ", | ||
481 | r#" | ||
482 | if "if $0 {}" | ||
483 | match "match $0 {}" | ||
484 | while "while $0 {}" | ||
485 | loop "loop {$0}" | ||
486 | return "return" | ||
487 | "#, | ||
488 | ); | ||
489 | } | ||
490 | |||
491 | #[test] | ||
492 | fn test_completion_else() { | ||
493 | check_keyword_completion( | ||
494 | r" | ||
495 | fn quux() { | ||
496 | if true { | ||
497 | () | ||
498 | } <|> | ||
499 | } | ||
500 | ", | ||
501 | r#" | ||
502 | if "if $0 {}" | ||
503 | match "match $0 {}" | ||
504 | while "while $0 {}" | ||
505 | loop "loop {$0}" | ||
506 | else "else {$0}" | ||
507 | else if "else if $0 {}" | ||
508 | return "return" | ||
509 | "#, | ||
510 | ); | ||
511 | } | ||
512 | |||
513 | #[test] | ||
514 | fn test_completion_return_value() { | ||
515 | check_keyword_completion( | ||
516 | r" | ||
517 | fn quux() -> i32 { | ||
518 | <|> | ||
519 | 92 | ||
520 | } | ||
521 | ", | ||
522 | r#" | ||
523 | if "if $0 {}" | ||
524 | match "match $0 {}" | ||
525 | while "while $0 {}" | ||
526 | loop "loop {$0}" | ||
527 | return "return $0;" | ||
528 | "#, | ||
529 | ); | ||
530 | check_keyword_completion( | ||
531 | r" | ||
532 | fn quux() { | ||
533 | <|> | ||
534 | 92 | ||
535 | } | ||
536 | ", | ||
537 | r#" | ||
538 | if "if $0 {}" | ||
539 | match "match $0 {}" | ||
540 | while "while $0 {}" | ||
541 | loop "loop {$0}" | ||
542 | return "return;" | ||
543 | "#, | ||
544 | ); | ||
545 | } | ||
546 | |||
547 | #[test] | ||
548 | fn test_completion_return_no_stmt() { | ||
549 | check_keyword_completion( | ||
550 | r" | ||
551 | fn quux() -> i32 { | ||
552 | match () { | ||
553 | () => <|> | ||
554 | } | ||
555 | } | ||
556 | ", | ||
557 | r#" | ||
558 | if "if $0 {}" | ||
559 | match "match $0 {}" | ||
560 | while "while $0 {}" | ||
561 | loop "loop {$0}" | ||
562 | return "return $0" | ||
563 | "#, | ||
564 | ); | ||
565 | } | ||
566 | |||
567 | #[test] | ||
568 | fn test_continue_break_completion() { | ||
569 | check_keyword_completion( | ||
570 | r" | ||
571 | fn quux() -> i32 { | ||
572 | loop { <|> } | ||
573 | } | ||
574 | ", | ||
575 | r#" | ||
576 | if "if $0 {}" | ||
577 | match "match $0 {}" | ||
578 | while "while $0 {}" | ||
579 | loop "loop {$0}" | ||
580 | continue "continue" | ||
581 | break "break" | ||
582 | return "return $0" | ||
583 | "#, | ||
584 | ); | ||
585 | check_keyword_completion( | ||
586 | r" | ||
587 | fn quux() -> i32 { | ||
588 | loop { || { <|> } } | ||
589 | } | ||
590 | ", | ||
591 | r#" | ||
592 | if "if $0 {}" | ||
593 | match "match $0 {}" | ||
594 | while "while $0 {}" | ||
595 | loop "loop {$0}" | ||
596 | return "return $0" | ||
597 | "#, | ||
598 | ); | ||
599 | } | ||
600 | |||
601 | #[test] | ||
602 | fn test_item_snippets() { | ||
603 | // check_snippet_completion(r" | ||
604 | // <|> | ||
605 | // ", | ||
606 | // r##"[CompletionItem { label: "Test function", lookup: None, snippet: Some("#[test]\nfn test_${1:feature}() {\n$0\n}"##, | ||
607 | // ); | ||
608 | check_snippet_completion( | ||
609 | r" | ||
610 | #[cfg(test)] | ||
611 | mod tests { | ||
612 | <|> | ||
613 | } | ||
614 | ", | ||
615 | r##" | ||
616 | tfn "Test function" "#[test]\nfn ${1:feature}() {\n $0\n}" | ||
617 | pub(crate) "pub(crate) $0" | ||
618 | "##, | ||
619 | ); | ||
620 | } | ||
621 | |||
622 | } | ||