diff options
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl.rs | 74 | ||||
-rw-r--r-- | crates/ra_hir/src/ids.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/module.rs | 172 | ||||
-rw-r--r-- | crates/ra_hir/src/module/nameres.rs | 4 |
7 files changed, 66 insertions, 233 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 236cb3ab4..eca7d0225 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -1,7 +1,6 @@ | |||
1 | use ra_db::{CrateId, Cancelable, FileId}; | 1 | use ra_db::{CrateId, Cancelable}; |
2 | use ra_syntax::ast; | ||
3 | 2 | ||
4 | use crate::{Name, db::HirDatabase, DefId, Path, PerNs}; | 3 | use crate::{Name, db::HirDatabase, DefId, Path, PerNs, module::{ModuleSource, ModuleScope}}; |
5 | 4 | ||
6 | /// hir::Crate describes a single crate. It's the main inteface with which | 5 | /// hir::Crate describes a single crate. It's the main inteface with which |
7 | /// crate's dependencies interact. Mostly, it should be just a proxy for the | 6 | /// crate's dependencies interact. Mostly, it should be just a proxy for the |
@@ -35,7 +34,8 @@ pub struct Module { | |||
35 | } | 34 | } |
36 | 35 | ||
37 | impl Module { | 36 | impl Module { |
38 | pub fn source(&self, db: &impl HirDatabase) -> Cancelable<(FileId, Option<ast::ModuleNode>)> { | 37 | // FIXME: what is a module source exactly? It should contain two nodes |
38 | pub fn source(&self, db: &impl HirDatabase) -> Cancelable<ModuleSource> { | ||
39 | Ok(self.source_impl(db)) | 39 | Ok(self.source_impl(db)) |
40 | } | 40 | } |
41 | 41 | ||
@@ -56,7 +56,10 @@ impl Module { | |||
56 | pub fn parent(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { | 56 | pub fn parent(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { |
57 | self.parent_impl(db) | 57 | self.parent_impl(db) |
58 | } | 58 | } |
59 | 59 | /// Returns a `ModuleScope`: a set of items, visible in this module. | |
60 | pub fn scope(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> { | ||
61 | self.scope_impl(db) | ||
62 | } | ||
60 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> { | 63 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> { |
61 | self.resolve_path_impl(db, path) | 64 | self.resolve_path_impl(db, path) |
62 | } | 65 | } |
diff --git a/crates/ra_hir/src/code_model_impl.rs b/crates/ra_hir/src/code_model_impl.rs index 678758956..7f5669c8f 100644 --- a/crates/ra_hir/src/code_model_impl.rs +++ b/crates/ra_hir/src/code_model_impl.rs | |||
@@ -1,7 +1,10 @@ | |||
1 | use ra_db::{CrateId, Cancelable, FileId}; | 1 | use ra_db::{CrateId, Cancelable, SourceRootId}; |
2 | use ra_syntax::{AstNode, ast}; | ||
3 | 2 | ||
4 | use crate::{HirFileId, db::HirDatabase, Crate, CrateDependency, AsName, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def}; | 3 | use crate::{ |
4 | HirFileId, Crate, CrateDependency, AsName, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def, ModuleId, | ||
5 | module::{ModuleSource, ModuleScope}, | ||
6 | db::HirDatabase, | ||
7 | }; | ||
5 | 8 | ||
6 | use crate::code_model_api::Module; | 9 | use crate::code_model_api::Module; |
7 | 10 | ||
@@ -48,21 +51,26 @@ impl Module { | |||
48 | pub(crate) fn new(def_id: DefId) -> Self { | 51 | pub(crate) fn new(def_id: DefId) -> Self { |
49 | crate::code_model_api::Module { def_id } | 52 | crate::code_model_api::Module { def_id } |
50 | } | 53 | } |
54 | pub(crate) fn from_module_id( | ||
55 | db: &impl HirDatabase, | ||
56 | source_root_id: SourceRootId, | ||
57 | module_id: ModuleId, | ||
58 | ) -> Cancelable<Self> { | ||
59 | let module_tree = db.module_tree(source_root_id)?; | ||
60 | let def_loc = DefLoc { | ||
61 | kind: DefKind::Module, | ||
62 | source_root_id, | ||
63 | module_id, | ||
64 | source_item_id: module_id.source(&module_tree).0, | ||
65 | }; | ||
66 | let def_id = def_loc.id(db); | ||
67 | let module = Module::new(def_id); | ||
68 | Ok(module) | ||
69 | } | ||
51 | 70 | ||
52 | pub(crate) fn source_impl(&self, db: &impl HirDatabase) -> (FileId, Option<ast::ModuleNode>) { | 71 | pub(crate) fn source_impl(&self, db: &impl HirDatabase) -> ModuleSource { |
53 | let loc = self.def_id.loc(db); | 72 | let loc = self.def_id.loc(db); |
54 | let source_item_id = loc.source_item_id; | 73 | ModuleSource(loc.source_item_id) |
55 | let module = match source_item_id.item_id { | ||
56 | None => None, | ||
57 | Some(_) => { | ||
58 | let syntax_node = db.file_item(source_item_id); | ||
59 | let module = ast::Module::cast(syntax_node.borrowed()).unwrap().owned(); | ||
60 | Some(module) | ||
61 | } | ||
62 | }; | ||
63 | // FIXME: remove `as_original_file` here | ||
64 | let file_id = source_item_id.file_id.as_original_file(); | ||
65 | (file_id, module) | ||
66 | } | 74 | } |
67 | 75 | ||
68 | pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> { | 76 | pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> { |
@@ -79,41 +87,27 @@ impl Module { | |||
79 | let loc = self.def_id.loc(db); | 87 | let loc = self.def_id.loc(db); |
80 | let module_tree = db.module_tree(loc.source_root_id)?; | 88 | let module_tree = db.module_tree(loc.source_root_id)?; |
81 | let module_id = loc.module_id.crate_root(&module_tree); | 89 | let module_id = loc.module_id.crate_root(&module_tree); |
82 | let def_loc = DefLoc { | 90 | Module::from_module_id(db, loc.source_root_id, module_id) |
83 | module_id, | ||
84 | source_item_id: module_id.source(&module_tree).0, | ||
85 | ..loc | ||
86 | }; | ||
87 | let def_id = def_loc.id(db); | ||
88 | let module = Module::new(def_id); | ||
89 | Ok(module) | ||
90 | } | 91 | } |
91 | /// Finds a child module with the specified name. | 92 | /// Finds a child module with the specified name. |
92 | pub fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { | 93 | pub fn child_impl(&self, db: &impl HirDatabase, name: &Name) -> Cancelable<Option<Module>> { |
93 | let loc = self.def_id.loc(db); | 94 | let loc = self.def_id.loc(db); |
94 | let module_tree = db.module_tree(loc.source_root_id)?; | 95 | let module_tree = db.module_tree(loc.source_root_id)?; |
95 | let child_id = ctry!(loc.module_id.child(&module_tree, name)); | 96 | let child_id = ctry!(loc.module_id.child(&module_tree, name)); |
96 | let def_loc = DefLoc { | 97 | Module::from_module_id(db, loc.source_root_id, child_id).map(Some) |
97 | module_id: child_id, | ||
98 | source_item_id: child_id.source(&module_tree).0, | ||
99 | ..loc | ||
100 | }; | ||
101 | let def_id = def_loc.id(db); | ||
102 | let module = Module::new(def_id); | ||
103 | Ok(Some(module)) | ||
104 | } | 98 | } |
105 | pub fn parent_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { | 99 | pub fn parent_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { |
106 | let loc = self.def_id.loc(db); | 100 | let loc = self.def_id.loc(db); |
107 | let module_tree = db.module_tree(loc.source_root_id)?; | 101 | let module_tree = db.module_tree(loc.source_root_id)?; |
108 | let parent_id = ctry!(loc.module_id.parent(&module_tree)); | 102 | let parent_id = ctry!(loc.module_id.parent(&module_tree)); |
109 | let def_loc = DefLoc { | 103 | Module::from_module_id(db, loc.source_root_id, parent_id).map(Some) |
110 | module_id: parent_id, | 104 | } |
111 | source_item_id: parent_id.source(&module_tree).0, | 105 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
112 | ..loc | 106 | pub fn scope_impl(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> { |
113 | }; | 107 | let loc = self.def_id.loc(db); |
114 | let def_id = def_loc.id(db); | 108 | let item_map = db.item_map(loc.source_root_id)?; |
115 | let module = Module::new(def_id); | 109 | let res = item_map.per_module[&loc.module_id].clone(); |
116 | Ok(Some(module)) | 110 | Ok(res) |
117 | } | 111 | } |
118 | pub fn resolve_path_impl( | 112 | pub fn resolve_path_impl( |
119 | &self, | 113 | &self, |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index 4d6378e02..c7391ee05 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -2,7 +2,9 @@ use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId}; | |||
2 | use ra_syntax::{SourceFileNode, SyntaxKind, SyntaxNode, SyntaxNodeRef, SourceFile, AstNode, ast}; | 2 | use ra_syntax::{SourceFileNode, SyntaxKind, SyntaxNode, SyntaxNodeRef, SourceFile, AstNode, ast}; |
3 | use ra_arena::{Arena, RawId, impl_arena_id}; | 3 | use ra_arena::{Arena, RawId, impl_arena_id}; |
4 | 4 | ||
5 | use crate::{HirDatabase, PerNs, ModuleId, Module, Def, Function, Struct, Enum, ImplBlock, Crate}; | 5 | use crate::{HirDatabase, PerNs, ModuleId, Def, Function, Struct, Enum, ImplBlock, Crate}; |
6 | |||
7 | use crate::code_model_api::Module; | ||
6 | 8 | ||
7 | /// hir makes a heavy use of ids: integer (u32) handlers to various things. You | 9 | /// hir makes a heavy use of ids: integer (u32) handlers to various things. You |
8 | /// can think of id as a pointer (but without a lifetime) or a file descriptor | 10 | /// can think of id as a pointer (but without a lifetime) or a file descriptor |
@@ -151,7 +153,7 @@ impl DefId { | |||
151 | let loc = self.loc(db); | 153 | let loc = self.loc(db); |
152 | let res = match loc.kind { | 154 | let res = match loc.kind { |
153 | DefKind::Module => { | 155 | DefKind::Module => { |
154 | let module = Module::new(db, loc.source_root_id, loc.module_id)?; | 156 | let module = Module::from_module_id(db, loc.source_root_id, loc.module_id)?; |
155 | Def::Module(module) | 157 | Def::Module(module) |
156 | } | 158 | } |
157 | DefKind::Function => { | 159 | DefKind::Function => { |
@@ -175,12 +177,12 @@ impl DefId { | |||
175 | /// For a module, returns that module; for any other def, returns the containing module. | 177 | /// For a module, returns that module; for any other def, returns the containing module. |
176 | pub fn module(self, db: &impl HirDatabase) -> Cancelable<Module> { | 178 | pub fn module(self, db: &impl HirDatabase) -> Cancelable<Module> { |
177 | let loc = self.loc(db); | 179 | let loc = self.loc(db); |
178 | Module::new(db, loc.source_root_id, loc.module_id) | 180 | Module::from_module_id(db, loc.source_root_id, loc.module_id) |
179 | } | 181 | } |
180 | 182 | ||
181 | /// Returns the containing crate. | 183 | /// Returns the containing crate. |
182 | pub fn krate(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> { | 184 | pub fn krate(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> { |
183 | Ok(self.module(db)?.krate(db)) | 185 | Ok(self.module(db)?.krate(db)?) |
184 | } | 186 | } |
185 | 187 | ||
186 | /// Returns the containing impl block, if this is an impl item. | 188 | /// Returns the containing impl block, if this is an impl item. |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 01afa84c4..891c93434 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -7,12 +7,14 @@ use ra_db::{LocationIntener, Cancelable, SourceRootId}; | |||
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | DefId, DefLoc, DefKind, SourceItemId, SourceFileItems, | 9 | DefId, DefLoc, DefKind, SourceItemId, SourceFileItems, |
10 | Module, Function, | 10 | Function, |
11 | db::HirDatabase, | 11 | db::HirDatabase, |
12 | type_ref::TypeRef, | 12 | type_ref::TypeRef, |
13 | module::{ModuleSourceNode, ModuleId}, | 13 | module::{ModuleSourceNode, ModuleId}, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | use crate::code_model_api::Module; | ||
17 | |||
16 | #[derive(Debug, Clone, PartialEq, Eq)] | 18 | #[derive(Debug, Clone, PartialEq, Eq)] |
17 | pub struct ImplBlock { | 19 | pub struct ImplBlock { |
18 | module_impl_blocks: Arc<ModuleImplBlocks>, | 20 | module_impl_blocks: Arc<ModuleImplBlocks>, |
@@ -64,7 +66,7 @@ impl ImplData { | |||
64 | ) -> Self { | 66 | ) -> Self { |
65 | let target_trait = node.target_type().map(TypeRef::from_ast); | 67 | let target_trait = node.target_type().map(TypeRef::from_ast); |
66 | let target_type = TypeRef::from_ast_opt(node.target_type()); | 68 | let target_type = TypeRef::from_ast_opt(node.target_type()); |
67 | let file_id = module.source().file_id(); | 69 | let module_loc = module.def_id.loc(db); |
68 | let items = if let Some(item_list) = node.item_list() { | 70 | let items = if let Some(item_list) = node.item_list() { |
69 | item_list | 71 | item_list |
70 | .impl_items() | 72 | .impl_items() |
@@ -75,14 +77,14 @@ impl ImplData { | |||
75 | ast::ImplItem::TypeDef(..) => DefKind::Item, | 77 | ast::ImplItem::TypeDef(..) => DefKind::Item, |
76 | }; | 78 | }; |
77 | let item_id = file_items.id_of_unchecked(item_node.syntax()); | 79 | let item_id = file_items.id_of_unchecked(item_node.syntax()); |
80 | let source_item_id = SourceItemId { | ||
81 | file_id: module_loc.source_item_id.file_id, | ||
82 | item_id: Some(item_id), | ||
83 | }; | ||
78 | let def_loc = DefLoc { | 84 | let def_loc = DefLoc { |
79 | kind, | 85 | kind, |
80 | source_root_id: module.source_root_id, | 86 | source_item_id, |
81 | module_id: module.module_id, | 87 | ..module_loc |
82 | source_item_id: SourceItemId { | ||
83 | file_id, | ||
84 | item_id: Some(item_id), | ||
85 | }, | ||
86 | }; | 88 | }; |
87 | let def_id = def_loc.id(db); | 89 | let def_id = def_loc.id(db); |
88 | match item_node { | 90 | match item_node { |
@@ -148,13 +150,13 @@ impl ModuleImplBlocks { | |||
148 | } | 150 | } |
149 | 151 | ||
150 | fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> { | 152 | fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> { |
151 | let module_source_node = module.source().resolve(db); | 153 | let module_source_node = module.source(db)?.resolve(db); |
152 | let node = match &module_source_node { | 154 | let node = match &module_source_node { |
153 | ModuleSourceNode::SourceFile(node) => node.borrowed().syntax(), | 155 | ModuleSourceNode::SourceFile(node) => node.borrowed().syntax(), |
154 | ModuleSourceNode::Module(node) => node.borrowed().syntax(), | 156 | ModuleSourceNode::Module(node) => node.borrowed().syntax(), |
155 | }; | 157 | }; |
156 | 158 | ||
157 | let source_file_items = db.file_items(module.source().file_id()); | 159 | let source_file_items = db.file_items(module.source(db)?.file_id()); |
158 | 160 | ||
159 | for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { | 161 | for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { |
160 | let impl_block = ImplData::from_ast(db, &source_file_items, &module, impl_block_ast); | 162 | let impl_block = ImplData::from_ast(db, &source_file_items, &module, impl_block_ast); |
@@ -174,7 +176,7 @@ pub(crate) fn impls_in_module( | |||
174 | module_id: ModuleId, | 176 | module_id: ModuleId, |
175 | ) -> Cancelable<Arc<ModuleImplBlocks>> { | 177 | ) -> Cancelable<Arc<ModuleImplBlocks>> { |
176 | let mut result = ModuleImplBlocks::new(); | 178 | let mut result = ModuleImplBlocks::new(); |
177 | let module = Module::new(db, source_root_id, module_id)?; | 179 | let module = Module::from_module_id(db, source_root_id, module_id)?; |
178 | result.collect(db, module)?; | 180 | result.collect(db, module)?; |
179 | Ok(Arc::new(result)) | 181 | Ok(Arc::new(result)) |
180 | } | 182 | } |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 0fe80deb5..2fa357fec 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -56,6 +56,8 @@ pub use self::{ | |||
56 | 56 | ||
57 | pub use self::function::FnSignatureInfo; | 57 | pub use self::function::FnSignatureInfo; |
58 | 58 | ||
59 | pub use self::code_model_api::Module; | ||
60 | |||
59 | pub enum Def { | 61 | pub enum Def { |
60 | Module(Module), | 62 | Module(Module), |
61 | Function(Function), | 63 | Function(Function), |
diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs index 11e3f6782..d1005eab6 100644 --- a/crates/ra_hir/src/module.rs +++ b/crates/ra_hir/src/module.rs | |||
@@ -1,7 +1,6 @@ | |||
1 | pub(super) mod imp; | 1 | pub(super) mod imp; |
2 | pub(super) mod nameres; | 2 | pub(super) mod nameres; |
3 | 3 | ||
4 | use std::sync::Arc; | ||
5 | use log; | 4 | use log; |
6 | 5 | ||
7 | use ra_syntax::{ | 6 | use ra_syntax::{ |
@@ -10,184 +9,15 @@ use ra_syntax::{ | |||
10 | SyntaxNode, | 9 | SyntaxNode, |
11 | }; | 10 | }; |
12 | use ra_arena::{Arena, RawId, impl_arena_id}; | 11 | use ra_arena::{Arena, RawId, impl_arena_id}; |
13 | use ra_db::{SourceRootId, FileId, Cancelable}; | ||
14 | use relative_path::RelativePathBuf; | 12 | use relative_path::RelativePathBuf; |
15 | 13 | ||
16 | use crate::{ | 14 | use crate::{ |
17 | Def, DefKind, DefLoc, DefId, | 15 | Name, HirDatabase, SourceItemId, SourceFileItemId, |
18 | Name, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate, | ||
19 | HirFileId, | 16 | HirFileId, |
20 | }; | 17 | }; |
21 | 18 | ||
22 | pub use self::nameres::{ModuleScope, Resolution, Namespace, PerNs}; | 19 | pub use self::nameres::{ModuleScope, Resolution, Namespace, PerNs}; |
23 | 20 | ||
24 | /// `Module` is API entry point to get all the information | ||
25 | /// about a particular module. | ||
26 | #[derive(Debug, Clone)] | ||
27 | pub struct Module { | ||
28 | tree: Arc<ModuleTree>, | ||
29 | pub(crate) source_root_id: SourceRootId, | ||
30 | pub(crate) module_id: ModuleId, | ||
31 | } | ||
32 | |||
33 | impl Module { | ||
34 | pub(super) fn new( | ||
35 | db: &impl HirDatabase, | ||
36 | source_root_id: SourceRootId, | ||
37 | module_id: ModuleId, | ||
38 | ) -> Cancelable<Module> { | ||
39 | let module_tree = db.module_tree(source_root_id)?; | ||
40 | let res = Module { | ||
41 | tree: module_tree, | ||
42 | source_root_id, | ||
43 | module_id, | ||
44 | }; | ||
45 | Ok(res) | ||
46 | } | ||
47 | |||
48 | /// Returns `mod foo;` or `mod foo {}` node whihc declared this module. | ||
49 | /// Returns `None` for the root module | ||
50 | pub fn parent_link_source(&self, db: &impl HirDatabase) -> Option<(FileId, ast::ModuleNode)> { | ||
51 | let link = self.module_id.parent_link(&self.tree)?; | ||
52 | let file_id = link | ||
53 | .owner(&self.tree) | ||
54 | .source(&self.tree) | ||
55 | .file_id() | ||
56 | .as_original_file(); | ||
57 | let src = link.bind_source(&self.tree, db); | ||
58 | Some((file_id, src)) | ||
59 | } | ||
60 | |||
61 | pub fn file_id(&self) -> FileId { | ||
62 | self.source().file_id().as_original_file() | ||
63 | } | ||
64 | |||
65 | /// Parent module. Returns `None` if this is a root module. | ||
66 | pub fn parent(&self) -> Option<Module> { | ||
67 | let parent_id = self.module_id.parent(&self.tree)?; | ||
68 | Some(Module { | ||
69 | module_id: parent_id, | ||
70 | ..self.clone() | ||
71 | }) | ||
72 | } | ||
73 | |||
74 | /// Returns an iterator of all children of this module. | ||
75 | pub fn children<'a>(&'a self) -> impl Iterator<Item = (Name, Module)> + 'a { | ||
76 | self.module_id | ||
77 | .children(&self.tree) | ||
78 | .map(move |(name, module_id)| { | ||
79 | ( | ||
80 | name, | ||
81 | Module { | ||
82 | module_id, | ||
83 | ..self.clone() | ||
84 | }, | ||
85 | ) | ||
86 | }) | ||
87 | } | ||
88 | |||
89 | /// Returns the crate this module is part of. | ||
90 | pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { | ||
91 | let root_id = self.module_id.crate_root(&self.tree); | ||
92 | let file_id = root_id.source(&self.tree).file_id().as_original_file(); | ||
93 | let crate_graph = db.crate_graph(); | ||
94 | let crate_id = crate_graph.crate_id_for_crate_root(file_id)?; | ||
95 | Some(Crate::new(crate_id)) | ||
96 | } | ||
97 | |||
98 | /// Returns the all modules on the way to the root. | ||
99 | pub fn path_to_root(&self) -> Vec<Module> { | ||
100 | generate(Some(self.clone()), move |it| it.parent()).collect::<Vec<Module>>() | ||
101 | } | ||
102 | |||
103 | /// The root of the tree this module is part of | ||
104 | pub fn crate_root(&self) -> Module { | ||
105 | let root_id = self.module_id.crate_root(&self.tree); | ||
106 | Module { | ||
107 | module_id: root_id, | ||
108 | ..self.clone() | ||
109 | } | ||
110 | } | ||
111 | |||
112 | /// `name` is `None` for the crate's root module | ||
113 | pub fn name(&self) -> Option<&Name> { | ||
114 | let link = self.module_id.parent_link(&self.tree)?; | ||
115 | Some(link.name(&self.tree)) | ||
116 | } | ||
117 | |||
118 | pub fn def_id(&self, db: &impl HirDatabase) -> DefId { | ||
119 | let def_loc = DefLoc { | ||
120 | kind: DefKind::Module, | ||
121 | source_root_id: self.source_root_id, | ||
122 | module_id: self.module_id, | ||
123 | source_item_id: self.module_id.source(&self.tree).0, | ||
124 | }; | ||
125 | def_loc.id(db) | ||
126 | } | ||
127 | |||
128 | /// Finds a child module with the specified name. | ||
129 | pub fn child(&self, name: &Name) -> Option<Module> { | ||
130 | let child_id = self.module_id.child(&self.tree, name)?; | ||
131 | Some(Module { | ||
132 | module_id: child_id, | ||
133 | ..self.clone() | ||
134 | }) | ||
135 | } | ||
136 | |||
137 | /// Returns a `ModuleScope`: a set of items, visible in this module. | ||
138 | pub fn scope(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> { | ||
139 | let item_map = db.item_map(self.source_root_id)?; | ||
140 | let res = item_map.per_module[&self.module_id].clone(); | ||
141 | Ok(res) | ||
142 | } | ||
143 | |||
144 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> { | ||
145 | let mut curr_per_ns = PerNs::types( | ||
146 | match path.kind { | ||
147 | PathKind::Crate => self.crate_root(), | ||
148 | PathKind::Self_ | PathKind::Plain => self.clone(), | ||
149 | PathKind::Super => { | ||
150 | if let Some(p) = self.parent() { | ||
151 | p | ||
152 | } else { | ||
153 | return Ok(PerNs::none()); | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | .def_id(db), | ||
158 | ); | ||
159 | |||
160 | let segments = &path.segments; | ||
161 | for name in segments.iter() { | ||
162 | let curr = if let Some(r) = curr_per_ns.as_ref().take(Namespace::Types) { | ||
163 | r | ||
164 | } else { | ||
165 | return Ok(PerNs::none()); | ||
166 | }; | ||
167 | let module = match curr.resolve(db)? { | ||
168 | Def::Module(it) => it, | ||
169 | // TODO here would be the place to handle enum variants... | ||
170 | _ => return Ok(PerNs::none()), | ||
171 | }; | ||
172 | let scope = module.scope(db)?; | ||
173 | curr_per_ns = if let Some(r) = scope.get(&name) { | ||
174 | r.def_id | ||
175 | } else { | ||
176 | return Ok(PerNs::none()); | ||
177 | }; | ||
178 | } | ||
179 | Ok(curr_per_ns) | ||
180 | } | ||
181 | |||
182 | pub fn problems(&self, db: &impl HirDatabase) -> Vec<(SyntaxNode, Problem)> { | ||
183 | self.module_id.problems(&self.tree, db) | ||
184 | } | ||
185 | |||
186 | pub(crate) fn source(&self) -> ModuleSource { | ||
187 | self.module_id.source(&self.tree) | ||
188 | } | ||
189 | } | ||
190 | |||
191 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 21 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
192 | pub struct ModuleId(RawId); | 22 | pub struct ModuleId(RawId); |
193 | impl_arena_id!(ModuleId); | 23 | impl_arena_id!(ModuleId); |
diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs index dac524384..7d5e86c89 100644 --- a/crates/ra_hir/src/module/nameres.rs +++ b/crates/ra_hir/src/module/nameres.rs | |||
@@ -31,7 +31,7 @@ use crate::{ | |||
31 | Path, PathKind, | 31 | Path, PathKind, |
32 | HirDatabase, Crate, | 32 | HirDatabase, Crate, |
33 | Name, AsName, | 33 | Name, AsName, |
34 | module::{Module, ModuleId, ModuleTree}, | 34 | module::{ModuleId, ModuleTree}, |
35 | }; | 35 | }; |
36 | 36 | ||
37 | /// Item map is the result of the name resolution. Item map contains, for each | 37 | /// Item map is the result of the name resolution. Item map contains, for each |
@@ -466,7 +466,7 @@ where | |||
466 | if source_root_id == self.source_root { | 466 | if source_root_id == self.source_root { |
467 | target_module_id | 467 | target_module_id |
468 | } else { | 468 | } else { |
469 | let module = Module::new(self.db, source_root_id, target_module_id)?; | 469 | let module = crate::code_model_api::Module::new(type_def_id); |
470 | let path = Path { | 470 | let path = Path { |
471 | segments: import.path.segments[i + 1..].iter().cloned().collect(), | 471 | segments: import.path.segments[i + 1..].iter().cloned().collect(), |
472 | kind: PathKind::Crate, | 472 | kind: PathKind::Crate, |