From 98957f4e6f66469310072dff5dfc3e521a7cd555 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 6 Jan 2019 01:00:34 +0100 Subject: Add fn signature query --- crates/ra_hir/src/function.rs | 60 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir/src/function.rs') diff --git a/crates/ra_hir/src/function.rs b/crates/ra_hir/src/function.rs index 4dbdf81d8..4627be071 100644 --- a/crates/ra_hir/src/function.rs +++ b/crates/ra_hir/src/function.rs @@ -11,7 +11,7 @@ use ra_syntax::{ ast::{self, AstNode, DocCommentsOwner, NameOwner}, }; -use crate::{DefId, DefKind, HirDatabase, ty::InferenceResult, Module, Crate, impl_block::ImplBlock, expr::{Body, BodySyntaxMapping}}; +use crate::{DefId, DefKind, HirDatabase, ty::InferenceResult, Module, Crate, impl_block::ImplBlock, expr::{Body, BodySyntaxMapping}, type_ref::{TypeRef, Mutability}, Name}; pub use self::scope::{FnScopes, ScopesWithSyntaxMapping}; @@ -53,6 +53,10 @@ impl Function { }) } + pub fn signature(&self, db: &impl HirDatabase) -> Arc { + db.fn_signature(self.def_id) + } + pub fn signature_info(&self, db: &impl HirDatabase) -> Option { let syntax = self.syntax(db); FnSignatureInfo::new(syntax.borrowed()) @@ -76,6 +80,60 @@ impl Function { } } +/// The declared signature of a function. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FnSignature { + args: Vec, + ret_type: TypeRef, +} + +impl FnSignature { + pub fn args(&self) -> &[TypeRef] { + &self.args + } + + pub fn ret_type(&self) -> &TypeRef { + &self.ret_type + } +} + +pub(crate) fn fn_signature(db: &impl HirDatabase, def_id: DefId) -> Arc { + let func = Function::new(def_id); + let syntax = func.syntax(db); + let node = syntax.borrowed(); + let mut args = Vec::new(); + if let Some(param_list) = node.param_list() { + if let Some(self_param) = param_list.self_param() { + let self_type = if let Some(type_ref) = self_param.type_ref() { + TypeRef::from_ast(type_ref) + } else { + let self_type = TypeRef::Path(Name::self_type().into()); + match self_param.flavor() { + ast::SelfParamFlavor::Owned => self_type, + ast::SelfParamFlavor::Ref => { + TypeRef::Reference(Box::new(self_type), Mutability::Shared) + } + ast::SelfParamFlavor::MutRef => { + TypeRef::Reference(Box::new(self_type), Mutability::Mut) + } + } + }; + args.push(self_type); + } + for param in param_list.params() { + let type_ref = TypeRef::from_ast_opt(param.type_ref()); + args.push(type_ref); + } + } + let ret_type = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) { + TypeRef::from_ast(type_ref) + } else { + TypeRef::unit() + }; + let sig = FnSignature { args, ret_type }; + Arc::new(sig) +} + #[derive(Debug, Clone)] pub struct FnSignatureInfo { pub name: String, -- cgit v1.2.3