]> git.lizzy.rs Git - rust.git/blob - crates/completion/src/completions/unqualified_path.rs
Better config name
[rust.git] / crates / completion / src / completions / unqualified_path.rs
1 //! Completion of names from the current scope, e.g. locals and imported items.
2
3 use either::Either;
4 use hir::{Adt, ModuleDef, ScopeDef, Type};
5 use ide_db::helpers::insert_use::ImportScope;
6 use ide_db::imports_locator;
7 use syntax::AstNode;
8 use test_utils::mark;
9
10 use crate::{
11     render::{render_resolution_with_import, RenderContext},
12     CompletionContext, Completions, ImportEdit,
13 };
14
15 pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
16     if !(ctx.is_trivial_path || ctx.is_pat_binding_or_const) {
17         return;
18     }
19     if ctx.record_lit_syntax.is_some()
20         || ctx.record_pat_syntax.is_some()
21         || ctx.attribute_under_caret.is_some()
22         || ctx.mod_declaration_under_caret.is_some()
23     {
24         return;
25     }
26
27     if let Some(ty) = &ctx.expected_type {
28         complete_enum_variants(acc, ctx, ty);
29     }
30
31     if ctx.is_pat_binding_or_const {
32         return;
33     }
34
35     ctx.scope.process_all_names(&mut |name, res| {
36         if ctx.use_item_syntax.is_some() {
37             if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) {
38                 if name_ref.syntax().text() == name.to_string().as_str() {
39                     mark::hit!(self_fulfilling_completion);
40                     return;
41                 }
42             }
43         }
44         acc.add_resolution(ctx, name.to_string(), &res)
45     });
46
47     if ctx.config.enable_autoimport_completions && ctx.config.resolve_additional_edits_lazily() {
48         fuzzy_completion(acc, ctx).unwrap_or_default()
49     }
50 }
51
52 fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &Type) {
53     if let Some(Adt::Enum(enum_data)) = ty.as_adt() {
54         let variants = enum_data.variants(ctx.db);
55
56         let module = if let Some(module) = ctx.scope.module() {
57             // Compute path from the completion site if available.
58             module
59         } else {
60             // Otherwise fall back to the enum's definition site.
61             enum_data.module(ctx.db)
62         };
63
64         for variant in variants {
65             if let Some(path) = module.find_use_path(ctx.db, ModuleDef::from(variant)) {
66                 // Variants with trivial paths are already added by the existing completion logic,
67                 // so we should avoid adding these twice
68                 if path.segments.len() > 1 {
69                     acc.add_qualified_enum_variant(ctx, variant, path);
70                 }
71             }
72         }
73     }
74 }
75
76 // Feature: Fuzzy Completion and Autoimports
77 //
78 // When completing names in the current scope, proposes additional imports from other modules or crates,
79 // if they can be qualified in the scope and their name contains all symbols from the completion input
80 // (case-insensitive, in any order or places).
81 //
82 // ```
83 // fn main() {
84 //     pda<|>
85 // }
86 // # pub mod std { pub mod marker { pub struct PhantomData { } } }
87 // ```
88 // ->
89 // ```
90 // use std::marker::PhantomData;
91 //
92 // fn main() {
93 //     PhantomData
94 // }
95 // # pub mod std { pub mod marker { pub struct PhantomData { } } }
96 // ```
97 //
98 // .Fuzzy search details
99 //
100 // To avoid an excessive amount of the results returned, completion input is checked for inclusion in the identifiers only
101 // (i.e. in `HashMap` in the `std::collections::HashMap` path), also not in the module indentifiers.
102 // It also avoids searching for any imports for inputs with their length less that 3 symbols.
103 //
104 // .Merge Behaviour
105 //
106 // It is possible to configure how use-trees are merged with the `importMergeBehaviour` setting.
107 // Mimics the corresponding behaviour of the `Auto Import` feature.
108 //
109 // .LSP and performance implications
110 //
111 // The feature is enabled only if the LSP client supports LSP protocol version 3.16+ and reports the `additionalTextEdits`
112 // (case sensitive) resolve client capability in its client capabilities.
113 // This way the server is able to defer the costly computations, doing them for a selected completion item only.
114 // For clients with no such support, all edits have to be calculated on the completion request, including the fuzzy search completion ones,
115 // which might be slow ergo the feature is automatically disabled.
116 //
117 // .Feature toggle
118 //
119 // The feature can be forcefully turned off in the settings with the `rust-analyzer.completion.enableAutoimportCompletions` flag.
120 // Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corredponding
121 // capability enabled.
122 fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
123     let _p = profile::span("fuzzy_completion");
124     let potential_import_name = ctx.token.to_string();
125
126     if potential_import_name.len() < 3 {
127         return None;
128     }
129
130     let current_module = ctx.scope.module()?;
131     let anchor = ctx.name_ref_syntax.as_ref()?;
132     let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?;
133
134     let possible_imports =
135         imports_locator::find_similar_imports(&ctx.sema, ctx.krate?, &potential_import_name, true)
136             .filter_map(|import_candidate| {
137                 Some(match import_candidate {
138                     Either::Left(module_def) => (
139                         current_module.find_use_path(ctx.db, module_def)?,
140                         ScopeDef::ModuleDef(module_def),
141                     ),
142                     Either::Right(macro_def) => (
143                         current_module.find_use_path(ctx.db, macro_def)?,
144                         ScopeDef::MacroDef(macro_def),
145                     ),
146                 })
147             })
148             .filter(|(mod_path, _)| mod_path.len() > 1)
149             .filter_map(|(import_path, definition)| {
150                 render_resolution_with_import(
151                     RenderContext::new(ctx),
152                     ImportEdit {
153                         import_path: import_path.clone(),
154                         import_scope: import_scope.clone(),
155                         merge_behaviour: ctx.config.merge,
156                     },
157                     &definition,
158                 )
159             });
160
161     acc.add_all(possible_imports);
162     Some(())
163 }
164
165 #[cfg(test)]
166 mod tests {
167     use expect_test::{expect, Expect};
168     use test_utils::mark;
169
170     use crate::{
171         test_utils::{check_edit, check_edit_with_config, completion_list},
172         CompletionConfig, CompletionKind,
173     };
174
175     fn check(ra_fixture: &str, expect: Expect) {
176         let actual = completion_list(ra_fixture, CompletionKind::Reference);
177         expect.assert_eq(&actual)
178     }
179
180     #[test]
181     fn self_fulfilling_completion() {
182         mark::check!(self_fulfilling_completion);
183         check(
184             r#"
185 use foo<|>
186 use std::collections;
187 "#,
188             expect![[r#"
189                 ?? collections
190             "#]],
191         );
192     }
193
194     #[test]
195     fn bind_pat_and_path_ignore_at() {
196         check(
197             r#"
198 enum Enum { A, B }
199 fn quux(x: Option<Enum>) {
200     match x {
201         None => (),
202         Some(en<|> @ Enum::A) => (),
203     }
204 }
205 "#,
206             expect![[""]],
207         );
208     }
209
210     #[test]
211     fn bind_pat_and_path_ignore_ref() {
212         check(
213             r#"
214 enum Enum { A, B }
215 fn quux(x: Option<Enum>) {
216     match x {
217         None => (),
218         Some(ref en<|>) => (),
219     }
220 }
221 "#,
222             expect![[""]],
223         );
224     }
225
226     #[test]
227     fn bind_pat_and_path() {
228         check(
229             r#"
230 enum Enum { A, B }
231 fn quux(x: Option<Enum>) {
232     match x {
233         None => (),
234         Some(En<|>) => (),
235     }
236 }
237 "#,
238             expect![[r#"
239                 en Enum
240             "#]],
241         );
242     }
243
244     #[test]
245     fn completes_bindings_from_let() {
246         check(
247             r#"
248 fn quux(x: i32) {
249     let y = 92;
250     1 + <|>;
251     let z = ();
252 }
253 "#,
254             expect![[r#"
255                 fn quux(…) fn quux(x: i32)
256                 bn x       i32
257                 bn y       i32
258             "#]],
259         );
260     }
261
262     #[test]
263     fn completes_bindings_from_if_let() {
264         check(
265             r#"
266 fn quux() {
267     if let Some(x) = foo() {
268         let y = 92;
269     };
270     if let Some(a) = bar() {
271         let b = 62;
272         1 + <|>
273     }
274 }
275 "#,
276             expect![[r#"
277                 bn a
278                 bn b      i32
279                 fn quux() fn quux()
280             "#]],
281         );
282     }
283
284     #[test]
285     fn completes_bindings_from_for() {
286         check(
287             r#"
288 fn quux() {
289     for x in &[1, 2, 3] { <|> }
290 }
291 "#,
292             expect![[r#"
293                 fn quux() fn quux()
294                 bn x
295             "#]],
296         );
297     }
298
299     #[test]
300     fn completes_if_prefix_is_keyword() {
301         mark::check!(completes_if_prefix_is_keyword);
302         check_edit(
303             "wherewolf",
304             r#"
305 fn main() {
306     let wherewolf = 92;
307     drop(where<|>)
308 }
309 "#,
310             r#"
311 fn main() {
312     let wherewolf = 92;
313     drop(wherewolf)
314 }
315 "#,
316         )
317     }
318
319     #[test]
320     fn completes_generic_params() {
321         check(
322             r#"fn quux<T>() { <|> }"#,
323             expect![[r#"
324                 tp T
325                 fn quux() fn quux<T>()
326             "#]],
327         );
328     }
329
330     #[test]
331     fn completes_generic_params_in_struct() {
332         check(
333             r#"struct S<T> { x: <|>}"#,
334             expect![[r#"
335                 st S<…>
336                 tp Self
337                 tp T
338             "#]],
339         );
340     }
341
342     #[test]
343     fn completes_self_in_enum() {
344         check(
345             r#"enum X { Y(<|>) }"#,
346             expect![[r#"
347                 tp Self
348                 en X
349             "#]],
350         );
351     }
352
353     #[test]
354     fn completes_module_items() {
355         check(
356             r#"
357 struct S;
358 enum E {}
359 fn quux() { <|> }
360 "#,
361             expect![[r#"
362                 en E
363                 st S
364                 fn quux() fn quux()
365             "#]],
366         );
367     }
368
369     /// Regression test for issue #6091.
370     #[test]
371     fn correctly_completes_module_items_prefixed_with_underscore() {
372         check_edit(
373             "_alpha",
374             r#"
375 fn main() {
376     _<|>
377 }
378 fn _alpha() {}
379 "#,
380             r#"
381 fn main() {
382     _alpha()$0
383 }
384 fn _alpha() {}
385 "#,
386         )
387     }
388
389     #[test]
390     fn completes_extern_prelude() {
391         check(
392             r#"
393 //- /lib.rs crate:main deps:other_crate
394 use <|>;
395
396 //- /other_crate/lib.rs crate:other_crate
397 // nothing here
398 "#,
399             expect![[r#"
400                 md other_crate
401             "#]],
402         );
403     }
404
405     #[test]
406     fn completes_module_items_in_nested_modules() {
407         check(
408             r#"
409 struct Foo;
410 mod m {
411     struct Bar;
412     fn quux() { <|> }
413 }
414 "#,
415             expect![[r#"
416                 st Bar
417                 fn quux() fn quux()
418             "#]],
419         );
420     }
421
422     #[test]
423     fn completes_return_type() {
424         check(
425             r#"
426 struct Foo;
427 fn x() -> <|>
428 "#,
429             expect![[r#"
430                 st Foo
431                 fn x() fn x()
432             "#]],
433         );
434     }
435
436     #[test]
437     fn dont_show_both_completions_for_shadowing() {
438         check(
439             r#"
440 fn foo() {
441     let bar = 92;
442     {
443         let bar = 62;
444         drop(<|>)
445     }
446 }
447 "#,
448             // FIXME: should be only one bar here
449             expect![[r#"
450                 bn bar   i32
451                 bn bar   i32
452                 fn foo() fn foo()
453             "#]],
454         );
455     }
456
457     #[test]
458     fn completes_self_in_methods() {
459         check(
460             r#"impl S { fn foo(&self) { <|> } }"#,
461             expect![[r#"
462                 tp Self
463                 bn self &{unknown}
464             "#]],
465         );
466     }
467
468     #[test]
469     fn completes_prelude() {
470         check(
471             r#"
472 //- /main.rs crate:main deps:std
473 fn foo() { let x: <|> }
474
475 //- /std/lib.rs crate:std
476 #[prelude_import]
477 use prelude::*;
478
479 mod prelude { struct Option; }
480 "#,
481             expect![[r#"
482                 st Option
483                 fn foo()  fn foo()
484                 md std
485             "#]],
486         );
487     }
488
489     #[test]
490     fn completes_std_prelude_if_core_is_defined() {
491         check(
492             r#"
493 //- /main.rs crate:main deps:core,std
494 fn foo() { let x: <|> }
495
496 //- /core/lib.rs crate:core
497 #[prelude_import]
498 use prelude::*;
499
500 mod prelude { struct Option; }
501
502 //- /std/lib.rs crate:std deps:core
503 #[prelude_import]
504 use prelude::*;
505
506 mod prelude { struct String; }
507 "#,
508             expect![[r#"
509                 st String
510                 md core
511                 fn foo()  fn foo()
512                 md std
513             "#]],
514         );
515     }
516
517     #[test]
518     fn completes_macros_as_value() {
519         check(
520             r#"
521 macro_rules! foo { () => {} }
522
523 #[macro_use]
524 mod m1 {
525     macro_rules! bar { () => {} }
526 }
527
528 mod m2 {
529     macro_rules! nope { () => {} }
530
531     #[macro_export]
532     macro_rules! baz { () => {} }
533 }
534
535 fn main() { let v = <|> }
536 "#,
537             expect![[r##"
538                 ma bar!(…) macro_rules! bar
539                 ma baz!(…) #[macro_export]
540                 macro_rules! baz
541                 ma foo!(…) macro_rules! foo
542                 md m1
543                 md m2
544                 fn main()  fn main()
545             "##]],
546         );
547     }
548
549     #[test]
550     fn completes_both_macro_and_value() {
551         check(
552             r#"
553 macro_rules! foo { () => {} }
554 fn foo() { <|> }
555 "#,
556             expect![[r#"
557                 ma foo!(…) macro_rules! foo
558                 fn foo()   fn foo()
559             "#]],
560         );
561     }
562
563     #[test]
564     fn completes_macros_as_type() {
565         check(
566             r#"
567 macro_rules! foo { () => {} }
568 fn main() { let x: <|> }
569 "#,
570             expect![[r#"
571                 ma foo!(…) macro_rules! foo
572                 fn main()  fn main()
573             "#]],
574         );
575     }
576
577     #[test]
578     fn completes_macros_as_stmt() {
579         check(
580             r#"
581 macro_rules! foo { () => {} }
582 fn main() { <|> }
583 "#,
584             expect![[r#"
585                 ma foo!(…) macro_rules! foo
586                 fn main()  fn main()
587             "#]],
588         );
589     }
590
591     #[test]
592     fn completes_local_item() {
593         check(
594             r#"
595 fn main() {
596     return f<|>;
597     fn frobnicate() {}
598 }
599 "#,
600             expect![[r#"
601                 fn frobnicate() fn frobnicate()
602                 fn main()       fn main()
603             "#]],
604         );
605     }
606
607     #[test]
608     fn completes_in_simple_macro_1() {
609         check(
610             r#"
611 macro_rules! m { ($e:expr) => { $e } }
612 fn quux(x: i32) {
613     let y = 92;
614     m!(<|>);
615 }
616 "#,
617             expect![[r#"
618                 ma m!(…)   macro_rules! m
619                 fn quux(…) fn quux(x: i32)
620                 bn x       i32
621                 bn y       i32
622             "#]],
623         );
624     }
625
626     #[test]
627     fn completes_in_simple_macro_2() {
628         check(
629             r"
630 macro_rules! m { ($e:expr) => { $e } }
631 fn quux(x: i32) {
632     let y = 92;
633     m!(x<|>);
634 }
635 ",
636             expect![[r#"
637                 ma m!(…)   macro_rules! m
638                 fn quux(…) fn quux(x: i32)
639                 bn x       i32
640                 bn y       i32
641             "#]],
642         );
643     }
644
645     #[test]
646     fn completes_in_simple_macro_without_closing_parens() {
647         check(
648             r#"
649 macro_rules! m { ($e:expr) => { $e } }
650 fn quux(x: i32) {
651     let y = 92;
652     m!(x<|>
653 }
654 "#,
655             expect![[r#"
656                 ma m!(…)   macro_rules! m
657                 fn quux(…) fn quux(x: i32)
658                 bn x       i32
659                 bn y       i32
660             "#]],
661         );
662     }
663
664     #[test]
665     fn completes_unresolved_uses() {
666         check(
667             r#"
668 use spam::Quux;
669
670 fn main() { <|> }
671 "#,
672             expect![[r#"
673                 ?? Quux
674                 fn main() fn main()
675             "#]],
676         );
677     }
678     #[test]
679     fn completes_enum_variant_matcharm() {
680         check(
681             r#"
682 enum Foo { Bar, Baz, Quux }
683
684 fn main() {
685     let foo = Foo::Quux;
686     match foo { Qu<|> }
687 }
688 "#,
689             expect![[r#"
690                 en Foo
691                 ev Foo::Bar  ()
692                 ev Foo::Baz  ()
693                 ev Foo::Quux ()
694             "#]],
695         )
696     }
697
698     #[test]
699     fn completes_enum_variant_iflet() {
700         check(
701             r#"
702 enum Foo { Bar, Baz, Quux }
703
704 fn main() {
705     let foo = Foo::Quux;
706     if let Qu<|> = foo { }
707 }
708 "#,
709             expect![[r#"
710                 en Foo
711                 ev Foo::Bar  ()
712                 ev Foo::Baz  ()
713                 ev Foo::Quux ()
714             "#]],
715         )
716     }
717
718     #[test]
719     fn completes_enum_variant_basic_expr() {
720         check(
721             r#"
722 enum Foo { Bar, Baz, Quux }
723 fn main() { let foo: Foo = Q<|> }
724 "#,
725             expect![[r#"
726                 en Foo
727                 ev Foo::Bar  ()
728                 ev Foo::Baz  ()
729                 ev Foo::Quux ()
730                 fn main()    fn main()
731             "#]],
732         )
733     }
734
735     #[test]
736     fn completes_enum_variant_from_module() {
737         check(
738             r#"
739 mod m { pub enum E { V } }
740 fn f() -> m::E { V<|> }
741 "#,
742             expect![[r#"
743                 fn f()     fn f() -> m::E
744                 md m
745                 ev m::E::V ()
746             "#]],
747         )
748     }
749
750     #[test]
751     fn dont_complete_attr() {
752         check(
753             r#"
754 struct Foo;
755 #[<|>]
756 fn f() {}
757 "#,
758             expect![[""]],
759         )
760     }
761
762     #[test]
763     fn completes_type_or_trait_in_impl_block() {
764         check(
765             r#"
766 trait MyTrait {}
767 struct MyStruct {}
768
769 impl My<|>
770 "#,
771             expect![[r#"
772                 st MyStruct
773                 tt MyTrait
774                 tp Self
775             "#]],
776         )
777     }
778
779     #[test]
780     fn function_fuzzy_completion() {
781         let mut completion_config = CompletionConfig::default();
782         completion_config
783             .active_resolve_capabilities
784             .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
785
786         check_edit_with_config(
787             completion_config,
788             "stdin",
789             r#"
790 //- /lib.rs crate:dep
791 pub mod io {
792     pub fn stdin() {}
793 };
794
795 //- /main.rs crate:main deps:dep
796 fn main() {
797     stdi<|>
798 }
799 "#,
800             r#"
801 use dep::io::stdin;
802
803 fn main() {
804     stdin()$0
805 }
806 "#,
807         );
808     }
809
810     #[test]
811     fn macro_fuzzy_completion() {
812         let mut completion_config = CompletionConfig::default();
813         completion_config
814             .active_resolve_capabilities
815             .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
816
817         check_edit_with_config(
818             completion_config,
819             "macro_with_curlies!",
820             r#"
821 //- /lib.rs crate:dep
822 /// Please call me as macro_with_curlies! {}
823 #[macro_export]
824 macro_rules! macro_with_curlies {
825     () => {}
826 }
827
828 //- /main.rs crate:main deps:dep
829 fn main() {
830     curli<|>
831 }
832 "#,
833             r#"
834 use dep::macro_with_curlies;
835
836 fn main() {
837     macro_with_curlies! {$0}
838 }
839 "#,
840         );
841     }
842
843     #[test]
844     fn struct_fuzzy_completion() {
845         let mut completion_config = CompletionConfig::default();
846         completion_config
847             .active_resolve_capabilities
848             .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
849
850         check_edit_with_config(
851             completion_config,
852             "ThirdStruct",
853             r#"
854 //- /lib.rs crate:dep
855 pub struct FirstStruct;
856 pub mod some_module {
857     pub struct SecondStruct;
858     pub struct ThirdStruct;
859 }
860
861 //- /main.rs crate:main deps:dep
862 use dep::{FirstStruct, some_module::SecondStruct};
863
864 fn main() {
865     this<|>
866 }
867 "#,
868             r#"
869 use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}};
870
871 fn main() {
872     ThirdStruct
873 }
874 "#,
875         );
876     }
877 }