Unnamed repository; edit this file 'description' to name the repository.
Even more completion context filtering
Lukas Wirth 2022-06-20
parent ce5859e · commit 7685245
-rw-r--r--crates/ide-completion/src/completions.rs122
-rw-r--r--crates/ide-completion/src/completions/attribute.rs14
-rw-r--r--crates/ide-completion/src/completions/attribute/derive.rs12
-rw-r--r--crates/ide-completion/src/completions/dot.rs23
-rw-r--r--crates/ide-completion/src/completions/expr.rs36
-rw-r--r--crates/ide-completion/src/completions/field.rs16
-rw-r--r--crates/ide-completion/src/completions/item_list.rs39
-rw-r--r--crates/ide-completion/src/completions/item_list/trait_impl.rs23
-rw-r--r--crates/ide-completion/src/completions/keyword.rs4
-rw-r--r--crates/ide-completion/src/completions/pattern.rs9
-rw-r--r--crates/ide-completion/src/completions/record.rs15
-rw-r--r--crates/ide-completion/src/completions/snippet.rs57
-rw-r--r--crates/ide-completion/src/completions/type.rs27
-rw-r--r--crates/ide-completion/src/completions/use_.rs11
-rw-r--r--crates/ide-completion/src/completions/vis.rs12
-rw-r--r--crates/ide-completion/src/context.rs5
-rw-r--r--crates/ide-completion/src/lib.rs94
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<ast::NameRef>,
-) -> Option<()> {
- match path_ctx {
- PathCompletionCtx {
- kind: PathKind::Item { kind: ItemListKind::TraitImpl(Some(impl_)) },
- ..
- } if path_ctx.is_trivial_path() => complete_trait_impl(
+ impl_: &Option<ast::Impl>,
+) {
+ 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<ast::NameRef>,
) {
- 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<hir::Macro>,
+ 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<hir::Macro>;
+
#[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);