aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/from_source.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/from_source.rs')
-rw-r--r--crates/ra_hir/src/from_source.rs80
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
2use hir_def::{ 4use 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};
7use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind}; 9use hir_expand::{name::AsName, AstId, MacroDefId, MacroDefKind};
8use ra_syntax::{ 10use ra_syntax::{
@@ -11,14 +13,14 @@ use ra_syntax::{
11}; 13};
12 14
13use crate::{ 15use 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
19pub trait FromSource: Sized { 21pub 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
24pub trait FromSourceByContainer: Sized { 26pub 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
65impl FromSource for MacroDef { 67impl 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
81impl FromSource for EnumVariant { 83impl 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
94impl FromSource for StructField { 96impl 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
214fn analyze_container(db: &impl DefDatabase, src: InFile<&SyntaxNode>) -> DynMap { 216fn 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
218fn _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}