diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index c925d242a4..c1081dbde3 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -22,7 +22,7 @@ pub(crate) mod vis; use std::iter; -use hir::{db::HirDatabase, known, ScopeDef}; +use hir::{known, ScopeDef}; use ide_db::SymbolKind; use syntax::ast; @@ -46,22 +46,6 @@ use crate::{ CompletionContext, CompletionItem, CompletionItemKind, }; -fn module_or_attr(db: &dyn HirDatabase, def: ScopeDef) -> Option { - match def { - ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_attr(db) => Some(def), - ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => Some(def), - _ => None, - } -} - -fn module_or_fn_macro(db: &dyn HirDatabase, def: ScopeDef) -> Option { - match def { - ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_fn_like(db) => Some(def), - ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => Some(def), - _ => None, - } -} - /// Represents an in-progress set of completions being built. #[derive(Debug, Default)] pub struct Completions { @@ -184,6 +168,15 @@ impl Completions { self.add(render_resolution_simple(RenderContext::new(ctx), local_name, resolution).build()); } + pub(crate) fn add_module( + &mut self, + ctx: &CompletionContext, + module: hir::Module, + local_name: hir::Name, + ) { + self.add_resolution(ctx, local_name, hir::ScopeDef::ModuleDef(module.into())); + } + pub(crate) fn add_macro( &mut self, ctx: &CompletionContext, @@ -486,16 +479,19 @@ pub(super) fn complete_name_ref( match kind { NameRefKind::Path(path_ctx) => { flyimport::import_on_the_fly_path(acc, ctx, path_ctx); + match &path_ctx.kind { PathKind::Expr { expr_ctx } => { - dot::complete_undotted_self(acc, ctx, path_ctx, expr_ctx); expr::complete_expr_path(acc, ctx, path_ctx, expr_ctx); + + dot::complete_undotted_self(acc, ctx, path_ctx, expr_ctx); item_list::complete_item_list_in_expr(acc, ctx, path_ctx, expr_ctx); record::complete_record_expr_func_update(acc, ctx, path_ctx, expr_ctx); snippet::complete_expr_snippet(acc, ctx, path_ctx, expr_ctx); } PathKind::Type { location } => { r#type::complete_type_path(acc, ctx, path_ctx, location); + match location { TypeLocation::TupleField => { field::complete_field_list_tuple_variant(acc, ctx, path_ctx); @@ -511,13 +507,14 @@ pub(super) fn complete_name_ref( } } PathKind::Attr { attr_ctx } => { - attribute::complete_attribute(acc, ctx, path_ctx, attr_ctx); + attribute::complete_attribute_path(acc, ctx, path_ctx, attr_ctx); } PathKind::Derive { existing_derives } => { - attribute::complete_derive(acc, ctx, path_ctx, existing_derives); + attribute::complete_derive_path(acc, ctx, path_ctx, existing_derives); } PathKind::Item { kind } => { item_list::complete_item_list(acc, ctx, path_ctx, kind); + snippet::complete_item_snippet(acc, ctx, path_ctx, kind); if let ItemListKind::TraitImpl(impl_) = kind { item_list::trait_impl::complete_trait_impl_item_by_name( @@ -532,7 +529,7 @@ pub(super) fn complete_name_ref( vis::complete_vis_path(acc, ctx, path_ctx, has_in_token); } PathKind::Use => { - use_::complete_use_tree(acc, ctx, path_ctx, nameref); + use_::complete_use_path(acc, ctx, path_ctx, nameref); } } } diff --git a/crates/ide-completion/src/completions/attribute.rs b/crates/ide-completion/src/completions/attribute.rs index 712163d81d..37e042a160 100644 --- a/crates/ide-completion/src/completions/attribute.rs +++ b/crates/ide-completion/src/completions/attribute.rs @@ -17,7 +17,6 @@ use syntax::{ }; use crate::{ - completions::module_or_attr, context::{AttrCtx, CompletionContext, PathCompletionCtx, Qualified}, item::CompletionItem, Completions, @@ -28,7 +27,7 @@ mod derive; mod lint; mod repr; -pub(crate) use self::derive::complete_derive; +pub(crate) use self::derive::complete_derive_path; /// Complete inputs to known builtin attributes as well as derive attributes pub(crate) fn complete_known_attribute_input( @@ -69,7 +68,7 @@ pub(crate) fn complete_known_attribute_input( Some(()) } -pub(crate) fn complete_attribute( +pub(crate) fn complete_attribute_path( acc: &mut Completions, ctx: &CompletionContext, PathCompletionCtx { qualified, .. }: &PathCompletionCtx, @@ -88,8 +87,14 @@ pub(crate) fn complete_attribute( } for (name, def) in module.scope(ctx.db, Some(ctx.module)) { - if let Some(def) = module_or_attr(ctx.db, def) { - acc.add_resolution(ctx, name, def); + match def { + hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_attr(ctx.db) => { + acc.add_macro(ctx, m, name) + } + hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => { + acc.add_module(ctx, m, name) + } + _ => (), } } return; @@ -98,10 +103,12 @@ pub(crate) fn complete_attribute( Qualified::Absolute => acc.add_crate_roots(ctx), // only show modules in a fresh UseTree Qualified::No => { - ctx.process_all_names(&mut |name, def| { - if let Some(def) = module_or_attr(ctx.db, def) { - acc.add_resolution(ctx, name, def); + ctx.process_all_names(&mut |name, def| match def { + hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_attr(ctx.db) => { + acc.add_macro(ctx, m, name) } + hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => acc.add_module(ctx, m, name), + _ => (), }); acc.add_nameref_keywords_with_colon(ctx); } diff --git a/crates/ide-completion/src/completions/attribute/derive.rs b/crates/ide-completion/src/completions/attribute/derive.rs index 5dee4d7956..0e10f38153 100644 --- a/crates/ide-completion/src/completions/attribute/derive.rs +++ b/crates/ide-completion/src/completions/attribute/derive.rs @@ -10,7 +10,7 @@ use crate::{ Completions, }; -pub(crate) fn complete_derive( +pub(crate) fn complete_derive_path( acc: &mut Completions, ctx: &CompletionContext, PathCompletionCtx { qualified, .. }: &PathCompletionCtx, @@ -29,15 +29,14 @@ pub(crate) fn complete_derive( } for (name, def) in module.scope(ctx.db, Some(ctx.module)) { - let add_def = match def { - ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => { - !existing_derives.contains(&mac) && mac.is_derive(ctx.db) + match def { + ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) + if !existing_derives.contains(&mac) && mac.is_derive(ctx.db) => + { + acc.add_macro(ctx, mac, name) } - ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => true, - _ => false, - }; - if add_def { - acc.add_resolution(ctx, name, def); + ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => acc.add_module(ctx, m, name), + _ => (), } } } @@ -51,8 +50,8 @@ pub(crate) fn complete_derive( { mac } - ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => { - return acc.add_resolution(ctx, name, def); + ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => { + return acc.add_module(ctx, m, name); } _ => return, }; @@ -60,7 +59,7 @@ pub(crate) fn complete_derive( match (core, mac.module(ctx.db).krate()) { // show derive dependencies for `core`/`std` derives (Some(core), mac_krate) if core == mac_krate => {} - _ => return acc.add_resolution(ctx, name, def), + _ => return acc.add_macro(ctx, mac, name), }; let name_ = name.to_smol_str(); @@ -93,7 +92,7 @@ pub(crate) fn complete_derive( item.lookup_by(lookup); item.add_to(acc); } - None => acc.add_resolution(ctx, name, def), + None => acc.add_macro(ctx, mac, name), } }); acc.add_nameref_keywords_with_colon(ctx); diff --git a/crates/ide-completion/src/completions/item_list.rs b/crates/ide-completion/src/completions/item_list.rs index 33130028db..e697e1971e 100644 --- a/crates/ide-completion/src/completions/item_list.rs +++ b/crates/ide-completion/src/completions/item_list.rs @@ -1,7 +1,6 @@ //! Completion of paths and keywords at item list position. use crate::{ - completions::module_or_fn_macro, context::{ExprCtx, ItemListKind, PathCompletionCtx, Qualified}, CompletionContext, Completions, }; @@ -41,8 +40,14 @@ pub(crate) fn complete_item_list( .. } => { for (name, def) in module.scope(ctx.db, Some(ctx.module)) { - if let Some(def) = module_or_fn_macro(ctx.db, def) { - acc.add_resolution(ctx, name, def); + match def { + hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_fn_like(ctx.db) => { + acc.add_macro(ctx, m, name) + } + hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => { + acc.add_module(ctx, m, name) + } + _ => (), } } @@ -52,10 +57,12 @@ pub(crate) fn complete_item_list( } Qualified::Absolute => acc.add_crate_roots(ctx), Qualified::No if ctx.qualifier_ctx.none() => { - ctx.process_all_names(&mut |name, def| { - if let Some(def) = module_or_fn_macro(ctx.db, def) { - acc.add_resolution(ctx, name, def); + ctx.process_all_names(&mut |name, def| match def { + hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_fn_like(ctx.db) => { + acc.add_macro(ctx, m, name) } + hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => acc.add_module(ctx, m, name), + _ => (), }); acc.add_nameref_keywords_with_colon(ctx); } diff --git a/crates/ide-completion/src/completions/use_.rs b/crates/ide-completion/src/completions/use_.rs index 9ebbc8ab9d..f262355fc0 100644 --- a/crates/ide-completion/src/completions/use_.rs +++ b/crates/ide-completion/src/completions/use_.rs @@ -10,7 +10,7 @@ use crate::{ CompletionItem, CompletionItemKind, CompletionRelevance, Completions, }; -pub(crate) fn complete_use_tree( +pub(crate) fn complete_use_path( acc: &mut Completions, ctx: &CompletionContext, PathCompletionCtx { qualified, use_tree_parent, .. }: &PathCompletionCtx, @@ -96,8 +96,8 @@ pub(crate) fn complete_use_tree( cov_mark::hit!(unqualified_path_selected_only); ctx.process_all_names(&mut |name, res| { match res { - ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => { - acc.add_resolution(ctx, name, res); + ScopeDef::ModuleDef(hir::ModuleDef::Module(module)) => { + acc.add_module(ctx, module, name); } ScopeDef::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(e))) => { // exclude prelude enum diff --git a/crates/ide-completion/src/completions/vis.rs b/crates/ide-completion/src/completions/vis.rs index 86ffe32ff3..30de0e94f7 100644 --- a/crates/ide-completion/src/completions/vis.rs +++ b/crates/ide-completion/src/completions/vis.rs @@ -1,7 +1,5 @@ //! Completion for visibility specifiers. -use hir::ScopeDef; - use crate::{ context::{CompletionContext, PathCompletionCtx, Qualified}, Completions, @@ -25,7 +23,7 @@ pub(crate) fn complete_vis_path( if let Some(next) = next_towards_current { if let Some(name) = next.name(ctx.db) { cov_mark::hit!(visibility_qualified); - acc.add_resolution(ctx, name, ScopeDef::ModuleDef(next.into())); + acc.add_module(ctx, next, name); } }