diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 40 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl.rs | 51 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/module.rs | 25 |
4 files changed, 102 insertions, 28 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index eca7d0225..0c7f743d4 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -1,6 +1,7 @@ | |||
1 | use ra_db::{CrateId, Cancelable}; | 1 | use ra_db::{CrateId, Cancelable, FileId}; |
2 | use ra_syntax::{ast, SyntaxNode}; | ||
2 | 3 | ||
3 | use crate::{Name, db::HirDatabase, DefId, Path, PerNs, module::{ModuleSource, ModuleScope}}; | 4 | use crate::{Name, db::HirDatabase, DefId, Path, PerNs, module::{Problem, ModuleScope}}; |
4 | 5 | ||
5 | /// hir::Crate describes a single crate. It's the main inteface with which | 6 | /// hir::Crate describes a single crate. It's the main inteface with which |
6 | /// crate's dependencies interact. Mostly, it should be just a proxy for the | 7 | /// crate's dependencies interact. Mostly, it should be just a proxy for the |
@@ -33,10 +34,27 @@ pub struct Module { | |||
33 | pub(crate) def_id: DefId, | 34 | pub(crate) def_id: DefId, |
34 | } | 35 | } |
35 | 36 | ||
37 | /// An owned syntax node for a module. Unlike `ModuleSource`, | ||
38 | /// this holds onto the AST for the whole file. | ||
39 | pub enum ModuleSource { | ||
40 | SourceFile(ast::SourceFileNode), | ||
41 | Module(ast::ModuleNode), | ||
42 | } | ||
43 | |||
36 | impl Module { | 44 | impl Module { |
37 | // FIXME: what is a module source exactly? It should contain two nodes | 45 | pub fn name(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> { |
38 | pub fn source(&self, db: &impl HirDatabase) -> Cancelable<ModuleSource> { | 46 | self.name_impl(db) |
39 | Ok(self.source_impl(db)) | 47 | } |
48 | |||
49 | pub fn defenition_source(&self, db: &impl HirDatabase) -> Cancelable<(FileId, ModuleSource)> { | ||
50 | self.defenition_source_impl(db) | ||
51 | } | ||
52 | |||
53 | pub fn declaration_source( | ||
54 | &self, | ||
55 | db: &impl HirDatabase, | ||
56 | ) -> Cancelable<Option<(FileId, ast::ModuleNode)>> { | ||
57 | self.declaration_source_impl(db) | ||
40 | } | 58 | } |
41 | 59 | ||
42 | /// Returns the crate this module is part of. | 60 | /// Returns the crate this module is part of. |
@@ -56,6 +74,15 @@ impl Module { | |||
56 | pub fn parent(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { | 74 | pub fn parent(&self, db: &impl HirDatabase) -> Cancelable<Option<Module>> { |
57 | self.parent_impl(db) | 75 | self.parent_impl(db) |
58 | } | 76 | } |
77 | pub fn path_to_root(&self, db: &impl HirDatabase) -> Cancelable<Vec<Module>> { | ||
78 | let mut res = vec![self.clone()]; | ||
79 | let mut curr = self.clone(); | ||
80 | while let Some(next) = curr.parent(db)? { | ||
81 | res.push(next.clone()); | ||
82 | curr = next | ||
83 | } | ||
84 | Ok(res) | ||
85 | } | ||
59 | /// Returns a `ModuleScope`: a set of items, visible in this module. | 86 | /// Returns a `ModuleScope`: a set of items, visible in this module. |
60 | pub fn scope(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> { | 87 | pub fn scope(&self, db: &impl HirDatabase) -> Cancelable<ModuleScope> { |
61 | self.scope_impl(db) | 88 | self.scope_impl(db) |
@@ -63,4 +90,7 @@ impl Module { | |||
63 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> { | 90 | pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> { |
64 | self.resolve_path_impl(db, path) | 91 | self.resolve_path_impl(db, path) |
65 | } | 92 | } |
93 | pub fn problems(&self, db: &impl HirDatabase) -> Cancelable<Vec<(SyntaxNode, Problem)>> { | ||
94 | self.problems_impl(db) | ||
95 | } | ||
66 | } | 96 | } |
diff --git a/crates/ra_hir/src/code_model_impl.rs b/crates/ra_hir/src/code_model_impl.rs index 7f5669c8f..4f4b506dd 100644 --- a/crates/ra_hir/src/code_model_impl.rs +++ b/crates/ra_hir/src/code_model_impl.rs | |||
@@ -1,12 +1,13 @@ | |||
1 | use ra_db::{CrateId, Cancelable, SourceRootId}; | 1 | use ra_db::{CrateId, Cancelable, SourceRootId, FileId}; |
2 | use ra_syntax::{ast, SyntaxNode, AstNode}; | ||
2 | 3 | ||
3 | use crate::{ | 4 | use crate::{ |
4 | HirFileId, Crate, CrateDependency, AsName, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def, ModuleId, | 5 | HirFileId, Crate, CrateDependency, AsName, DefId, DefLoc, DefKind, Name, Path, PathKind, PerNs, Def, ModuleId, |
5 | module::{ModuleSource, ModuleScope}, | 6 | module::{ModuleScope, Problem}, |
6 | db::HirDatabase, | 7 | db::HirDatabase, |
7 | }; | 8 | }; |
8 | 9 | ||
9 | use crate::code_model_api::Module; | 10 | use crate::code_model_api::{Module, ModuleSource}; |
10 | 11 | ||
11 | impl Crate { | 12 | impl Crate { |
12 | pub(crate) fn new(crate_id: CrateId) -> Crate { | 13 | pub(crate) fn new(crate_id: CrateId) -> Crate { |
@@ -68,9 +69,44 @@ impl Module { | |||
68 | Ok(module) | 69 | Ok(module) |
69 | } | 70 | } |
70 | 71 | ||
71 | pub(crate) fn source_impl(&self, db: &impl HirDatabase) -> ModuleSource { | 72 | pub(crate) fn name_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Name>> { |
72 | let loc = self.def_id.loc(db); | 73 | let loc = self.def_id.loc(db); |
73 | ModuleSource(loc.source_item_id) | 74 | let module_tree = db.module_tree(loc.source_root_id)?; |
75 | let link = ctry!(loc.module_id.parent_link(&module_tree)); | ||
76 | Ok(Some(link.name(&module_tree).clone())) | ||
77 | } | ||
78 | |||
79 | pub fn defenition_source_impl( | ||
80 | &self, | ||
81 | db: &impl HirDatabase, | ||
82 | ) -> Cancelable<(FileId, ModuleSource)> { | ||
83 | let loc = self.def_id.loc(db); | ||
84 | let file_id = loc.source_item_id.file_id.as_original_file(); | ||
85 | let syntax_node = db.file_item(loc.source_item_id); | ||
86 | let syntax_node = syntax_node.borrowed(); | ||
87 | let module_source = if let Some(source_file) = ast::SourceFile::cast(syntax_node) { | ||
88 | ModuleSource::SourceFile(source_file.owned()) | ||
89 | } else { | ||
90 | let module = ast::Module::cast(syntax_node).unwrap(); | ||
91 | ModuleSource::Module(module.owned()) | ||
92 | }; | ||
93 | Ok((file_id, module_source)) | ||
94 | } | ||
95 | |||
96 | pub fn declaration_source_impl( | ||
97 | &self, | ||
98 | db: &impl HirDatabase, | ||
99 | ) -> Cancelable<Option<(FileId, ast::ModuleNode)>> { | ||
100 | let loc = self.def_id.loc(db); | ||
101 | let module_tree = db.module_tree(loc.source_root_id)?; | ||
102 | let link = ctry!(loc.module_id.parent_link(&module_tree)); | ||
103 | let file_id = link | ||
104 | .owner(&module_tree) | ||
105 | .source(&module_tree) | ||
106 | .file_id() | ||
107 | .as_original_file(); | ||
108 | let src = link.bind_source(&module_tree, db); | ||
109 | Ok(Some((file_id, src))) | ||
74 | } | 110 | } |
75 | 111 | ||
76 | pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> { | 112 | pub(crate) fn krate_impl(&self, db: &impl HirDatabase) -> Cancelable<Option<Crate>> { |
@@ -150,4 +186,9 @@ impl Module { | |||
150 | } | 186 | } |
151 | Ok(curr_per_ns) | 187 | Ok(curr_per_ns) |
152 | } | 188 | } |
189 | pub fn problems_impl(&self, db: &impl HirDatabase) -> Cancelable<Vec<(SyntaxNode, Problem)>> { | ||
190 | let loc = self.def_id.loc(db); | ||
191 | let module_tree = db.module_tree(loc.source_root_id)?; | ||
192 | Ok(loc.module_id.problems(&module_tree, db)) | ||
193 | } | ||
153 | } | 194 | } |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 891c93434..0d1b94c42 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -10,10 +10,10 @@ use crate::{ | |||
10 | Function, | 10 | Function, |
11 | db::HirDatabase, | 11 | db::HirDatabase, |
12 | type_ref::TypeRef, | 12 | type_ref::TypeRef, |
13 | module::{ModuleSourceNode, ModuleId}, | 13 | module::ModuleId, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | use crate::code_model_api::Module; | 16 | use crate::code_model_api::{Module, ModuleSource}; |
17 | 17 | ||
18 | #[derive(Debug, Clone, PartialEq, Eq)] | 18 | #[derive(Debug, Clone, PartialEq, Eq)] |
19 | pub struct ImplBlock { | 19 | pub struct ImplBlock { |
@@ -150,13 +150,13 @@ impl ModuleImplBlocks { | |||
150 | } | 150 | } |
151 | 151 | ||
152 | fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> { | 152 | fn collect(&mut self, db: &impl HirDatabase, module: Module) -> Cancelable<()> { |
153 | let module_source_node = module.source(db)?.resolve(db); | 153 | let (file_id, module_source) = module.defenition_source(db)?; |
154 | let node = match &module_source_node { | 154 | let node = match &module_source { |
155 | ModuleSourceNode::SourceFile(node) => node.borrowed().syntax(), | 155 | ModuleSource::SourceFile(node) => node.borrowed().syntax(), |
156 | ModuleSourceNode::Module(node) => node.borrowed().syntax(), | 156 | ModuleSource::Module(node) => node.borrowed().syntax(), |
157 | }; | 157 | }; |
158 | 158 | ||
159 | let source_file_items = db.file_items(module.source(db)?.file_id()); | 159 | let source_file_items = db.file_items(file_id.into()); |
160 | 160 | ||
161 | 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) { |
162 | 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); |
diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs index d1005eab6..ebaf5f47a 100644 --- a/crates/ra_hir/src/module.rs +++ b/crates/ra_hir/src/module.rs | |||
@@ -1,8 +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 log; | ||
5 | |||
6 | use ra_syntax::{ | 4 | use ra_syntax::{ |
7 | algo::generate, | 5 | algo::generate, |
8 | ast::{self, AstNode, NameOwner}, | 6 | ast::{self, AstNode, NameOwner}, |
@@ -11,10 +9,7 @@ use ra_syntax::{ | |||
11 | use ra_arena::{Arena, RawId, impl_arena_id}; | 9 | use ra_arena::{Arena, RawId, impl_arena_id}; |
12 | use relative_path::RelativePathBuf; | 10 | use relative_path::RelativePathBuf; |
13 | 11 | ||
14 | use crate::{ | 12 | use crate::{Name, HirDatabase, SourceItemId, SourceFileItemId, HirFileId}; |
15 | Name, HirDatabase, SourceItemId, SourceFileItemId, | ||
16 | HirFileId, | ||
17 | }; | ||
18 | 13 | ||
19 | pub use self::nameres::{ModuleScope, Resolution, Namespace, PerNs}; | 14 | pub use self::nameres::{ModuleScope, Resolution, Namespace, PerNs}; |
20 | 15 | ||
@@ -78,7 +73,7 @@ impl ModuleId { | |||
78 | pub(crate) fn source(self, tree: &ModuleTree) -> ModuleSource { | 73 | pub(crate) fn source(self, tree: &ModuleTree) -> ModuleSource { |
79 | tree.mods[self].source | 74 | tree.mods[self].source |
80 | } | 75 | } |
81 | fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> { | 76 | pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> { |
82 | tree.mods[self].parent | 77 | tree.mods[self].parent |
83 | } | 78 | } |
84 | pub(crate) fn parent(self, tree: &ModuleTree) -> Option<ModuleId> { | 79 | pub(crate) fn parent(self, tree: &ModuleTree) -> Option<ModuleId> { |
@@ -105,7 +100,11 @@ impl ModuleId { | |||
105 | Some((link.name.clone(), module)) | 100 | Some((link.name.clone(), module)) |
106 | }) | 101 | }) |
107 | } | 102 | } |
108 | fn problems(self, tree: &ModuleTree, db: &impl HirDatabase) -> Vec<(SyntaxNode, Problem)> { | 103 | pub(crate) fn problems( |
104 | self, | ||
105 | tree: &ModuleTree, | ||
106 | db: &impl HirDatabase, | ||
107 | ) -> Vec<(SyntaxNode, Problem)> { | ||
109 | tree.mods[self] | 108 | tree.mods[self] |
110 | .children | 109 | .children |
111 | .iter() | 110 | .iter() |
@@ -120,13 +119,17 @@ impl ModuleId { | |||
120 | } | 119 | } |
121 | 120 | ||
122 | impl LinkId { | 121 | impl LinkId { |
123 | fn owner(self, tree: &ModuleTree) -> ModuleId { | 122 | pub(crate) fn owner(self, tree: &ModuleTree) -> ModuleId { |
124 | tree.links[self].owner | 123 | tree.links[self].owner |
125 | } | 124 | } |
126 | fn name(self, tree: &ModuleTree) -> &Name { | 125 | pub(crate) fn name(self, tree: &ModuleTree) -> &Name { |
127 | &tree.links[self].name | 126 | &tree.links[self].name |
128 | } | 127 | } |
129 | fn bind_source<'a>(self, tree: &ModuleTree, db: &impl HirDatabase) -> ast::ModuleNode { | 128 | pub(crate) fn bind_source<'a>( |
129 | self, | ||
130 | tree: &ModuleTree, | ||
131 | db: &impl HirDatabase, | ||
132 | ) -> ast::ModuleNode { | ||
130 | let owner = self.owner(tree); | 133 | let owner = self.owner(tree); |
131 | match owner.source(tree).resolve(db) { | 134 | match owner.source(tree).resolve(db) { |
132 | ModuleSourceNode::SourceFile(root) => { | 135 | ModuleSourceNode::SourceFile(root) => { |