aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/completions
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/completions')
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs6
-rw-r--r--crates/ide_completion/src/completions/keyword.rs29
-rw-r--r--crates/ide_completion/src/completions/qualified_path.rs32
-rw-r--r--crates/ide_completion/src/completions/unqualified_path.rs27
4 files changed, 76 insertions, 18 deletions
diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs
index be9cfbded..df27e7a84 100644
--- a/crates/ide_completion/src/completions/flyimport.rs
+++ b/crates/ide_completion/src/completions/flyimport.rs
@@ -110,7 +110,11 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
110 if !ctx.config.enable_imports_on_the_fly { 110 if !ctx.config.enable_imports_on_the_fly {
111 return None; 111 return None;
112 } 112 }
113 if ctx.use_item_syntax.is_some() || ctx.is_path_disallowed() { 113 if ctx.use_item_syntax.is_some()
114 || ctx.is_path_disallowed()
115 || ctx.expects_item()
116 || ctx.expects_assoc_item()
117 {
114 return None; 118 return None;
115 } 119 }
116 let potential_import_name = { 120 let potential_import_name = {
diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs
index 58e35bad9..96447a603 100644
--- a/crates/ide_completion/src/completions/keyword.rs
+++ b/crates/ide_completion/src/completions/keyword.rs
@@ -49,35 +49,35 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
49 return; 49 return;
50 } 50 }
51 51
52 let has_trait_or_impl_parent = ctx.has_impl_or_trait_parent(); 52 let expects_assoc_item = ctx.expects_assoc_item();
53 let has_block_expr_parent = ctx.has_block_expr_parent(); 53 let has_block_expr_parent = ctx.has_block_expr_parent();
54 let has_item_list_parent = ctx.has_item_list_parent(); 54 let expects_item = ctx.expects_item();
55 if ctx.has_impl_or_trait_prev_sibling() { 55 if ctx.has_impl_or_trait_prev_sibling() {
56 add_keyword(ctx, acc, "where", "where "); 56 add_keyword(ctx, acc, "where", "where ");
57 return; 57 return;
58 } 58 }
59 if ctx.previous_token_is(T![unsafe]) { 59 if ctx.previous_token_is(T![unsafe]) {
60 if has_item_list_parent || has_block_expr_parent { 60 if expects_item || has_block_expr_parent {
61 add_keyword(ctx, acc, "fn", "fn $1($2) {\n $0\n}") 61 add_keyword(ctx, acc, "fn", "fn $1($2) {\n $0\n}")
62 } 62 }
63 63
64 if has_item_list_parent || has_block_expr_parent { 64 if expects_item || has_block_expr_parent {
65 add_keyword(ctx, acc, "trait", "trait $1 {\n $0\n}"); 65 add_keyword(ctx, acc, "trait", "trait $1 {\n $0\n}");
66 add_keyword(ctx, acc, "impl", "impl $1 {\n $0\n}"); 66 add_keyword(ctx, acc, "impl", "impl $1 {\n $0\n}");
67 } 67 }
68 68
69 return; 69 return;
70 } 70 }
71 if has_item_list_parent || has_trait_or_impl_parent || has_block_expr_parent { 71 if expects_item || expects_assoc_item || has_block_expr_parent {
72 add_keyword(ctx, acc, "fn", "fn $1($2) {\n $0\n}"); 72 add_keyword(ctx, acc, "fn", "fn $1($2) {\n $0\n}");
73 } 73 }
74 if has_item_list_parent || has_block_expr_parent { 74 if expects_item || has_block_expr_parent {
75 add_keyword(ctx, acc, "use", "use "); 75 add_keyword(ctx, acc, "use", "use ");
76 add_keyword(ctx, acc, "impl", "impl $1 {\n $0\n}"); 76 add_keyword(ctx, acc, "impl", "impl $1 {\n $0\n}");
77 add_keyword(ctx, acc, "trait", "trait $1 {\n $0\n}"); 77 add_keyword(ctx, acc, "trait", "trait $1 {\n $0\n}");
78 } 78 }
79 79
80 if has_item_list_parent { 80 if expects_item {
81 add_keyword(ctx, acc, "enum", "enum $1 {\n $0\n}"); 81 add_keyword(ctx, acc, "enum", "enum $1 {\n $0\n}");
82 add_keyword(ctx, acc, "struct", "struct $0"); 82 add_keyword(ctx, acc, "struct", "struct $0");
83 add_keyword(ctx, acc, "union", "union $1 {\n $0\n}"); 83 add_keyword(ctx, acc, "union", "union $1 {\n $0\n}");
@@ -101,24 +101,23 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
101 add_keyword(ctx, acc, "else", "else {\n $0\n}"); 101 add_keyword(ctx, acc, "else", "else {\n $0\n}");
102 add_keyword(ctx, acc, "else if", "else if $1 {\n $0\n}"); 102 add_keyword(ctx, acc, "else if", "else if $1 {\n $0\n}");
103 } 103 }
104 if has_item_list_parent || has_block_expr_parent { 104 if expects_item || has_block_expr_parent {
105 add_keyword(ctx, acc, "mod", "mod $0"); 105 add_keyword(ctx, acc, "mod", "mod $0");
106 } 106 }
107 if ctx.has_ident_or_ref_pat_parent() { 107 if ctx.expects_ident_pat_or_ref_expr() {
108 add_keyword(ctx, acc, "mut", "mut "); 108 add_keyword(ctx, acc, "mut", "mut ");
109 } 109 }
110 if has_item_list_parent || has_trait_or_impl_parent || has_block_expr_parent { 110 if expects_item || expects_assoc_item || has_block_expr_parent {
111 add_keyword(ctx, acc, "const", "const "); 111 add_keyword(ctx, acc, "const", "const ");
112 add_keyword(ctx, acc, "type", "type "); 112 add_keyword(ctx, acc, "type", "type ");
113 } 113 }
114 if has_item_list_parent || has_block_expr_parent { 114 if expects_item || has_block_expr_parent {
115 add_keyword(ctx, acc, "static", "static "); 115 add_keyword(ctx, acc, "static", "static ");
116 }; 116 };
117 if has_item_list_parent || has_block_expr_parent { 117 if expects_item || has_block_expr_parent {
118 add_keyword(ctx, acc, "extern", "extern "); 118 add_keyword(ctx, acc, "extern", "extern ");
119 } 119 }
120 if has_item_list_parent || has_trait_or_impl_parent || has_block_expr_parent || ctx.is_match_arm 120 if expects_item || expects_assoc_item || has_block_expr_parent || ctx.is_match_arm {
121 {
122 add_keyword(ctx, acc, "unsafe", "unsafe "); 121 add_keyword(ctx, acc, "unsafe", "unsafe ");
123 } 122 }
124 if ctx.in_loop_body { 123 if ctx.in_loop_body {
@@ -130,7 +129,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
130 add_keyword(ctx, acc, "break", "break"); 129 add_keyword(ctx, acc, "break", "break");
131 } 130 }
132 } 131 }
133 if has_item_list_parent || ctx.has_impl_parent() || ctx.has_field_list_parent() { 132 if expects_item || ctx.expects_non_trait_assoc_item() || ctx.expect_record_field() {
134 add_keyword(ctx, acc, "pub(crate)", "pub(crate) "); 133 add_keyword(ctx, acc, "pub(crate)", "pub(crate) ");
135 add_keyword(ctx, acc, "pub", "pub "); 134 add_keyword(ctx, acc, "pub", "pub ");
136 } 135 }
diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs
index ed48f61af..c16bb215f 100644
--- a/crates/ide_completion/src/completions/qualified_path.rs
+++ b/crates/ide_completion/src/completions/qualified_path.rs
@@ -20,6 +20,17 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
20 None => return, 20 None => return,
21 }; 21 };
22 let context_module = ctx.scope.module(); 22 let context_module = ctx.scope.module();
23 if ctx.expects_item() || ctx.expects_assoc_item() {
24 if let PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
25 let module_scope = module.scope(ctx.db, context_module);
26 for (name, def) in module_scope {
27 if let ScopeDef::MacroDef(macro_def) = def {
28 acc.add_macro(ctx, Some(name.to_string()), macro_def);
29 }
30 }
31 }
32 return;
33 }
23 34
24 // Add associated types on type parameters and `Self`. 35 // Add associated types on type parameters and `Self`.
25 resolution.assoc_type_shorthand_candidates(ctx.db, |_, alias| { 36 resolution.assoc_type_shorthand_candidates(ctx.db, |_, alias| {
@@ -594,7 +605,7 @@ fn main() { T::$0; }
594macro_rules! foo { () => {} } 605macro_rules! foo { () => {} }
595 606
596fn main() { let _ = crate::$0 } 607fn main() { let _ = crate::$0 }
597 "#, 608"#,
598 expect![[r##" 609 expect![[r##"
599 fn main() fn() 610 fn main() fn()
600 ma foo!(…) #[macro_export] macro_rules! foo 611 ma foo!(…) #[macro_export] macro_rules! foo
@@ -603,6 +614,25 @@ fn main() { let _ = crate::$0 }
603 } 614 }
604 615
605 #[test] 616 #[test]
617 fn completes_qualified_macros_in_impl() {
618 check(
619 r#"
620#[macro_export]
621macro_rules! foo { () => {} }
622
623struct MyStruct {}
624
625impl MyStruct {
626 crate::$0
627}
628"#,
629 expect![[r##"
630 ma foo! #[macro_export] macro_rules! foo
631 "##]],
632 );
633 }
634
635 #[test]
606 fn test_super_super_completion() { 636 fn test_super_super_completion() {
607 check( 637 check(
608 r#" 638 r#"
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs
index 046a393ae..cbac88240 100644
--- a/crates/ide_completion/src/completions/unqualified_path.rs
+++ b/crates/ide_completion/src/completions/unqualified_path.rs
@@ -12,6 +12,14 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
12 if ctx.is_path_disallowed() { 12 if ctx.is_path_disallowed() {
13 return; 13 return;
14 } 14 }
15 if ctx.expects_item() || ctx.expects_assoc_item() {
16 ctx.scope.process_all_names(&mut |name, def| {
17 if let ScopeDef::MacroDef(macro_def) = def {
18 acc.add_macro(ctx, Some(name.to_string()), macro_def);
19 }
20 });
21 return;
22 }
15 23
16 if let Some(hir::Adt::Enum(e)) = 24 if let Some(hir::Adt::Enum(e)) =
17 ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt()) 25 ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
@@ -647,7 +655,7 @@ fn f() {}
647 } 655 }
648 656
649 #[test] 657 #[test]
650 fn completes_type_or_trait_in_impl_block() { 658 fn completes_target_type_or_trait_in_impl_block() {
651 check( 659 check(
652 r#" 660 r#"
653trait MyTrait {} 661trait MyTrait {}
@@ -662,4 +670,21 @@ impl My$0
662 "#]], 670 "#]],
663 ) 671 )
664 } 672 }
673
674 #[test]
675 fn only_completes_macros_in_assoc_item_list() {
676 check(
677 r#"
678struct MyStruct {}
679macro_rules! foo {}
680
681impl MyStruct {
682 $0
683}
684"#,
685 expect![[r#"
686 ma foo! macro_rules! foo
687 "#]],
688 )
689 }
665} 690}