diff options
Diffstat (limited to 'crates/ra_hir/src/from_source.rs')
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 80 |
1 files changed, 48 insertions, 32 deletions
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 7abb4bd75..42ca55fe7 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs | |||
@@ -1,8 +1,10 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! Finds a corresponding hir data structure for a syntax node in a specific |
2 | //! file. | ||
3 | |||
2 | use hir_def::{ | 4 | use hir_def::{ |
3 | child_by_source::ChildBySource, dyn_map::DynMap, keys, keys::Key, nameres::ModuleSource, | 5 | child_by_source::ChildBySource, dyn_map::DynMap, keys, keys::Key, nameres::ModuleSource, |
4 | ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, StaticId, StructId, | 6 | ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, |
5 | TraitId, TypeAliasId, UnionId, VariantId, | 7 | StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId, |
6 | }; | 8 | }; |
7 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; | 9 | use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; |
8 | use ra_syntax::{ | 10 | use ra_syntax::{ |
@@ -11,14 +13,14 @@ use ra_syntax::{ | |||
11 | }; | 13 | }; |
12 | 14 | ||
13 | use crate::{ | 15 | use crate::{ |
14 | db::{AstDatabase, DefDatabase, HirDatabase}, | 16 | db::{DefDatabase, HirDatabase}, |
15 | Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, ImplBlock, InFile, Local, | 17 | Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, ImplBlock, InFile, Local, |
16 | MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, | 18 | MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, |
17 | }; | 19 | }; |
18 | 20 | ||
19 | pub trait FromSource: Sized { | 21 | pub trait FromSource: Sized { |
20 | type Ast; | 22 | type Ast; |
21 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self>; | 23 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self>; |
22 | } | 24 | } |
23 | 25 | ||
24 | pub trait FromSourceByContainer: Sized { | 26 | pub trait FromSourceByContainer: Sized { |
@@ -32,7 +34,7 @@ where | |||
32 | T: From<<T as FromSourceByContainer>::Id>, | 34 | T: From<<T as FromSourceByContainer>::Id>, |
33 | { | 35 | { |
34 | type Ast = <T as FromSourceByContainer>::Ast; | 36 | type Ast = <T as FromSourceByContainer>::Ast; |
35 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 37 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> { |
36 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[T::KEY] | 38 | analyze_container(db, src.as_ref().map(|it| it.syntax()))[T::KEY] |
37 | .get(&src) | 39 | .get(&src) |
38 | .copied() | 40 | .copied() |
@@ -64,7 +66,7 @@ from_source_by_container_impls![ | |||
64 | 66 | ||
65 | impl FromSource for MacroDef { | 67 | impl FromSource for MacroDef { |
66 | type Ast = ast::MacroCall; | 68 | type Ast = ast::MacroCall; |
67 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 69 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> { |
68 | let kind = MacroDefKind::Declarative; | 70 | let kind = MacroDefKind::Declarative; |
69 | 71 | ||
70 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); | 72 | let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); |
@@ -80,7 +82,7 @@ impl FromSource for MacroDef { | |||
80 | 82 | ||
81 | impl FromSource for EnumVariant { | 83 | impl FromSource for EnumVariant { |
82 | type Ast = ast::EnumVariant; | 84 | type Ast = ast::EnumVariant; |
83 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 85 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> { |
84 | let parent_enum = src.value.parent_enum(); | 86 | let parent_enum = src.value.parent_enum(); |
85 | let src_enum = InFile { file_id: src.file_id, value: parent_enum }; | 87 | let src_enum = InFile { file_id: src.file_id, value: parent_enum }; |
86 | let parent_enum = Enum::from_source(db, src_enum)?; | 88 | let parent_enum = Enum::from_source(db, src_enum)?; |
@@ -93,7 +95,7 @@ impl FromSource for EnumVariant { | |||
93 | 95 | ||
94 | impl FromSource for StructField { | 96 | impl FromSource for StructField { |
95 | type Ast = FieldSource; | 97 | type Ast = FieldSource; |
96 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: InFile<Self::Ast>) -> Option<Self> { | 98 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self> { |
97 | let src = src.as_ref(); | 99 | let src = src.as_ref(); |
98 | 100 | ||
99 | // FIXME this is buggy | 101 | // FIXME this is buggy |
@@ -212,29 +214,43 @@ impl Module { | |||
212 | } | 214 | } |
213 | 215 | ||
214 | fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap { | 216 | fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap { |
215 | _analyze_container(db, src).unwrap_or_default() | 217 | return child_by_source(db, src).unwrap_or_default(); |
216 | } | ||
217 | 218 | ||
218 | fn _analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<DynMap> { | 219 | fn child_by_source(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> Option<DynMap> { |
219 | // FIXME: this doesn't try to handle nested declarations | 220 | for container in src.value.ancestors().skip(1) { |
220 | for container in src.value.ancestors().skip(1) { | 221 | let res = match_ast! { |
221 | let res = match_ast! { | 222 | match container { |
222 | match container { | 223 | ast::TraitDef(it) => { |
223 | ast::TraitDef(it) => { | 224 | let def = Trait::from_source(db, src.with_value(it))?; |
224 | let c = Trait::from_source(db, src.with_value(it))?; | 225 | def.id.child_by_source(db) |
225 | c.id.child_by_source(db) | 226 | }, |
226 | }, | 227 | ast::ImplBlock(it) => { |
227 | ast::ImplBlock(it) => { | 228 | let def = ImplBlock::from_source(db, src.with_value(it))?; |
228 | let c = ImplBlock::from_source(db, src.with_value(it))?; | 229 | def.id.child_by_source(db) |
229 | c.id.child_by_source(db) | 230 | }, |
230 | }, | 231 | ast::FnDef(it) => { |
231 | _ => { continue }, | 232 | let def = Function::from_source(db, src.with_value(it))?; |
232 | } | 233 | DefWithBodyId::from(def.id) |
233 | }; | 234 | .child_by_source(db) |
234 | return Some(res); | 235 | }, |
235 | } | 236 | ast::StaticDef(it) => { |
237 | let def = Static::from_source(db, src.with_value(it))?; | ||
238 | DefWithBodyId::from(def.id) | ||
239 | .child_by_source(db) | ||
240 | }, | ||
241 | ast::ConstDef(it) => { | ||
242 | let def = Const::from_source(db, src.with_value(it))?; | ||
243 | DefWithBodyId::from(def.id) | ||
244 | .child_by_source(db) | ||
245 | }, | ||
246 | _ => { continue }, | ||
247 | } | ||
248 | }; | ||
249 | return Some(res); | ||
250 | } | ||
236 | 251 | ||
237 | let module_source = ModuleSource::from_child_node(db, src); | 252 | let module_source = ModuleSource::from_child_node(db, src); |
238 | let c = Module::from_definition(db, src.with_value(module_source))?; | 253 | let c = Module::from_definition(db, src.with_value(module_source))?; |
239 | Some(c.id.child_by_source(db)) | 254 | Some(c.id.child_by_source(db)) |
255 | } | ||
240 | } | 256 | } |