Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide-completion/src/completions/attribute.rs39
-rw-r--r--crates/ide-completion/src/completions/attribute/cfg.rs7
-rw-r--r--crates/ide-completion/src/completions/attribute/diagnostic.rs70
-rw-r--r--crates/ide-completion/src/completions/attribute/feature.rs30
-rw-r--r--crates/ide-completion/src/completions/attribute/lint.rs32
-rw-r--r--crates/ide-completion/src/completions/attribute/macro_use.rs6
-rw-r--r--crates/ide-completion/src/completions/attribute/repr.rs56
-rw-r--r--crates/ide-completion/src/lib.rs2
8 files changed, 124 insertions, 118 deletions
diff --git a/crates/ide-completion/src/completions/attribute.rs b/crates/ide-completion/src/completions/attribute.rs
index da1e664f96..0ce0dde2e2 100644
--- a/crates/ide-completion/src/completions/attribute.rs
+++ b/crates/ide-completion/src/completions/attribute.rs
@@ -4,13 +4,7 @@
use std::sync::LazyLock;
-use ide_db::{
- FxHashMap, SymbolKind,
- generated::lints::{
- CLIPPY_LINT_GROUPS, CLIPPY_LINTS, DEFAULT_LINTS, FEATURES, Lint, RUSTDOC_LINTS,
- },
- syntax_helpers::node_ext::parse_tt_as_comma_sep_paths,
-};
+use ide_db::{FxHashMap, SymbolKind, syntax_helpers::node_ext::parse_tt_as_comma_sep_paths};
use itertools::Itertools;
use syntax::{
AstNode, Edition, SyntaxKind, T,
@@ -26,6 +20,7 @@ use crate::{
mod cfg;
mod derive;
mod diagnostic;
+mod feature;
mod lint;
mod macro_use;
mod repr;
@@ -37,7 +32,7 @@ pub(crate) use self::derive::complete_derive_path;
pub(crate) fn complete_known_attribute_input(
acc: &mut Completions,
ctx: &CompletionContext<'_>,
- &colon_prefix: &bool,
+ colon_prefix: bool,
fake_attribute_under_caret: &ast::TokenTreeMeta,
extern_crate: Option<&ast::ExternCrate>,
) -> Option<()> {
@@ -49,35 +44,25 @@ pub(crate) fn complete_known_attribute_input(
let tt = attribute.token_tree()?;
match segments.as_slice() {
- ["repr"] => repr::complete_repr(acc, ctx, tt),
- ["feature"] => lint::complete_lint(
+ ["repr"] => repr::complete_repr(acc, ctx, &parse_comma_sep_expr(tt)?),
+ ["feature"] => {
+ feature::complete_feature(acc, ctx, &parse_tt_as_comma_sep_paths(tt, ctx.edition)?)
+ }
+ ["allow" | "expect" | "deny" | "forbid" | "warn"] => lint::complete_lint(
acc,
ctx,
colon_prefix,
&parse_tt_as_comma_sep_paths(tt, ctx.edition)?,
- FEATURES,
),
- ["allow"] | ["expect"] | ["deny"] | ["forbid"] | ["warn"] => {
- let existing_lints = parse_tt_as_comma_sep_paths(tt, ctx.edition)?;
-
- let lints: Vec<Lint> = CLIPPY_LINT_GROUPS
- .iter()
- .map(|g| &g.lint)
- .chain(DEFAULT_LINTS)
- .chain(CLIPPY_LINTS)
- .chain(RUSTDOC_LINTS)
- .cloned()
- .collect();
-
- lint::complete_lint(acc, ctx, colon_prefix, &existing_lints, &lints);
- }
["macro_use"] => macro_use::complete_macro_use(
acc,
ctx,
extern_crate,
&parse_tt_as_comma_sep_paths(tt, ctx.edition)?,
),
- ["diagnostic", "on_unimplemented"] => diagnostic::complete_on_unimplemented(acc, ctx, tt),
+ ["diagnostic", "on_unimplemented"] => {
+ diagnostic::complete_on_unimplemented(acc, ctx, &parse_comma_sep_expr(tt)?)
+ }
_ => (),
}
Some(())
@@ -190,7 +175,7 @@ pub(crate) fn complete_attribute_path(
match attributes {
Some(applicable) => applicable
.iter()
- .flat_map(|name| ATTRIBUTES.binary_search_by(|attr| attr.key().cmp(name)).ok())
+ .flat_map(|name| ATTRIBUTES.binary_search_by_key(name, |attr| attr.key()).ok())
.flat_map(|idx| ATTRIBUTES.get(idx))
.for_each(add_completion),
None if is_inner => ATTRIBUTES.iter().for_each(add_completion),
diff --git a/crates/ide-completion/src/completions/attribute/cfg.rs b/crates/ide-completion/src/completions/attribute/cfg.rs
index 0d36fb7a40..1bd6e6d9bf 100644
--- a/crates/ide-completion/src/completions/attribute/cfg.rs
+++ b/crates/ide-completion/src/completions/attribute/cfg.rs
@@ -11,7 +11,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) {
let mut completion =
CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), item, ctx.edition);
completion.insert_text(format!(r#""{item}""#));
- acc.add(completion.build(ctx.db));
+ completion.add_to(acc, ctx.db);
};
// FIXME: Move this into context/analysis.rs
@@ -49,8 +49,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) {
ctx.edition,
);
item.insert_text(insert_text);
-
- acc.add(item.build(ctx.db));
+ item.add_to(acc, ctx.db);
}),
},
None => ctx
@@ -82,7 +81,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) {
{
item.insert_snippet(cap, snippet);
}
- acc.add(item.build(ctx.db));
+ item.add_to(acc, ctx.db);
}),
}
}
diff --git a/crates/ide-completion/src/completions/attribute/diagnostic.rs b/crates/ide-completion/src/completions/attribute/diagnostic.rs
index 8adc974239..0899bbff14 100644
--- a/crates/ide-completion/src/completions/attribute/diagnostic.rs
+++ b/crates/ide-completion/src/completions/attribute/diagnostic.rs
@@ -10,46 +10,44 @@ use super::AttrCompletion;
pub(super) fn complete_on_unimplemented(
acc: &mut Completions,
ctx: &CompletionContext<'_>,
- input: ast::TokenTree,
+ existing_keys: &[ast::Expr],
) {
- if let Some(existing_keys) = super::parse_comma_sep_expr(input) {
- for attr in ATTRIBUTE_ARGS {
- let already_annotated = existing_keys
- .iter()
- .filter_map(|expr| match expr {
- ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
- ast::Expr::BinExpr(bin)
- if bin.op_kind() == Some(ast::BinaryOp::Assignment { op: None }) =>
- {
- match bin.lhs()? {
- ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
- _ => None,
- }
+ for attr in ATTRIBUTE_ARGS {
+ let already_annotated = existing_keys
+ .iter()
+ .filter_map(|expr| match expr {
+ ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
+ ast::Expr::BinExpr(bin)
+ if bin.op_kind() == Some(ast::BinaryOp::Assignment { op: None }) =>
+ {
+ match bin.lhs()? {
+ ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
+ _ => None,
}
- _ => None,
- })
- .any(|it| {
- let text = it.text();
- attr.key() == text && text != "note"
- });
- if already_annotated {
- continue;
- }
+ }
+ _ => None,
+ })
+ .any(|it| {
+ let text = it.text();
+ attr.key() == text && text != "note"
+ });
+ if already_annotated {
+ continue;
+ }
- let mut item = CompletionItem::new(
- SymbolKind::BuiltinAttr,
- ctx.source_range(),
- attr.label,
- ctx.edition,
- );
- if let Some(lookup) = attr.lookup {
- item.lookup_by(lookup);
- }
- if let Some((snippet, cap)) = attr.snippet.zip(ctx.config.snippet_cap) {
- item.insert_snippet(cap, snippet);
- }
- item.add_to(acc, ctx.db);
+ let mut item = CompletionItem::new(
+ SymbolKind::BuiltinAttr,
+ ctx.source_range(),
+ attr.label,
+ ctx.edition,
+ );
+ if let Some(lookup) = attr.lookup {
+ item.lookup_by(lookup);
+ }
+ if let Some((snippet, cap)) = attr.snippet.zip(ctx.config.snippet_cap) {
+ item.insert_snippet(cap, snippet);
}
+ item.add_to(acc, ctx.db);
}
}
diff --git a/crates/ide-completion/src/completions/attribute/feature.rs b/crates/ide-completion/src/completions/attribute/feature.rs
new file mode 100644
index 0000000000..1e6baca864
--- /dev/null
+++ b/crates/ide-completion/src/completions/attribute/feature.rs
@@ -0,0 +1,30 @@
+//! Completion for features
+use ide_db::{
+ SymbolKind,
+ documentation::Documentation,
+ generated::lints::{FEATURES, Lint},
+};
+use syntax::ast;
+
+use crate::{Completions, context::CompletionContext, item::CompletionItem};
+
+pub(super) fn complete_feature(
+ acc: &mut Completions,
+ ctx: &CompletionContext<'_>,
+ existing_features: &[ast::Path],
+) {
+ for &Lint { label, description, .. } in FEATURES {
+ let feature_already_annotated = existing_features
+ .iter()
+ .filter_map(|p| p.as_single_name_ref())
+ .any(|n| n.text() == label);
+ if feature_already_annotated {
+ continue;
+ }
+
+ let mut item =
+ CompletionItem::new(SymbolKind::Attribute, ctx.source_range(), label, ctx.edition);
+ item.documentation(Documentation::new_borrowed(description));
+ item.add_to(acc, ctx.db)
+ }
+}
diff --git a/crates/ide-completion/src/completions/attribute/lint.rs b/crates/ide-completion/src/completions/attribute/lint.rs
index df577b8ed0..f810196bfe 100644
--- a/crates/ide-completion/src/completions/attribute/lint.rs
+++ b/crates/ide-completion/src/completions/attribute/lint.rs
@@ -1,5 +1,9 @@
//! Completion for lints
-use ide_db::{SymbolKind, documentation::Documentation, generated::lints::Lint};
+use ide_db::{
+ SymbolKind,
+ documentation::Documentation,
+ generated::lints::{CLIPPY_LINT_GROUPS, CLIPPY_LINTS, DEFAULT_LINTS, Lint, RUSTDOC_LINTS},
+};
use syntax::ast;
use crate::{Completions, context::CompletionContext, item::CompletionItem};
@@ -9,21 +13,17 @@ pub(super) fn complete_lint(
ctx: &CompletionContext<'_>,
is_qualified: bool,
existing_lints: &[ast::Path],
- lints_completions: &[Lint],
) {
- for &Lint { label, description, .. } in lints_completions {
- let (qual, name) = {
- // FIXME: change `Lint`'s label to not store a path in it but split the prefix off instead?
- let mut parts = label.split("::");
- let ns_or_label = match parts.next() {
- Some(it) => it,
- None => continue,
- };
- let label = parts.next();
- match label {
- Some(label) => (Some(ns_or_label), label),
- None => (None, ns_or_label),
- }
+ let lints = (CLIPPY_LINT_GROUPS.iter().map(|g| &g.lint))
+ .chain(DEFAULT_LINTS)
+ .chain(CLIPPY_LINTS)
+ .chain(RUSTDOC_LINTS);
+
+ for &Lint { label, description, .. } in lints {
+ // FIXME: change `Lint`'s label to not store a path in it but split the prefix off instead?
+ let (qual, name) = match label.split_once("::") {
+ Some((qual, name)) => (Some(qual), name),
+ None => (None, label),
};
if qual.is_none() && is_qualified {
// qualified completion requested, but this lint is unqualified
@@ -56,7 +56,7 @@ pub(super) fn complete_lint(
};
let mut item =
CompletionItem::new(SymbolKind::Attribute, ctx.source_range(), label, ctx.edition);
- item.documentation(Documentation::new_owned(description.to_owned()));
+ item.documentation(Documentation::new_borrowed(description));
item.add_to(acc, ctx.db)
}
}
diff --git a/crates/ide-completion/src/completions/attribute/macro_use.rs b/crates/ide-completion/src/completions/attribute/macro_use.rs
index 136315c61f..9c0fe0055d 100644
--- a/crates/ide-completion/src/completions/attribute/macro_use.rs
+++ b/crates/ide-completion/src/completions/attribute/macro_use.rs
@@ -20,11 +20,11 @@ pub(super) fn complete_macro_use(
let mac_name = mac.name(ctx.db);
let mac_name = mac_name.as_str();
- let existing_import = existing_imports
+ let already_imported = existing_imports
.iter()
.filter_map(|p| p.as_single_name_ref())
- .find(|n| n.text() == mac_name);
- if existing_import.is_some() {
+ .any(|n| n.text() == mac_name);
+ if already_imported {
continue;
}
diff --git a/crates/ide-completion/src/completions/attribute/repr.rs b/crates/ide-completion/src/completions/attribute/repr.rs
index cb7ccf7373..b04358963a 100644
--- a/crates/ide-completion/src/completions/attribute/repr.rs
+++ b/crates/ide-completion/src/completions/attribute/repr.rs
@@ -8,42 +8,36 @@ use crate::{Completions, context::CompletionContext, item::CompletionItem};
pub(super) fn complete_repr(
acc: &mut Completions,
ctx: &CompletionContext<'_>,
- input: ast::TokenTree,
+ existing_reprs: &[ast::Expr],
) {
- if let Some(existing_reprs) = super::parse_comma_sep_expr(input) {
- for &ReprCompletion { label, snippet, lookup, collides } in REPR_COMPLETIONS {
- let repr_already_annotated = existing_reprs
- .iter()
- .filter_map(|expr| match expr {
+ for &ReprCompletion { label, snippet, lookup, collides } in REPR_COMPLETIONS {
+ let repr_already_annotated = existing_reprs
+ .iter()
+ .filter_map(|expr| match expr {
+ ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
+ ast::Expr::CallExpr(call) => match call.expr()? {
ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
- ast::Expr::CallExpr(call) => match call.expr()? {
- ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
- _ => None,
- },
_ => None,
- })
- .any(|it| {
- let text = it.text();
- lookup.unwrap_or(label) == text || collides.contains(&text.as_str())
- });
- if repr_already_annotated {
- continue;
- }
+ },
+ _ => None,
+ })
+ .any(|it| {
+ let text = it.text();
+ lookup.unwrap_or(label) == text || collides.contains(&text.as_str())
+ });
+ if repr_already_annotated {
+ continue;
+ }
- let mut item = CompletionItem::new(
- SymbolKind::BuiltinAttr,
- ctx.source_range(),
- label,
- ctx.edition,
- );
- if let Some(lookup) = lookup {
- item.lookup_by(lookup);
- }
- if let Some((snippet, cap)) = snippet.zip(ctx.config.snippet_cap) {
- item.insert_snippet(cap, snippet);
- }
- item.add_to(acc, ctx.db);
+ let mut item =
+ CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), label, ctx.edition);
+ if let Some(lookup) = lookup {
+ item.lookup_by(lookup);
+ }
+ if let Some((snippet, cap)) = snippet.zip(ctx.config.snippet_cap) {
+ item.insert_snippet(cap, snippet);
}
+ item.add_to(acc, ctx.db);
}
}
diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs
index 3df511a5ad..66ecb790a0 100644
--- a/crates/ide-completion/src/lib.rs
+++ b/crates/ide-completion/src/lib.rs
@@ -258,7 +258,7 @@ pub fn completions(
completions::attribute::complete_known_attribute_input(
acc,
ctx,
- colon_prefix,
+ *colon_prefix,
attr,
extern_crate.as_ref(),
);