diff options
Diffstat (limited to 'crates/ra_hir/src/from_source.rs')
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 78 |
1 files changed, 38 insertions, 40 deletions
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 9793af858..ec56dfa6a 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir_def::{StructId, StructOrUnionId, UnionId}; | 3 | use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId}; |
4 | use hir_expand::name::AsName; | 4 | use hir_expand::name::AsName; |
5 | use ra_syntax::{ | 5 | use ra_syntax::{ |
6 | ast::{self, AstNode, NameOwner}, | 6 | ast::{self, AstNode, NameOwner}, |
@@ -10,9 +10,9 @@ use ra_syntax::{ | |||
10 | use crate::{ | 10 | use crate::{ |
11 | db::{AstDatabase, DefDatabase, HirDatabase}, | 11 | db::{AstDatabase, DefDatabase, HirDatabase}, |
12 | ids::{AstItemDef, LocationCtx}, | 12 | ids::{AstItemDef, LocationCtx}, |
13 | AstId, Const, Crate, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, | 13 | Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, ImplBlock, |
14 | ImplBlock, Local, Module, ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, | 14 | Local, Module, ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, Union, |
15 | Union, VariantDef, | 15 | VariantDef, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | pub trait FromSource: Sized { | 18 | pub trait FromSource: Sized { |
@@ -82,14 +82,8 @@ impl FromSource for TypeAlias { | |||
82 | impl FromSource for ImplBlock { | 82 | impl FromSource for ImplBlock { |
83 | type Ast = ast::ImplBlock; | 83 | type Ast = ast::ImplBlock; |
84 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { | 84 | fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> { |
85 | let module_src = crate::ModuleSource::from_child_node( | 85 | let id = from_source(db, src)?; |
86 | db, | 86 | Some(ImplBlock { id }) |
87 | src.file_id.original_file(db), | ||
88 | &src.ast.syntax(), | ||
89 | ); | ||
90 | let module = Module::from_definition(db, Source { file_id: src.file_id, ast: module_src })?; | ||
91 | let impls = module.impl_blocks(db); | ||
92 | impls.into_iter().find(|b| b.source(db) == src) | ||
93 | } | 87 | } |
94 | } | 88 | } |
95 | 89 | ||
@@ -152,44 +146,48 @@ impl Local { | |||
152 | } | 146 | } |
153 | 147 | ||
154 | impl Module { | 148 | impl Module { |
155 | pub fn from_declaration(db: &impl HirDatabase, src: Source<ast::Module>) -> Option<Self> { | 149 | pub fn from_declaration(db: &impl DefDatabase, src: Source<ast::Module>) -> Option<Self> { |
156 | let src_parent = Source { | 150 | let parent_declaration = src.ast.syntax().ancestors().skip(1).find_map(ast::Module::cast); |
157 | file_id: src.file_id, | 151 | |
158 | ast: ModuleSource::new(db, Some(src.file_id.original_file(db)), None), | 152 | let parent_module = match parent_declaration { |
159 | }; | 153 | Some(parent_declaration) => { |
160 | let parent_module = Module::from_definition(db, src_parent)?; | 154 | let src_parent = Source { file_id: src.file_id, ast: parent_declaration }; |
155 | Module::from_declaration(db, src_parent) | ||
156 | } | ||
157 | _ => { | ||
158 | let src_parent = Source { | ||
159 | file_id: src.file_id, | ||
160 | ast: ModuleSource::new(db, Some(src.file_id.original_file(db)), None), | ||
161 | }; | ||
162 | Module::from_definition(db, src_parent) | ||
163 | } | ||
164 | }?; | ||
165 | |||
161 | let child_name = src.ast.name()?; | 166 | let child_name = src.ast.name()?; |
162 | parent_module.child(db, &child_name.as_name()) | 167 | parent_module.child(db, &child_name.as_name()) |
163 | } | 168 | } |
164 | 169 | ||
165 | pub fn from_definition( | 170 | pub fn from_definition(db: &impl DefDatabase, src: Source<ModuleSource>) -> Option<Self> { |
166 | db: &(impl DefDatabase + AstDatabase), | 171 | match src.ast { |
167 | src: Source<ModuleSource>, | ||
168 | ) -> Option<Self> { | ||
169 | let decl_id = match src.ast { | ||
170 | ModuleSource::Module(ref module) => { | 172 | ModuleSource::Module(ref module) => { |
171 | assert!(!module.has_semi()); | 173 | assert!(!module.has_semi()); |
172 | let ast_id_map = db.ast_id_map(src.file_id); | 174 | return Module::from_declaration( |
173 | let item_id = AstId::new(src.file_id, ast_id_map.ast_id(module)); | 175 | db, |
174 | Some(item_id) | 176 | Source { file_id: src.file_id, ast: module.clone() }, |
177 | ); | ||
175 | } | 178 | } |
176 | ModuleSource::SourceFile(_) => None, | 179 | ModuleSource::SourceFile(_) => (), |
177 | }; | 180 | }; |
178 | 181 | ||
179 | db.relevant_crates(src.file_id.original_file(db)).iter().find_map(|&crate_id| { | 182 | let original_file = src.file_id.original_file(db); |
180 | let def_map = db.crate_def_map(crate_id); | ||
181 | |||
182 | let (module_id, _module_data) = | ||
183 | def_map.modules.iter().find(|(_module_id, module_data)| { | ||
184 | if decl_id.is_some() { | ||
185 | module_data.declaration == decl_id | ||
186 | } else { | ||
187 | module_data.definition.map(|it| it.into()) == Some(src.file_id) | ||
188 | } | ||
189 | })?; | ||
190 | 183 | ||
191 | Some(Module::new(Crate { crate_id }, module_id)) | 184 | let (krate, module_id) = |
192 | }) | 185 | db.relevant_crates(original_file).iter().find_map(|&crate_id| { |
186 | let crate_def_map = db.crate_def_map(crate_id); | ||
187 | let local_module_id = crate_def_map.modules_for_file(original_file).next()?; | ||
188 | Some((crate_id, local_module_id)) | ||
189 | })?; | ||
190 | Some(Module { id: ModuleId { krate, module_id } }) | ||
193 | } | 191 | } |
194 | } | 192 | } |
195 | 193 | ||