From 414d8d9c3884cd4144b9dab7eb4a0d72b8f3a496 Mon Sep 17 00:00:00 2001 From: oxalica Date: Thu, 30 Apr 2020 00:34:46 +0800 Subject: Include function qualifiers in signature --- crates/ra_ide/src/display/function_signature.rs | 40 +++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/crates/ra_ide/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs index b5e2785fe..db3907fe6 100644 --- a/crates/ra_ide/src/display/function_signature.rs +++ b/crates/ra_ide/src/display/function_signature.rs @@ -26,6 +26,8 @@ pub struct FunctionSignature { pub kind: CallableKind, /// Optional visibility pub visibility: Option, + /// Qualifiers like `async`, `unsafe`, ... + pub qualifier: FunctionQualifier, /// Name of the function pub name: Option, /// Documentation for the function @@ -46,6 +48,16 @@ pub struct FunctionSignature { pub has_self_param: bool, } +#[derive(Debug, Default)] +pub struct FunctionQualifier { + // `async` and `const` are mutually exclusive. Do we need to enforcing it here? + pub is_async: bool, + pub is_const: bool, + pub is_unsafe: bool, + /// The string `extern ".."` + pub extern_abi: Option, +} + impl FunctionSignature { pub(crate) fn with_doc_opt(mut self, doc: Option) -> Self { self.doc = doc; @@ -83,6 +95,8 @@ impl FunctionSignature { FunctionSignature { kind: CallableKind::StructConstructor, visibility: node.visibility().map(|n| n.syntax().text().to_string()), + // Do we need `const`? + qualifier: Default::default(), name: node.name().map(|n| n.text().to_string()), ret_type: node.name().map(|n| n.text().to_string()), parameters: params, @@ -128,6 +142,8 @@ impl FunctionSignature { FunctionSignature { kind: CallableKind::VariantConstructor, visibility: None, + // Do we need `const`? + qualifier: Default::default(), name: Some(name), ret_type: None, parameters: params, @@ -151,6 +167,7 @@ impl FunctionSignature { FunctionSignature { kind: CallableKind::Macro, visibility: None, + qualifier: Default::default(), name: node.name().map(|n| n.text().to_string()), ret_type: None, parameters: params, @@ -223,6 +240,12 @@ impl From<&'_ ast::FnDef> for FunctionSignature { FunctionSignature { kind: CallableKind::Function, visibility: node.visibility().map(|n| n.syntax().text().to_string()), + qualifier: FunctionQualifier { + is_async: node.async_token().is_some(), + is_const: node.const_token().is_some(), + is_unsafe: node.unsafe_token().is_some(), + extern_abi: node.abi().map(|n| n.to_string()), + }, name: node.name().map(|n| n.text().to_string()), ret_type: node .ret_type() @@ -246,6 +269,23 @@ impl Display for FunctionSignature { write!(f, "{} ", t)?; } + if self.qualifier.is_async { + write!(f, "async ")?; + } + + if self.qualifier.is_const { + write!(f, "const ")?; + } + + if self.qualifier.is_unsafe { + write!(f, "unsafe ")?; + } + + if let Some(extern_abi) = &self.qualifier.extern_abi { + // Keyword `extern` is included in the string. + write!(f, "{} ", extern_abi)?; + } + if let Some(name) = &self.name { match self.kind { CallableKind::Function => write!(f, "fn {}", name)?, -- cgit v1.2.3