1 //! Completion for representations.
2
3 use syntax::ast;
4
5 use crate::{
6 context::CompletionContext,
7 item::{CompletionItem, CompletionItemKind},
8 Completions,
9 };
10
complete_repr(acc: &mut Completions, ctx: &CompletionContext, input: ast::TokenTree)11 pub(super) fn complete_repr(acc: &mut Completions, ctx: &CompletionContext, input: ast::TokenTree) {
12 if let Some(existing_reprs) = super::parse_comma_sep_expr(input) {
13 for &ReprCompletion { label, snippet, lookup, collides } in REPR_COMPLETIONS {
14 let repr_already_annotated = existing_reprs
15 .iter()
16 .filter_map(|expr| match expr {
17 ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
18 ast::Expr::CallExpr(call) => match call.expr()? {
19 ast::Expr::PathExpr(path) => path.path()?.as_single_name_ref(),
20 _ => return None,
21 },
22 _ => None,
23 })
24 .any(|it| {
25 let text = it.text();
26 lookup.unwrap_or(label) == text || collides.contains(&text.as_str())
27 });
28 if repr_already_annotated {
29 continue;
30 }
31
32 let mut item =
33 CompletionItem::new(CompletionItemKind::Attribute, ctx.source_range(), label);
34 if let Some(lookup) = lookup {
35 item.lookup_by(lookup);
36 }
37 if let Some((snippet, cap)) = snippet.zip(ctx.config.snippet_cap) {
38 item.insert_snippet(cap, snippet);
39 }
40 item.add_to(acc);
41 }
42 }
43 }
44
45 struct ReprCompletion {
46 label: &'static str,
47 snippet: Option<&'static str>,
48 lookup: Option<&'static str>,
49 collides: &'static [&'static str],
50 }
51
attr(label: &'static str, collides: &'static [&'static str]) -> ReprCompletion52 const fn attr(label: &'static str, collides: &'static [&'static str]) -> ReprCompletion {
53 ReprCompletion { label, snippet: None, lookup: None, collides }
54 }
55
56 #[rustfmt::skip]
57 const REPR_COMPLETIONS: &[ReprCompletion] = &[
58 ReprCompletion { label: "align($0)", snippet: Some("align($0)"), lookup: Some("align"), collides: &["transparent", "packed"] },
59 attr("packed", &["transparent", "align"]),
60 attr("transparent", &["C", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
61 attr("C", &["transparent"]),
62 attr("u8", &["transparent", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
63 attr("u16", &["transparent", "u8", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
64 attr("u32", &["transparent", "u8", "u16", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
65 attr("u64", &["transparent", "u8", "u16", "u32", "u128", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
66 attr("u128", &["transparent", "u8", "u16", "u32", "u64", "usize", "i8", "i16", "i32", "i64", "i128", "isize"]),
67 attr("usize", &["transparent", "u8", "u16", "u32", "u64", "u128", "i8", "i16", "i32", "i64", "i128", "isize"]),
68 attr("i8", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i16", "i32", "i64", "i128", "isize"]),
69 attr("i16", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i32", "i64", "i128", "isize"]),
70 attr("i32", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i64", "i128", "isize"]),
71 attr("i64", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i128", "isize"]),
72 attr("i28", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "isize"]),
73 attr("isize", &["transparent", "u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128"]),
74 ];
75