diff options
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 23 | ||||
-rw-r--r-- | crates/ra_hir_def/src/generics.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir_def/src/keys.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 14 | ||||
-rw-r--r-- | crates/ra_ide/src/references/classify.rs | 9 |
6 files changed, 68 insertions, 5 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 8833750c8..0295eb948 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -865,6 +865,10 @@ impl GenericParam { | |||
865 | let params = db.generic_params(self.id.parent); | 865 | let params = db.generic_params(self.id.parent); |
866 | params.params[self.id.local_id].name.clone() | 866 | params.params[self.id.local_id].name.clone() |
867 | } | 867 | } |
868 | |||
869 | pub fn module(self, db: &impl HirDatabase) -> Module { | ||
870 | self.id.parent.module(db).into() | ||
871 | } | ||
868 | } | 872 | } |
869 | 873 | ||
870 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 874 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 437f800c1..686ab1d79 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | use hir_def::{ | 2 | use hir_def::{ |
3 | child_by_source::ChildBySource, dyn_map::DynMap, keys, nameres::ModuleSource, AstItemDef, | 3 | child_by_source::ChildBySource, dyn_map::DynMap, keys, nameres::ModuleSource, AstItemDef, |
4 | EnumVariantId, LocationCtx, ModuleId, VariantId, | 4 | EnumVariantId, GenericDefId, LocationCtx, ModuleId, VariantId, |
5 | }; | 5 | }; |
6 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; | 6 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
@@ -11,8 +11,8 @@ use ra_syntax::{ | |||
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | db::{AstDatabase, DefDatabase, HirDatabase}, | 13 | db::{AstDatabase, DefDatabase, HirDatabase}, |
14 | Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, ImplBlock, InFile, Local, | 14 | Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, GenericParam, ImplBlock, InFile, |
15 | MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, Union, | 15 | Local, MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, Union, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | pub trait FromSource: Sized { | 18 | pub trait FromSource: Sized { |
@@ -177,6 +177,23 @@ impl Local { | |||
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
180 | impl GenericParam { | ||
181 | pub fn from_source(db: &impl HirDatabase, src: InFile<ast::TypeParam>) -> Option<Self> { | ||
182 | let file_id = src.file_id; | ||
183 | let parent: GenericDefId = src.value.syntax().ancestors().find_map(|it| { | ||
184 | let res = match_ast! { | ||
185 | match it { | ||
186 | ast::FnDef(value) => { Function::from_source(db, InFile { value, file_id})?.id.into() }, | ||
187 | _ => return None, | ||
188 | } | ||
189 | }; | ||
190 | Some(res) | ||
191 | })?; | ||
192 | let &id = parent.child_by_source(db)[keys::TYPE_PARAM].get(&src)?; | ||
193 | Some(GenericParam { id }) | ||
194 | } | ||
195 | } | ||
196 | |||
180 | impl Module { | 197 | impl Module { |
181 | pub fn from_declaration(db: &impl DefDatabase, src: InFile<ast::Module>) -> Option<Self> { | 198 | pub fn from_declaration(db: &impl DefDatabase, src: InFile<ast::Module>) -> Option<Self> { |
182 | let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast); | 199 | let parent_declaration = src.value.syntax().ancestors().skip(1).find_map(ast::Module::cast); |
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 0df5a20f5..159f9034b 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs | |||
@@ -14,11 +14,14 @@ use ra_db::FileId; | |||
14 | use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; | 14 | use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; |
15 | 15 | ||
16 | use crate::{ | 16 | use crate::{ |
17 | child_by_source::ChildBySource, | ||
17 | db::DefDatabase, | 18 | db::DefDatabase, |
19 | dyn_map::DynMap, | ||
20 | keys, | ||
18 | src::HasChildSource, | 21 | src::HasChildSource, |
19 | src::HasSource, | 22 | src::HasSource, |
20 | type_ref::{TypeBound, TypeRef}, | 23 | type_ref::{TypeBound, TypeRef}, |
21 | AdtId, AstItemDef, GenericDefId, LocalGenericParamId, Lookup, | 24 | AdtId, AstItemDef, GenericDefId, GenericParamId, LocalGenericParamId, Lookup, |
22 | }; | 25 | }; |
23 | 26 | ||
24 | /// Data about a generic parameter (to a function, struct, impl, ...). | 27 | /// Data about a generic parameter (to a function, struct, impl, ...). |
@@ -183,3 +186,18 @@ impl HasChildSource for GenericDefId { | |||
183 | sm | 186 | sm |
184 | } | 187 | } |
185 | } | 188 | } |
189 | |||
190 | impl ChildBySource for GenericDefId { | ||
191 | fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { | ||
192 | let mut res = DynMap::default(); | ||
193 | let arena_map = self.child_source(db); | ||
194 | let arena_map = arena_map.as_ref(); | ||
195 | for (local_id, src) in arena_map.value.iter() { | ||
196 | let id = GenericParamId { parent: *self, local_id }; | ||
197 | if let Either::Right(type_param) = src { | ||
198 | res[keys::TYPE_PARAM].insert(arena_map.with_value(type_param.clone()), id) | ||
199 | } | ||
200 | } | ||
201 | res | ||
202 | } | ||
203 | } | ||
diff --git a/crates/ra_hir_def/src/keys.rs b/crates/ra_hir_def/src/keys.rs index 447b7e3ba..ca5630c80 100644 --- a/crates/ra_hir_def/src/keys.rs +++ b/crates/ra_hir_def/src/keys.rs | |||
@@ -8,7 +8,7 @@ use rustc_hash::FxHashMap; | |||
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | dyn_map::{DynMap, Policy}, | 10 | dyn_map::{DynMap, Policy}, |
11 | ConstId, EnumVariantId, FunctionId, StaticId, StructFieldId, TypeAliasId, | 11 | ConstId, EnumVariantId, FunctionId, GenericParamId, StaticId, StructFieldId, TypeAliasId, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>; | 14 | type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>; |
@@ -20,6 +20,7 @@ pub const ENUM_VARIANT: Key<ast::EnumVariant, EnumVariantId> = Key::new(); | |||
20 | pub const TYPE_ALIAS: Key<ast::TypeAliasDef, TypeAliasId> = Key::new(); | 20 | pub const TYPE_ALIAS: Key<ast::TypeAliasDef, TypeAliasId> = Key::new(); |
21 | pub const TUPLE_FIELD: Key<ast::TupleFieldDef, StructFieldId> = Key::new(); | 21 | pub const TUPLE_FIELD: Key<ast::TupleFieldDef, StructFieldId> = Key::new(); |
22 | pub const RECORD_FIELD: Key<ast::RecordFieldDef, StructFieldId> = Key::new(); | 22 | pub const RECORD_FIELD: Key<ast::RecordFieldDef, StructFieldId> = Key::new(); |
23 | pub const TYPE_PARAM: Key<ast::TypeParam, GenericParamId> = Key::new(); | ||
23 | 24 | ||
24 | /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are | 25 | /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are |
25 | /// equal if they point to exactly the same object. | 26 | /// equal if they point to exactly the same object. |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index b8dfc0ab1..6dfb3c03d 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -525,6 +525,20 @@ impl HasModule for DefWithBodyId { | |||
525 | } | 525 | } |
526 | } | 526 | } |
527 | 527 | ||
528 | impl HasModule for GenericDefId { | ||
529 | fn module(&self, db: &impl db::DefDatabase) -> ModuleId { | ||
530 | match self { | ||
531 | GenericDefId::FunctionId(it) => it.lookup(db).module(db), | ||
532 | GenericDefId::AdtId(it) => it.module(db), | ||
533 | GenericDefId::TraitId(it) => it.module(db), | ||
534 | GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), | ||
535 | GenericDefId::ImplId(it) => it.module(db), | ||
536 | GenericDefId::EnumVariantId(it) => it.parent.module(db), | ||
537 | GenericDefId::ConstId(it) => it.lookup(db).module(db), | ||
538 | } | ||
539 | } | ||
540 | } | ||
541 | |||
528 | impl HasModule for StaticLoc { | 542 | impl HasModule for StaticLoc { |
529 | fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { | 543 | fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { |
530 | self.container | 544 | self.container |
diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs index b716d32e5..65df2e335 100644 --- a/crates/ra_ide/src/references/classify.rs +++ b/crates/ra_ide/src/references/classify.rs | |||
@@ -110,6 +110,15 @@ pub(crate) fn classify_name(db: &RootDatabase, name: InFile<&ast::Name>) -> Opti | |||
110 | kind: NameKind::Macro(def), | 110 | kind: NameKind::Macro(def), |
111 | }) | 111 | }) |
112 | }, | 112 | }, |
113 | ast::TypeParam(it) => { | ||
114 | let src = name.with_value(it); | ||
115 | let def = hir::GenericParam::from_source(db, src)?; | ||
116 | Some(NameDefinition { | ||
117 | visibility: None, | ||
118 | container: def.module(db), | ||
119 | kind: NameKind::GenericParam(def), | ||
120 | }) | ||
121 | }, | ||
113 | _ => None, | 122 | _ => None, |
114 | } | 123 | } |
115 | } | 124 | } |