]> git.lizzy.rs Git - rust.git/blob - crates/ide_completion/src/completions/attribute/cfg.rs
d1a4722b3018b5b67c3f6e777a8a5e48a5b718f2
[rust.git] / crates / ide_completion / src / completions / attribute / cfg.rs
1 //! Completion for cfg
2
3 use std::iter;
4
5 use ide_db::SymbolKind;
6 use syntax::SyntaxKind;
7
8 use crate::{completions::Completions, context::CompletionContext, CompletionItem};
9
10 pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext) {
11     let add_completion = |item: &str| {
12         let mut completion = CompletionItem::new(SymbolKind::Attribute, ctx.source_range(), item);
13         completion.insert_text(format!(r#""{}""#, item));
14         acc.add(completion.build());
15     };
16
17     let previous = iter::successors(ctx.original_token.prev_token(), |t| {
18         (matches!(t.kind(), SyntaxKind::EQ) || t.kind().is_trivia())
19             .then(|| t.prev_token())
20             .flatten()
21     })
22     .find(|t| matches!(t.kind(), SyntaxKind::IDENT));
23
24     match previous.as_ref().map(|p| p.text()) {
25         Some("target_arch") => KNOWN_ARCH.iter().copied().for_each(add_completion),
26         Some("target_env") => KNOWN_ENV.iter().copied().for_each(add_completion),
27         Some("target_os") => KNOWN_OS.iter().copied().for_each(add_completion),
28         Some("target_vendor") => KNOWN_VENDOR.iter().copied().for_each(add_completion),
29         Some("target_endian") => ["little", "big"].into_iter().for_each(add_completion),
30         Some(name) => {
31             if let Some(krate) = ctx.krate {
32                 krate.potential_cfg(ctx.db).get_cfg_values(&name).cloned().for_each(|s| {
33                     let insert_text = format!(r#""{}""#, s);
34                     let mut item =
35                         CompletionItem::new(SymbolKind::Attribute, ctx.source_range(), s);
36                     item.insert_text(insert_text);
37
38                     acc.add(item.build());
39                 })
40             };
41         }
42         None => {
43             if let Some(krate) = ctx.krate {
44                 krate.potential_cfg(ctx.db).get_cfg_keys().cloned().for_each(|s| {
45                     let item = CompletionItem::new(SymbolKind::Attribute, ctx.source_range(), s);
46                     acc.add(item.build());
47                 })
48             }
49         }
50     };
51 }
52
53 const KNOWN_ARCH: [&str; 19] = [
54     "aarch64",
55     "arm",
56     "avr",
57     "hexagon",
58     "mips",
59     "mips64",
60     "msp430",
61     "nvptx64",
62     "powerpc",
63     "powerpc64",
64     "riscv32",
65     "riscv64",
66     "s390x",
67     "sparc",
68     "sparc64",
69     "wasm32",
70     "wasm64",
71     "x86",
72     "x86_64",
73 ];
74
75 const KNOWN_ENV: [&str; 7] = ["eabihf", "gnu", "gnueabihf", "msvc", "relibc", "sgx", "uclibc"];
76
77 const KNOWN_OS: [&str; 20] = [
78     "cuda",
79     "dragonfly",
80     "emscripten",
81     "freebsd",
82     "fuchsia",
83     "haiku",
84     "hermit",
85     "illumos",
86     "l4re",
87     "linux",
88     "netbsd",
89     "none",
90     "openbsd",
91     "psp",
92     "redox",
93     "solaris",
94     "uefi",
95     "unknown",
96     "vxworks",
97     "windows",
98 ];
99
100 const KNOWN_VENDOR: [&str; 8] =
101     ["apple", "fortanix", "nvidia", "pc", "sony", "unknown", "wrs", "uwp"];