Unnamed repository; edit this file 'description' to name the repository.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! Completion for lints
use ide_db::helpers::generated_lints::Lint;
use syntax::{ast, T};

use crate::{
    context::CompletionContext,
    item::{CompletionItem, CompletionItemKind, CompletionKind},
    Completions,
};

pub(super) fn complete_lint(
    acc: &mut Completions,
    ctx: &CompletionContext,
    derive_input: ast::TokenTree,
    lints_completions: &[Lint],
) {
    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)
                .insert_text(insert)
                .documentation(hir::Documentation::new(description.to_owned()));
            item.add_to(acc)
        }
    }
}