From 5c69df93df2746d0bd97ec81c48668729568dcb9 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 20 Jun 2022 13:17:30 +0200 Subject: [PATCH 1/4] Split remaining completion calls on the context kinds --- .../ide-completion/src/completions/field.rs | 20 +-- .../src/completions/item_list/trait_impl.rs | 59 ++++---- crates/ide-completion/src/completions/mod_.rs | 11 +- crates/ide-completion/src/completions/use_.rs | 23 +--- crates/ide-completion/src/lib.rs | 129 +++++++++++------- crates/ide-completion/src/snippet.rs | 6 +- 6 files changed, 130 insertions(+), 118 deletions(-) diff --git a/crates/ide-completion/src/completions/field.rs b/crates/ide-completion/src/completions/field.rs index 6d346c5fd4..505f5f1edf 100644 --- a/crates/ide-completion/src/completions/field.rs +++ b/crates/ide-completion/src/completions/field.rs @@ -1,7 +1,7 @@ //! Completion of field list position. use crate::{ - context::{NameContext, NameKind, PathCompletionCtx, PathKind, Qualified, TypeLocation}, + context::{PathCompletionCtx, PathKind, Qualified, TypeLocation}, CompletionContext, Completions, }; @@ -30,17 +30,11 @@ pub(crate) fn complete_field_list_tuple_variant( } } -pub(crate) fn complete_field_list_record_variant( - acc: &mut Completions, - ctx: &CompletionContext, - name_ctx: &NameContext, -) { - if let NameContext { kind: NameKind::RecordField, .. } = name_ctx { - if ctx.qualifier_ctx.vis_node.is_none() { - let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet); - add_keyword("pub(crate)", "pub(crate)"); - add_keyword("pub(super)", "pub(super)"); - add_keyword("pub", "pub"); - } +pub(crate) fn complete_field_list_record_variant(acc: &mut Completions, ctx: &CompletionContext) { + if ctx.qualifier_ctx.vis_node.is_none() { + let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet); + add_keyword("pub(crate)", "pub(crate)"); + add_keyword("pub(super)", "pub(super)"); + add_keyword("pub", "pub"); } } diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs index 58b894bdd4..83d78e1093 100644 --- a/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -43,10 +43,7 @@ use syntax::{ use text_edit::TextEdit; use crate::{ - context::{ - ItemListKind, NameContext, NameKind, NameRefContext, NameRefKind, PathCompletionCtx, - PathKind, - }, + context::{ItemListKind, PathCompletionCtx, PathKind}, CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance, Completions, }; @@ -58,17 +55,36 @@ enum ImplCompletionKind { Const, } -pub(crate) fn complete_trait_impl_name( +pub(crate) fn complete_trait_impl_const( acc: &mut Completions, ctx: &CompletionContext, - NameContext { name, kind, .. }: &NameContext, + name: &Option, +) -> Option<()> { + complete_trait_impl_name(acc, ctx, name, ImplCompletionKind::Const) +} + +pub(crate) fn complete_trait_impl_type_alias( + acc: &mut Completions, + ctx: &CompletionContext, + name: &Option, +) -> Option<()> { + complete_trait_impl_name(acc, ctx, name, ImplCompletionKind::TypeAlias) +} + +pub(crate) fn complete_trait_impl_fn( + acc: &mut Completions, + ctx: &CompletionContext, + name: &Option, +) -> Option<()> { + complete_trait_impl_name(acc, ctx, name, ImplCompletionKind::Fn) +} + +fn complete_trait_impl_name( + acc: &mut Completions, + ctx: &CompletionContext, + name: &Option, + kind: ImplCompletionKind, ) -> Option<()> { - let kind = match kind { - NameKind::Const => ImplCompletionKind::Const, - NameKind::Function => ImplCompletionKind::Fn, - NameKind::TypeAlias => ImplCompletionKind::TypeAlias, - _ => return None, - }; let token = ctx.token.clone(); let item = match name { Some(name) => name.syntax().parent(), @@ -89,23 +105,18 @@ pub(crate) fn complete_trait_impl_name( pub(crate) fn complete_trait_impl_name_ref( acc: &mut Completions, ctx: &CompletionContext, - name_ref_ctx: &NameRefContext, + path_ctx: &PathCompletionCtx, + name_ref: &Option, ) -> Option<()> { - match name_ref_ctx { - NameRefContext { - nameref, - kind: - NameRefKind::Path( - path_ctx @ PathCompletionCtx { - kind: PathKind::Item { kind: ItemListKind::TraitImpl(Some(impl_)) }, - .. - }, - ), + match path_ctx { + PathCompletionCtx { + kind: PathKind::Item { kind: ItemListKind::TraitImpl(Some(impl_)) }, + .. } if path_ctx.is_trivial_path() => complete_trait_impl( acc, ctx, ImplCompletionKind::All, - match nameref { + match name_ref { Some(name) => name.syntax().text_range(), None => ctx.source_range(), }, diff --git a/crates/ide-completion/src/completions/mod_.rs b/crates/ide-completion/src/completions/mod_.rs index 8dd1d1d8ac..6f67c38dfd 100644 --- a/crates/ide-completion/src/completions/mod_.rs +++ b/crates/ide-completion/src/completions/mod_.rs @@ -9,21 +9,14 @@ use ide_db::{ }; use syntax::{ast, AstNode, SyntaxKind}; -use crate::{ - context::{CompletionContext, NameContext, NameKind}, - CompletionItem, Completions, -}; +use crate::{context::CompletionContext, CompletionItem, Completions}; /// Complete mod declaration, i.e. `mod $0;` pub(crate) fn complete_mod( acc: &mut Completions, ctx: &CompletionContext, - name_ctx: &NameContext, + mod_under_caret: &ast::Module, ) -> Option<()> { - let mod_under_caret = match name_ctx { - NameContext { kind: NameKind::Module(mod_under_caret), .. } => mod_under_caret, - _ => return None, - }; if mod_under_caret.item_list().is_some() { return None; } diff --git a/crates/ide-completion/src/completions/use_.rs b/crates/ide-completion/src/completions/use_.rs index 2cdd93f95b..e12acc34e7 100644 --- a/crates/ide-completion/src/completions/use_.rs +++ b/crates/ide-completion/src/completions/use_.rs @@ -5,9 +5,7 @@ use ide_db::{FxHashSet, SymbolKind}; use syntax::{ast, AstNode}; use crate::{ - context::{ - CompletionContext, NameRefContext, NameRefKind, PathCompletionCtx, PathKind, Qualified, - }, + context::{CompletionContext, PathCompletionCtx, PathKind, Qualified}, item::Builder, CompletionItem, CompletionItemKind, CompletionRelevance, Completions, }; @@ -15,20 +13,13 @@ use crate::{ pub(crate) fn complete_use_tree( acc: &mut Completions, ctx: &CompletionContext, - name_ref_ctx: &NameRefContext, + path_ctx: &PathCompletionCtx, + name_ref: &Option, ) { - let (qualified, name_ref, use_tree_parent) = match name_ref_ctx { - NameRefContext { - kind: - NameRefKind::Path(PathCompletionCtx { - kind: PathKind::Use, - qualified, - use_tree_parent, - .. - }), - nameref, - .. - } => (qualified, nameref, use_tree_parent), + let (qualified, name_ref, use_tree_parent) = match path_ctx { + PathCompletionCtx { kind: PathKind::Use, qualified, use_tree_parent, .. } => { + (qualified, name_ref, use_tree_parent) + } _ => return, }; diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs index 27fe66e385..5e9923eb0f 100644 --- a/crates/ide-completion/src/lib.rs +++ b/crates/ide-completion/src/lib.rs @@ -24,7 +24,9 @@ use text_edit::TextEdit; use crate::{ completions::Completions, - context::{CompletionContext, IdentContext, NameKind, NameRefContext, NameRefKind}, + context::{ + CompletionContext, IdentContext, NameContext, NameKind, NameRefContext, NameRefKind, + }, }; pub use crate::{ @@ -164,63 +166,86 @@ pub fn completions( let acc = &mut completions; match &ctx.ident_ctx { - IdentContext::Name(name_ctx) => { - completions::field::complete_field_list_record_variant(acc, ctx, name_ctx); - completions::item_list::trait_impl::complete_trait_impl_name(acc, ctx, name_ctx); - completions::mod_::complete_mod(acc, ctx, name_ctx); - if let NameKind::IdentPat(pattern_ctx) = &name_ctx.kind { + IdentContext::Name(NameContext { name, kind }) => match kind { + NameKind::Const => { + completions::item_list::trait_impl::complete_trait_impl_const(acc, ctx, name); + } + NameKind::Function => { + completions::item_list::trait_impl::complete_trait_impl_fn(acc, ctx, name); + } + NameKind::IdentPat(pattern_ctx) => { completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); completions::pattern::complete_pattern(acc, ctx, pattern_ctx); completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); } - } - IdentContext::NameRef(name_ctx @ NameRefContext { kind, .. }) => { - completions::item_list::trait_impl::complete_trait_impl_name_ref( - acc, ctx, name_ctx, - ); - completions::use_::complete_use_tree(acc, ctx, name_ctx); - - match kind { - NameRefKind::Path(path_ctx) => { - completions::attribute::complete_attribute(acc, ctx, path_ctx); - completions::attribute::complete_derive(acc, ctx, path_ctx); - completions::dot::complete_undotted_self(acc, ctx, path_ctx); - completions::expr::complete_expr_path(acc, ctx, path_ctx); - completions::field::complete_field_list_tuple_variant(acc, ctx, path_ctx); - completions::flyimport::import_on_the_fly_path(acc, ctx, path_ctx); - completions::item_list::complete_item_list(acc, ctx, path_ctx); - completions::pattern::pattern_path_completion(acc, ctx, path_ctx); - completions::r#type::complete_inferred_type(acc, ctx, path_ctx); - completions::r#type::complete_type_path(acc, ctx, path_ctx); - completions::record::complete_record_expr_func_update(acc, ctx, path_ctx); - completions::snippet::complete_expr_snippet(acc, ctx, path_ctx); - completions::snippet::complete_item_snippet(acc, ctx, path_ctx); - completions::vis::complete_vis_path(acc, ctx, path_ctx); - } - NameRefKind::DotAccess(dot_access) => { - completions::flyimport::import_on_the_fly_dot(acc, ctx, dot_access); - completions::dot::complete_dot(acc, ctx, dot_access); - completions::postfix::complete_postfix(acc, ctx, dot_access); - } - NameRefKind::Keyword(item) => { - completions::keyword::complete_special_keywords(acc, ctx, item); - } - NameRefKind::RecordExpr(record_expr) => { - completions::record::complete_record_expr_fields_record_expr( - acc, - ctx, - record_expr, - ); - } - NameRefKind::Pattern(pattern_ctx) => { - completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); - completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); - completions::pattern::complete_pattern(acc, ctx, pattern_ctx); - completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); - } + NameKind::Module(mod_under_caret) => { + completions::mod_::complete_mod(acc, ctx, mod_under_caret); } - } + NameKind::TypeAlias => { + completions::item_list::trait_impl::complete_trait_impl_type_alias( + acc, ctx, name, + ); + } + NameKind::RecordField => { + completions::field::complete_field_list_record_variant(acc, ctx); + } + NameKind::ConstParam + | NameKind::Enum + | NameKind::MacroDef + | NameKind::MacroRules + | NameKind::Rename + | NameKind::SelfParam + | NameKind::Static + | NameKind::Struct + | NameKind::Trait + | NameKind::TypeParam + | NameKind::Union + | NameKind::Variant => (), + }, + IdentContext::NameRef(NameRefContext { kind, nameref }) => match kind { + NameRefKind::Path(path_ctx) => { + completions::attribute::complete_attribute(acc, ctx, path_ctx); + completions::attribute::complete_derive(acc, ctx, path_ctx); + completions::dot::complete_undotted_self(acc, ctx, path_ctx); + completions::expr::complete_expr_path(acc, ctx, path_ctx); + completions::field::complete_field_list_tuple_variant(acc, ctx, path_ctx); + completions::flyimport::import_on_the_fly_path(acc, ctx, path_ctx); + completions::item_list::complete_item_list(acc, ctx, path_ctx); + completions::item_list::trait_impl::complete_trait_impl_name_ref( + acc, ctx, path_ctx, nameref, + ); + completions::pattern::pattern_path_completion(acc, ctx, path_ctx); + completions::r#type::complete_inferred_type(acc, ctx, path_ctx); + completions::r#type::complete_type_path(acc, ctx, path_ctx); + completions::record::complete_record_expr_func_update(acc, ctx, path_ctx); + completions::snippet::complete_expr_snippet(acc, ctx, path_ctx); + completions::snippet::complete_item_snippet(acc, ctx, path_ctx); + completions::use_::complete_use_tree(acc, ctx, path_ctx, nameref); + completions::vis::complete_vis_path(acc, ctx, path_ctx); + } + NameRefKind::DotAccess(dot_access) => { + completions::flyimport::import_on_the_fly_dot(acc, ctx, dot_access); + completions::dot::complete_dot(acc, ctx, dot_access); + completions::postfix::complete_postfix(acc, ctx, dot_access); + } + NameRefKind::Keyword(item) => { + completions::keyword::complete_special_keywords(acc, ctx, item); + } + NameRefKind::RecordExpr(record_expr) => { + completions::record::complete_record_expr_fields_record_expr( + acc, + ctx, + record_expr, + ); + } + NameRefKind::Pattern(pattern_ctx) => { + completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); + completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); + completions::pattern::complete_pattern(acc, ctx, pattern_ctx); + completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); + } + }, IdentContext::Lifetime(lifetime_ctx) => { completions::lifetime::complete_label(acc, ctx, lifetime_ctx); completions::lifetime::complete_lifetime(acc, ctx, lifetime_ctx); diff --git a/crates/ide-completion/src/snippet.rs b/crates/ide-completion/src/snippet.rs index 82632f440d..a6bb3d0648 100644 --- a/crates/ide-completion/src/snippet.rs +++ b/crates/ide-completion/src/snippet.rs @@ -2,8 +2,6 @@ //! //! Actual logic is implemented in [`crate::completions::postfix`] and [`crate::completions::snippet`] respectively. -use std::ops::Deref; - // Feature: User Snippet Completions // // rust-analyzer allows the user to define custom (postfix)-snippets that may depend on items to be accessible for the current scope to be applicable. @@ -146,8 +144,8 @@ impl Snippet { let (requires, snippet, description) = validate_snippet(snippet, description, requires)?; Some(Snippet { // Box::into doesn't work as that has a Copy bound 😒 - postfix_triggers: postfix_triggers.iter().map(Deref::deref).map(Into::into).collect(), - prefix_triggers: prefix_triggers.iter().map(Deref::deref).map(Into::into).collect(), + postfix_triggers: postfix_triggers.iter().map(String::as_str).map(Into::into).collect(), + prefix_triggers: prefix_triggers.iter().map(String::as_str).map(Into::into).collect(), scope, snippet, description, From ce5859e38745d3e5e5fc48f54f6a9b5d10150ff4 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 20 Jun 2022 13:29:13 +0200 Subject: [PATCH 2/4] Lift out PathKind variant fields into structs --- .../src/completions/attribute.rs | 4 +- crates/ide-completion/src/completions/dot.rs | 5 +- crates/ide-completion/src/completions/expr.rs | 53 ++++++------------- .../src/completions/item_list.rs | 9 ++-- .../ide-completion/src/completions/record.rs | 4 +- .../ide-completion/src/completions/snippet.rs | 8 +-- crates/ide-completion/src/context.rs | 35 +++++++----- crates/ide-completion/src/context/analysis.rs | 38 +++++++------ crates/ide-completion/src/lib.rs | 21 ++++---- 9 files changed, 86 insertions(+), 91 deletions(-) diff --git a/crates/ide-completion/src/completions/attribute.rs b/crates/ide-completion/src/completions/attribute.rs index 992d7eabd8..a82ebbdd91 100644 --- a/crates/ide-completion/src/completions/attribute.rs +++ b/crates/ide-completion/src/completions/attribute.rs @@ -18,7 +18,7 @@ use syntax::{ use crate::{ completions::module_or_attr, - context::{CompletionContext, PathCompletionCtx, PathKind, Qualified}, + context::{AttrCtx, CompletionContext, PathCompletionCtx, PathKind, Qualified}, item::CompletionItem, Completions, }; @@ -76,7 +76,7 @@ pub(crate) fn complete_attribute( ) { let (qualified, is_inner, annotated_item_kind) = match path_ctx { &PathCompletionCtx { - kind: PathKind::Attr { kind, annotated_item_kind }, + kind: PathKind::Attr { attr_ctx: AttrCtx { kind, annotated_item_kind } }, ref qualified, .. } => (qualified, kind == AttrKind::Inner, annotated_item_kind), diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs index da26c2ad68..fea4fbf4d5 100644 --- a/crates/ide-completion/src/completions/dot.rs +++ b/crates/ide-completion/src/completions/dot.rs @@ -4,7 +4,8 @@ use ide_db::FxHashSet; use crate::{ context::{ - CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind, Qualified, + CompletionContext, DotAccess, DotAccessKind, ExprCtx, PathCompletionCtx, PathKind, + Qualified, }, CompletionItem, CompletionItemKind, Completions, }; @@ -49,7 +50,7 @@ pub(crate) fn complete_undotted_self( let self_param = match path_ctx { PathCompletionCtx { qualified: Qualified::No, - kind: PathKind::Expr { self_param: Some(self_param), .. }, + kind: PathKind::Expr { expr_ctx: ExprCtx { self_param: Some(self_param), .. } }, .. } if path_ctx.is_trivial_path() && ctx.qualifier_ctx.none() => self_param, _ => return, diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs index 83ecb51aaa..6bc453a514 100644 --- a/crates/ide-completion/src/completions/expr.rs +++ b/crates/ide-completion/src/completions/expr.rs @@ -4,7 +4,7 @@ use hir::ScopeDef; use ide_db::FxHashSet; use crate::{ - context::{PathCompletionCtx, PathKind, Qualified}, + context::{ExprCtx, PathCompletionCtx, PathKind, Qualified}, CompletionContext, Completions, }; @@ -19,47 +19,28 @@ pub(crate) fn complete_expr_path( } let ( qualified, - in_block_expr, - in_loop_body, - is_func_update, - after_if_expr, - wants_mut_token, - in_condition, - ty, - incomplete_let, - impl_, - ) = match path_ctx { - &PathCompletionCtx { - kind: - PathKind::Expr { - in_block_expr, - in_loop_body, - after_if_expr, - in_condition, - incomplete_let, - ref ref_expr_parent, - ref is_func_update, - ref innermost_ret_ty, - ref impl_, - .. - }, - ref qualified, - .. - } => ( - qualified, + &ExprCtx { in_block_expr, in_loop_body, - is_func_update.is_some(), after_if_expr, - ref_expr_parent.as_ref().map(|it| it.mut_token().is_none()).unwrap_or(false), in_condition, - innermost_ret_ty, incomplete_let, - impl_, - ), + ref ref_expr_parent, + ref is_func_update, + ref innermost_ret_ty, + ref impl_, + .. + }, + ) = match path_ctx { + PathCompletionCtx { kind: PathKind::Expr { expr_ctx }, qualified, .. } => { + (qualified, expr_ctx) + } _ => return, }; + let wants_mut_token = + ref_expr_parent.as_ref().map(|it| it.mut_token().is_none()).unwrap_or(false); + let scope_def_applicable = |def| { use hir::{GenericParam::*, ModuleDef::*}; match def { @@ -230,7 +211,7 @@ pub(crate) fn complete_expr_path( } }); - if !is_func_update { + if is_func_update.is_none() { let mut add_keyword = |kw, snippet| acc.add_keyword_snippet_expr(ctx, kw, snippet, incomplete_let); @@ -270,7 +251,7 @@ pub(crate) fn complete_expr_path( } } - if let Some(ty) = ty { + if let Some(ty) = innermost_ret_ty { add_keyword( "return", match (in_block_expr, ty.is_unit()) { diff --git a/crates/ide-completion/src/completions/item_list.rs b/crates/ide-completion/src/completions/item_list.rs index 941273fa97..8ced01da67 100644 --- a/crates/ide-completion/src/completions/item_list.rs +++ b/crates/ide-completion/src/completions/item_list.rs @@ -2,7 +2,7 @@ use crate::{ completions::module_or_fn_macro, - context::{ItemListKind, PathCompletionCtx, PathKind, Qualified}, + context::{ExprCtx, ItemListKind, PathCompletionCtx, PathKind, Qualified}, CompletionContext, Completions, }; @@ -21,9 +21,10 @@ pub(crate) fn complete_item_list( } qualified } - PathCompletionCtx { kind: PathKind::Expr { in_block_expr: true, .. }, .. } - if path_ctx.is_trivial_path() => - { + PathCompletionCtx { + kind: PathKind::Expr { expr_ctx: ExprCtx { in_block_expr: true, .. } }, + .. + } if path_ctx.is_trivial_path() => { add_keywords(acc, ctx, None); return; } diff --git a/crates/ide-completion/src/completions/record.rs b/crates/ide-completion/src/completions/record.rs index eaab4cb4ee..1811524106 100644 --- a/crates/ide-completion/src/completions/record.rs +++ b/crates/ide-completion/src/completions/record.rs @@ -6,7 +6,7 @@ use syntax::{ }; use crate::{ - context::{PathCompletionCtx, PathKind, PatternContext, Qualified}, + context::{ExprCtx, PathCompletionCtx, PathKind, PatternContext, Qualified}, CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevancePostfixMatch, Completions, }; @@ -87,7 +87,7 @@ pub(crate) fn complete_record_expr_func_update( path_ctx: &PathCompletionCtx, ) { if let PathCompletionCtx { - kind: PathKind::Expr { is_func_update: Some(record_expr), .. }, + kind: PathKind::Expr { expr_ctx: ExprCtx { is_func_update: Some(record_expr), .. } }, qualified: Qualified::No, .. } = path_ctx diff --git a/crates/ide-completion/src/completions/snippet.rs b/crates/ide-completion/src/completions/snippet.rs index 48366987f4..af315616fa 100644 --- a/crates/ide-completion/src/completions/snippet.rs +++ b/crates/ide-completion/src/completions/snippet.rs @@ -4,7 +4,7 @@ use hir::Documentation; use ide_db::{imports::insert_use::ImportScope, SnippetCap}; use crate::{ - context::{ItemListKind, PathCompletionCtx, PathKind, Qualified}, + context::{ExprCtx, ItemListKind, PathCompletionCtx, PathKind, Qualified}, item::Builder, CompletionContext, CompletionItem, CompletionItemKind, Completions, SnippetScope, }; @@ -23,7 +23,7 @@ pub(crate) fn complete_expr_snippet( let &can_be_stmt = match path_ctx { PathCompletionCtx { qualified: Qualified::No, - kind: PathKind::Expr { in_block_expr, .. }, + kind: PathKind::Expr { expr_ctx: ExprCtx { in_block_expr, .. } }, .. } => in_block_expr, _ => return, @@ -52,7 +52,9 @@ pub(crate) fn complete_item_snippet( let path_kind = match path_ctx { PathCompletionCtx { qualified: Qualified::No, - kind: kind @ (PathKind::Item { .. } | PathKind::Expr { in_block_expr: true, .. }), + kind: + kind @ (PathKind::Item { .. } + | PathKind::Expr { expr_ctx: ExprCtx { in_block_expr: true, .. }, .. }), .. } => kind, _ => return, diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index 0c7c6ab5af..c212b5b9b9 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -88,24 +88,13 @@ impl PathCompletionCtx { #[derive(Debug, PartialEq, Eq)] pub(super) enum PathKind { Expr { - in_block_expr: bool, - in_loop_body: bool, - after_if_expr: bool, - /// Whether this expression is the direct condition of an if or while expression - in_condition: bool, - incomplete_let: bool, - ref_expr_parent: Option, - is_func_update: Option, - self_param: Option, - innermost_ret_ty: Option, - impl_: Option, + expr_ctx: ExprCtx, }, Type { location: TypeLocation, }, Attr { - kind: AttrKind, - annotated_item_kind: Option, + attr_ctx: AttrCtx, }, Derive { existing_derives: FxHashSet, @@ -122,6 +111,26 @@ pub(super) enum PathKind { }, Use, } +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct AttrCtx { + pub(crate) kind: AttrKind, + pub(crate) annotated_item_kind: Option, +} + +#[derive(Debug, PartialEq, Eq)] +pub(crate) struct ExprCtx { + pub(crate) in_block_expr: bool, + pub(crate) in_loop_body: bool, + pub(crate) after_if_expr: bool, + /// Whether this expression is the direct condition of an if or while expression + pub(crate) in_condition: bool, + pub(crate) incomplete_let: bool, + pub(crate) ref_expr_parent: Option, + pub(crate) is_func_update: Option, + pub(crate) self_param: Option, + pub(crate) innermost_ret_ty: Option, + pub(crate) impl_: Option, +} /// Original file ast nodes #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index 9ceb60f90f..551fa7fb86 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -11,10 +11,10 @@ use syntax::{ }; use crate::context::{ - CompletionContext, DotAccess, DotAccessKind, IdentContext, ItemListKind, LifetimeContext, - LifetimeKind, NameContext, NameKind, NameRefContext, NameRefKind, ParamKind, PathCompletionCtx, - PathKind, PatternContext, PatternRefutability, Qualified, QualifierCtx, TypeAscriptionTarget, - TypeLocation, COMPLETION_MARKER, + AttrCtx, CompletionContext, DotAccess, DotAccessKind, ExprCtx, IdentContext, ItemListKind, + LifetimeContext, LifetimeKind, NameContext, NameKind, NameRefContext, NameRefKind, ParamKind, + PathCompletionCtx, PathKind, PatternContext, PatternRefutability, Qualified, QualifierCtx, + TypeAscriptionTarget, TypeLocation, COMPLETION_MARKER, }; impl<'a> CompletionContext<'a> { @@ -765,16 +765,18 @@ impl<'a> CompletionContext<'a> { let impl_ = fetch_immediate_impl(sema, original_file, expr.syntax()); PathKind::Expr { - in_block_expr, - in_loop_body, - after_if_expr, - in_condition, - ref_expr_parent, - is_func_update, - innermost_ret_ty, - self_param, - incomplete_let, - impl_, + expr_ctx: ExprCtx { + in_block_expr, + in_loop_body, + after_if_expr, + in_condition, + ref_expr_parent, + is_func_update, + innermost_ret_ty, + self_param, + incomplete_let, + impl_, + }, } }; let make_path_kind_type = |ty: ast::Type| { @@ -858,8 +860,10 @@ impl<'a> CompletionContext<'a> { Some(attached.kind()) }; PathKind::Attr { - kind, - annotated_item_kind, + attr_ctx: AttrCtx { + kind, + annotated_item_kind, + } } }, ast::Visibility(it) => PathKind::Vis { has_in_token: it.in_token().is_some() }, @@ -914,7 +918,7 @@ impl<'a> CompletionContext<'a> { if path_ctx.is_trivial_path() { // fetch the full expression that may have qualifiers attached to it let top_node = match path_ctx.kind { - PathKind::Expr { in_block_expr: true, .. } => { + PathKind::Expr { expr_ctx: ExprCtx { in_block_expr: true, .. } } => { parent.ancestors().find(|it| ast::PathExpr::can_cast(it.kind())).and_then(|p| { let parent = p.parent()?; if ast::StmtList::can_cast(parent.kind()) { diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs index 5e9923eb0f..5a3ddeea25 100644 --- a/crates/ide-completion/src/lib.rs +++ b/crates/ide-completion/src/lib.rs @@ -165,6 +165,13 @@ pub fn completions( { let acc = &mut completions; + let mut complete_patterns = |pattern_ctx| { + completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); + completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); + completions::pattern::complete_pattern(acc, ctx, pattern_ctx); + completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); + }; + match &ctx.ident_ctx { IdentContext::Name(NameContext { name, kind }) => match kind { NameKind::Const => { @@ -173,12 +180,7 @@ pub fn completions( NameKind::Function => { completions::item_list::trait_impl::complete_trait_impl_fn(acc, ctx, name); } - NameKind::IdentPat(pattern_ctx) => { - completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); - completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); - completions::pattern::complete_pattern(acc, ctx, pattern_ctx); - completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); - } + NameKind::IdentPat(pattern_ctx) => complete_patterns(pattern_ctx), NameKind::Module(mod_under_caret) => { completions::mod_::complete_mod(acc, ctx, mod_under_caret); } @@ -239,12 +241,7 @@ pub fn completions( record_expr, ); } - NameRefKind::Pattern(pattern_ctx) => { - completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); - completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); - completions::pattern::complete_pattern(acc, ctx, pattern_ctx); - completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); - } + NameRefKind::Pattern(pattern_ctx) => complete_patterns(pattern_ctx), }, IdentContext::Lifetime(lifetime_ctx) => { completions::lifetime::complete_label(acc, ctx, lifetime_ctx); From 76852452825191da01e7d5a4db0c1638c02514be Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 20 Jun 2022 14:23:46 +0200 Subject: [PATCH 3/4] Even more completion context filtering --- crates/ide-completion/src/completions.rs | 122 +++++++++++++++++- .../src/completions/attribute.rs | 14 +- .../src/completions/attribute/derive.rs | 12 +- crates/ide-completion/src/completions/dot.rs | 23 ++-- crates/ide-completion/src/completions/expr.rs | 36 ++---- .../ide-completion/src/completions/field.rs | 16 +-- .../src/completions/item_list.rs | 39 +++--- .../src/completions/item_list/trait_impl.rs | 23 ++-- .../ide-completion/src/completions/keyword.rs | 4 +- .../ide-completion/src/completions/pattern.rs | 9 +- .../ide-completion/src/completions/record.rs | 15 +-- .../ide-completion/src/completions/snippet.rs | 57 ++++---- crates/ide-completion/src/completions/type.rs | 27 ++-- crates/ide-completion/src/completions/use_.rs | 11 +- crates/ide-completion/src/completions/vis.rs | 12 +- crates/ide-completion/src/context.rs | 5 +- crates/ide-completion/src/lib.rs | 94 ++------------ 17 files changed, 263 insertions(+), 256 deletions(-) diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index 284372f7fc..c925d242a4 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -27,7 +27,10 @@ use ide_db::SymbolKind; use syntax::ast; use crate::{ - context::Visible, + context::{ + ItemListKind, NameContext, NameKind, NameRefContext, NameRefKind, PathKind, PatternContext, + TypeLocation, Visible, + }, item::Builder, render::{ const_::render_const, @@ -437,3 +440,120 @@ fn enum_variants_with_paths( } } } + +pub(super) fn complete_name( + acc: &mut Completions, + ctx: &CompletionContext, + NameContext { name, kind }: &NameContext, +) { + match kind { + NameKind::Const => { + item_list::trait_impl::complete_trait_impl_const(acc, ctx, name); + } + NameKind::Function => { + item_list::trait_impl::complete_trait_impl_fn(acc, ctx, name); + } + NameKind::IdentPat(pattern_ctx) => complete_patterns(acc, ctx, pattern_ctx), + NameKind::Module(mod_under_caret) => { + mod_::complete_mod(acc, ctx, mod_under_caret); + } + NameKind::TypeAlias => { + item_list::trait_impl::complete_trait_impl_type_alias(acc, ctx, name); + } + NameKind::RecordField => { + field::complete_field_list_record_variant(acc, ctx); + } + NameKind::ConstParam + | NameKind::Enum + | NameKind::MacroDef + | NameKind::MacroRules + | NameKind::Rename + | NameKind::SelfParam + | NameKind::Static + | NameKind::Struct + | NameKind::Trait + | NameKind::TypeParam + | NameKind::Union + | NameKind::Variant => (), + } +} + +pub(super) fn complete_name_ref( + acc: &mut Completions, + ctx: &CompletionContext, + NameRefContext { nameref, kind }: &NameRefContext, +) { + 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); + 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); + } + TypeLocation::TypeAscription(ascription) => { + r#type::complete_ascribed_type(acc, ctx, path_ctx, ascription); + } + TypeLocation::GenericArgList(_) + | TypeLocation::TypeBound + | TypeLocation::ImplTarget + | TypeLocation::ImplTrait + | TypeLocation::Other => (), + } + } + PathKind::Attr { attr_ctx } => { + attribute::complete_attribute(acc, ctx, path_ctx, attr_ctx); + } + PathKind::Derive { existing_derives } => { + attribute::complete_derive(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( + acc, ctx, path_ctx, nameref, impl_, + ); + } + } + PathKind::Pat { .. } => { + pattern::complete_pattern_path(acc, ctx, path_ctx); + } + PathKind::Vis { has_in_token } => { + vis::complete_vis_path(acc, ctx, path_ctx, has_in_token); + } + PathKind::Use => { + use_::complete_use_tree(acc, ctx, path_ctx, nameref); + } + } + } + NameRefKind::DotAccess(dot_access) => { + flyimport::import_on_the_fly_dot(acc, ctx, dot_access); + dot::complete_dot(acc, ctx, dot_access); + postfix::complete_postfix(acc, ctx, dot_access); + } + NameRefKind::Keyword(item) => { + keyword::complete_for_and_where(acc, ctx, item); + } + NameRefKind::RecordExpr(record_expr) => { + record::complete_record_expr_fields(acc, ctx, record_expr); + } + NameRefKind::Pattern(pattern_ctx) => complete_patterns(acc, ctx, pattern_ctx), + } +} + +fn complete_patterns(acc: &mut Completions, ctx: &CompletionContext, pattern_ctx: &PatternContext) { + flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); + fn_param::complete_fn_param(acc, ctx, pattern_ctx); + pattern::complete_pattern(acc, ctx, pattern_ctx); + record::complete_record_pattern_fields(acc, ctx, pattern_ctx); +} diff --git a/crates/ide-completion/src/completions/attribute.rs b/crates/ide-completion/src/completions/attribute.rs index a82ebbdd91..712163d81d 100644 --- a/crates/ide-completion/src/completions/attribute.rs +++ b/crates/ide-completion/src/completions/attribute.rs @@ -18,7 +18,7 @@ use syntax::{ use crate::{ completions::module_or_attr, - context::{AttrCtx, CompletionContext, PathCompletionCtx, PathKind, Qualified}, + context::{AttrCtx, CompletionContext, PathCompletionCtx, Qualified}, item::CompletionItem, Completions, }; @@ -72,16 +72,10 @@ pub(crate) fn complete_known_attribute_input( pub(crate) fn complete_attribute( acc: &mut Completions, ctx: &CompletionContext, - path_ctx: &PathCompletionCtx, + PathCompletionCtx { qualified, .. }: &PathCompletionCtx, + &AttrCtx { kind, annotated_item_kind }: &AttrCtx, ) { - let (qualified, is_inner, annotated_item_kind) = match path_ctx { - &PathCompletionCtx { - kind: PathKind::Attr { attr_ctx: AttrCtx { kind, annotated_item_kind } }, - ref qualified, - .. - } => (qualified, kind == AttrKind::Inner, annotated_item_kind), - _ => return, - }; + let is_inner = kind == AttrKind::Inner; match qualified { Qualified::With { diff --git a/crates/ide-completion/src/completions/attribute/derive.rs b/crates/ide-completion/src/completions/attribute/derive.rs index 0927d2f764..5dee4d7956 100644 --- a/crates/ide-completion/src/completions/attribute/derive.rs +++ b/crates/ide-completion/src/completions/attribute/derive.rs @@ -5,7 +5,7 @@ use itertools::Itertools; use syntax::SmolStr; use crate::{ - context::{CompletionContext, PathCompletionCtx, PathKind, Qualified}, + context::{CompletionContext, ExistingDerives, PathCompletionCtx, Qualified}, item::CompletionItem, Completions, }; @@ -13,15 +13,9 @@ use crate::{ pub(crate) fn complete_derive( acc: &mut Completions, ctx: &CompletionContext, - path_ctx: &PathCompletionCtx, + PathCompletionCtx { qualified, .. }: &PathCompletionCtx, + existing_derives: &ExistingDerives, ) { - let (qualified, existing_derives) = match path_ctx { - PathCompletionCtx { kind: PathKind::Derive { existing_derives }, qualified, .. } => { - (qualified, existing_derives) - } - _ => return, - }; - let core = ctx.famous_defs().core(); match qualified { diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs index fea4fbf4d5..a8a57c0c7d 100644 --- a/crates/ide-completion/src/completions/dot.rs +++ b/crates/ide-completion/src/completions/dot.rs @@ -3,10 +3,7 @@ use ide_db::FxHashSet; use crate::{ - context::{ - CompletionContext, DotAccess, DotAccessKind, ExprCtx, PathCompletionCtx, PathKind, - Qualified, - }, + context::{CompletionContext, DotAccess, DotAccessKind, ExprCtx, PathCompletionCtx, Qualified}, CompletionItem, CompletionItemKind, Completions, }; @@ -43,16 +40,22 @@ pub(crate) fn complete_undotted_self( acc: &mut Completions, ctx: &CompletionContext, path_ctx: &PathCompletionCtx, + expr_ctx: &ExprCtx, ) { if !ctx.config.enable_self_on_the_fly { return; } - let self_param = match path_ctx { - PathCompletionCtx { - qualified: Qualified::No, - kind: PathKind::Expr { expr_ctx: ExprCtx { self_param: Some(self_param), .. } }, - .. - } if path_ctx.is_trivial_path() && ctx.qualifier_ctx.none() => self_param, + if !path_ctx.is_trivial_path() { + return; + } + if !ctx.qualifier_ctx.none() { + return; + } + if !matches!(path_ctx.qualified, Qualified::No) { + return; + } + let self_param = match expr_ctx { + ExprCtx { self_param: Some(self_param), .. } => self_param, _ => return, }; diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs index 6bc453a514..84ae596a8d 100644 --- a/crates/ide-completion/src/completions/expr.rs +++ b/crates/ide-completion/src/completions/expr.rs @@ -4,39 +4,31 @@ use hir::ScopeDef; use ide_db::FxHashSet; use crate::{ - context::{ExprCtx, PathCompletionCtx, PathKind, Qualified}, + context::{ExprCtx, PathCompletionCtx, Qualified}, CompletionContext, Completions, }; pub(crate) fn complete_expr_path( acc: &mut Completions, ctx: &CompletionContext, - path_ctx: &PathCompletionCtx, + PathCompletionCtx { qualified, .. }: &PathCompletionCtx, + &ExprCtx { + in_block_expr, + in_loop_body, + after_if_expr, + in_condition, + incomplete_let, + ref ref_expr_parent, + ref is_func_update, + ref innermost_ret_ty, + ref impl_, + .. + }: &ExprCtx, ) { let _p = profile::span("complete_expr_path"); if !ctx.qualifier_ctx.none() { return; } - let ( - qualified, - &ExprCtx { - in_block_expr, - in_loop_body, - after_if_expr, - in_condition, - incomplete_let, - ref ref_expr_parent, - ref is_func_update, - ref innermost_ret_ty, - ref impl_, - .. - }, - ) = match path_ctx { - PathCompletionCtx { kind: PathKind::Expr { expr_ctx }, qualified, .. } => { - (qualified, expr_ctx) - } - _ => return, - }; let wants_mut_token = ref_expr_parent.as_ref().map(|it| it.mut_token().is_none()).unwrap_or(false); diff --git a/crates/ide-completion/src/completions/field.rs b/crates/ide-completion/src/completions/field.rs index 505f5f1edf..738c24574c 100644 --- a/crates/ide-completion/src/completions/field.rs +++ b/crates/ide-completion/src/completions/field.rs @@ -1,7 +1,7 @@ //! Completion of field list position. use crate::{ - context::{PathCompletionCtx, PathKind, Qualified, TypeLocation}, + context::{PathCompletionCtx, Qualified}, CompletionContext, Completions, }; @@ -10,21 +10,21 @@ pub(crate) fn complete_field_list_tuple_variant( ctx: &CompletionContext, path_ctx: &PathCompletionCtx, ) { + if ctx.qualifier_ctx.vis_node.is_some() { + return; + } match path_ctx { PathCompletionCtx { has_macro_bang: false, qualified: Qualified::No, parent: None, - kind: PathKind::Type { location: TypeLocation::TupleField }, has_type_args: false, .. } => { - if ctx.qualifier_ctx.vis_node.is_none() { - let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet); - add_keyword("pub(crate)", "pub(crate)"); - add_keyword("pub(super)", "pub(super)"); - add_keyword("pub", "pub"); - } + let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet); + add_keyword("pub(crate)", "pub(crate)"); + add_keyword("pub(super)", "pub(super)"); + add_keyword("pub", "pub"); } _ => (), } diff --git a/crates/ide-completion/src/completions/item_list.rs b/crates/ide-completion/src/completions/item_list.rs index 8ced01da67..33130028db 100644 --- a/crates/ide-completion/src/completions/item_list.rs +++ b/crates/ide-completion/src/completions/item_list.rs @@ -2,34 +2,37 @@ use crate::{ completions::module_or_fn_macro, - context::{ExprCtx, ItemListKind, PathCompletionCtx, PathKind, Qualified}, + context::{ExprCtx, ItemListKind, PathCompletionCtx, Qualified}, CompletionContext, Completions, }; pub(crate) mod trait_impl; -pub(crate) fn complete_item_list( +pub(crate) fn complete_item_list_in_expr( acc: &mut Completions, ctx: &CompletionContext, path_ctx: &PathCompletionCtx, + expr_ctx: &ExprCtx, +) { + if !expr_ctx.in_block_expr { + return; + } + if !path_ctx.is_trivial_path() { + return; + } + add_keywords(acc, ctx, None); +} + +pub(crate) fn complete_item_list( + acc: &mut Completions, + ctx: &CompletionContext, + path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx, + kind: &ItemListKind, ) { let _p = profile::span("complete_item_list"); - let qualified = match path_ctx { - PathCompletionCtx { kind: PathKind::Item { kind }, qualified, .. } => { - if path_ctx.is_trivial_path() { - add_keywords(acc, ctx, Some(kind)); - } - qualified - } - PathCompletionCtx { - kind: PathKind::Expr { expr_ctx: ExprCtx { in_block_expr: true, .. } }, - .. - } if path_ctx.is_trivial_path() => { - add_keywords(acc, ctx, None); - return; - } - _ => return, - }; + if path_ctx.is_trivial_path() { + add_keywords(acc, ctx, Some(kind)); + } match qualified { Qualified::With { diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs index 83d78e1093..972a7d2f21 100644 --- a/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -43,8 +43,8 @@ use syntax::{ use text_edit::TextEdit; use crate::{ - context::{ItemListKind, PathCompletionCtx, PathKind}, - CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance, Completions, + context::PathCompletionCtx, CompletionContext, CompletionItem, CompletionItemKind, + CompletionRelevance, Completions, }; #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -102,17 +102,18 @@ fn complete_trait_impl_name( Some(()) } -pub(crate) fn complete_trait_impl_name_ref( +pub(crate) fn complete_trait_impl_item_by_name( acc: &mut Completions, ctx: &CompletionContext, path_ctx: &PathCompletionCtx, name_ref: &Option, -) -> Option<()> { - match path_ctx { - PathCompletionCtx { - kind: PathKind::Item { kind: ItemListKind::TraitImpl(Some(impl_)) }, - .. - } if path_ctx.is_trivial_path() => complete_trait_impl( + impl_: &Option, +) { + if !path_ctx.is_trivial_path() { + return; + } + if let Some(impl_) = impl_ { + complete_trait_impl( acc, ctx, ImplCompletionKind::All, @@ -121,10 +122,8 @@ pub(crate) fn complete_trait_impl_name_ref( None => ctx.source_range(), }, impl_, - ), - _ => (), + ); } - Some(()) } fn complete_trait_impl( diff --git a/crates/ide-completion/src/completions/keyword.rs b/crates/ide-completion/src/completions/keyword.rs index 57d545ab8f..7d8d3a9636 100644 --- a/crates/ide-completion/src/completions/keyword.rs +++ b/crates/ide-completion/src/completions/keyword.rs @@ -4,7 +4,7 @@ use syntax::ast::{self, Item}; use crate::{CompletionContext, Completions}; -pub(crate) fn complete_special_keywords( +pub(crate) fn complete_for_and_where( acc: &mut Completions, ctx: &CompletionContext, keyword_item: &ast::Item, @@ -60,8 +60,6 @@ mod tests { kw fn kw impl kw trait - sn pd - sn ppd "#]], ); } diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs index 149acb3c1b..e2e8d3f205 100644 --- a/crates/ide-completion/src/completions/pattern.rs +++ b/crates/ide-completion/src/completions/pattern.rs @@ -5,7 +5,7 @@ use ide_db::FxHashSet; use syntax::ast::Pat; use crate::{ - context::{PathCompletionCtx, PathKind, PatternContext, PatternRefutability, Qualified}, + context::{PathCompletionCtx, PatternContext, PatternRefutability, Qualified}, CompletionContext, Completions, }; @@ -108,14 +108,11 @@ pub(crate) fn complete_pattern( }); } -pub(crate) fn pattern_path_completion( +pub(crate) fn complete_pattern_path( acc: &mut Completions, ctx: &CompletionContext, - PathCompletionCtx { qualified, kind, .. }: &PathCompletionCtx, + PathCompletionCtx { qualified, .. }: &PathCompletionCtx, ) { - if !matches!(kind, PathKind::Pat { .. }) { - return; - } match qualified { Qualified::With { resolution: Some(resolution), is_super_chain, .. } => { if *is_super_chain { diff --git a/crates/ide-completion/src/completions/record.rs b/crates/ide-completion/src/completions/record.rs index 1811524106..12c449bf35 100644 --- a/crates/ide-completion/src/completions/record.rs +++ b/crates/ide-completion/src/completions/record.rs @@ -6,7 +6,7 @@ use syntax::{ }; use crate::{ - context::{ExprCtx, PathCompletionCtx, PathKind, PatternContext, Qualified}, + context::{ExprCtx, PathCompletionCtx, PatternContext, Qualified}, CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevancePostfixMatch, Completions, }; @@ -20,7 +20,7 @@ pub(crate) fn complete_record_pattern_fields( complete_fields(acc, ctx, ctx.sema.record_pattern_missing_fields(record_pat)); } } -pub(crate) fn complete_record_expr_fields_record_expr( +pub(crate) fn complete_record_expr_fields( acc: &mut Completions, ctx: &CompletionContext, record_expr: &ast::RecordExpr, @@ -85,13 +85,12 @@ pub(crate) fn complete_record_expr_func_update( acc: &mut Completions, ctx: &CompletionContext, path_ctx: &PathCompletionCtx, + expr_ctx: &ExprCtx, ) { - if let PathCompletionCtx { - kind: PathKind::Expr { expr_ctx: ExprCtx { is_func_update: Some(record_expr), .. } }, - qualified: Qualified::No, - .. - } = path_ctx - { + if !matches!(path_ctx.qualified, Qualified::No) { + return; + } + if let ExprCtx { is_func_update: Some(record_expr), .. } = expr_ctx { let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone())); match ty.as_ref().and_then(|t| t.original.as_adt()) { diff --git a/crates/ide-completion/src/completions/snippet.rs b/crates/ide-completion/src/completions/snippet.rs index af315616fa..9992a81fe0 100644 --- a/crates/ide-completion/src/completions/snippet.rs +++ b/crates/ide-completion/src/completions/snippet.rs @@ -4,7 +4,7 @@ use hir::Documentation; use ide_db::{imports::insert_use::ImportScope, SnippetCap}; use crate::{ - context::{ExprCtx, ItemListKind, PathCompletionCtx, PathKind, Qualified}, + context::{ExprCtx, ItemListKind, PathCompletionCtx, Qualified}, item::Builder, CompletionContext, CompletionItem, CompletionItemKind, Completions, SnippetScope, }; @@ -19,15 +19,14 @@ pub(crate) fn complete_expr_snippet( acc: &mut Completions, ctx: &CompletionContext, path_ctx: &PathCompletionCtx, + &ExprCtx { in_block_expr, .. }: &ExprCtx, ) { - let &can_be_stmt = match path_ctx { - PathCompletionCtx { - qualified: Qualified::No, - kind: PathKind::Expr { expr_ctx: ExprCtx { in_block_expr, .. } }, - .. - } => in_block_expr, - _ => return, - }; + if !matches!(path_ctx.qualified, Qualified::No) { + return; + } + if !ctx.qualifier_ctx.none() { + return; + } let cap = match ctx.config.snippet_cap { Some(it) => it, @@ -38,9 +37,21 @@ pub(crate) fn complete_expr_snippet( add_custom_completions(acc, ctx, cap, SnippetScope::Expr); } - if can_be_stmt { + if in_block_expr { snippet(ctx, cap, "pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc); snippet(ctx, cap, "ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc); + let item = snippet( + ctx, + cap, + "macro_rules", + "\ +macro_rules! $1 { + ($2) => { + $0 + }; +}", + ); + item.add_to(acc); } } @@ -48,23 +59,13 @@ pub(crate) fn complete_item_snippet( acc: &mut Completions, ctx: &CompletionContext, path_ctx: &PathCompletionCtx, + kind: &ItemListKind, ) { - let path_kind = match path_ctx { - PathCompletionCtx { - qualified: Qualified::No, - kind: - kind @ (PathKind::Item { .. } - | PathKind::Expr { expr_ctx: ExprCtx { in_block_expr: true, .. }, .. }), - .. - } => kind, - _ => return, - }; - if !ctx.qualifier_ctx.none() { + if !matches!(path_ctx.qualified, Qualified::No) { return; } - if ctx.qualifier_ctx.vis_node.is_some() { - return; // technically we could do some of these snippet completions if we were to put the - // attributes before the vis node. + if !ctx.qualifier_ctx.none() { + return; } let cap = match ctx.config.snippet_cap { Some(it) => it, @@ -76,8 +77,7 @@ pub(crate) fn complete_item_snippet( } // Test-related snippets shouldn't be shown in blocks. - if let PathKind::Item { kind: ItemListKind::SourceFile | ItemListKind::Module, .. } = path_kind - { + if let ItemListKind::SourceFile | ItemListKind::Module = kind { let mut item = snippet( ctx, cap, @@ -108,10 +108,7 @@ fn ${1:feature}() { ); item.lookup_by("tfn"); item.add_to(acc); - } - if let PathKind::Item { kind: ItemListKind::SourceFile | ItemListKind::Module, .. } - | PathKind::Expr { .. } = path_kind - { + let item = snippet( ctx, cap, diff --git a/crates/ide-completion/src/completions/type.rs b/crates/ide-completion/src/completions/type.rs index b8d172696d..0f7ca75868 100644 --- a/crates/ide-completion/src/completions/type.rs +++ b/crates/ide-completion/src/completions/type.rs @@ -5,7 +5,7 @@ use ide_db::FxHashSet; use syntax::{ast, AstNode}; use crate::{ - context::{PathCompletionCtx, PathKind, Qualified, TypeAscriptionTarget, TypeLocation}, + context::{PathCompletionCtx, Qualified, TypeAscriptionTarget, TypeLocation}, render::render_type_inference, CompletionContext, Completions, }; @@ -13,17 +13,11 @@ use crate::{ pub(crate) fn complete_type_path( acc: &mut Completions, ctx: &CompletionContext, - path_ctx: &PathCompletionCtx, + PathCompletionCtx { qualified, .. }: &PathCompletionCtx, + location: &TypeLocation, ) { let _p = profile::span("complete_type_path"); - let (location, qualified) = match path_ctx { - PathCompletionCtx { kind: PathKind::Type { location }, qualified, .. } => { - (location, qualified) - } - _ => return, - }; - let scope_def_applicable = |def| { use hir::{GenericParam::*, ModuleDef::*}; match def { @@ -191,19 +185,16 @@ pub(crate) fn complete_type_path( } } -pub(crate) fn complete_inferred_type( +pub(crate) fn complete_ascribed_type( acc: &mut Completions, ctx: &CompletionContext, path_ctx: &PathCompletionCtx, + ascription: &TypeAscriptionTarget, ) -> Option<()> { - let pat = match path_ctx { - PathCompletionCtx { - kind: PathKind::Type { location: TypeLocation::TypeAscription(ascription), .. }, - .. - } if path_ctx.is_trivial_path() => ascription, - _ => return None, - }; - let x = match pat { + if !path_ctx.is_trivial_path() { + return None; + } + let x = match ascription { TypeAscriptionTarget::Let(pat) | TypeAscriptionTarget::FnParam(pat) => { ctx.sema.type_of_pat(pat.as_ref()?) } diff --git a/crates/ide-completion/src/completions/use_.rs b/crates/ide-completion/src/completions/use_.rs index e12acc34e7..9ebbc8ab9d 100644 --- a/crates/ide-completion/src/completions/use_.rs +++ b/crates/ide-completion/src/completions/use_.rs @@ -5,7 +5,7 @@ use ide_db::{FxHashSet, SymbolKind}; use syntax::{ast, AstNode}; use crate::{ - context::{CompletionContext, PathCompletionCtx, PathKind, Qualified}, + context::{CompletionContext, PathCompletionCtx, Qualified}, item::Builder, CompletionItem, CompletionItemKind, CompletionRelevance, Completions, }; @@ -13,16 +13,9 @@ use crate::{ pub(crate) fn complete_use_tree( acc: &mut Completions, ctx: &CompletionContext, - path_ctx: &PathCompletionCtx, + PathCompletionCtx { qualified, use_tree_parent, .. }: &PathCompletionCtx, name_ref: &Option, ) { - let (qualified, name_ref, use_tree_parent) = match path_ctx { - PathCompletionCtx { kind: PathKind::Use, qualified, use_tree_parent, .. } => { - (qualified, name_ref, use_tree_parent) - } - _ => return, - }; - match qualified { Qualified::With { path, resolution: Some(resolution), is_super_chain } => { if *is_super_chain { diff --git a/crates/ide-completion/src/completions/vis.rs b/crates/ide-completion/src/completions/vis.rs index 18513039e6..86ffe32ff3 100644 --- a/crates/ide-completion/src/completions/vis.rs +++ b/crates/ide-completion/src/completions/vis.rs @@ -3,22 +3,16 @@ use hir::ScopeDef; use crate::{ - context::{CompletionContext, PathCompletionCtx, PathKind, Qualified}, + context::{CompletionContext, PathCompletionCtx, Qualified}, Completions, }; pub(crate) fn complete_vis_path( acc: &mut Completions, ctx: &CompletionContext, - path_ctx: &PathCompletionCtx, + PathCompletionCtx { qualified, .. }: &PathCompletionCtx, + &has_in_token: &bool, ) { - let (qualified, &has_in_token) = match path_ctx { - PathCompletionCtx { kind: PathKind::Vis { has_in_token }, qualified, .. } => { - (qualified, has_in_token) - } - _ => return, - }; - match qualified { Qualified::With { resolution: Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))), diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index c212b5b9b9..8c73709f4c 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -97,7 +97,7 @@ pub(super) enum PathKind { attr_ctx: AttrCtx, }, Derive { - existing_derives: FxHashSet, + existing_derives: ExistingDerives, }, /// Path in item position, that is inside an (Assoc)ItemList Item { @@ -111,6 +111,9 @@ pub(super) enum PathKind { }, Use, } + +pub(crate) type ExistingDerives = FxHashSet; + #[derive(Debug, PartialEq, Eq)] pub(crate) struct AttrCtx { pub(crate) kind: AttrKind, diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs index 5a3ddeea25..90e2628439 100644 --- a/crates/ide-completion/src/lib.rs +++ b/crates/ide-completion/src/lib.rs @@ -25,7 +25,7 @@ use text_edit::TextEdit; use crate::{ completions::Completions, context::{ - CompletionContext, IdentContext, NameContext, NameKind, NameRefContext, NameRefKind, + CompletionContext, IdentContext, NameRefContext, NameRefKind, PathCompletionCtx, PathKind, }, }; @@ -153,10 +153,13 @@ pub fn completions( // prevent `(` from triggering unwanted completion noise if trigger_character == Some('(') { - if let IdentContext::NameRef(NameRefContext { kind: NameRefKind::Path(path_ctx), .. }) = - &ctx.ident_ctx - { - completions::vis::complete_vis_path(&mut completions, ctx, path_ctx); + if let IdentContext::NameRef(NameRefContext { kind, .. }) = &ctx.ident_ctx { + if let NameRefKind::Path( + path_ctx @ PathCompletionCtx { kind: PathKind::Vis { has_in_token }, .. }, + ) = kind + { + completions::vis::complete_vis_path(&mut completions, ctx, path_ctx, has_in_token); + } } // prevent `(` from triggering unwanted completion noise return Some(completions); @@ -165,84 +168,11 @@ pub fn completions( { let acc = &mut completions; - let mut complete_patterns = |pattern_ctx| { - completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); - completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); - completions::pattern::complete_pattern(acc, ctx, pattern_ctx); - completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); - }; - match &ctx.ident_ctx { - IdentContext::Name(NameContext { name, kind }) => match kind { - NameKind::Const => { - completions::item_list::trait_impl::complete_trait_impl_const(acc, ctx, name); - } - NameKind::Function => { - completions::item_list::trait_impl::complete_trait_impl_fn(acc, ctx, name); - } - NameKind::IdentPat(pattern_ctx) => complete_patterns(pattern_ctx), - NameKind::Module(mod_under_caret) => { - completions::mod_::complete_mod(acc, ctx, mod_under_caret); - } - NameKind::TypeAlias => { - completions::item_list::trait_impl::complete_trait_impl_type_alias( - acc, ctx, name, - ); - } - NameKind::RecordField => { - completions::field::complete_field_list_record_variant(acc, ctx); - } - NameKind::ConstParam - | NameKind::Enum - | NameKind::MacroDef - | NameKind::MacroRules - | NameKind::Rename - | NameKind::SelfParam - | NameKind::Static - | NameKind::Struct - | NameKind::Trait - | NameKind::TypeParam - | NameKind::Union - | NameKind::Variant => (), - }, - IdentContext::NameRef(NameRefContext { kind, nameref }) => match kind { - NameRefKind::Path(path_ctx) => { - completions::attribute::complete_attribute(acc, ctx, path_ctx); - completions::attribute::complete_derive(acc, ctx, path_ctx); - completions::dot::complete_undotted_self(acc, ctx, path_ctx); - completions::expr::complete_expr_path(acc, ctx, path_ctx); - completions::field::complete_field_list_tuple_variant(acc, ctx, path_ctx); - completions::flyimport::import_on_the_fly_path(acc, ctx, path_ctx); - completions::item_list::complete_item_list(acc, ctx, path_ctx); - completions::item_list::trait_impl::complete_trait_impl_name_ref( - acc, ctx, path_ctx, nameref, - ); - completions::pattern::pattern_path_completion(acc, ctx, path_ctx); - completions::r#type::complete_inferred_type(acc, ctx, path_ctx); - completions::r#type::complete_type_path(acc, ctx, path_ctx); - completions::record::complete_record_expr_func_update(acc, ctx, path_ctx); - completions::snippet::complete_expr_snippet(acc, ctx, path_ctx); - completions::snippet::complete_item_snippet(acc, ctx, path_ctx); - completions::use_::complete_use_tree(acc, ctx, path_ctx, nameref); - completions::vis::complete_vis_path(acc, ctx, path_ctx); - } - NameRefKind::DotAccess(dot_access) => { - completions::flyimport::import_on_the_fly_dot(acc, ctx, dot_access); - completions::dot::complete_dot(acc, ctx, dot_access); - completions::postfix::complete_postfix(acc, ctx, dot_access); - } - NameRefKind::Keyword(item) => { - completions::keyword::complete_special_keywords(acc, ctx, item); - } - NameRefKind::RecordExpr(record_expr) => { - completions::record::complete_record_expr_fields_record_expr( - acc, - ctx, - record_expr, - ); - } - NameRefKind::Pattern(pattern_ctx) => complete_patterns(pattern_ctx), - }, + IdentContext::Name(name_ctx) => completions::complete_name(acc, ctx, name_ctx), + IdentContext::NameRef(name_ref_ctx) => { + completions::complete_name_ref(acc, ctx, name_ref_ctx) + } IdentContext::Lifetime(lifetime_ctx) => { completions::lifetime::complete_label(acc, ctx, lifetime_ctx); completions::lifetime::complete_lifetime(acc, ctx, lifetime_ctx); From 90483321ee0b47d48a5019bd9bbb11b45a24ac84 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 20 Jun 2022 14:47:30 +0200 Subject: [PATCH 4/4] Remove some usages of `Completions::add_resolution` --- crates/ide-completion/src/completions.rs | 39 +++++++++---------- .../src/completions/attribute.rs | 23 +++++++---- .../src/completions/attribute/derive.rs | 25 ++++++------ .../src/completions/item_list.rs | 19 ++++++--- crates/ide-completion/src/completions/use_.rs | 6 +-- crates/ide-completion/src/completions/vis.rs | 4 +- 6 files changed, 62 insertions(+), 54 deletions(-) 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); } }