Unnamed repository; edit this file 'description' to name the repository.
copy `attribute/lint.rs` to `attribute/feature.rs`
this is to make next commit's diff clearer
| -rw-r--r-- | crates/ide-completion/src/completions/attribute.rs | 3 | ||||
| -rw-r--r-- | crates/ide-completion/src/completions/attribute/feature.rs | 54 |
2 files changed, 56 insertions, 1 deletions
diff --git a/crates/ide-completion/src/completions/attribute.rs b/crates/ide-completion/src/completions/attribute.rs index a518e70861..766352aad9 100644 --- a/crates/ide-completion/src/completions/attribute.rs +++ b/crates/ide-completion/src/completions/attribute.rs @@ -26,6 +26,7 @@ use crate::{ mod cfg; mod derive; mod diagnostic; +mod feature; mod lint; mod macro_use; mod repr; @@ -50,7 +51,7 @@ pub(crate) fn complete_known_attribute_input( match segments.as_slice() { ["repr"] => repr::complete_repr(acc, ctx, &parse_comma_sep_expr(tt)?), - ["feature"] => lint::complete_lint( + ["feature"] => feature::complete_lint( acc, ctx, colon_prefix, 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..d662f5d543 --- /dev/null +++ b/crates/ide-completion/src/completions/attribute/feature.rs @@ -0,0 +1,54 @@ +//! Completion for lints +use ide_db::{SymbolKind, documentation::Documentation, generated::lints::Lint}; +use syntax::ast; + +use crate::{Completions, context::CompletionContext, item::CompletionItem}; + +pub(super) fn complete_lint( + acc: &mut Completions, + ctx: &CompletionContext<'_>, + is_qualified: bool, + existing_lints: &[ast::Path], + lints_completions: &[Lint], +) { + for &Lint { label, description, .. } in lints_completions { + // 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 + continue; + } + let lint_already_annotated = existing_lints + .iter() + .filter_map(|path| { + let q = path.qualifier(); + if q.as_ref().and_then(|it| it.qualifier()).is_some() { + return None; + } + Some((q.and_then(|it| it.as_single_name_ref()), path.segment()?.name_ref()?)) + }) + .any(|(q, name_ref)| { + let qualifier_matches = match (q, qual) { + (None, None) => true, + (None, Some(_)) => false, + (Some(_), None) => false, + (Some(q), Some(ns)) => q.text() == ns, + }; + qualifier_matches && name_ref.text() == name + }); + if lint_already_annotated { + continue; + } + let label = match qual { + Some(qual) if !is_qualified => format!("{qual}::{name}"), + _ => name.to_owned(), + }; + 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) + } +} |