diff options
Diffstat (limited to 'crates/ide_completion')
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 | ||
3 | use crate::{CompletionContext, Completions}; | 3 | use crate::{CompletionContext, Completions}; |
4 | 4 | ||
5 | // Ideally this should be removed and moved into `(un)qualified_path` respectively | ||
5 | pub(crate) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) { | 6 | pub(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; | |||
7 | use crate::{CompletionContext, Completions}; | 7 | use crate::{CompletionContext, Completions}; |
8 | 8 | ||
9 | pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) { | 9 | pub(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] |
621 | macro_rules! foo { () => {} } | 624 | macro_rules! foo { () => {} } |
625 | mod bar {} | ||
622 | 626 | ||
623 | struct MyStruct {} | 627 | struct MyStruct {} |
624 | |||
625 | impl MyStruct { | 628 | impl 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#" | ||
644 | struct MyStruct {} | ||
645 | macro_rules! foo {} | ||
646 | mod bar {} | ||
647 | |||
648 | crate::$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#" |
678 | struct MyStruct {} | ||
679 | macro_rules! foo {} | 681 | macro_rules! foo {} |
682 | mod bar {} | ||
680 | 683 | ||
684 | struct MyStruct {} | ||
681 | impl MyStruct { | 685 | impl 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#" | ||
701 | struct MyStruct {} | ||
702 | macro_rules! foo {} | ||
703 | mod 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, |