aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model.rs4
-rw-r--r--crates/ra_hir/src/from_source.rs23
-rw-r--r--crates/ra_hir_def/src/generics.rs20
-rw-r--r--crates/ra_hir_def/src/keys.rs3
-rw-r--r--crates/ra_hir_def/src/lib.rs14
-rw-r--r--crates/ra_ide/src/references/classify.rs9
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
2use hir_def::{ 2use 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};
6use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; 6use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
7use ra_syntax::{ 7use ra_syntax::{
@@ -11,8 +11,8 @@ use ra_syntax::{
11 11
12use crate::{ 12use 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
18pub trait FromSource: Sized { 18pub trait FromSource: Sized {
@@ -177,6 +177,23 @@ impl Local {
177 } 177 }
178} 178}
179 179
180impl 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
180impl Module { 197impl 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;
14use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; 14use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner};
15 15
16use crate::{ 16use 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
190impl 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
9use crate::{ 9use 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
14type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>; 14type 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();
20pub const TYPE_ALIAS: Key<ast::TypeAliasDef, TypeAliasId> = Key::new(); 20pub const TYPE_ALIAS: Key<ast::TypeAliasDef, TypeAliasId> = Key::new();
21pub const TUPLE_FIELD: Key<ast::TupleFieldDef, StructFieldId> = Key::new(); 21pub const TUPLE_FIELD: Key<ast::TupleFieldDef, StructFieldId> = Key::new();
22pub const RECORD_FIELD: Key<ast::RecordFieldDef, StructFieldId> = Key::new(); 22pub const RECORD_FIELD: Key<ast::RecordFieldDef, StructFieldId> = Key::new();
23pub 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
528impl 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
528impl HasModule for StaticLoc { 542impl 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 }