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 existing_keys: &[ast::Expr],
14) {
15 for attr in ATTRIBUTE_ARGS {
16 let already_annotated = existing_keys
17 .iter()
18 .filter_map(|expr| match expr {
19 ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
20 ast::Expr::BinExpr(bin)
21 if bin.op_kind() == Some(ast::BinaryOp::Assignment { op: None }) =>
22 {
23 match bin.lhs()? {
24 ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
25 _ => None,
26 }
27 }
28 _ => None,
29 })
30 .any(|it| {
31 let text = it.text();
32 attr.key() == text && text != "note"
33 });
34 if already_annotated {
35 continue;
36 }
37
38 let mut item = CompletionItem::new(
39 SymbolKind::BuiltinAttr,
40 ctx.source_range(),
41 attr.label,
42 ctx.edition,
43 );
44 if let Some(lookup) = attr.lookup {
45 item.lookup_by(lookup);
46 }
47 if let Some((snippet, cap)) = attr.snippet.zip(ctx.config.snippet_cap) {
48 item.insert_snippet(cap, snippet);
49 }
50 item.add_to(acc, ctx.db);
51 }
52}
53
54const ATTRIBUTE_ARGS: &[AttrCompletion] = &[
55 super::attr(r#"label = "…""#, Some("label"), Some(r#"label = "${0:label}""#)),
56 super::attr(r#"message = "…""#, Some("message"), Some(r#"message = "${0:message}""#)),
57 super::attr(r#"note = "…""#, Some("note"), Some(r#"note = "${0:note}""#)),
58];