From 7ad378fec06dae4ba2417f2a109e4759bbcf75db Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 27 May 2021 20:53:38 +0200 Subject: Complete modules in assoc item lists --- crates/ide_completion/src/completions/qualified_path.rs | 8 ++++++-- crates/ide_completion/src/completions/unqualified_path.rs | 9 +++++++-- crates/ide_completion/src/patterns.rs | 1 - 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs index c16bb215f..4aa37df91 100644 --- a/crates/ide_completion/src/completions/qualified_path.rs +++ b/crates/ide_completion/src/completions/qualified_path.rs @@ -27,6 +27,9 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon if let ScopeDef::MacroDef(macro_def) = def { acc.add_macro(ctx, Some(name.to_string()), macro_def); } + if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def { + acc.add_resolution(ctx, name.to_string(), &def); + } } } return; @@ -614,19 +617,20 @@ fn main() { let _ = crate::$0 } } #[test] - fn completes_qualified_macros_in_impl() { + fn completes_in_assoc_item_list() { check( r#" #[macro_export] macro_rules! foo { () => {} } +mod bar {} struct MyStruct {} - impl MyStruct { crate::$0 } "#, expect![[r##" + md bar ma foo! #[macro_export] macro_rules! foo "##]], ); diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs index cbac88240..dc93e368d 100644 --- a/crates/ide_completion/src/completions/unqualified_path.rs +++ b/crates/ide_completion/src/completions/unqualified_path.rs @@ -17,6 +17,9 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC if let ScopeDef::MacroDef(macro_def) = def { acc.add_macro(ctx, Some(name.to_string()), macro_def); } + if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def { + acc.add_resolution(ctx, name.to_string(), &def); + } }); return; } @@ -672,17 +675,19 @@ impl My$0 } #[test] - fn only_completes_macros_in_assoc_item_list() { + fn completes_in_assoc_item_list() { check( r#" -struct MyStruct {} macro_rules! foo {} +mod bar {} +struct MyStruct {} impl MyStruct { $0 } "#, expect![[r#" + md bar ma foo! macro_rules! foo "#]], ) 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 ast::SourceFile(_it) => ImmediateLocation::ItemList, ast::ItemList(_it) => ImmediateLocation::ItemList, ast::RefExpr(_it) => ImmediateLocation::RefExpr, - ast::RefPat(_it) => ImmediateLocation::RefExpr, ast::RecordField(_it) => ImmediateLocation::RecordField, ast::AssocItemList(it) => match it.syntax().parent().map(|it| it.kind()) { Some(IMPL) => ImmediateLocation::Impl, -- cgit v1.2.3 From ea251cbd4a22c7754bb5668b9f25fc0c7b47284c Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 27 May 2021 21:12:50 +0200 Subject: Complete modules in item lists --- .../src/completions/macro_in_item_position.rs | 5 +++++ .../src/completions/qualified_path.rs | 22 ++++++++++++++++++++-- .../src/completions/unqualified_path.rs | 22 ++++++++++++++++++++-- 3 files changed, 45 insertions(+), 4 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 @@ use crate::{CompletionContext, Completions}; +// Ideally this should be removed and moved into `(un)qualified_path` respectively pub(crate) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &CompletionContext) { // Show only macros in top level. if !ctx.is_new_item { @@ -12,6 +13,10 @@ pub(crate) fn complete_macro_in_item_position(acc: &mut Completions, ctx: &Compl if let hir::ScopeDef::MacroDef(mac) = res { acc.add_macro(ctx, Some(name.to_string()), mac); } + // FIXME: This should be done in qualified_path/unqualified_path instead? + if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res { + acc.add_resolution(ctx, name.to_string(), &res); + } }) } diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs index 4aa37df91..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; use crate::{CompletionContext, Completions}; pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) { - if ctx.is_path_disallowed() { + if ctx.is_path_disallowed() || ctx.expects_item() { return; } let path = match &ctx.path_qual { @@ -20,7 +20,7 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon None => return, }; let context_module = ctx.scope.module(); - if ctx.expects_item() || ctx.expects_assoc_item() { + if ctx.expects_assoc_item() { if let PathResolution::Def(hir::ModuleDef::Module(module)) = resolution { let module_scope = module.scope(ctx.db, context_module); for (name, def) in module_scope { @@ -636,6 +636,24 @@ impl MyStruct { ); } + #[test] + #[ignore] // FIXME doesn't complete anything atm + fn completes_in_item_list() { + check( + r#" +struct MyStruct {} +macro_rules! foo {} +mod bar {} + +crate::$0 +"#, + expect![[r#" + md bar + ma foo! macro_rules! foo + "#]], + ) + } + #[test] fn test_super_super_completion() { check( diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs index dc93e368d..c901b358b 100644 --- a/crates/ide_completion/src/completions/unqualified_path.rs +++ b/crates/ide_completion/src/completions/unqualified_path.rs @@ -9,10 +9,10 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC if !ctx.is_trivial_path { return; } - if ctx.is_path_disallowed() { + if ctx.is_path_disallowed() || ctx.expects_item() { return; } - if ctx.expects_item() || ctx.expects_assoc_item() { + if ctx.expects_assoc_item() { ctx.scope.process_all_names(&mut |name, def| { if let ScopeDef::MacroDef(macro_def) = def { acc.add_macro(ctx, Some(name.to_string()), macro_def); @@ -692,4 +692,22 @@ impl MyStruct { "#]], ) } + + // FIXME: The completions here currently come from `macro_in_item_position`, but they shouldn't + #[test] + fn completes_in_item_list() { + check( + r#" +struct MyStruct {} +macro_rules! foo {} +mod bar {} + +$0 +"#, + expect![[r#" + md bar + ma foo!(…) macro_rules! foo + "#]], + ) + } } -- cgit v1.2.3