about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2022-02-03 16:29:23 +0100
committerLukas Wirth <lukastw97@gmail.com>2022-02-03 16:33:42 +0100
commitc83081879f72ff745edc901dcd6f954edfc414a4 (patch)
treef82cbd9b6f6ef72ffc0484442f3bfad4626c132c
parentd3f3b6a87fb5b2a7fb305896a05bd65c7b53b099 (diff)
downloadrust-c83081879f72ff745edc901dcd6f954edfc414a4.tar.gz
rust-c83081879f72ff745edc901dcd6f954edfc414a4.zip
Add abi string completions
-rw-r--r--crates/ide_completion/src/completions.rs1
-rw-r--r--crates/ide_completion/src/completions/extern_abi.rs104
-rw-r--r--crates/ide_completion/src/lib.rs1
3 files changed, 106 insertions, 0 deletions
diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs
index 9c65efdb102..c11a1efce4f 100644
--- a/crates/ide_completion/src/completions.rs
+++ b/crates/ide_completion/src/completions.rs
@@ -2,6 +2,7 @@
 
 pub(crate) mod attribute;
 pub(crate) mod dot;
+pub(crate) mod extern_abi;
 pub(crate) mod flyimport;
 pub(crate) mod fn_param;
 pub(crate) mod format_string;
diff --git a/crates/ide_completion/src/completions/extern_abi.rs b/crates/ide_completion/src/completions/extern_abi.rs
new file mode 100644
index 00000000000..87fccec008e
--- /dev/null
+++ b/crates/ide_completion/src/completions/extern_abi.rs
@@ -0,0 +1,104 @@
+//! Completes function abi strings.
+use syntax::{
+    ast::{self, IsString},
+    AstNode, AstToken,
+};
+
+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",
+    "amdgpu-kernel",
+    "efiapi",
+    "avr-interrupt",
+    "avr-non-blocking-interrupt",
+    "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) -> Option<()> {
+    if ctx.token.parent().and_then(ast::Abi::cast).is_none() {
+        return None;
+    }
+    let abi_str = ast::String::cast(ctx.token.clone())?;
+    let source_range = abi_str.text_range_between_quotes()?;
+    for &abi in SUPPORTED_CALLING_CONVENTIONS {
+        CompletionItem::new(CompletionItemKind::Keyword, source_range, abi).add_to(acc);
+    }
+    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 {}
+"#,
+        );
+    }
+}
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs
index d58edda304f..9f6f6592de5 100644
--- a/crates/ide_completion/src/lib.rs
+++ b/crates/ide_completion/src/lib.rs
@@ -154,6 +154,7 @@ pub fn completions(
     completions::attribute::complete_attribute(&mut acc, &ctx);
     completions::attribute::complete_known_attribute_input(&mut acc, &ctx);
     completions::dot::complete_dot(&mut acc, &ctx);
+    completions::extern_abi::complete_extern_abi(&mut acc, &ctx);
     completions::flyimport::import_on_the_fly(&mut acc, &ctx);
     completions::fn_param::complete_fn_param(&mut acc, &ctx);
     completions::format_string::format_string(&mut acc, &ctx);