Unnamed repository; edit this file 'description' to name the repository.
Add doc(alias)-based field completion
hecatia-elegua 2023-04-06
parent da9c0bd · commit 410acd7
-rw-r--r--crates/ide-completion/src/completions.rs3
-rw-r--r--crates/ide-completion/src/context.rs12
-rw-r--r--crates/ide-completion/src/item.rs12
-rw-r--r--crates/ide-completion/src/render.rs7
-rw-r--r--crates/ide-completion/src/tests/special.rs19
5 files changed, 40 insertions, 13 deletions
diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs
index b6a066f4f5..333a333875 100644
--- a/crates/ide-completion/src/completions.rs
+++ b/crates/ide-completion/src/completions.rs
@@ -430,8 +430,9 @@ impl Completions {
Visible::Editable => true,
Visible::No => return,
};
+ let doc_aliases = ctx.doc_aliases(&field);
let item = render_field(
- RenderContext::new(ctx).private_editable(is_private_editable),
+ RenderContext::new(ctx).private_editable(is_private_editable).doc_aliases(doc_aliases),
dot_access,
receiver,
field,
diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs
index f6478d2ceb..f9bc13f7d2 100644
--- a/crates/ide-completion/src/context.rs
+++ b/crates/ide-completion/src/context.rs
@@ -441,6 +441,14 @@ impl<'a> CompletionContext<'a> {
self.is_visible_impl(&vis, &attrs, item.krate(self.db))
}
+ pub(crate) fn doc_aliases<I>(&self, item: &I) -> Vec<SmolStr>
+ where
+ I: hir::HasAttrs + Copy,
+ {
+ let attrs = item.attrs(self.db);
+ attrs.doc_aliases().collect()
+ }
+
/// Check if an item is `#[doc(hidden)]`.
pub(crate) fn is_item_hidden(&self, item: &hir::ItemInNs) -> bool {
let attrs = item.attrs(self.db);
@@ -499,7 +507,7 @@ impl<'a> CompletionContext<'a> {
if self.is_scope_def_hidden(def) {
return;
}
- let doc_aliases = self.doc_aliases(def);
+ let doc_aliases = self.doc_aliases_in_scope(def);
f(name, def, doc_aliases);
});
}
@@ -547,7 +555,7 @@ impl<'a> CompletionContext<'a> {
self.krate != defining_crate && attrs.has_doc_hidden()
}
- fn doc_aliases(&self, scope_def: ScopeDef) -> Vec<SmolStr> {
+ fn doc_aliases_in_scope(&self, scope_def: ScopeDef) -> Vec<SmolStr> {
if let Some(attrs) = scope_def.attrs(self.db) {
attrs.doc_aliases().collect()
} else {
diff --git a/crates/ide-completion/src/item.rs b/crates/ide-completion/src/item.rs
index c2c4a663c6..ab27b8c0a9 100644
--- a/crates/ide-completion/src/item.rs
+++ b/crates/ide-completion/src/item.rs
@@ -4,6 +4,7 @@ use std::fmt;
use hir::{Documentation, Mutability};
use ide_db::{imports::import_assets::LocatedImport, SnippetCap, SymbolKind};
+use itertools::Itertools;
use smallvec::SmallVec;
use stdx::{impl_from, never};
use syntax::{SmolStr, TextRange, TextSize};
@@ -353,7 +354,7 @@ impl CompletionItem {
relevance: CompletionRelevance::default(),
ref_match: None,
imports_to_add: Default::default(),
- doc_aliases: None,
+ doc_aliases: vec![],
}
}
@@ -386,7 +387,7 @@ pub(crate) struct Builder {
source_range: TextRange,
imports_to_add: SmallVec<[LocatedImport; 1]>,
trait_name: Option<SmolStr>,
- doc_aliases: Option<SmolStr>,
+ doc_aliases: Vec<SmolStr>,
label: SmolStr,
insert_text: Option<String>,
is_snippet: bool,
@@ -418,7 +419,8 @@ impl Builder {
let mut lookup = self.lookup.unwrap_or_else(|| label.clone());
let insert_text = self.insert_text.unwrap_or_else(|| label.to_string());
- if let Some(doc_aliases) = self.doc_aliases {
+ if !self.doc_aliases.is_empty() {
+ let doc_aliases = self.doc_aliases.into_iter().join(", ");
label = SmolStr::from(format!("{label} (alias {doc_aliases})"));
lookup = SmolStr::from(format!("{lookup} {doc_aliases}"));
}
@@ -464,8 +466,8 @@ impl Builder {
self.trait_name = Some(trait_name);
self
}
- pub(crate) fn doc_aliases(&mut self, doc_aliases: SmolStr) -> &mut Builder {
- self.doc_aliases = Some(doc_aliases);
+ pub(crate) fn doc_aliases(&mut self, doc_aliases: Vec<SmolStr>) -> &mut Builder {
+ self.doc_aliases = doc_aliases;
self
}
pub(crate) fn insert_text(&mut self, insert_text: impl Into<String>) -> &mut Builder {
diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs
index 514a684726..62a357e085 100644
--- a/crates/ide-completion/src/render.rs
+++ b/crates/ide-completion/src/render.rs
@@ -152,6 +152,7 @@ pub(crate) fn render_field(
}
}
}
+ item.doc_aliases(ctx.doc_aliases);
item.build()
}
@@ -361,11 +362,7 @@ fn render_resolution_simple_(
item.add_import(import_to_add);
}
- let doc_aliases = ctx.doc_aliases;
- if !doc_aliases.is_empty() {
- let doc_aliases = doc_aliases.into_iter().join(", ").into();
- item.doc_aliases(doc_aliases);
- }
+ item.doc_aliases(ctx.doc_aliases);
item
}
diff --git a/crates/ide-completion/src/tests/special.rs b/crates/ide-completion/src/tests/special.rs
index 1749e8e70f..5f53e5b6a9 100644
--- a/crates/ide-completion/src/tests/special.rs
+++ b/crates/ide-completion/src/tests/special.rs
@@ -1086,3 +1086,22 @@ fn here_we_go() {
"#]],
);
}
+
+#[test]
+fn completes_field_name_via_doc_alias_in_fn_body() {
+ check(
+ r#"
+struct Foo {
+ #[doc(alias = "qux")]
+ bar: u8
+};
+
+fn here_we_go() {
+ let foo = Foo { q$0 }
+}
+"#,
+ expect![[r#"
+ fd bar (alias qux) u8
+ "#]],
+ );
+}