ide_completion/completions/attribute/
diagnostic.rs

1//! Completion for diagnostic attributes.
2
3use ide_db::SymbolKind;
4use syntax::ast;
5
6use crate::{CompletionItem, Completions, context::CompletionContext};
7
8use super::AttrCompletion;
9
10pub(super) fn complete_on_unimplemented(
11    acc: &mut Completions,
12    ctx: &CompletionContext<'_>,
13    input: ast::TokenTree,
14) {
15    if let Some(existing_keys) = super::parse_comma_sep_expr(input) {
16        for attr in ATTRIBUTE_ARGS {
17            let already_annotated = existing_keys
18                .iter()
19                .filter_map(|expr| match expr {
20                    ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
21                    ast::Expr::BinExpr(bin)
22                        if bin.op_kind() == Some(ast::BinaryOp::Assignment { op: None }) =>
23                    {
24                        match bin.lhs()? {
25                            ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
26                            _ => None,
27                        }
28                    }
29                    _ => None,
30                })
31                .any(|it| {
32                    let text = it.text();
33                    attr.key() == text && text != "note"
34                });
35            if already_annotated {
36                continue;
37            }
38
39            let mut item = CompletionItem::new(
40                SymbolKind::BuiltinAttr,
41                ctx.source_range(),
42                attr.label,
43                ctx.edition,
44            );
45            if let Some(lookup) = attr.lookup {
46                item.lookup_by(lookup);
47            }
48            if let Some((snippet, cap)) = attr.snippet.zip(ctx.config.snippet_cap) {
49                item.insert_snippet(cap, snippet);
50            }
51            item.add_to(acc, ctx.db);
52        }
53    }
54}
55
56const ATTRIBUTE_ARGS: &[AttrCompletion] = &[
57    super::attr(r#"label = "…""#, Some("label"), Some(r#"label = "${0:label}""#)),
58    super::attr(r#"message = "…""#, Some("message"), Some(r#"message = "${0:message}""#)),
59    super::attr(r#"note = "…""#, Some("note"), Some(r#"note = "${0:note}""#)),
60];