aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model_api.rs162
-rw-r--r--crates/ra_hir/src/code_model_impl.rs1
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs99
3 files changed, 105 insertions, 157 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index 637ebb7ec..4447c608a 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -1,10 +1,10 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_db::{CrateId, SourceRootId, Edition}; 3use ra_db::{CrateId, SourceRootId, Edition, FileId};
4use ra_syntax::{ast::self, TreeArc}; 4use ra_syntax::{ast::self, TreeArc};
5 5
6use crate::{ 6use crate::{
7 Name, AsName, Ty, HirFileId, Either, 7 Name, AsName, AstId, Ty, HirFileId, Either,
8 HirDatabase, DefDatabase, 8 HirDatabase, DefDatabase,
9 type_ref::TypeRef, 9 type_ref::TypeRef,
10 nameres::{ModuleScope, Namespace, ImportId, CrateModuleId}, 10 nameres::{ModuleScope, Namespace, ImportId, CrateModuleId},
@@ -107,29 +107,66 @@ pub enum ModuleSource {
107 Module(TreeArc<ast::Module>), 107 Module(TreeArc<ast::Module>),
108} 108}
109 109
110impl ModuleSource {
111 pub(crate) fn new(
112 db: &impl DefDatabase,
113 file_id: Option<FileId>,
114 decl_id: Option<AstId<ast::Module>>,
115 ) -> ModuleSource {
116 match (file_id, decl_id) {
117 (Some(file_id), _) => {
118 let source_file = db.parse(file_id);
119 ModuleSource::SourceFile(source_file)
120 }
121 (None, Some(item_id)) => {
122 let module = item_id.to_node(db);
123 assert!(module.item_list().is_some(), "expected inline module");
124 ModuleSource::Module(module.to_owned())
125 }
126 (None, None) => panic!(),
127 }
128 }
129}
130
110impl Module { 131impl Module {
111 /// Name of this module. 132 /// Name of this module.
112 pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { 133 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
113 self.name_impl(db) 134 let def_map = db.crate_def_map(self.krate);
135 let parent = def_map[self.module_id].parent?;
136 def_map[parent].children.iter().find_map(|(name, module_id)| {
137 if *module_id == self.module_id {
138 Some(name.clone())
139 } else {
140 None
141 }
142 })
114 } 143 }
115 144
116 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. 145 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
117 pub fn definition_source(&self, db: &impl DefDatabase) -> (HirFileId, ModuleSource) { 146 pub fn definition_source(self, db: &impl DefDatabase) -> (HirFileId, ModuleSource) {
118 self.definition_source_impl(db) 147 let def_map = db.crate_def_map(self.krate);
148 let decl_id = def_map[self.module_id].declaration;
149 let file_id = def_map[self.module_id].definition;
150 let module_source = ModuleSource::new(db, file_id, decl_id);
151 let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id());
152 (file_id, module_source)
119 } 153 }
120 154
121 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. 155 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
122 /// `None` for the crate root. 156 /// `None` for the crate root.
123 pub fn declaration_source( 157 pub fn declaration_source(
124 &self, 158 self,
125 db: &impl HirDatabase, 159 db: &impl HirDatabase,
126 ) -> Option<(HirFileId, TreeArc<ast::Module>)> { 160 ) -> Option<(HirFileId, TreeArc<ast::Module>)> {
127 self.declaration_source_impl(db) 161 let def_map = db.crate_def_map(self.krate);
162 let decl = def_map[self.module_id].declaration?;
163 let ast = decl.to_node(db);
164 Some((decl.file_id(), ast))
128 } 165 }
129 166
130 /// Returns the syntax of the last path segment corresponding to this import 167 /// Returns the syntax of the last path segment corresponding to this import
131 pub fn import_source( 168 pub fn import_source(
132 &self, 169 self,
133 db: &impl HirDatabase, 170 db: &impl HirDatabase,
134 import: ImportId, 171 import: ImportId,
135 ) -> Either<TreeArc<ast::UseTree>, TreeArc<ast::ExternCrateItem>> { 172 ) -> Either<TreeArc<ast::UseTree>, TreeArc<ast::ExternCrateItem>> {
@@ -139,33 +176,44 @@ impl Module {
139 } 176 }
140 177
141 /// Returns the crate this module is part of. 178 /// Returns the crate this module is part of.
142 pub fn krate(&self, _db: &impl DefDatabase) -> Option<Crate> { 179 pub fn krate(self, _db: &impl DefDatabase) -> Option<Crate> {
143 Some(self.krate) 180 Some(self.krate)
144 } 181 }
145 182
146 /// Topmost parent of this module. Every module has a `crate_root`, but some 183 /// Topmost parent of this module. Every module has a `crate_root`, but some
147 /// might be missing `krate`. This can happen if a module's file is not included 184 /// might be missing `krate`. This can happen if a module's file is not included
148 /// in the module tree of any target in `Cargo.toml`. 185 /// in the module tree of any target in `Cargo.toml`.
149 pub fn crate_root(&self, db: &impl DefDatabase) -> Module { 186 pub fn crate_root(self, db: &impl DefDatabase) -> Module {
150 self.crate_root_impl(db) 187 let def_map = db.crate_def_map(self.krate);
188 self.with_module_id(def_map.root())
151 } 189 }
152 190
153 /// Finds a child module with the specified name. 191 /// Finds a child module with the specified name.
154 pub fn child(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> { 192 pub fn child(self, db: &impl HirDatabase, name: &Name) -> Option<Module> {
155 self.child_impl(db, name) 193 let def_map = db.crate_def_map(self.krate);
194 let child_id = def_map[self.module_id].children.get(name)?;
195 Some(self.with_module_id(*child_id))
156 } 196 }
157 197
158 /// Iterates over all child modules. 198 /// Iterates over all child modules.
159 pub fn children(&self, db: &impl DefDatabase) -> impl Iterator<Item = Module> { 199 pub fn children(self, db: &impl DefDatabase) -> impl Iterator<Item = Module> {
160 self.children_impl(db) 200 let def_map = db.crate_def_map(self.krate);
201 let children = def_map[self.module_id]
202 .children
203 .iter()
204 .map(|(_, module_id)| self.with_module_id(*module_id))
205 .collect::<Vec<_>>();
206 children.into_iter()
161 } 207 }
162 208
163 /// Finds a parent module. 209 /// Finds a parent module.
164 pub fn parent(&self, db: &impl DefDatabase) -> Option<Module> { 210 pub fn parent(self, db: &impl DefDatabase) -> Option<Module> {
165 self.parent_impl(db) 211 let def_map = db.crate_def_map(self.krate);
212 let parent_id = def_map[self.module_id].parent?;
213 Some(self.with_module_id(parent_id))
166 } 214 }
167 215
168 pub fn path_to_root(&self, db: &impl HirDatabase) -> Vec<Module> { 216 pub fn path_to_root(self, db: &impl HirDatabase) -> Vec<Module> {
169 let mut res = vec![self.clone()]; 217 let mut res = vec![self.clone()];
170 let mut curr = self.clone(); 218 let mut curr = self.clone();
171 while let Some(next) = curr.parent(db) { 219 while let Some(next) = curr.parent(db) {
@@ -176,11 +224,11 @@ impl Module {
176 } 224 }
177 225
178 /// Returns a `ModuleScope`: a set of items, visible in this module. 226 /// Returns a `ModuleScope`: a set of items, visible in this module.
179 pub fn scope(&self, db: &impl HirDatabase) -> ModuleScope { 227 pub fn scope(self, db: &impl HirDatabase) -> ModuleScope {
180 db.crate_def_map(self.krate)[self.module_id].scope.clone() 228 db.crate_def_map(self.krate)[self.module_id].scope.clone()
181 } 229 }
182 230
183 pub fn diagnostics(&self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { 231 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
184 db.crate_def_map(self.krate).add_diagnostics(db, self.module_id, sink); 232 db.crate_def_map(self.krate).add_diagnostics(db, self.module_id, sink);
185 for decl in self.declarations(db) { 233 for decl in self.declarations(db) {
186 match decl { 234 match decl {
@@ -200,7 +248,7 @@ impl Module {
200 } 248 }
201 } 249 }
202 250
203 pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { 251 pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver {
204 let def_map = db.crate_def_map(self.krate); 252 let def_map = db.crate_def_map(self.krate);
205 Resolver::default().push_module_scope(def_map, self.module_id) 253 Resolver::default().push_module_scope(def_map, self.module_id)
206 } 254 }
@@ -225,6 +273,10 @@ impl Module {
225 .map(|(impl_id, _)| ImplBlock::from_id(self, impl_id)) 273 .map(|(impl_id, _)| ImplBlock::from_id(self, impl_id))
226 .collect() 274 .collect()
227 } 275 }
276
277 fn with_module_id(&self, module_id: CrateModuleId) -> Module {
278 Module { module_id, krate: self.krate }
279 }
228} 280}
229 281
230impl Docs for Module { 282impl Docs for Module {
@@ -278,49 +330,49 @@ pub struct Struct {
278} 330}
279 331
280impl Struct { 332impl Struct {
281 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StructDef>) { 333 pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StructDef>) {
282 self.id.source(db) 334 self.id.source(db)
283 } 335 }
284 336
285 pub fn module(&self, db: &impl HirDatabase) -> Module { 337 pub fn module(self, db: &impl HirDatabase) -> Module {
286 self.id.module(db) 338 self.id.module(db)
287 } 339 }
288 340
289 pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { 341 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
290 db.struct_data(*self).name.clone() 342 db.struct_data(self).name.clone()
291 } 343 }
292 344
293 pub fn fields(&self, db: &impl HirDatabase) -> Vec<StructField> { 345 pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> {
294 db.struct_data(*self) 346 db.struct_data(self)
295 .variant_data 347 .variant_data
296 .fields() 348 .fields()
297 .into_iter() 349 .into_iter()
298 .flat_map(|it| it.iter()) 350 .flat_map(|it| it.iter())
299 .map(|(id, _)| StructField { parent: (*self).into(), id }) 351 .map(|(id, _)| StructField { parent: self.into(), id })
300 .collect() 352 .collect()
301 } 353 }
302 354
303 pub fn field(&self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { 355 pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> {
304 db.struct_data(*self) 356 db.struct_data(self)
305 .variant_data 357 .variant_data
306 .fields() 358 .fields()
307 .into_iter() 359 .into_iter()
308 .flat_map(|it| it.iter()) 360 .flat_map(|it| it.iter())
309 .find(|(_id, data)| data.name == *name) 361 .find(|(_id, data)| data.name == *name)
310 .map(|(id, _)| StructField { parent: (*self).into(), id }) 362 .map(|(id, _)| StructField { parent: self.into(), id })
311 } 363 }
312 364
313 pub fn ty(&self, db: &impl HirDatabase) -> Ty { 365 pub fn ty(self, db: &impl HirDatabase) -> Ty {
314 db.type_for_def((*self).into(), Namespace::Types) 366 db.type_for_def(self.into(), Namespace::Types)
315 } 367 }
316 368
317 pub fn constructor_ty(&self, db: &impl HirDatabase) -> Ty { 369 pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty {
318 db.type_for_def((*self).into(), Namespace::Values) 370 db.type_for_def(self.into(), Namespace::Values)
319 } 371 }
320 372
321 // FIXME move to a more general type 373 // FIXME move to a more general type
322 /// Builds a resolver for type references inside this struct. 374 /// Builds a resolver for type references inside this struct.
323 pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { 375 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
324 // take the outer scope... 376 // take the outer scope...
325 let r = self.module(db).resolver(db); 377 let r = self.module(db).resolver(db);
326 // ...and add generic params, if present 378 // ...and add generic params, if present
@@ -342,21 +394,21 @@ pub struct Union {
342} 394}
343 395
344impl Union { 396impl Union {
345 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StructDef>) { 397 pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::StructDef>) {
346 self.id.source(db) 398 self.id.source(db)
347 } 399 }
348 400
349 pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { 401 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
350 db.struct_data(Struct { id: self.id }).name.clone() 402 db.struct_data(Struct { id: self.id }).name.clone()
351 } 403 }
352 404
353 pub fn module(&self, db: &impl HirDatabase) -> Module { 405 pub fn module(self, db: &impl HirDatabase) -> Module {
354 self.id.module(db) 406 self.id.module(db)
355 } 407 }
356 408
357 // FIXME move to a more general type 409 // FIXME move to a more general type
358 /// Builds a resolver for type references inside this union. 410 /// Builds a resolver for type references inside this union.
359 pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { 411 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
360 // take the outer scope... 412 // take the outer scope...
361 let r = self.module(db).resolver(db); 413 let r = self.module(db).resolver(db);
362 // ...and add generic params, if present 414 // ...and add generic params, if present
@@ -378,41 +430,37 @@ pub struct Enum {
378} 430}
379 431
380impl Enum { 432impl Enum {
381 pub fn source(&self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) { 433 pub fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<ast::EnumDef>) {
382 self.id.source(db) 434 self.id.source(db)
383 } 435 }
384 436
385 pub fn module(&self, db: &impl HirDatabase) -> Module { 437 pub fn module(self, db: &impl HirDatabase) -> Module {
386 self.id.module(db) 438 self.id.module(db)
387 } 439 }
388 440
389 pub fn name(&self, db: &impl HirDatabase) -> Option<Name> { 441 pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
390 db.enum_data(*self).name.clone() 442 db.enum_data(self).name.clone()
391 } 443 }
392 444
393 pub fn variants(&self, db: &impl DefDatabase) -> Vec<EnumVariant> { 445 pub fn variants(self, db: &impl DefDatabase) -> Vec<EnumVariant> {
394 db.enum_data(*self) 446 db.enum_data(self).variants.iter().map(|(id, _)| EnumVariant { parent: self, id }).collect()
395 .variants
396 .iter()
397 .map(|(id, _)| EnumVariant { parent: *self, id })
398 .collect()
399 } 447 }
400 448
401 pub fn variant(&self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> { 449 pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option<EnumVariant> {
402 db.enum_data(*self) 450 db.enum_data(self)
403 .variants 451 .variants
404 .iter() 452 .iter()
405 .find(|(_id, data)| data.name.as_ref() == Some(name)) 453 .find(|(_id, data)| data.name.as_ref() == Some(name))
406 .map(|(id, _)| EnumVariant { parent: *self, id }) 454 .map(|(id, _)| EnumVariant { parent: self, id })
407 } 455 }
408 456
409 pub fn ty(&self, db: &impl HirDatabase) -> Ty { 457 pub fn ty(self, db: &impl HirDatabase) -> Ty {
410 db.type_for_def((*self).into(), Namespace::Types) 458 db.type_for_def(self.into(), Namespace::Types)
411 } 459 }
412 460
413 // FIXME: move to a more general type 461 // FIXME: move to a more general type
414 /// Builds a resolver for type references inside this struct. 462 /// Builds a resolver for type references inside this struct.
415 pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { 463 pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver {
416 // take the outer scope... 464 // take the outer scope...
417 let r = self.module(db).resolver(db); 465 let r = self.module(db).resolver(db);
418 // ...and add generic params, if present 466 // ...and add generic params, if present
diff --git a/crates/ra_hir/src/code_model_impl.rs b/crates/ra_hir/src/code_model_impl.rs
index 991533b5b..7bdd86eae 100644
--- a/crates/ra_hir/src/code_model_impl.rs
+++ b/crates/ra_hir/src/code_model_impl.rs
@@ -1,3 +1,2 @@
1mod konst; // `const` is invalid ident :( 1mod konst; // `const` is invalid ident :(
2mod module;
3pub(crate) mod function; 2pub(crate) mod function;
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
deleted file mode 100644
index 5c2ea73ce..000000000
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ /dev/null
@@ -1,99 +0,0 @@
1use ra_db::FileId;
2use ra_syntax::{ast, TreeArc};
3
4use crate::{
5 Module, ModuleSource, Name, AstId,
6 nameres::CrateModuleId,
7 HirDatabase, DefDatabase,
8 HirFileId,
9};
10
11impl ModuleSource {
12 pub(crate) fn new(
13 db: &impl DefDatabase,
14 file_id: Option<FileId>,
15 decl_id: Option<AstId<ast::Module>>,
16 ) -> ModuleSource {
17 match (file_id, decl_id) {
18 (Some(file_id), _) => {
19 let source_file = db.parse(file_id);
20 ModuleSource::SourceFile(source_file)
21 }
22 (None, Some(item_id)) => {
23 let module = item_id.to_node(db);
24 assert!(module.item_list().is_some(), "expected inline module");
25 ModuleSource::Module(module.to_owned())
26 }
27 (None, None) => panic!(),
28 }
29 }
30}
31
32impl Module {
33 fn with_module_id(&self, module_id: CrateModuleId) -> Module {
34 Module { module_id, krate: self.krate }
35 }
36
37 pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Option<Name> {
38 let def_map = db.crate_def_map(self.krate);
39 let parent = def_map[self.module_id].parent?;
40 def_map[parent].children.iter().find_map(|(name, module_id)| {
41 if *module_id == self.module_id {
42 Some(name.clone())
43 } else {
44 None
45 }
46 })
47 }
48
49 pub(crate) fn definition_source_impl(
50 &self,
51 db: &impl DefDatabase,
52 ) -> (HirFileId, ModuleSource) {
53 let def_map = db.crate_def_map(self.krate);
54 let decl_id = def_map[self.module_id].declaration;
55 let file_id = def_map[self.module_id].definition;
56 let module_source = ModuleSource::new(db, file_id, decl_id);
57 let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id());
58 (file_id, module_source)
59 }
60
61 pub(crate) fn declaration_source_impl(
62 &self,
63 db: &impl HirDatabase,
64 ) -> Option<(HirFileId, TreeArc<ast::Module>)> {
65 let def_map = db.crate_def_map(self.krate);
66 let decl = def_map[self.module_id].declaration?;
67 let ast = decl.to_node(db);
68 Some((decl.file_id(), ast))
69 }
70
71 pub(crate) fn crate_root_impl(&self, db: &impl DefDatabase) -> Module {
72 let def_map = db.crate_def_map(self.krate);
73 self.with_module_id(def_map.root())
74 }
75
76 /// Finds a child module with the specified name.
77 pub(crate) fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Option<Module> {
78 let def_map = db.crate_def_map(self.krate);
79 let child_id = def_map[self.module_id].children.get(name)?;
80 Some(self.with_module_id(*child_id))
81 }
82
83 /// Iterates over all child modules.
84 pub(crate) fn children_impl(&self, db: &impl DefDatabase) -> impl Iterator<Item = Module> {
85 let def_map = db.crate_def_map(self.krate);
86 let children = def_map[self.module_id]
87 .children
88 .iter()
89 .map(|(_, module_id)| self.with_module_id(*module_id))
90 .collect::<Vec<_>>();
91 children.into_iter()
92 }
93
94 pub(crate) fn parent_impl(&self, db: &impl DefDatabase) -> Option<Module> {
95 let def_map = db.crate_def_map(self.krate);
96 let parent_id = def_map[self.module_id].parent?;
97 Some(self.with_module_id(parent_id))
98 }
99}