]> git.lizzy.rs Git - rust.git/blob - src/tools/rust-analyzer/crates/ide-completion/src/completions/extern_abi.rs
Auto merge of #101168 - jachris:dataflow-const-prop, r=oli-obk
[rust.git] / src / tools / rust-analyzer / crates / ide-completion / src / completions / extern_abi.rs
1 //! Completes function abi strings.
2 use syntax::{
3     ast::{self, IsString},
4     AstNode, AstToken,
5 };
6
7 use crate::{
8     completions::Completions, context::CompletionContext, CompletionItem, CompletionItemKind,
9 };
10
11 // Most of these are feature gated, we should filter/add feature gate completions once we have them.
12 const SUPPORTED_CALLING_CONVENTIONS: &[&str] = &[
13     "Rust",
14     "C",
15     "C-unwind",
16     "cdecl",
17     "stdcall",
18     "stdcall-unwind",
19     "fastcall",
20     "vectorcall",
21     "thiscall",
22     "thiscall-unwind",
23     "aapcs",
24     "win64",
25     "sysv64",
26     "ptx-kernel",
27     "msp430-interrupt",
28     "x86-interrupt",
29     "amdgpu-kernel",
30     "efiapi",
31     "avr-interrupt",
32     "avr-non-blocking-interrupt",
33     "C-cmse-nonsecure-call",
34     "wasm",
35     "system",
36     "system-unwind",
37     "rust-intrinsic",
38     "rust-call",
39     "platform-intrinsic",
40     "unadjusted",
41 ];
42
43 pub(crate) fn complete_extern_abi(
44     acc: &mut Completions,
45     _ctx: &CompletionContext<'_>,
46     expanded: &ast::String,
47 ) -> Option<()> {
48     if !expanded.syntax().parent().map_or(false, |it| ast::Abi::can_cast(it.kind())) {
49         return None;
50     }
51     let abi_str = expanded;
52     let source_range = abi_str.text_range_between_quotes()?;
53     for &abi in SUPPORTED_CALLING_CONVENTIONS {
54         CompletionItem::new(CompletionItemKind::Keyword, source_range, abi).add_to(acc);
55     }
56     Some(())
57 }
58
59 #[cfg(test)]
60 mod tests {
61     use expect_test::{expect, Expect};
62
63     use crate::tests::{check_edit, completion_list_no_kw};
64
65     fn check(ra_fixture: &str, expect: Expect) {
66         let actual = completion_list_no_kw(ra_fixture);
67         expect.assert_eq(&actual);
68     }
69
70     #[test]
71     fn only_completes_in_string_literals() {
72         check(
73             r#"
74 $0 fn foo {}
75 "#,
76             expect![[]],
77         );
78     }
79
80     #[test]
81     fn requires_extern_prefix() {
82         check(
83             r#"
84 "$0" fn foo {}
85 "#,
86             expect![[]],
87         );
88     }
89
90     #[test]
91     fn works() {
92         check(
93             r#"
94 extern "$0" fn foo {}
95 "#,
96             expect![[]],
97         );
98         check_edit(
99             "Rust",
100             r#"
101 extern "$0" fn foo {}
102 "#,
103             r#"
104 extern "Rust" fn foo {}
105 "#,
106         );
107     }
108 }