| //! Completes function abi strings. |
| use syntax::{ |
| ast::{self, IsString}, |
| AstNode, AstToken, SmolStr, |
| }; |
| |
| use crate::{ |
| completions::Completions, context::CompletionContext, CompletionItem, CompletionItemKind, |
| }; |
| |
| // Most of these are feature gated, we should filter/add feature gate completions once we have them. |
| const SUPPORTED_CALLING_CONVENTIONS: &[&str] = &[ |
| "Rust", |
| "C", |
| "C-unwind", |
| "cdecl", |
| "stdcall", |
| "stdcall-unwind", |
| "fastcall", |
| "vectorcall", |
| "thiscall", |
| "thiscall-unwind", |
| "aapcs", |
| "win64", |
| "sysv64", |
| "ptx-kernel", |
| "msp430-interrupt", |
| "x86-interrupt", |
| "efiapi", |
| "avr-interrupt", |
| "avr-non-blocking-interrupt", |
| "riscv-interrupt-m", |
| "riscv-interrupt-s", |
| "C-cmse-nonsecure-call", |
| "wasm", |
| "system", |
| "system-unwind", |
| "rust-intrinsic", |
| "rust-call", |
| "platform-intrinsic", |
| "unadjusted", |
| ]; |
| |
| pub(crate) fn complete_extern_abi( |
| acc: &mut Completions, |
| ctx: &CompletionContext<'_>, |
| expanded: &ast::String, |
| ) -> Option<()> { |
| if !expanded.syntax().parent().map_or(false, |it| ast::Abi::can_cast(it.kind())) { |
| return None; |
| } |
| let abi_str = expanded; |
| let source_range = abi_str.text_range_between_quotes()?; |
| for &abi in SUPPORTED_CALLING_CONVENTIONS { |
| CompletionItem::new(CompletionItemKind::Keyword, source_range, SmolStr::new_static(abi)) |
| .add_to(acc, ctx.db); |
| } |
| Some(()) |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use expect_test::{expect, Expect}; |
| |
| use crate::tests::{check_edit, completion_list_no_kw}; |
| |
| fn check(ra_fixture: &str, expect: Expect) { |
| let actual = completion_list_no_kw(ra_fixture); |
| expect.assert_eq(&actual); |
| } |
| |
| #[test] |
| fn only_completes_in_string_literals() { |
| check( |
| r#" |
| $0 fn foo {} |
| "#, |
| expect![[]], |
| ); |
| } |
| |
| #[test] |
| fn requires_extern_prefix() { |
| check( |
| r#" |
| "$0" fn foo {} |
| "#, |
| expect![[]], |
| ); |
| } |
| |
| #[test] |
| fn works() { |
| check( |
| r#" |
| extern "$0" fn foo {} |
| "#, |
| expect![[]], |
| ); |
| check_edit( |
| "Rust", |
| r#" |
| extern "$0" fn foo {} |
| "#, |
| r#" |
| extern "Rust" fn foo {} |
| "#, |
| ); |
| } |
| } |