aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-01-06 00:00:34 +0000
committerFlorian Diebold <[email protected]>2019-01-06 00:13:31 +0000
commit98957f4e6f66469310072dff5dfc3e521a7cd555 (patch)
tree8c8075dcc234c3548f63bfb74fbc9d5806933c14 /crates
parente5a6cf815372150ad40dee995b7b89f29e701427 (diff)
Add fn signature query
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_analysis/src/db.rs1
-rw-r--r--crates/ra_hir/src/db.rs7
-rw-r--r--crates/ra_hir/src/function.rs60
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/mock.rs1
-rw-r--r--crates/ra_hir/src/name.rs4
-rw-r--r--crates/ra_hir/src/path.rs14
-rw-r--r--crates/ra_hir/src/type_ref.rs4
8 files changed, 86 insertions, 7 deletions
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs
index 074a7a7f6..1709be5cf 100644
--- a/crates/ra_analysis/src/db.rs
+++ b/crates/ra_analysis/src/db.rs
@@ -108,6 +108,7 @@ salsa::database_storage! {
108 fn impls_in_module() for hir::db::ImplsInModuleQuery; 108 fn impls_in_module() for hir::db::ImplsInModuleQuery;
109 fn body_hir() for hir::db::BodyHirQuery; 109 fn body_hir() for hir::db::BodyHirQuery;
110 fn body_syntax_mapping() for hir::db::BodySyntaxMappingQuery; 110 fn body_syntax_mapping() for hir::db::BodySyntaxMappingQuery;
111 fn fn_signature() for hir::db::FnSignatureQuery;
111 } 112 }
112 } 113 }
113} 114}
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index aaf367e08..96a3c60b9 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -7,7 +7,7 @@ use crate::{
7 DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId, 7 DefLoc, DefId, MacroCallLoc, MacroCallId, Name, HirFileId,
8 SourceFileItems, SourceItemId, 8 SourceFileItems, SourceItemId,
9 query_definitions, 9 query_definitions,
10 FnScopes, 10 FnSignature, FnScopes,
11 macros::MacroExpansion, 11 macros::MacroExpansion,
12 module::{ModuleId, ModuleTree, ModuleSource, 12 module::{ModuleId, ModuleTree, ModuleSource,
13 nameres::{ItemMap, InputModuleItems}}, 13 nameres::{ItemMap, InputModuleItems}},
@@ -103,6 +103,11 @@ pub trait HirDatabase: SyntaxDatabase
103 type BodySyntaxMappingQuery; 103 type BodySyntaxMappingQuery;
104 use fn crate::expr::body_syntax_mapping; 104 use fn crate::expr::body_syntax_mapping;
105 } 105 }
106
107 fn fn_signature(def_id: DefId) -> Arc<FnSignature> {
108 type FnSignatureQuery;
109 use fn crate::function::fn_signature;
110 }
106} 111}
107 112
108} 113}
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::{
11 ast::{self, AstNode, DocCommentsOwner, NameOwner}, 11 ast::{self, AstNode, DocCommentsOwner, NameOwner},
12}; 12};
13 13
14use crate::{DefId, DefKind, HirDatabase, ty::InferenceResult, Module, Crate, impl_block::ImplBlock, expr::{Body, BodySyntaxMapping}}; 14use crate::{DefId, DefKind, HirDatabase, ty::InferenceResult, Module, Crate, impl_block::ImplBlock, expr::{Body, BodySyntaxMapping}, type_ref::{TypeRef, Mutability}, Name};
15 15
16pub use self::scope::{FnScopes, ScopesWithSyntaxMapping}; 16pub use self::scope::{FnScopes, ScopesWithSyntaxMapping};
17 17
@@ -53,6 +53,10 @@ impl Function {
53 }) 53 })
54 } 54 }
55 55
56 pub fn signature(&self, db: &impl HirDatabase) -> Arc<FnSignature> {
57 db.fn_signature(self.def_id)
58 }
59
56 pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> { 60 pub fn signature_info(&self, db: &impl HirDatabase) -> Option<FnSignatureInfo> {
57 let syntax = self.syntax(db); 61 let syntax = self.syntax(db);
58 FnSignatureInfo::new(syntax.borrowed()) 62 FnSignatureInfo::new(syntax.borrowed())
@@ -76,6 +80,60 @@ impl Function {
76 } 80 }
77} 81}
78 82
83/// The declared signature of a function.
84#[derive(Debug, Clone, PartialEq, Eq)]
85pub struct FnSignature {
86 args: Vec<TypeRef>,
87 ret_type: TypeRef,
88}
89
90impl FnSignature {
91 pub fn args(&self) -> &[TypeRef] {
92 &self.args
93 }
94
95 pub fn ret_type(&self) -> &TypeRef {
96 &self.ret_type
97 }
98}
99
100pub(crate) fn fn_signature(db: &impl HirDatabase, def_id: DefId) -> Arc<FnSignature> {
101 let func = Function::new(def_id);
102 let syntax = func.syntax(db);
103 let node = syntax.borrowed();
104 let mut args = Vec::new();
105 if let Some(param_list) = node.param_list() {
106 if let Some(self_param) = param_list.self_param() {
107 let self_type = if let Some(type_ref) = self_param.type_ref() {
108 TypeRef::from_ast(type_ref)
109 } else {
110 let self_type = TypeRef::Path(Name::self_type().into());
111 match self_param.flavor() {
112 ast::SelfParamFlavor::Owned => self_type,
113 ast::SelfParamFlavor::Ref => {
114 TypeRef::Reference(Box::new(self_type), Mutability::Shared)
115 }
116 ast::SelfParamFlavor::MutRef => {
117 TypeRef::Reference(Box::new(self_type), Mutability::Mut)
118 }
119 }
120 };
121 args.push(self_type);
122 }
123 for param in param_list.params() {
124 let type_ref = TypeRef::from_ast_opt(param.type_ref());
125 args.push(type_ref);
126 }
127 }
128 let ret_type = if let Some(type_ref) = node.ret_type().and_then(|rt| rt.type_ref()) {
129 TypeRef::from_ast(type_ref)
130 } else {
131 TypeRef::unit()
132 };
133 let sig = FnSignature { args, ret_type };
134 Arc::new(sig)
135}
136
79#[derive(Debug, Clone)] 137#[derive(Debug, Clone)]
80pub struct FnSignatureInfo { 138pub struct FnSignatureInfo {
81 pub name: String, 139 pub name: String,
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 82dc287de..d600b91df 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -47,7 +47,7 @@ pub use self::{
47 ids::{HirFileId, DefId, DefLoc, MacroCallId, MacroCallLoc}, 47 ids::{HirFileId, DefId, DefLoc, MacroCallId, MacroCallLoc},
48 macros::{MacroDef, MacroInput, MacroExpansion}, 48 macros::{MacroDef, MacroInput, MacroExpansion},
49 module::{Module, ModuleId, Problem, nameres::{ItemMap, PerNs, Namespace}, ModuleScope, Resolution}, 49 module::{Module, ModuleId, Problem, nameres::{ItemMap, PerNs, Namespace}, ModuleScope, Resolution},
50 function::{Function, FnScopes, ScopesWithSyntaxMapping}, 50 function::{Function, FnSignature, FnScopes, ScopesWithSyntaxMapping},
51 adt::{Struct, Enum}, 51 adt::{Struct, Enum},
52 ty::Ty, 52 ty::Ty,
53 impl_block::{ImplBlock, ImplItem}, 53 impl_block::{ImplBlock, ImplItem},
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs
index 661a5a26b..8d176662c 100644
--- a/crates/ra_hir/src/mock.rs
+++ b/crates/ra_hir/src/mock.rs
@@ -210,6 +210,7 @@ salsa::database_storage! {
210 fn impls_in_module() for db::ImplsInModuleQuery; 210 fn impls_in_module() for db::ImplsInModuleQuery;
211 fn body_hir() for db::BodyHirQuery; 211 fn body_hir() for db::BodyHirQuery;
212 fn body_syntax_mapping() for db::BodySyntaxMappingQuery; 212 fn body_syntax_mapping() for db::BodySyntaxMappingQuery;
213 fn fn_signature() for db::FnSignatureQuery;
213 } 214 }
214 } 215 }
215} 216}
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs
index 6f95b168f..90229bc54 100644
--- a/crates/ra_hir/src/name.rs
+++ b/crates/ra_hir/src/name.rs
@@ -35,6 +35,10 @@ impl Name {
35 Name::new("self".into()) 35 Name::new("self".into())
36 } 36 }
37 37
38 pub(crate) fn self_type() -> Name {
39 Name::new("Self".into())
40 }
41
38 pub(crate) fn tuple_field_name(idx: usize) -> Name { 42 pub(crate) fn tuple_field_name(idx: usize) -> Name {
39 Name::new(idx.to_string().into()) 43 Name::new(idx.to_string().into())
40 } 44 }
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs
index 2e42caffe..dcf4cf8b6 100644
--- a/crates/ra_hir/src/path.rs
+++ b/crates/ra_hir/src/path.rs
@@ -67,10 +67,7 @@ impl Path {
67 67
68 /// Converts an `ast::NameRef` into a single-identifier `Path`. 68 /// Converts an `ast::NameRef` into a single-identifier `Path`.
69 pub fn from_name_ref(name_ref: ast::NameRef) -> Path { 69 pub fn from_name_ref(name_ref: ast::NameRef) -> Path {
70 Path { 70 name_ref.as_name().into()
71 kind: PathKind::Plain,
72 segments: vec![name_ref.as_name()],
73 }
74 } 71 }
75 72
76 /// `true` is this path is a single identifier, like `foo` 73 /// `true` is this path is a single identifier, like `foo`
@@ -92,6 +89,15 @@ impl Path {
92 } 89 }
93} 90}
94 91
92impl From<Name> for Path {
93 fn from(name: Name) -> Path {
94 Path {
95 kind: PathKind::Plain,
96 segments: vec![name],
97 }
98 }
99}
100
95fn expand_use_tree( 101fn expand_use_tree(
96 prefix: Option<Path>, 102 prefix: Option<Path>,
97 tree: ast::UseTree, 103 tree: ast::UseTree,
diff --git a/crates/ra_hir/src/type_ref.rs b/crates/ra_hir/src/type_ref.rs
index b36bb35d8..859f330c2 100644
--- a/crates/ra_hir/src/type_ref.rs
+++ b/crates/ra_hir/src/type_ref.rs
@@ -107,4 +107,8 @@ impl TypeRef {
107 TypeRef::Error 107 TypeRef::Error
108 } 108 }
109 } 109 }
110
111 pub fn unit() -> TypeRef {
112 TypeRef::Tuple(Vec::new())
113 }
110} 114}