Unnamed repository; edit this file 'description' to name the repository.
Simplify
Lukas Wirth 2022-06-04
parent 98c0578 · commit a0c1816
-rw-r--r--crates/ide-completion/src/completions/item_list.rs132
-rw-r--r--crates/ide-completion/src/completions/item_list/trait_impl.rs85
-rw-r--r--crates/ide-completion/src/context.rs2
3 files changed, 113 insertions, 106 deletions
diff --git a/crates/ide-completion/src/completions/item_list.rs b/crates/ide-completion/src/completions/item_list.rs
index 9b03d8bc5f..7c6d72a031 100644
--- a/crates/ide-completion/src/completions/item_list.rs
+++ b/crates/ide-completion/src/completions/item_list.rs
@@ -32,74 +32,11 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
_ => return,
};
- let in_item_list = matches!(kind, Some(ItemListKind::SourceFile | ItemListKind::Module) | None);
- let in_assoc_non_trait_impl = matches!(kind, Some(ItemListKind::Impl | ItemListKind::Trait));
- let in_extern_block = matches!(kind, Some(ItemListKind::ExternBlock));
- let in_trait = matches!(kind, Some(ItemListKind::Trait));
- let in_trait_impl = matches!(kind, Some(ItemListKind::TraitImpl));
- let in_inherent_impl = matches!(kind, Some(ItemListKind::Impl));
- let no_qualifiers = ctx.qualifier_ctx.vis_node.is_none();
- let in_block = matches!(kind, None);
-
- if in_trait_impl {
+ if matches!(kind, Some(ItemListKind::TraitImpl)) {
trait_impl::complete_trait_impl(acc, ctx);
}
- let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
-
- 'block: loop {
- if ctx.is_non_trivial_path() {
- break 'block;
- }
- if !in_trait_impl {
- if ctx.qualifier_ctx.unsafe_tok.is_some() {
- if in_item_list || in_assoc_non_trait_impl {
- add_keyword("fn", "fn $1($2) {\n $0\n}");
- }
- if in_item_list {
- add_keyword("trait", "trait $1 {\n $0\n}");
- if no_qualifiers {
- add_keyword("impl", "impl $1 {\n $0\n}");
- }
- }
- break 'block;
- }
-
- if in_item_list {
- add_keyword("enum", "enum $1 {\n $0\n}");
- add_keyword("mod", "mod $0");
- add_keyword("static", "static $0");
- add_keyword("struct", "struct $0");
- add_keyword("trait", "trait $1 {\n $0\n}");
- add_keyword("union", "union $1 {\n $0\n}");
- add_keyword("use", "use $0");
- if no_qualifiers {
- add_keyword("impl", "impl $1 {\n $0\n}");
- }
- }
- if !in_trait && !in_block && no_qualifiers {
- add_keyword("pub(crate)", "pub(crate)");
- add_keyword("pub(super)", "pub(super)");
- add_keyword("pub", "pub");
- }
-
- if in_extern_block {
- add_keyword("fn", "fn $1($2);");
- } else {
- if !in_inherent_impl {
- if !in_trait {
- add_keyword("extern", "extern $0");
- }
- add_keyword("type", "type $0");
- }
-
- add_keyword("fn", "fn $1($2) {\n $0\n}");
- add_keyword("unsafe", "unsafe");
- add_keyword("const", "const $0");
- }
- }
- break 'block;
- }
+ add_keywords(acc, ctx, kind);
if kind.is_none() {
// this is already handled by expression
@@ -132,3 +69,68 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
None => {}
}
}
+
+fn add_keywords(acc: &mut Completions, ctx: &CompletionContext, kind: Option<&ItemListKind>) {
+ if ctx.is_non_trivial_path() {
+ return;
+ }
+ let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
+
+ let in_item_list = matches!(kind, Some(ItemListKind::SourceFile | ItemListKind::Module) | None);
+ let in_assoc_non_trait_impl = matches!(kind, Some(ItemListKind::Impl | ItemListKind::Trait));
+ let in_extern_block = matches!(kind, Some(ItemListKind::ExternBlock));
+ let in_trait = matches!(kind, Some(ItemListKind::Trait));
+ let in_trait_impl = matches!(kind, Some(ItemListKind::TraitImpl));
+ let in_inherent_impl = matches!(kind, Some(ItemListKind::Impl));
+ let no_qualifiers = ctx.qualifier_ctx.vis_node.is_none();
+ let in_block = matches!(kind, None);
+
+ if !in_trait_impl {
+ if ctx.qualifier_ctx.unsafe_tok.is_some() {
+ if in_item_list || in_assoc_non_trait_impl {
+ add_keyword("fn", "fn $1($2) {\n $0\n}");
+ }
+ if in_item_list {
+ add_keyword("trait", "trait $1 {\n $0\n}");
+ if no_qualifiers {
+ add_keyword("impl", "impl $1 {\n $0\n}");
+ }
+ }
+ return;
+ }
+
+ if in_item_list {
+ add_keyword("enum", "enum $1 {\n $0\n}");
+ add_keyword("mod", "mod $0");
+ add_keyword("static", "static $0");
+ add_keyword("struct", "struct $0");
+ add_keyword("trait", "trait $1 {\n $0\n}");
+ add_keyword("union", "union $1 {\n $0\n}");
+ add_keyword("use", "use $0");
+ if no_qualifiers {
+ add_keyword("impl", "impl $1 {\n $0\n}");
+ }
+ }
+
+ if !in_trait && !in_block && no_qualifiers {
+ add_keyword("pub(crate)", "pub(crate)");
+ add_keyword("pub(super)", "pub(super)");
+ add_keyword("pub", "pub");
+ }
+
+ if in_extern_block {
+ add_keyword("fn", "fn $1($2);");
+ } else {
+ if !in_inherent_impl {
+ if !in_trait {
+ add_keyword("extern", "extern $0");
+ }
+ add_keyword("type", "type $0");
+ }
+
+ add_keyword("fn", "fn $1($2) {\n $0\n}");
+ add_keyword("unsafe", "unsafe");
+ add_keyword("const", "const $0");
+ }
+ }
+}
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 627752b1cd..8a2bbae73f 100644
--- a/crates/ide-completion/src/completions/item_list/trait_impl.rs
+++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs
@@ -43,7 +43,10 @@ use syntax::{
use text_edit::TextEdit;
use crate::{
- context::{ItemListKind, NameContext, NameKind, NameRefContext, PathCompletionCtx, PathKind},
+ context::{
+ IdentContext, ItemListKind, NameContext, NameKind, NameRefContext, PathCompletionCtx,
+ PathKind,
+ },
CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance, Completions,
};
@@ -78,47 +81,49 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext
}
fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, TextRange, ast::Impl)> {
- let token = ctx.token.clone();
-
- if let Some(NameContext { name, kind, .. }) = ctx.name_ctx() {
- let kind = match kind {
- NameKind::Const => ImplCompletionKind::Const,
- NameKind::Function => ImplCompletionKind::Fn,
- NameKind::TypeAlias => ImplCompletionKind::TypeAlias,
- _ => return None,
- };
- let item = match name {
- Some(name) => name.syntax().parent(),
- None => {
- if token.kind() == SyntaxKind::WHITESPACE { token.prev_token()? } else { token }
- .parent()
- }
- }?;
- return Some((
- kind,
- replacement_range(ctx, &item),
- // item -> ASSOC_ITEM_LIST -> IMPL
- ast::Impl::cast(item.parent()?.parent()?)?,
- ));
- } else if let Some(NameRefContext {
- nameref,
- path_ctx:
- Some(PathCompletionCtx { kind: PathKind::Item { kind: ItemListKind::TraitImpl }, .. }),
- ..
- }) = ctx.nameref_ctx()
- {
- if !ctx.is_non_trivial_path() {
- return Some((
- ImplCompletionKind::All,
- match nameref {
- Some(name) => name.syntax().text_range(),
- None => TextRange::empty(ctx.position.offset),
- },
- ctx.impl_def.clone()?,
- ));
+ match &ctx.ident_ctx {
+ IdentContext::Name(NameContext { name, kind, .. }) => {
+ 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(),
+ None => {
+ if token.kind() == SyntaxKind::WHITESPACE { token.prev_token()? } else { token }
+ .parent()
+ }
+ }?;
+ Some((
+ kind,
+ replacement_range(ctx, &item),
+ // item -> ASSOC_ITEM_LIST -> IMPL
+ ast::Impl::cast(item.parent()?.parent()?)?,
+ ))
}
+ IdentContext::NameRef(NameRefContext {
+ nameref,
+ path_ctx:
+ Some(
+ path_ctx @ PathCompletionCtx {
+ kind: PathKind::Item { kind: ItemListKind::TraitImpl },
+ ..
+ },
+ ),
+ ..
+ }) if path_ctx.is_trivial_path() => Some((
+ ImplCompletionKind::All,
+ match nameref {
+ Some(name) => name.syntax().text_range(),
+ None => TextRange::empty(ctx.position.offset),
+ },
+ ctx.impl_def.clone()?,
+ )),
+ _ => None,
}
- None
}
fn add_function_impl(
diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs
index 83815f6d5d..d41ca88e89 100644
--- a/crates/ide-completion/src/context.rs
+++ b/crates/ide-completion/src/context.rs
@@ -109,7 +109,7 @@ pub(crate) struct PathCompletionCtx {
}
impl PathCompletionCtx {
- fn is_trivial_path(&self) -> bool {
+ pub(super) fn is_trivial_path(&self) -> bool {
matches!(
self,
PathCompletionCtx {