aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ide_completion/src/completions/macro_in_item_position.rs5
-rw-r--r--crates/ide_completion/src/completions/qualified_path.rs30
-rw-r--r--crates/ide_completion/src/completions/unqualified_path.rs31
-rw-r--r--crates/ide_completion/src/patterns.rs1
4 files changed, 58 insertions, 9 deletions
diff --git a/crates/ide_completion/src/completions/macro_in_item_position.rs b/crates/ide_completion/src/completions/macro_in_item_position.rs
index c5e377500..ec57aee30 100644
--- a/crates/ide_completion/src/completions/macro_in_item_position.rs
+++ b/crates/ide_completion/src/completions/macro_in_item_position.rs
@@ -2,6 +2,7 @@
2 2
3use crate::{CompletionContext, Completions}; 3use crate::{CompletionContext, Completions};
4 4
5// Ideally this should be removed and moved into `(un)qualified_path` respectively
5pub(crate) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) { 6pub(crate) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) {
6 // Show only macros in top level. 7 // Show only macros in top level.
7 if !ctx.is_new_item { 8 if !ctx.is_new_item {
@@ -12,6 +13,10 @@ pub(crate) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &Compl
12 if let hir::ScopeDef::MacroDef(mac) = res { 13 if let hir::ScopeDef::MacroDef(mac) = res {
13 acc.add_macro(ctx, Some(name.to_string()), mac); 14 acc.add_macro(ctx, Some(name.to_string()), mac);
14 } 15 }
16 // FIXME: This should be done in qualified_path/unqualified_path instead?
17 if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
18 acc.add_resolution(ctx, name.to_string(), &res);
19 }
15 }) 20 })
16} 21}
17 22
diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs
index c16bb215f..7a0e1ead3 100644
--- a/crates/ide_completion/src/completions/qualified_path.rs
+++ b/crates/ide_completion/src/completions/qualified_path.rs
@@ -7,7 +7,7 @@ use syntax::AstNode;
7use crate::{CompletionContext, Completions}; 7use crate::{CompletionContext, Completions};
8 8
9pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) { 9pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
10 if ctx.is_path_disallowed() { 10 if ctx.is_path_disallowed() || ctx.expects_item() {
11 return; 11 return;
12 } 12 }
13 let path = match &ctx.path_qual { 13 let path = match &ctx.path_qual {
@@ -20,13 +20,16 @@ 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() { 23 if ctx.expects_assoc_item() {
24 if let PathResolution::Def(hir::ModuleDef::Module(module)) = resolution { 24 if let PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
25 let module_scope = module.scope(ctx.db, context_module); 25 let module_scope = module.scope(ctx.db, context_module);
26 for (name, def) in module_scope { 26 for (name, def) in module_scope {
27 if let ScopeDef::MacroDef(macro_def) = def { 27 if let ScopeDef::MacroDef(macro_def) = def {
28 acc.add_macro(ctx, Some(name.to_string()), macro_def); 28 acc.add_macro(ctx, Some(name.to_string()), macro_def);
29 } 29 }
30 if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
31 acc.add_resolution(ctx, name.to_string(), &def);
32 }
30 } 33 }
31 } 34 }
32 return; 35 return;
@@ -614,25 +617,44 @@ fn main() { let _ = crate::$0 }
614 } 617 }
615 618
616 #[test] 619 #[test]
617 fn completes_qualified_macros_in_impl() { 620 fn completes_in_assoc_item_list() {
618 check( 621 check(
619 r#" 622 r#"
620#[macro_export] 623#[macro_export]
621macro_rules! foo { () => {} } 624macro_rules! foo { () => {} }
625mod bar {}
622 626
623struct MyStruct {} 627struct MyStruct {}
624
625impl MyStruct { 628impl MyStruct {
626 crate::$0 629 crate::$0
627} 630}
628"#, 631"#,
629 expect![[r##" 632 expect![[r##"
633 md bar
630 ma foo! #[macro_export] macro_rules! foo 634 ma foo! #[macro_export] macro_rules! foo
631 "##]], 635 "##]],
632 ); 636 );
633 } 637 }
634 638
635 #[test] 639 #[test]
640 #[ignore] // FIXME doesn't complete anything atm
641 fn completes_in_item_list() {
642 check(
643 r#"
644struct MyStruct {}
645macro_rules! foo {}
646mod bar {}
647
648crate::$0
649"#,
650 expect![[r#"
651 md bar
652 ma foo! macro_rules! foo
653 "#]],
654 )
655 }
656
657 #[test]
636 fn test_super_super_completion() { 658 fn test_super_super_completion() {
637 check( 659 check(
638 r#" 660 r#"
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs
index cbac88240..c901b358b 100644
--- a/crates/ide_completion/src/completions/unqualified_path.rs
+++ b/crates/ide_completion/src/completions/unqualified_path.rs
@@ -9,14 +9,17 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
9 if !ctx.is_trivial_path { 9 if !ctx.is_trivial_path {
10 return; 10 return;
11 } 11 }
12 if ctx.is_path_disallowed() { 12 if ctx.is_path_disallowed() || ctx.expects_item() {
13 return; 13 return;
14 } 14 }
15 if ctx.expects_item() || ctx.expects_assoc_item() { 15 if ctx.expects_assoc_item() {
16 ctx.scope.process_all_names(&mut |name, def| { 16 ctx.scope.process_all_names(&mut |name, def| {
17 if let ScopeDef::MacroDef(macro_def) = def { 17 if let ScopeDef::MacroDef(macro_def) = def {
18 acc.add_macro(ctx, Some(name.to_string()), macro_def); 18 acc.add_macro(ctx, Some(name.to_string()), macro_def);
19 } 19 }
20 if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
21 acc.add_resolution(ctx, name.to_string(), &def);
22 }
20 }); 23 });
21 return; 24 return;
22 } 25 }
@@ -672,19 +675,39 @@ impl My$0
672 } 675 }
673 676
674 #[test] 677 #[test]
675 fn only_completes_macros_in_assoc_item_list() { 678 fn completes_in_assoc_item_list() {
676 check( 679 check(
677 r#" 680 r#"
678struct MyStruct {}
679macro_rules! foo {} 681macro_rules! foo {}
682mod bar {}
680 683
684struct MyStruct {}
681impl MyStruct { 685impl MyStruct {
682 $0 686 $0
683} 687}
684"#, 688"#,
685 expect![[r#" 689 expect![[r#"
690 md bar
686 ma foo! macro_rules! foo 691 ma foo! macro_rules! foo
687 "#]], 692 "#]],
688 ) 693 )
689 } 694 }
695
696 // FIXME: The completions here currently come from `macro_in_item_position`, but they shouldn't
697 #[test]
698 fn completes_in_item_list() {
699 check(
700 r#"
701struct MyStruct {}
702macro_rules! foo {}
703mod bar {}
704
705$0
706"#,
707 expect![[r#"
708 md bar
709 ma foo!(…) macro_rules! foo
710 "#]],
711 )
712 }
690} 713}
diff --git a/crates/ide_completion/src/patterns.rs b/crates/ide_completion/src/patterns.rs
index ed289d561..19e42ba43 100644
--- a/crates/ide_completion/src/patterns.rs
+++ b/crates/ide_completion/src/patterns.rs
@@ -62,7 +62,6 @@ pub(crate) fn determine_location(tok: SyntaxToken) -> Option<ImmediateLocation>
62 ast::SourceFile(_it) => ImmediateLocation::ItemList, 62 ast::SourceFile(_it) => ImmediateLocation::ItemList,
63 ast::ItemList(_it) => ImmediateLocation::ItemList, 63 ast::ItemList(_it) => ImmediateLocation::ItemList,
64 ast::RefExpr(_it) => ImmediateLocation::RefExpr, 64 ast::RefExpr(_it) => ImmediateLocation::RefExpr,
65 ast::RefPat(_it) => ImmediateLocation::RefExpr,
66 ast::RecordField(_it) => ImmediateLocation::RecordField, 65 ast::RecordField(_it) => ImmediateLocation::RecordField,
67 ast::AssocItemList(it) => match it.syntax().parent().map(|it| it.kind()) { 66 ast::AssocItemList(it) => match it.syntax().parent().map(|it| it.kind()) {
68 Some(IMPL) => ImmediateLocation::Impl, 67 Some(IMPL) => ImmediateLocation::Impl,