diff options
Diffstat (limited to 'crates/ide_completion')
-rw-r--r-- | crates/ide_completion/src/completions/attribute.rs | 15 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/attribute/cfg.rs | 126 |
2 files changed, 141 insertions, 0 deletions
diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs index 78fc30e16..cc4f4b2af 100644 --- a/crates/ide_completion/src/completions/attribute.rs +++ b/crates/ide_completion/src/completions/attribute.rs | |||
@@ -15,6 +15,7 @@ use crate::{ | |||
15 | Completions, | 15 | Completions, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | mod cfg; | ||
18 | mod derive; | 19 | mod derive; |
19 | mod lint; | 20 | mod lint; |
20 | mod repr; | 21 | mod repr; |
@@ -30,6 +31,9 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) | |||
30 | lint::complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINTS); | 31 | lint::complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINTS); |
31 | lint::complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); | 32 | lint::complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); |
32 | } | 33 | } |
34 | "cfg" => { | ||
35 | cfg::complete_cfg(acc, ctx); | ||
36 | } | ||
33 | _ => (), | 37 | _ => (), |
34 | }, | 38 | }, |
35 | (None, Some(_)) => (), | 39 | (None, Some(_)) => (), |
@@ -852,4 +856,15 @@ mod tests { | |||
852 | "#]], | 856 | "#]], |
853 | ); | 857 | ); |
854 | } | 858 | } |
859 | |||
860 | #[test] | ||
861 | fn test_cfg() { | ||
862 | check( | ||
863 | r#"#[cfg(target_endian = $0"#, | ||
864 | expect![[r#" | ||
865 | at little | ||
866 | at big | ||
867 | "#]], | ||
868 | ); | ||
869 | } | ||
855 | } | 870 | } |
diff --git a/crates/ide_completion/src/completions/attribute/cfg.rs b/crates/ide_completion/src/completions/attribute/cfg.rs new file mode 100644 index 000000000..71e659563 --- /dev/null +++ b/crates/ide_completion/src/completions/attribute/cfg.rs | |||
@@ -0,0 +1,126 @@ | |||
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("feature") => { | ||
30 | ctx.krate.map(|krate| { | ||
31 | krate.features(ctx.db).iter().for_each(|f| { | ||
32 | let mut item = CompletionItem::new( | ||
33 | CompletionKind::Attribute, | ||
34 | ctx.source_range(), | ||
35 | f.clone(), | ||
36 | ); | ||
37 | item.insert_text(format!(r#""{}""#, f)); | ||
38 | |||
39 | acc.add(item.build()) | ||
40 | }) | ||
41 | }); | ||
42 | } | ||
43 | Some("target_arch") => KNOWN_ARCH.iter().for_each(add_completion), | ||
44 | Some("target_env") => KNOWN_ENV.iter().for_each(add_completion), | ||
45 | Some("target_os") => KNOWN_OS.iter().for_each(add_completion), | ||
46 | Some("target_vendor") => KNOWN_VENDOR.iter().for_each(add_completion), | ||
47 | Some("target_endian") => ["little", "big"].iter().for_each(add_completion), | ||
48 | Some(name) => { | ||
49 | ctx.krate.map(|krate| { | ||
50 | krate.cfg(ctx.db).get_cfg_values(&name).iter().for_each(|s| { | ||
51 | let mut item = CompletionItem::new( | ||
52 | CompletionKind::Attribute, | ||
53 | ctx.source_range(), | ||
54 | s.as_str(), | ||
55 | ); | ||
56 | item.insert_text(format!(r#""{}""#, s)); | ||
57 | |||
58 | acc.add(item.build()); | ||
59 | }) | ||
60 | }); | ||
61 | } | ||
62 | None => { | ||
63 | ctx.krate.map(|krate| { | ||
64 | krate.cfg(ctx.db).get_cfg_keys().iter().for_each(|s| { | ||
65 | let item = CompletionItem::new( | ||
66 | CompletionKind::Attribute, | ||
67 | ctx.source_range(), | ||
68 | s.as_str(), | ||
69 | ); | ||
70 | acc.add(item.build()); | ||
71 | }) | ||
72 | }); | ||
73 | } | ||
74 | }; | ||
75 | } | ||
76 | |||
77 | const KNOWN_ARCH: [&'static str; 19] = [ | ||
78 | "aarch64", | ||
79 | "arm", | ||
80 | "avr", | ||
81 | "hexagon", | ||
82 | "mips", | ||
83 | "mips64", | ||
84 | "msp430", | ||
85 | "nvptx64", | ||
86 | "powerpc", | ||
87 | "powerpc64", | ||
88 | "riscv32", | ||
89 | "riscv64", | ||
90 | "s390x", | ||
91 | "sparc", | ||
92 | "sparc64", | ||
93 | "wasm32", | ||
94 | "wasm64", | ||
95 | "x86", | ||
96 | "x86_64", | ||
97 | ]; | ||
98 | |||
99 | const KNOWN_ENV: [&'static str; 7] = | ||
100 | ["eabihf", "gnu", "gnueabihf", "msvc", "relibc", "sgx", "uclibc"]; | ||
101 | |||
102 | const KNOWN_OS: [&'static str; 20] = [ | ||
103 | "cuda", | ||
104 | "dragonfly", | ||
105 | "emscripten", | ||
106 | "freebsd", | ||
107 | "fuchsia", | ||
108 | "haiku", | ||
109 | "hermit", | ||
110 | "illumos", | ||
111 | "l4re", | ||
112 | "linux", | ||
113 | "netbsd", | ||
114 | "none", | ||
115 | "openbsd", | ||
116 | "psp", | ||
117 | "redox", | ||
118 | "solaris", | ||
119 | "uefi", | ||
120 | "unknown", | ||
121 | "vxworks", | ||
122 | "windows", | ||
123 | ]; | ||
124 | |||
125 | const KNOWN_VENDOR: [&'static str; 8] = | ||
126 | ["apple", "fortanix", "nvidia", "pc", "sony", "unknown", "wrs", "uwp"]; | ||