1 //! Completion for lints
2 use ide_db
::{generated::lints::Lint, SymbolKind}
;
5 use crate::{context::CompletionContext, item::CompletionItem, Completions}
;
7 pub(super) fn complete_lint(
9 ctx
: &CompletionContext
<'_
>,
11 existing_lints
: &[ast
::Path
],
12 lints_completions
: &[Lint
],
14 for &Lint { label, description }
in lints_completions
{
16 // FIXME: change `Lint`'s label to not store a path in it but split the prefix off instead?
17 let mut parts
= label
.split("::");
18 let ns_or_label
= match parts
.next() {
22 let label
= parts
.next();
24 Some(label
) => (Some(ns_or_label
), label
),
25 None
=> (None
, ns_or_label
),
28 if qual
.is_none() && is_qualified
{
29 // qualified completion requested, but this lint is unqualified
32 let lint_already_annotated
= existing_lints
35 let q
= path
.qualifier();
36 if q
.as_ref().and_then(|it
| it
.qualifier()).is_some() {
39 Some((q
.and_then(|it
| it
.as_single_name_ref()), path
.segment()?
.name_ref()?
))
41 .any(|(q
, name_ref
)| {
42 let qualifier_matches
= match (q
, qual
) {
44 (None
, Some(_
)) => false,
45 (Some(_
), None
) => false,
46 (Some(q
), Some(ns
)) => q
.text() == ns
,
48 qualifier_matches
&& name_ref
.text() == name
50 if lint_already_annotated
{
53 let label
= match qual
{
54 Some(qual
) if !is_qualified
=> format
!("{qual}::{name}"),
57 let mut item
= CompletionItem
::new(SymbolKind
::Attribute
, ctx
.source_range(), label
);
58 item
.documentation(hir
::Documentation
::new(description
.to_owned()));
59 item
.add_to(acc
, ctx
.db
)