diff options
Diffstat (limited to 'crates/hir/src')
-rw-r--r-- | crates/hir/src/semantics.rs | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 945638cc5..2a0a36de4 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -2,10 +2,12 @@ | |||
2 | 2 | ||
3 | mod source_to_def; | 3 | mod source_to_def; |
4 | 4 | ||
5 | use std::{cell::RefCell, fmt, iter::successors}; | 5 | use std::{cell::RefCell, collections::VecDeque, fmt, iter::successors}; |
6 | 6 | ||
7 | use base_db::{FileId, FileRange}; | 7 | use base_db::{FileId, FileRange}; |
8 | use either::Either; | ||
8 | use hir_def::{ | 9 | use hir_def::{ |
10 | nameres::ModuleSource, | ||
9 | resolver::{self, HasResolver, Resolver, TypeNs}, | 11 | resolver::{self, HasResolver, Resolver, TypeNs}, |
10 | AsMacroCall, FunctionId, TraitId, VariantId, | 12 | AsMacroCall, FunctionId, TraitId, VariantId, |
11 | }; | 13 | }; |
@@ -155,6 +157,28 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
155 | self.imp.ancestors_at_offset_with_macros(node, offset) | 157 | self.imp.ancestors_at_offset_with_macros(node, offset) |
156 | } | 158 | } |
157 | 159 | ||
160 | /// Iterates all `ModuleDef`s and `Impl` blocks of the given file. | ||
161 | pub fn visit_file_defs(&self, file_id: FileId, cb: &mut dyn FnMut(Either<ModuleDef, Impl>)) { | ||
162 | let module = match self.to_module_def(file_id) { | ||
163 | Some(it) => it, | ||
164 | None => return, | ||
165 | }; | ||
166 | let mut defs: VecDeque<_> = module.declarations(self.db).into(); | ||
167 | while let Some(def) = defs.pop_front() { | ||
168 | if let ModuleDef::Module(submodule) = def { | ||
169 | if let ModuleSource::Module(_) = submodule.definition_source(self.db).value { | ||
170 | defs.extend(submodule.declarations(self.db)); | ||
171 | submodule | ||
172 | .impl_defs(self.db) | ||
173 | .into_iter() | ||
174 | .for_each(|impl_| cb(Either::Right(impl_))); | ||
175 | } | ||
176 | } | ||
177 | cb(Either::Left(def)); | ||
178 | } | ||
179 | module.impl_defs(self.db).into_iter().for_each(|impl_| cb(Either::Right(impl_))); | ||
180 | } | ||
181 | |||
158 | /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*, | 182 | /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*, |
159 | /// search up until it is of the target AstNode type | 183 | /// search up until it is of the target AstNode type |
160 | pub fn find_node_at_offset_with_macros<N: AstNode>( | 184 | pub fn find_node_at_offset_with_macros<N: AstNode>( |