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