aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/generics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/generics.rs')
-rw-r--r--crates/ra_hir/src/generics.rs66
1 files changed, 51 insertions, 15 deletions
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs
index d8248ad49..88c53705f 100644
--- a/crates/ra_hir/src/generics.rs
+++ b/crates/ra_hir/src/generics.rs
@@ -5,9 +5,9 @@
5 5
6use std::sync::Arc; 6use std::sync::Arc;
7 7
8use ra_syntax::ast::{TypeParamList, AstNode, NameOwner}; 8use ra_syntax::ast::{self, AstNode, NameOwner, TypeParamsOwner};
9 9
10use crate::{db::HirDatabase, DefId, Name, AsName}; 10use crate::{db::HirDatabase, DefId, Name, AsName, Function};
11 11
12/// Data about a generic parameter (to a function, struct, impl, ...). 12/// Data about a generic parameter (to a function, struct, impl, ...).
13#[derive(Clone, PartialEq, Eq, Debug)] 13#[derive(Clone, PartialEq, Eq, Debug)]
@@ -22,26 +22,62 @@ pub struct GenericParams {
22 pub(crate) params: Vec<GenericParam>, 22 pub(crate) params: Vec<GenericParam>,
23} 23}
24 24
25#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
26pub enum GenericDef {
27 Function(Function),
28 Def(DefId),
29}
30
31impl From<Function> for GenericDef {
32 fn from(func: Function) -> GenericDef {
33 GenericDef::Function(func)
34 }
35}
36
37impl From<DefId> for GenericDef {
38 fn from(def_id: DefId) -> GenericDef {
39 GenericDef::Def(def_id)
40 }
41}
42
25impl GenericParams { 43impl GenericParams {
26 pub(crate) fn generic_params_query(db: &impl HirDatabase, def_id: DefId) -> Arc<GenericParams> { 44 pub(crate) fn generic_params_query(
27 let (_file_id, node) = def_id.source(db); 45 db: &impl HirDatabase,
46 def: GenericDef,
47 ) -> Arc<GenericParams> {
28 let mut generics = GenericParams::default(); 48 let mut generics = GenericParams::default();
29 if let Some(type_param_list) = node.children().find_map(TypeParamList::cast) { 49 match def {
30 for (idx, type_param) in type_param_list.type_params().enumerate() { 50 GenericDef::Function(func) => {
31 let name = type_param 51 let (_, fn_def) = func.source(db);
32 .name() 52 if let Some(type_param_list) = fn_def.type_param_list() {
33 .map(AsName::as_name) 53 generics.fill(type_param_list)
34 .unwrap_or_else(Name::missing); 54 }
35 let param = GenericParam { 55 }
36 idx: idx as u32, 56 GenericDef::Def(def_id) => {
37 name, 57 let (_file_id, node) = def_id.source(db);
38 }; 58 if let Some(type_param_list) = node.children().find_map(ast::TypeParamList::cast) {
39 generics.params.push(param); 59 generics.fill(type_param_list)
60 }
40 } 61 }
41 } 62 }
63
42 Arc::new(generics) 64 Arc::new(generics)
43 } 65 }
44 66
67 fn fill(&mut self, params: &ast::TypeParamList) {
68 for (idx, type_param) in params.type_params().enumerate() {
69 let name = type_param
70 .name()
71 .map(AsName::as_name)
72 .unwrap_or_else(Name::missing);
73 let param = GenericParam {
74 idx: idx as u32,
75 name,
76 };
77 self.params.push(param);
78 }
79 }
80
45 pub(crate) fn find_by_name(&self, name: &Name) -> Option<&GenericParam> { 81 pub(crate) fn find_by_name(&self, name: &Name) -> Option<&GenericParam> {
46 self.params.iter().find(|p| &p.name == name) 82 self.params.iter().find(|p| &p.name == name)
47 } 83 }