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