From a1c96e04be55b3412e5510fc8d09cd82675dd4cd Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 14 Mar 2021 16:12:38 +0100 Subject: Introduce Semantics::visit_file_defs --- crates/hir/src/semantics.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'crates/hir/src') 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 @@ mod source_to_def; -use std::{cell::RefCell, fmt, iter::successors}; +use std::{cell::RefCell, collections::VecDeque, fmt, iter::successors}; use base_db::{FileId, FileRange}; +use either::Either; use hir_def::{ + nameres::ModuleSource, resolver::{self, HasResolver, Resolver, TypeNs}, AsMacroCall, FunctionId, TraitId, VariantId, }; @@ -155,6 +157,28 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.imp.ancestors_at_offset_with_macros(node, offset) } + /// Iterates all `ModuleDef`s and `Impl` blocks of the given file. + pub fn visit_file_defs(&self, file_id: FileId, cb: &mut dyn FnMut(Either)) { + let module = match self.to_module_def(file_id) { + Some(it) => it, + None => return, + }; + let mut defs: VecDeque<_> = module.declarations(self.db).into(); + while let Some(def) = defs.pop_front() { + if let ModuleDef::Module(submodule) = def { + if let ModuleSource::Module(_) = submodule.definition_source(self.db).value { + defs.extend(submodule.declarations(self.db)); + submodule + .impl_defs(self.db) + .into_iter() + .for_each(|impl_| cb(Either::Right(impl_))); + } + } + cb(Either::Left(def)); + } + module.impl_defs(self.db).into_iter().for_each(|impl_| cb(Either::Right(impl_))); + } + /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*, /// search up until it is of the target AstNode type pub fn find_node_at_offset_with_macros( -- cgit v1.2.3