aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/completion/complete_unqualified_path.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/completion/complete_unqualified_path.rs')
-rw-r--r--crates/ra_ide/src/completion/complete_unqualified_path.rs1067
1 files changed, 1067 insertions, 0 deletions
diff --git a/crates/ra_ide/src/completion/complete_unqualified_path.rs b/crates/ra_ide/src/completion/complete_unqualified_path.rs
new file mode 100644
index 000000000..665597e4c
--- /dev/null
+++ b/crates/ra_ide/src/completion/complete_unqualified_path.rs
@@ -0,0 +1,1067 @@
1//! Completion of names from the current scope, e.g. locals and imported items.
2
3use crate::completion::{CompletionContext, Completions};
4
5pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) {
6 if !(ctx.is_trivial_path && !ctx.is_pat_binding_or_const) {
7 return;
8 }
9
10 ctx.scope().process_all_names(&mut |name, res| acc.add_resolution(ctx, name.to_string(), &res));
11}
12
13#[cfg(test)]
14mod tests {
15 use insta::assert_debug_snapshot;
16
17 use crate::completion::{test_utils::do_completion, CompletionItem, CompletionKind};
18
19 fn do_reference_completion(ra_fixture: &str) -> Vec<CompletionItem> {
20 do_completion(ra_fixture, CompletionKind::Reference)
21 }
22
23 #[test]
24 fn bind_pat_and_path_ignore_at() {
25 assert_debug_snapshot!(
26 do_reference_completion(
27 r"
28 enum Enum {
29 A,
30 B,
31 }
32 fn quux(x: Option<Enum>) {
33 match x {
34 None => (),
35 Some(en<|> @ Enum::A) => (),
36 }
37 }
38 "
39 ),
40 @r###"[]"###
41 );
42 }
43
44 #[test]
45 fn bind_pat_and_path_ignore_ref() {
46 assert_debug_snapshot!(
47 do_reference_completion(
48 r"
49 enum Enum {
50 A,
51 B,
52 }
53 fn quux(x: Option<Enum>) {
54 match x {
55 None => (),
56 Some(ref en<|>) => (),
57 }
58 }
59 "
60 ),
61 @r###"[]"###
62 );
63 }
64
65 #[test]
66 fn bind_pat_and_path() {
67 assert_debug_snapshot!(
68 do_reference_completion(
69 r"
70 enum Enum {
71 A,
72 B,
73 }
74 fn quux(x: Option<Enum>) {
75 match x {
76 None => (),
77 Some(En<|>) => (),
78 }
79 }
80 "
81 ),
82 @r###"
83 [
84 CompletionItem {
85 label: "Enum",
86 source_range: [231; 233),
87 delete: [231; 233),
88 insert: "Enum",
89 kind: Enum,
90 },
91 ]
92 "###
93 );
94 }
95
96 #[test]
97 fn completes_bindings_from_let() {
98 assert_debug_snapshot!(
99 do_reference_completion(
100 r"
101 fn quux(x: i32) {
102 let y = 92;
103 1 + <|>;
104 let z = ();
105 }
106 "
107 ),
108 @r###"
109 [
110 CompletionItem {
111 label: "quux(…)",
112 source_range: [91; 91),
113 delete: [91; 91),
114 insert: "quux(${1:x})$0",
115 kind: Function,
116 lookup: "quux",
117 detail: "fn quux(x: i32)",
118 trigger_call_info: true,
119 },
120 CompletionItem {
121 label: "x",
122 source_range: [91; 91),
123 delete: [91; 91),
124 insert: "x",
125 kind: Binding,
126 detail: "i32",
127 },
128 CompletionItem {
129 label: "y",
130 source_range: [91; 91),
131 delete: [91; 91),
132 insert: "y",
133 kind: Binding,
134 detail: "i32",
135 },
136 ]
137 "###
138 );
139 }
140
141 #[test]
142 fn completes_bindings_from_if_let() {
143 assert_debug_snapshot!(
144 do_reference_completion(
145 r"
146 fn quux() {
147 if let Some(x) = foo() {
148 let y = 92;
149 };
150 if let Some(a) = bar() {
151 let b = 62;
152 1 + <|>
153 }
154 }
155 "
156 ),
157 @r###"
158 [
159 CompletionItem {
160 label: "a",
161 source_range: [242; 242),
162 delete: [242; 242),
163 insert: "a",
164 kind: Binding,
165 },
166 CompletionItem {
167 label: "b",
168 source_range: [242; 242),
169 delete: [242; 242),
170 insert: "b",
171 kind: Binding,
172 detail: "i32",
173 },
174 CompletionItem {
175 label: "quux()",
176 source_range: [242; 242),
177 delete: [242; 242),
178 insert: "quux()$0",
179 kind: Function,
180 lookup: "quux",
181 detail: "fn quux()",
182 },
183 ]
184 "###
185 );
186 }
187
188 #[test]
189 fn completes_bindings_from_for() {
190 assert_debug_snapshot!(
191 do_reference_completion(
192 r"
193 fn quux() {
194 for x in &[1, 2, 3] {
195 <|>
196 }
197 }
198 "
199 ),
200 @r###"
201 [
202 CompletionItem {
203 label: "quux()",
204 source_range: [95; 95),
205 delete: [95; 95),
206 insert: "quux()$0",
207 kind: Function,
208 lookup: "quux",
209 detail: "fn quux()",
210 },
211 CompletionItem {
212 label: "x",
213 source_range: [95; 95),
214 delete: [95; 95),
215 insert: "x",
216 kind: Binding,
217 },
218 ]
219 "###
220 );
221 }
222
223 #[test]
224 fn completes_generic_params() {
225 assert_debug_snapshot!(
226 do_reference_completion(
227 r"
228 fn quux<T>() {
229 <|>
230 }
231 "
232 ),
233 @r###"
234 [
235 CompletionItem {
236 label: "T",
237 source_range: [52; 52),
238 delete: [52; 52),
239 insert: "T",
240 kind: TypeParam,
241 },
242 CompletionItem {
243 label: "quux()",
244 source_range: [52; 52),
245 delete: [52; 52),
246 insert: "quux()$0",
247 kind: Function,
248 lookup: "quux",
249 detail: "fn quux<T>()",
250 },
251 ]
252 "###
253 );
254 }
255
256 #[test]
257 fn completes_generic_params_in_struct() {
258 assert_debug_snapshot!(
259 do_reference_completion(
260 r"
261 struct X<T> {
262 x: <|>
263 }
264 "
265 ),
266 @r###"
267 [
268 CompletionItem {
269 label: "Self",
270 source_range: [54; 54),
271 delete: [54; 54),
272 insert: "Self",
273 kind: TypeParam,
274 },
275 CompletionItem {
276 label: "T",
277 source_range: [54; 54),
278 delete: [54; 54),
279 insert: "T",
280 kind: TypeParam,
281 },
282 CompletionItem {
283 label: "X<…>",
284 source_range: [54; 54),
285 delete: [54; 54),
286 insert: "X<$0>",
287 kind: Struct,
288 lookup: "X",
289 },
290 ]
291 "###
292 );
293 }
294
295 #[test]
296 fn completes_self_in_enum() {
297 assert_debug_snapshot!(
298 do_reference_completion(
299 r"
300 enum X {
301 Y(<|>)
302 }
303 "
304 ),
305 @r###"
306 [
307 CompletionItem {
308 label: "Self",
309 source_range: [48; 48),
310 delete: [48; 48),
311 insert: "Self",
312 kind: TypeParam,
313 },
314 CompletionItem {
315 label: "X",
316 source_range: [48; 48),
317 delete: [48; 48),
318 insert: "X",
319 kind: Enum,
320 },
321 ]
322 "###
323 );
324 }
325
326 #[test]
327 fn completes_module_items() {
328 assert_debug_snapshot!(
329 do_reference_completion(
330 r"
331 struct Foo;
332 enum Baz {}
333 fn quux() {
334 <|>
335 }
336 "
337 ),
338 @r###"
339 [
340 CompletionItem {
341 label: "Baz",
342 source_range: [105; 105),
343 delete: [105; 105),
344 insert: "Baz",
345 kind: Enum,
346 },
347 CompletionItem {
348 label: "Foo",
349 source_range: [105; 105),
350 delete: [105; 105),
351 insert: "Foo",
352 kind: Struct,
353 },
354 CompletionItem {
355 label: "quux()",
356 source_range: [105; 105),
357 delete: [105; 105),
358 insert: "quux()$0",
359 kind: Function,
360 lookup: "quux",
361 detail: "fn quux()",
362 },
363 ]
364 "###
365 );
366 }
367
368 #[test]
369 fn completes_extern_prelude() {
370 assert_debug_snapshot!(
371 do_reference_completion(
372 r"
373 //- /lib.rs
374 use <|>;
375
376 //- /other_crate/lib.rs
377 // nothing here
378 "
379 ),
380 @r###"
381 [
382 CompletionItem {
383 label: "other_crate",
384 source_range: [4; 4),
385 delete: [4; 4),
386 insert: "other_crate",
387 kind: Module,
388 },
389 ]
390 "###
391 );
392 }
393
394 #[test]
395 fn completes_module_items_in_nested_modules() {
396 assert_debug_snapshot!(
397 do_reference_completion(
398 r"
399 struct Foo;
400 mod m {
401 struct Bar;
402 fn quux() { <|> }
403 }
404 "
405 ),
406 @r###"
407 [
408 CompletionItem {
409 label: "Bar",
410 source_range: [117; 117),
411 delete: [117; 117),
412 insert: "Bar",
413 kind: Struct,
414 },
415 CompletionItem {
416 label: "quux()",
417 source_range: [117; 117),
418 delete: [117; 117),
419 insert: "quux()$0",
420 kind: Function,
421 lookup: "quux",
422 detail: "fn quux()",
423 },
424 ]
425 "###
426 );
427 }
428
429 #[test]
430 fn completes_return_type() {
431 assert_debug_snapshot!(
432 do_reference_completion(
433 r"
434 struct Foo;
435 fn x() -> <|>
436 "
437 ),
438 @r###"
439 [
440 CompletionItem {
441 label: "Foo",
442 source_range: [55; 55),
443 delete: [55; 55),
444 insert: "Foo",
445 kind: Struct,
446 },
447 CompletionItem {
448 label: "x()",
449 source_range: [55; 55),
450 delete: [55; 55),
451 insert: "x()$0",
452 kind: Function,
453 lookup: "x",
454 detail: "fn x()",
455 },
456 ]
457 "###
458 );
459 }
460
461 #[test]
462 fn dont_show_both_completions_for_shadowing() {
463 assert_debug_snapshot!(
464 do_reference_completion(
465 r"
466 fn foo() {
467 let bar = 92;
468 {
469 let bar = 62;
470 <|>
471 }
472 }
473 "
474 ),
475 @r###"
476 [
477 CompletionItem {
478 label: "bar",
479 source_range: [146; 146),
480 delete: [146; 146),
481 insert: "bar",
482 kind: Binding,
483 detail: "i32",
484 },
485 CompletionItem {
486 label: "foo()",
487 source_range: [146; 146),
488 delete: [146; 146),
489 insert: "foo()$0",
490 kind: Function,
491 lookup: "foo",
492 detail: "fn foo()",
493 },
494 ]
495 "###
496 );
497 }
498
499 #[test]
500 fn completes_self_in_methods() {
501 assert_debug_snapshot!(
502 do_reference_completion(r"impl S { fn foo(&self) { <|> } }"),
503 @r###"
504 [
505 CompletionItem {
506 label: "Self",
507 source_range: [25; 25),
508 delete: [25; 25),
509 insert: "Self",
510 kind: TypeParam,
511 },
512 CompletionItem {
513 label: "self",
514 source_range: [25; 25),
515 delete: [25; 25),
516 insert: "self",
517 kind: Binding,
518 detail: "&{unknown}",
519 },
520 ]
521 "###
522 );
523 }
524
525 #[test]
526 fn completes_prelude() {
527 assert_debug_snapshot!(
528 do_reference_completion(
529 "
530 //- /main.rs
531 fn foo() { let x: <|> }
532
533 //- /std/lib.rs
534 #[prelude_import]
535 use prelude::*;
536
537 mod prelude {
538 struct Option;
539 }
540 "
541 ),
542 @r###"
543 [
544 CompletionItem {
545 label: "Option",
546 source_range: [18; 18),
547 delete: [18; 18),
548 insert: "Option",
549 kind: Struct,
550 },
551 CompletionItem {
552 label: "foo()",
553 source_range: [18; 18),
554 delete: [18; 18),
555 insert: "foo()$0",
556 kind: Function,
557 lookup: "foo",
558 detail: "fn foo()",
559 },
560 CompletionItem {
561 label: "std",
562 source_range: [18; 18),
563 delete: [18; 18),
564 insert: "std",
565 kind: Module,
566 },
567 ]
568 "###
569 );
570 }
571
572 #[test]
573 fn completes_std_prelude_if_core_is_defined() {
574 assert_debug_snapshot!(
575 do_reference_completion(
576 "
577 //- /main.rs
578 fn foo() { let x: <|> }
579
580 //- /core/lib.rs
581 #[prelude_import]
582 use prelude::*;
583
584 mod prelude {
585 struct Option;
586 }
587
588 //- /std/lib.rs
589 #[prelude_import]
590 use prelude::*;
591
592 mod prelude {
593 struct String;
594 }
595 "
596 ),
597 @r###"
598 [
599 CompletionItem {
600 label: "String",
601 source_range: [18; 18),
602 delete: [18; 18),
603 insert: "String",
604 kind: Struct,
605 },
606 CompletionItem {
607 label: "core",
608 source_range: [18; 18),
609 delete: [18; 18),
610 insert: "core",
611 kind: Module,
612 },
613 CompletionItem {
614 label: "foo()",
615 source_range: [18; 18),
616 delete: [18; 18),
617 insert: "foo()$0",
618 kind: Function,
619 lookup: "foo",
620 detail: "fn foo()",
621 },
622 CompletionItem {
623 label: "std",
624 source_range: [18; 18),
625 delete: [18; 18),
626 insert: "std",
627 kind: Module,
628 },
629 ]
630 "###
631 );
632 }
633
634 #[test]
635 fn completes_macros_as_value() {
636 assert_debug_snapshot!(
637 do_reference_completion(
638 "
639 //- /main.rs
640 macro_rules! foo {
641 () => {}
642 }
643
644 #[macro_use]
645 mod m1 {
646 macro_rules! bar {
647 () => {}
648 }
649 }
650
651 mod m2 {
652 macro_rules! nope {
653 () => {}
654 }
655
656 #[macro_export]
657 macro_rules! baz {
658 () => {}
659 }
660 }
661
662 fn main() {
663 let v = <|>
664 }
665 "
666 ),
667 @r###"
668 [
669 CompletionItem {
670 label: "bar!",
671 source_range: [252; 252),
672 delete: [252; 252),
673 insert: "bar!($0)",
674 kind: Macro,
675 detail: "macro_rules! bar",
676 },
677 CompletionItem {
678 label: "baz!",
679 source_range: [252; 252),
680 delete: [252; 252),
681 insert: "baz!($0)",
682 kind: Macro,
683 detail: "#[macro_export]\nmacro_rules! baz",
684 },
685 CompletionItem {
686 label: "foo!",
687 source_range: [252; 252),
688 delete: [252; 252),
689 insert: "foo!($0)",
690 kind: Macro,
691 detail: "macro_rules! foo",
692 },
693 CompletionItem {
694 label: "m1",
695 source_range: [252; 252),
696 delete: [252; 252),
697 insert: "m1",
698 kind: Module,
699 },
700 CompletionItem {
701 label: "m2",
702 source_range: [252; 252),
703 delete: [252; 252),
704 insert: "m2",
705 kind: Module,
706 },
707 CompletionItem {
708 label: "main()",
709 source_range: [252; 252),
710 delete: [252; 252),
711 insert: "main()$0",
712 kind: Function,
713 lookup: "main",
714 detail: "fn main()",
715 },
716 ]
717 "###
718 );
719 }
720
721 #[test]
722 fn completes_both_macro_and_value() {
723 assert_debug_snapshot!(
724 do_reference_completion(
725 "
726 //- /main.rs
727 macro_rules! foo {
728 () => {}
729 }
730
731 fn foo() {
732 <|>
733 }
734 "
735 ),
736 @r###"
737 [
738 CompletionItem {
739 label: "foo!",
740 source_range: [49; 49),
741 delete: [49; 49),
742 insert: "foo!($0)",
743 kind: Macro,
744 detail: "macro_rules! foo",
745 },
746 CompletionItem {
747 label: "foo()",
748 source_range: [49; 49),
749 delete: [49; 49),
750 insert: "foo()$0",
751 kind: Function,
752 lookup: "foo",
753 detail: "fn foo()",
754 },
755 ]
756 "###
757 );
758 }
759
760 #[test]
761 fn completes_macros_as_type() {
762 assert_debug_snapshot!(
763 do_reference_completion(
764 "
765 //- /main.rs
766 macro_rules! foo {
767 () => {}
768 }
769
770 fn main() {
771 let x: <|>
772 }
773 "
774 ),
775 @r###"
776 [
777 CompletionItem {
778 label: "foo!",
779 source_range: [57; 57),
780 delete: [57; 57),
781 insert: "foo!($0)",
782 kind: Macro,
783 detail: "macro_rules! foo",
784 },
785 CompletionItem {
786 label: "main()",
787 source_range: [57; 57),
788 delete: [57; 57),
789 insert: "main()$0",
790 kind: Function,
791 lookup: "main",
792 detail: "fn main()",
793 },
794 ]
795 "###
796 );
797 }
798
799 #[test]
800 fn completes_macros_as_stmt() {
801 assert_debug_snapshot!(
802 do_reference_completion(
803 "
804 //- /main.rs
805 macro_rules! foo {
806 () => {}
807 }
808
809 fn main() {
810 <|>
811 }
812 "
813 ),
814 @r###"
815 [
816 CompletionItem {
817 label: "foo!",
818 source_range: [50; 50),
819 delete: [50; 50),
820 insert: "foo!($0)",
821 kind: Macro,
822 detail: "macro_rules! foo",
823 },
824 CompletionItem {
825 label: "main()",
826 source_range: [50; 50),
827 delete: [50; 50),
828 insert: "main()$0",
829 kind: Function,
830 lookup: "main",
831 detail: "fn main()",
832 },
833 ]
834 "###
835 );
836 }
837
838 #[test]
839 fn completes_local_item() {
840 assert_debug_snapshot!(
841 do_reference_completion(
842 "
843 //- /main.rs
844 fn main() {
845 return f<|>;
846 fn frobnicate() {}
847 }
848 "
849 ),
850 @r###"
851 [
852 CompletionItem {
853 label: "frobnicate()",
854 source_range: [23; 24),
855 delete: [23; 24),
856 insert: "frobnicate()$0",
857 kind: Function,
858 lookup: "frobnicate",
859 detail: "fn frobnicate()",
860 },
861 CompletionItem {
862 label: "main()",
863 source_range: [23; 24),
864 delete: [23; 24),
865 insert: "main()$0",
866 kind: Function,
867 lookup: "main",
868 detail: "fn main()",
869 },
870 ]
871 "###
872 )
873 }
874
875 #[test]
876 fn completes_in_simple_macro_1() {
877 assert_debug_snapshot!(
878 do_reference_completion(
879 r"
880 macro_rules! m { ($e:expr) => { $e } }
881 fn quux(x: i32) {
882 let y = 92;
883 m!(<|>);
884 }
885 "
886 ),
887 @r###"
888 [
889 CompletionItem {
890 label: "m!",
891 source_range: [145; 145),
892 delete: [145; 145),
893 insert: "m!($0)",
894 kind: Macro,
895 detail: "macro_rules! m",
896 },
897 CompletionItem {
898 label: "quux(…)",
899 source_range: [145; 145),
900 delete: [145; 145),
901 insert: "quux(${1:x})$0",
902 kind: Function,
903 lookup: "quux",
904 detail: "fn quux(x: i32)",
905 trigger_call_info: true,
906 },
907 CompletionItem {
908 label: "x",
909 source_range: [145; 145),
910 delete: [145; 145),
911 insert: "x",
912 kind: Binding,
913 detail: "i32",
914 },
915 CompletionItem {
916 label: "y",
917 source_range: [145; 145),
918 delete: [145; 145),
919 insert: "y",
920 kind: Binding,
921 detail: "i32",
922 },
923 ]
924 "###
925 );
926 }
927
928 #[test]
929 fn completes_in_simple_macro_2() {
930 assert_debug_snapshot!(
931 do_reference_completion(
932 r"
933 macro_rules! m { ($e:expr) => { $e } }
934 fn quux(x: i32) {
935 let y = 92;
936 m!(x<|>);
937 }
938 "
939 ),
940 @r###"
941 [
942 CompletionItem {
943 label: "m!",
944 source_range: [145; 146),
945 delete: [145; 146),
946 insert: "m!($0)",
947 kind: Macro,
948 detail: "macro_rules! m",
949 },
950 CompletionItem {
951 label: "quux(…)",
952 source_range: [145; 146),
953 delete: [145; 146),
954 insert: "quux(${1:x})$0",
955 kind: Function,
956 lookup: "quux",
957 detail: "fn quux(x: i32)",
958 trigger_call_info: true,
959 },
960 CompletionItem {
961 label: "x",
962 source_range: [145; 146),
963 delete: [145; 146),
964 insert: "x",
965 kind: Binding,
966 detail: "i32",
967 },
968 CompletionItem {
969 label: "y",
970 source_range: [145; 146),
971 delete: [145; 146),
972 insert: "y",
973 kind: Binding,
974 detail: "i32",
975 },
976 ]
977 "###
978 );
979 }
980
981 #[test]
982 fn completes_in_simple_macro_without_closing_parens() {
983 assert_debug_snapshot!(
984 do_reference_completion(
985 r"
986 macro_rules! m { ($e:expr) => { $e } }
987 fn quux(x: i32) {
988 let y = 92;
989 m!(x<|>
990 }
991 "
992 ),
993 @r###"
994 [
995 CompletionItem {
996 label: "m!",
997 source_range: [145; 146),
998 delete: [145; 146),
999 insert: "m!($0)",
1000 kind: Macro,
1001 detail: "macro_rules! m",
1002 },
1003 CompletionItem {
1004 label: "quux(…)",
1005 source_range: [145; 146),
1006 delete: [145; 146),
1007 insert: "quux(${1:x})$0",
1008 kind: Function,
1009 lookup: "quux",
1010 detail: "fn quux(x: i32)",
1011 trigger_call_info: true,
1012 },
1013 CompletionItem {
1014 label: "x",
1015 source_range: [145; 146),
1016 delete: [145; 146),
1017 insert: "x",
1018 kind: Binding,
1019 detail: "i32",
1020 },
1021 CompletionItem {
1022 label: "y",
1023 source_range: [145; 146),
1024 delete: [145; 146),
1025 insert: "y",
1026 kind: Binding,
1027 detail: "i32",
1028 },
1029 ]
1030 "###
1031 );
1032 }
1033
1034 #[test]
1035 fn completes_unresolved_uses() {
1036 assert_debug_snapshot!(
1037 do_reference_completion(
1038 r"
1039 use spam::Quux;
1040
1041 fn main() {
1042 <|>
1043 }
1044 "
1045 ),
1046 @r###"
1047 [
1048 CompletionItem {
1049 label: "Quux",
1050 source_range: [82; 82),
1051 delete: [82; 82),
1052 insert: "Quux",
1053 },
1054 CompletionItem {
1055 label: "main()",
1056 source_range: [82; 82),
1057 delete: [82; 82),
1058 insert: "main()$0",
1059 kind: Function,
1060 lookup: "main",
1061 detail: "fn main()",
1062 },
1063 ]
1064 "###
1065 );
1066 }
1067}