Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide_completion/src/completions/attribute/lint.rs')
| -rw-r--r-- | crates/ide_completion/src/completions/attribute/lint.rs | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/crates/ide_completion/src/completions/attribute/lint.rs b/crates/ide_completion/src/completions/attribute/lint.rs index 8b17be09b1..4f7930d0dd 100644 --- a/crates/ide_completion/src/completions/attribute/lint.rs +++ b/crates/ide_completion/src/completions/attribute/lint.rs @@ -1,6 +1,6 @@ //! Completion for lints use ide_db::helpers::generated_lints::Lint; -use syntax::ast; +use syntax::{ast, T}; use crate::{ context::CompletionContext, @@ -14,17 +14,51 @@ pub(super) fn complete_lint( derive_input: ast::TokenTree, lints_completions: &[Lint], ) { - if let Some(existing_lints) = super::parse_comma_sep_input(derive_input) { - for lint_completion in - lints_completions.iter().filter(|completion| !existing_lints.contains(completion.label)) - { - let mut item = CompletionItem::new( - CompletionKind::Attribute, - ctx.source_range(), - lint_completion.label, - ); + if let Some(existing_lints) = super::parse_comma_sep_paths(derive_input) { + 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 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 insert = match qual { + Some(qual) if !ctx.previous_token_is(T![:]) => format!("{}::{}", qual, name), + _ => name.to_owned(), + }; + let mut item = + CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label); item.kind(CompletionItemKind::Attribute) - .documentation(hir::Documentation::new(lint_completion.description.to_owned())); + .insert_text(insert) + .documentation(hir::Documentation::new(description.to_owned())); item.add_to(acc) } } |