aboutsummaryrefslogtreecommitdiff
path: root/crates/completion/src/completions/unqualified_path.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/completion/src/completions/unqualified_path.rs')
-rw-r--r--crates/completion/src/completions/unqualified_path.rs737
1 files changed, 0 insertions, 737 deletions
diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs
deleted file mode 100644
index ac5596ca4..000000000
--- a/crates/completion/src/completions/unqualified_path.rs
+++ /dev/null
@@ -1,737 +0,0 @@
1//! Completion of names from the current scope, e.g. locals and imported items.
2
3use std::iter;
4
5use hir::{Adt, ModuleDef, ScopeDef, Type};
6use syntax::AstNode;
7use test_utils::mark;
8
9use crate::{CompletionContext, Completions};
10
11pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
12 if !(ctx.is_trivial_path || ctx.is_pat_binding_or_const) {
13 return;
14 }
15 if ctx.record_lit_syntax.is_some()
16 || ctx.record_pat_syntax.is_some()
17 || ctx.attribute_under_caret.is_some()
18 || ctx.mod_declaration_under_caret.is_some()
19 {
20 return;
21 }
22
23 if let Some(ty) = &ctx.expected_type {
24 complete_enum_variants(acc, ctx, ty);
25 }
26
27 if ctx.is_pat_binding_or_const {
28 return;
29 }
30
31 ctx.scope.process_all_names(&mut |name, res| {
32 if ctx.use_item_syntax.is_some() {
33 if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) {
34 if name_ref.syntax().text() == name.to_string().as_str() {
35 mark::hit!(self_fulfilling_completion);
36 return;
37 }
38 }
39 }
40 acc.add_resolution(ctx, name.to_string(), &res)
41 });
42}
43
44fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &Type) {
45 if let Some(Adt::Enum(enum_data)) =
46 iter::successors(Some(ty.clone()), |ty| ty.remove_ref()).last().and_then(|ty| ty.as_adt())
47 {
48 let variants = enum_data.variants(ctx.db);
49
50 let module = if let Some(module) = ctx.scope.module() {
51 // Compute path from the completion site if available.
52 module
53 } else {
54 // Otherwise fall back to the enum's definition site.
55 enum_data.module(ctx.db)
56 };
57
58 for variant in variants {
59 if let Some(path) = module.find_use_path(ctx.db, ModuleDef::from(variant)) {
60 // Variants with trivial paths are already added by the existing completion logic,
61 // so we should avoid adding these twice
62 if path.segments.len() > 1 {
63 acc.add_qualified_enum_variant(ctx, variant, path);
64 }
65 }
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use expect_test::{expect, Expect};
73 use test_utils::mark;
74
75 use crate::{
76 test_utils::{check_edit, completion_list_with_config, TEST_CONFIG},
77 CompletionConfig, CompletionKind,
78 };
79
80 fn check(ra_fixture: &str, expect: Expect) {
81 check_with_config(TEST_CONFIG, ra_fixture, expect);
82 }
83
84 fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) {
85 let actual = completion_list_with_config(config, ra_fixture, CompletionKind::Reference);
86 expect.assert_eq(&actual)
87 }
88
89 #[test]
90 fn self_fulfilling_completion() {
91 mark::check!(self_fulfilling_completion);
92 check(
93 r#"
94use foo$0
95use std::collections;
96"#,
97 expect![[r#"
98 ?? collections
99 "#]],
100 );
101 }
102
103 #[test]
104 fn bind_pat_and_path_ignore_at() {
105 check(
106 r#"
107enum Enum { A, B }
108fn quux(x: Option<Enum>) {
109 match x {
110 None => (),
111 Some(en$0 @ Enum::A) => (),
112 }
113}
114"#,
115 expect![[""]],
116 );
117 }
118
119 #[test]
120 fn bind_pat_and_path_ignore_ref() {
121 check(
122 r#"
123enum Enum { A, B }
124fn quux(x: Option<Enum>) {
125 match x {
126 None => (),
127 Some(ref en$0) => (),
128 }
129}
130"#,
131 expect![[""]],
132 );
133 }
134
135 #[test]
136 fn bind_pat_and_path() {
137 check(
138 r#"
139enum Enum { A, B }
140fn quux(x: Option<Enum>) {
141 match x {
142 None => (),
143 Some(En$0) => (),
144 }
145}
146"#,
147 expect![[r#"
148 en Enum
149 "#]],
150 );
151 }
152
153 #[test]
154 fn completes_bindings_from_let() {
155 check(
156 r#"
157fn quux(x: i32) {
158 let y = 92;
159 1 + $0;
160 let z = ();
161}
162"#,
163 expect![[r#"
164 bn y i32
165 bn x i32
166 fn quux(…) fn quux(x: i32)
167 "#]],
168 );
169 }
170
171 #[test]
172 fn completes_bindings_from_if_let() {
173 check(
174 r#"
175fn quux() {
176 if let Some(x) = foo() {
177 let y = 92;
178 };
179 if let Some(a) = bar() {
180 let b = 62;
181 1 + $0
182 }
183}
184"#,
185 expect![[r#"
186 bn b i32
187 bn a
188 fn quux() fn quux()
189 "#]],
190 );
191 }
192
193 #[test]
194 fn completes_bindings_from_for() {
195 check(
196 r#"
197fn quux() {
198 for x in &[1, 2, 3] { $0 }
199}
200"#,
201 expect![[r#"
202 bn x
203 fn quux() fn quux()
204 "#]],
205 );
206 }
207
208 #[test]
209 fn completes_if_prefix_is_keyword() {
210 mark::check!(completes_if_prefix_is_keyword);
211 check_edit(
212 "wherewolf",
213 r#"
214fn main() {
215 let wherewolf = 92;
216 drop(where$0)
217}
218"#,
219 r#"
220fn main() {
221 let wherewolf = 92;
222 drop(wherewolf)
223}
224"#,
225 )
226 }
227
228 #[test]
229 fn completes_generic_params() {
230 check(
231 r#"fn quux<T>() { $0 }"#,
232 expect![[r#"
233 tp T
234 fn quux() fn quux<T>()
235 "#]],
236 );
237 }
238
239 #[test]
240 fn completes_generic_params_in_struct() {
241 check(
242 r#"struct S<T> { x: $0}"#,
243 expect![[r#"
244 tp Self
245 tp T
246 st S<…>
247 "#]],
248 );
249 }
250
251 #[test]
252 fn completes_self_in_enum() {
253 check(
254 r#"enum X { Y($0) }"#,
255 expect![[r#"
256 tp Self
257 en X
258 "#]],
259 );
260 }
261
262 #[test]
263 fn completes_module_items() {
264 check(
265 r#"
266struct S;
267enum E {}
268fn quux() { $0 }
269"#,
270 expect![[r#"
271 st S
272 fn quux() fn quux()
273 en E
274 "#]],
275 );
276 }
277
278 /// Regression test for issue #6091.
279 #[test]
280 fn correctly_completes_module_items_prefixed_with_underscore() {
281 check_edit(
282 "_alpha",
283 r#"
284fn main() {
285 _$0
286}
287fn _alpha() {}
288"#,
289 r#"
290fn main() {
291 _alpha()$0
292}
293fn _alpha() {}
294"#,
295 )
296 }
297
298 #[test]
299 fn completes_extern_prelude() {
300 check(
301 r#"
302//- /lib.rs crate:main deps:other_crate
303use $0;
304
305//- /other_crate/lib.rs crate:other_crate
306// nothing here
307"#,
308 expect![[r#"
309 md other_crate
310 "#]],
311 );
312 }
313
314 #[test]
315 fn completes_module_items_in_nested_modules() {
316 check(
317 r#"
318struct Foo;
319mod m {
320 struct Bar;
321 fn quux() { $0 }
322}
323"#,
324 expect![[r#"
325 fn quux() fn quux()
326 st Bar
327 "#]],
328 );
329 }
330
331 #[test]
332 fn completes_return_type() {
333 check(
334 r#"
335struct Foo;
336fn x() -> $0
337"#,
338 expect![[r#"
339 st Foo
340 fn x() fn x()
341 "#]],
342 );
343 }
344
345 #[test]
346 fn dont_show_both_completions_for_shadowing() {
347 check(
348 r#"
349fn foo() {
350 let bar = 92;
351 {
352 let bar = 62;
353 drop($0)
354 }
355}
356"#,
357 // FIXME: should be only one bar here
358 expect![[r#"
359 bn bar i32
360 bn bar i32
361 fn foo() fn foo()
362 "#]],
363 );
364 }
365
366 #[test]
367 fn completes_self_in_methods() {
368 check(
369 r#"impl S { fn foo(&self) { $0 } }"#,
370 expect![[r#"
371 bn self &{unknown}
372 tp Self
373 "#]],
374 );
375 }
376
377 #[test]
378 fn completes_prelude() {
379 check(
380 r#"
381//- /main.rs crate:main deps:std
382fn foo() { let x: $0 }
383
384//- /std/lib.rs crate:std
385#[prelude_import]
386use prelude::*;
387
388mod prelude { struct Option; }
389"#,
390 expect![[r#"
391 fn foo() fn foo()
392 md std
393 st Option
394 "#]],
395 );
396 }
397
398 #[test]
399 fn completes_prelude_macros() {
400 check(
401 r#"
402//- /main.rs crate:main deps:std
403fn f() {$0}
404
405//- /std/lib.rs crate:std
406#[prelude_import]
407pub use prelude::*;
408
409#[macro_use]
410mod prelude {
411 pub use crate::concat;
412}
413
414mod macros {
415 #[rustc_builtin_macro]
416 #[macro_export]
417 macro_rules! concat { }
418}
419"#,
420 expect![[r##"
421 fn f() fn f()
422 ma concat!(…) #[macro_export] macro_rules! concat
423 md std
424 "##]],
425 );
426 }
427
428 #[test]
429 fn completes_std_prelude_if_core_is_defined() {
430 check(
431 r#"
432//- /main.rs crate:main deps:core,std
433fn foo() { let x: $0 }
434
435//- /core/lib.rs crate:core
436#[prelude_import]
437use prelude::*;
438
439mod prelude { struct Option; }
440
441//- /std/lib.rs crate:std deps:core
442#[prelude_import]
443use prelude::*;
444
445mod prelude { struct String; }
446"#,
447 expect![[r#"
448 fn foo() fn foo()
449 md std
450 md core
451 st String
452 "#]],
453 );
454 }
455
456 #[test]
457 fn completes_macros_as_value() {
458 check(
459 r#"
460macro_rules! foo { () => {} }
461
462#[macro_use]
463mod m1 {
464 macro_rules! bar { () => {} }
465}
466
467mod m2 {
468 macro_rules! nope { () => {} }
469
470 #[macro_export]
471 macro_rules! baz { () => {} }
472}
473
474fn main() { let v = $0 }
475"#,
476 expect![[r##"
477 md m1
478 ma baz!(…) #[macro_export] macro_rules! baz
479 fn main() fn main()
480 md m2
481 ma bar!(…) macro_rules! bar
482 ma foo!(…) macro_rules! foo
483 "##]],
484 );
485 }
486
487 #[test]
488 fn completes_both_macro_and_value() {
489 check(
490 r#"
491macro_rules! foo { () => {} }
492fn foo() { $0 }
493"#,
494 expect![[r#"
495 fn foo() fn foo()
496 ma foo!(…) macro_rules! foo
497 "#]],
498 );
499 }
500
501 #[test]
502 fn completes_macros_as_type() {
503 check(
504 r#"
505macro_rules! foo { () => {} }
506fn main() { let x: $0 }
507"#,
508 expect![[r#"
509 fn main() fn main()
510 ma foo!(…) macro_rules! foo
511 "#]],
512 );
513 }
514
515 #[test]
516 fn completes_macros_as_stmt() {
517 check(
518 r#"
519macro_rules! foo { () => {} }
520fn main() { $0 }
521"#,
522 expect![[r#"
523 fn main() fn main()
524 ma foo!(…) macro_rules! foo
525 "#]],
526 );
527 }
528
529 #[test]
530 fn completes_local_item() {
531 check(
532 r#"
533fn main() {
534 return f$0;
535 fn frobnicate() {}
536}
537"#,
538 expect![[r#"
539 fn frobnicate() fn frobnicate()
540 fn main() fn main()
541 "#]],
542 );
543 }
544
545 #[test]
546 fn completes_in_simple_macro_1() {
547 check(
548 r#"
549macro_rules! m { ($e:expr) => { $e } }
550fn quux(x: i32) {
551 let y = 92;
552 m!($0);
553}
554"#,
555 expect![[r#"
556 bn y i32
557 bn x i32
558 fn quux(…) fn quux(x: i32)
559 ma m!(…) macro_rules! m
560 "#]],
561 );
562 }
563
564 #[test]
565 fn completes_in_simple_macro_2() {
566 check(
567 r"
568macro_rules! m { ($e:expr) => { $e } }
569fn quux(x: i32) {
570 let y = 92;
571 m!(x$0);
572}
573",
574 expect![[r#"
575 bn y i32
576 bn x i32
577 fn quux(…) fn quux(x: i32)
578 ma m!(…) macro_rules! m
579 "#]],
580 );
581 }
582
583 #[test]
584 fn completes_in_simple_macro_without_closing_parens() {
585 check(
586 r#"
587macro_rules! m { ($e:expr) => { $e } }
588fn quux(x: i32) {
589 let y = 92;
590 m!(x$0
591}
592"#,
593 expect![[r#"
594 bn y i32
595 bn x i32
596 fn quux(…) fn quux(x: i32)
597 ma m!(…) macro_rules! m
598 "#]],
599 );
600 }
601
602 #[test]
603 fn completes_unresolved_uses() {
604 check(
605 r#"
606use spam::Quux;
607
608fn main() { $0 }
609"#,
610 expect![[r#"
611 fn main() fn main()
612 ?? Quux
613 "#]],
614 );
615 }
616
617 #[test]
618 fn completes_enum_variant_matcharm() {
619 check(
620 r#"
621enum Foo { Bar, Baz, Quux }
622
623fn main() {
624 let foo = Foo::Quux;
625 match foo { Qu$0 }
626}
627"#,
628 expect![[r#"
629 ev Foo::Bar ()
630 ev Foo::Baz ()
631 ev Foo::Quux ()
632 en Foo
633 "#]],
634 )
635 }
636
637 #[test]
638 fn completes_enum_variant_matcharm_ref() {
639 check(
640 r#"
641enum Foo { Bar, Baz, Quux }
642
643fn main() {
644 let foo = Foo::Quux;
645 match &foo { Qu$0 }
646}
647"#,
648 expect![[r#"
649 ev Foo::Bar ()
650 ev Foo::Baz ()
651 ev Foo::Quux ()
652 en Foo
653 "#]],
654 )
655 }
656
657 #[test]
658 fn completes_enum_variant_iflet() {
659 check(
660 r#"
661enum Foo { Bar, Baz, Quux }
662
663fn main() {
664 let foo = Foo::Quux;
665 if let Qu$0 = foo { }
666}
667"#,
668 expect![[r#"
669 ev Foo::Bar ()
670 ev Foo::Baz ()
671 ev Foo::Quux ()
672 en Foo
673 "#]],
674 )
675 }
676
677 #[test]
678 fn completes_enum_variant_basic_expr() {
679 check(
680 r#"
681enum Foo { Bar, Baz, Quux }
682fn main() { let foo: Foo = Q$0 }
683"#,
684 expect![[r#"
685 ev Foo::Bar ()
686 ev Foo::Baz ()
687 ev Foo::Quux ()
688 en Foo
689 fn main() fn main()
690 "#]],
691 )
692 }
693
694 #[test]
695 fn completes_enum_variant_from_module() {
696 check(
697 r#"
698mod m { pub enum E { V } }
699fn f() -> m::E { V$0 }
700"#,
701 expect![[r#"
702 ev m::E::V ()
703 md m
704 fn f() fn f() -> m::E
705 "#]],
706 )
707 }
708
709 #[test]
710 fn dont_complete_attr() {
711 check(
712 r#"
713struct Foo;
714#[$0]
715fn f() {}
716"#,
717 expect![[""]],
718 )
719 }
720
721 #[test]
722 fn completes_type_or_trait_in_impl_block() {
723 check(
724 r#"
725trait MyTrait {}
726struct MyStruct {}
727
728impl My$0
729"#,
730 expect![[r#"
731 tp Self
732 tt MyTrait
733 st MyStruct
734 "#]],
735 )
736 }
737}