about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2022-02-02 12:05:21 +0100
committerLukas Wirth <lukastw97@gmail.com>2022-02-02 12:19:43 +0100
commit7267749f6b4b810f32dc503fe91fd0c03d097c91 (patch)
treee3549c177e3a727796d5420eb5febc5e6e8ad57d
parent70650897d889f2f37fb1be7e837300c87481d958 (diff)
downloadrust-7267749f6b4b810f32dc503fe91fd0c03d097c91.tar.gz
rust-7267749f6b4b810f32dc503fe91fd0c03d097c91.zip
Cleanup `Completions` api a bit
-rw-r--r--crates/ide_completion/src/completions.rs42
-rw-r--r--crates/ide_completion/src/completions/lifetime.rs8
-rw-r--r--crates/ide_completion/src/completions/mod_.rs2
-rw-r--r--crates/ide_completion/src/completions/qualified_path.rs24
-rw-r--r--crates/ide_completion/src/completions/record.rs8
-rw-r--r--crates/ide_completion/src/completions/trait_impl.rs35
-rw-r--r--crates/ide_completion/src/completions/unqualified_path.rs23
-rw-r--r--crates/ide_completion/src/context.rs4
-rw-r--r--crates/ide_completion/src/tests/visibility.rs1
9 files changed, 70 insertions, 77 deletions
diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs
index 515200ef881..92074b3e10d 100644
--- a/crates/ide_completion/src/completions.rs
+++ b/crates/ide_completion/src/completions.rs
@@ -18,7 +18,7 @@ pub(crate) mod format_string;
 
 use std::iter;
 
-use hir::known;
+use hir::{known, ScopeDef};
 use ide_db::SymbolKind;
 
 use crate::{
@@ -28,7 +28,6 @@ use crate::{
         const_::render_const,
         enum_variant::render_variant,
         function::{render_fn, render_method},
-        macro_::render_macro,
         pattern::{render_struct_pat, render_variant_pat},
         render_field, render_resolution, render_tuple_field,
         struct_literal::render_struct_literal,
@@ -38,6 +37,22 @@ use crate::{
     CompletionContext, CompletionItem, CompletionItemKind,
 };
 
+fn module_or_attr(def: ScopeDef) -> Option<ScopeDef> {
+    match def {
+        ScopeDef::MacroDef(mac) if mac.is_attr() => Some(def),
+        ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => Some(def),
+        _ => None,
+    }
+}
+
+fn module_or_fn_macro(def: ScopeDef) -> Option<ScopeDef> {
+    match def {
+        ScopeDef::MacroDef(mac) if mac.is_fn_like() => 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 {
@@ -95,19 +110,6 @@ impl Completions {
         self.add(render_resolution(RenderContext::new(ctx, false), local_name, resolution));
     }
 
-    pub(crate) fn add_macro(
-        &mut self,
-        ctx: &CompletionContext,
-        name: Option<hir::Name>,
-        macro_: hir::MacroDef,
-    ) {
-        let name = match name {
-            Some(it) => it,
-            None => return,
-        };
-        self.add(render_macro(RenderContext::new(ctx, false), None, name, macro_));
-    }
-
     pub(crate) fn add_function(
         &mut self,
         ctx: &CompletionContext,
@@ -227,9 +229,13 @@ impl Completions {
         self.add(item);
     }
 
-    pub(crate) fn add_static_lifetime(&mut self, ctx: &CompletionContext) {
-        let item = CompletionItem::new(SymbolKind::LifetimeParam, ctx.source_range(), "'static");
-        self.add(item.build());
+    pub(crate) fn add_lifetime(&mut self, ctx: &CompletionContext, name: hir::Name) {
+        CompletionItem::new(SymbolKind::LifetimeParam, ctx.source_range(), name.to_smol_str())
+            .add_to(self)
+    }
+
+    pub(crate) fn add_label(&mut self, ctx: &CompletionContext, name: hir::Name) {
+        CompletionItem::new(SymbolKind::Label, ctx.source_range(), name.to_smol_str()).add_to(self)
     }
 
     pub(crate) fn add_variant_pat(
diff --git a/crates/ide_completion/src/completions/lifetime.rs b/crates/ide_completion/src/completions/lifetime.rs
index 4082414f029..878d72ea0fb 100644
--- a/crates/ide_completion/src/completions/lifetime.rs
+++ b/crates/ide_completion/src/completions/lifetime.rs
@@ -7,7 +7,7 @@
 //! there is no value in lifting these out into the outline module test since they will either not
 //! show up for normal completions, or they won't show completions other than lifetimes depending
 //! on the fixture input.
-use hir::ScopeDef;
+use hir::{known, ScopeDef};
 use syntax::ast;
 
 use crate::{
@@ -35,12 +35,12 @@ pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext)
     ctx.scope.process_all_names(&mut |name, res| {
         if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res {
             if param_lifetime != Some(&*name.to_smol_str()) {
-                acc.add_resolution(ctx, name, res);
+                acc.add_lifetime(ctx, name);
             }
         }
     });
     if param_lifetime.is_none() {
-        acc.add_static_lifetime(ctx);
+        acc.add_lifetime(ctx, known::STATIC_LIFETIME);
     }
 }
 
@@ -51,7 +51,7 @@ pub(crate) fn complete_label(acc: &mut Completions, ctx: &CompletionContext) {
     }
     ctx.scope.process_all_names(&mut |name, res| {
         if let ScopeDef::Label(_) = res {
-            acc.add_resolution(ctx, name, res);
+            acc.add_label(ctx, name);
         }
     });
 }
diff --git a/crates/ide_completion/src/completions/mod_.rs b/crates/ide_completion/src/completions/mod_.rs
index 64e992c2e6b..7699c530c63 100644
--- a/crates/ide_completion/src/completions/mod_.rs
+++ b/crates/ide_completion/src/completions/mod_.rs
@@ -13,7 +13,7 @@ use crate::{patterns::ImmediateLocation, CompletionItem};
 
 use crate::{context::CompletionContext, Completions};
 
-/// Complete mod declaration, i.e. `mod $0 ;`
+/// Complete mod declaration, i.e. `mod $0;`
 pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
     let mod_under_caret = match &ctx.completion_location {
         Some(ImmediateLocation::ModDeclaration(mod_under_caret)) => mod_under_caret,
diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs
index 85df19f1dd4..cd1022b2e35 100644
--- a/crates/ide_completion/src/completions/qualified_path.rs
+++ b/crates/ide_completion/src/completions/qualified_path.rs
@@ -7,6 +7,7 @@ use rustc_hash::FxHashSet;
 use syntax::{ast, AstNode};
 
 use crate::{
+    completions::{module_or_attr, module_or_fn_macro},
     context::{PathCompletionContext, PathKind},
     patterns::ImmediateLocation,
     CompletionContext, Completions,
@@ -57,12 +58,7 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
         Some(ImmediateLocation::ItemList | ImmediateLocation::Trait | ImmediateLocation::Impl) => {
             if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
                 for (name, def) in module.scope(ctx.db, context_module) {
-                    if let ScopeDef::MacroDef(macro_def) = def {
-                        if macro_def.is_fn_like() {
-                            acc.add_macro(ctx, Some(name.clone()), macro_def);
-                        }
-                    }
-                    if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
+                    if let Some(def) = module_or_fn_macro(def) {
                         acc.add_resolution(ctx, name, def);
                     }
                 }
@@ -73,16 +69,18 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
     }
 
     match kind {
+        // Complete next child module that comes after the qualified module which is still our parent
         Some(PathKind::Vis { .. }) => {
             if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
                 if let Some(current_module) = ctx.module {
-                    if let Some(next) = current_module
+                    let next_towards_current = current_module
                         .path_to_root(ctx.db)
                         .into_iter()
                         .take_while(|&it| it != module)
-                        .next()
-                    {
+                        .next();
+                    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()));
                         }
                     }
@@ -93,12 +91,7 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
         Some(PathKind::Attr) => {
             if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
                 for (name, def) in module.scope(ctx.db, context_module) {
-                    let add_resolution = match def {
-                        ScopeDef::MacroDef(mac) => mac.is_attr(),
-                        ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => true,
-                        _ => false,
-                    };
-                    if add_resolution {
+                    if let Some(def) = module_or_attr(def) {
                         acc.add_resolution(ctx, name, def);
                     }
                 }
@@ -263,7 +256,6 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
                 );
             }
         }
-        hir::PathResolution::Macro(mac) => acc.add_macro(ctx, None, mac),
         _ => {}
     }
 }
diff --git a/crates/ide_completion/src/completions/record.rs b/crates/ide_completion/src/completions/record.rs
index ec1ee292be4..13b47356197 100644
--- a/crates/ide_completion/src/completions/record.rs
+++ b/crates/ide_completion/src/completions/record.rs
@@ -3,7 +3,8 @@ use ide_db::SymbolKind;
 use syntax::{ast::Expr, T};
 
 use crate::{
-    patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind, Completions,
+    patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind,
+    CompletionRelevance, Completions,
 };
 
 pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
@@ -25,7 +26,10 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
                     CompletionItem::new(SymbolKind::Field, ctx.source_range(), completion_text);
                 let completion_text =
                     completion_text.strip_prefix(ctx.token.text()).unwrap_or(completion_text);
-                item.insert_text(completion_text);
+                item.insert_text(completion_text).set_relevance(CompletionRelevance {
+                    exact_postfix_snippet_match: true,
+                    ..Default::default()
+                });
                 item.add_to(acc);
             }
             if ctx.previous_token_is(T![.]) {
diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs
index b214c5c154a..7a42cfbd42e 100644
--- a/crates/ide_completion/src/completions/trait_impl.rs
+++ b/crates/ide_completion/src/completions/trait_impl.rs
@@ -42,7 +42,7 @@ use text_edit::TextEdit;
 
 use crate::{CompletionContext, CompletionItem, CompletionItemKind, Completions};
 
-#[derive(Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
 enum ImplCompletionKind {
     All,
     Fn,
@@ -53,23 +53,22 @@ enum ImplCompletionKind {
 pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext) {
     if let Some((kind, trigger, impl_def)) = completion_match(ctx.token.clone()) {
         if let Some(hir_impl) = ctx.sema.to_def(&impl_def) {
-            get_missing_assoc_items(&ctx.sema, &impl_def).into_iter().for_each(|item| match item {
-                hir::AssocItem::Function(fn_item)
-                    if kind == ImplCompletionKind::All || kind == ImplCompletionKind::Fn =>
-                {
-                    add_function_impl(&trigger, acc, ctx, fn_item, hir_impl)
+            get_missing_assoc_items(&ctx.sema, &impl_def).into_iter().for_each(|item| {
+                match (item, kind) {
+                    (
+                        hir::AssocItem::Function(fn_item),
+                        ImplCompletionKind::All | ImplCompletionKind::Fn,
+                    ) => add_function_impl(&trigger, acc, ctx, fn_item, hir_impl),
+                    (
+                        hir::AssocItem::TypeAlias(type_item),
+                        ImplCompletionKind::All | ImplCompletionKind::TypeAlias,
+                    ) => add_type_alias_impl(&trigger, acc, ctx, type_item),
+                    (
+                        hir::AssocItem::Const(const_item),
+                        ImplCompletionKind::All | ImplCompletionKind::Const,
+                    ) => add_const_impl(&trigger, acc, ctx, const_item, hir_impl),
+                    _ => {}
                 }
-                hir::AssocItem::TypeAlias(type_item)
-                    if kind == ImplCompletionKind::All || kind == ImplCompletionKind::TypeAlias =>
-                {
-                    add_type_alias_impl(&trigger, acc, ctx, type_item)
-                }
-                hir::AssocItem::Const(const_item)
-                    if kind == ImplCompletionKind::All || kind == ImplCompletionKind::Const =>
-                {
-                    add_const_impl(&trigger, acc, ctx, const_item, hir_impl)
-                }
-                _ => {}
             });
         }
     }
@@ -194,7 +193,7 @@ fn get_transformed_assoc_item(
 
     transform.apply(assoc_item.syntax());
     if let ast::AssocItem::Fn(func) = &assoc_item {
-        func.remove_attrs_and_docs()
+        func.remove_attrs_and_docs();
     }
     Some(assoc_item)
 }
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs
index e7980c12d77..7e06b074ce2 100644
--- a/crates/ide_completion/src/completions/unqualified_path.rs
+++ b/crates/ide_completion/src/completions/unqualified_path.rs
@@ -4,6 +4,7 @@ use hir::ScopeDef;
 use syntax::{ast, AstNode};
 
 use crate::{
+    completions::{module_or_attr, module_or_fn_macro},
     context::{PathCompletionContext, PathKind},
     patterns::ImmediateLocation,
     CompletionContext, Completions,
@@ -36,14 +37,9 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
     match kind {
         Some(PathKind::Vis { .. }) => return,
         Some(PathKind::Attr) => {
-            ctx.process_all_names(&mut |name, res| {
-                let add_resolution = match res {
-                    ScopeDef::MacroDef(mac) => mac.is_attr(),
-                    ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => true,
-                    _ => false,
-                };
-                if add_resolution {
-                    acc.add_resolution(ctx, name, res);
+            ctx.process_all_names(&mut |name, def| {
+                if let Some(def) = module_or_attr(def) {
+                    acc.add_resolution(ctx, name, def);
                 }
             });
             return;
@@ -54,14 +50,9 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
     match &ctx.completion_location {
         Some(ImmediateLocation::ItemList | ImmediateLocation::Trait | ImmediateLocation::Impl) => {
             // only show macros in {Assoc}ItemList
-            ctx.process_all_names(&mut |name, res| {
-                if let hir::ScopeDef::MacroDef(mac) = res {
-                    if mac.is_fn_like() {
-                        acc.add_macro(ctx, Some(name.clone()), mac);
-                    }
-                }
-                if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
-                    acc.add_resolution(ctx, name, res);
+            ctx.process_all_names(&mut |name, def| {
+                if let Some(def) = module_or_fn_macro(def) {
+                    acc.add_resolution(ctx, name, def);
                 }
             });
             return;
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 5adb0c856bb..ab55d9cc04a 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -34,7 +34,7 @@ pub(crate) enum PatternRefutability {
     Refutable,
     Irrefutable,
 }
-pub enum Visible {
+pub(crate) enum Visible {
     Yes,
     Editable,
     No,
@@ -108,7 +108,7 @@ pub(crate) struct CompletionContext<'a> {
     pub(super) token: SyntaxToken,
     /// The crate of the current file.
     pub(super) krate: Option<hir::Crate>,
-    /// The crate of the `scope`.
+    /// The module of the `scope`.
     pub(super) module: Option<hir::Module>,
     pub(super) expected_name: Option<NameOrNameRef>,
     pub(super) expected_type: Option<Type>,
diff --git a/crates/ide_completion/src/tests/visibility.rs b/crates/ide_completion/src/tests/visibility.rs
index 8a024af24b8..2fd16235dc6 100644
--- a/crates/ide_completion/src/tests/visibility.rs
+++ b/crates/ide_completion/src/tests/visibility.rs
@@ -40,6 +40,7 @@ pub(in $0)
 
 #[test]
 fn qualified() {
+    cov_mark::check!(visibility_qualified);
     check(
         r#"
 mod foo {