ide_completion/completions/attribute/
diagnostic.rs1use 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];