From 41745f48d5f867ff0896ce7906b5b4c04e72a767 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 15 Mar 2021 12:18:52 +0100 Subject: move Semantics::visit_file_defs to ide_db::helpers --- crates/ide_db/src/helpers.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'crates/ide_db') diff --git a/crates/ide_db/src/helpers.rs b/crates/ide_db/src/helpers.rs index 3c95d3cff..9992a92bd 100644 --- a/crates/ide_db/src/helpers.rs +++ b/crates/ide_db/src/helpers.rs @@ -2,6 +2,10 @@ pub mod insert_use; pub mod import_assets; +use std::collections::VecDeque; + +use base_db::FileId; +use either::Either; use hir::{Crate, Enum, ItemInNs, MacroDef, Module, ModuleDef, Name, ScopeDef, Semantics, Trait}; use syntax::ast::{self, make}; @@ -39,6 +43,30 @@ pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path { make::path_from_segments(segments, is_abs) } +/// Iterates all `ModuleDef`s and `Impl` blocks of the given file. +pub fn visit_file_defs( + sema: &Semantics, + file_id: FileId, + cb: &mut dyn FnMut(Either), +) { + let db = sema.db; + let module = match sema.to_module_def(file_id) { + Some(it) => it, + None => return, + }; + let mut defs: VecDeque<_> = module.declarations(db).into(); + while let Some(def) = defs.pop_front() { + if let ModuleDef::Module(submodule) = def { + if let hir::ModuleSource::Module(_) = submodule.definition_source(db).value { + defs.extend(submodule.declarations(db)); + submodule.impl_defs(db).into_iter().for_each(|impl_| cb(Either::Right(impl_))); + } + } + cb(Either::Left(def)); + } + module.impl_defs(db).into_iter().for_each(|impl_| cb(Either::Right(impl_))); +} + /// Helps with finding well-know things inside the standard library. This is /// somewhat similar to the known paths infra inside hir, but it different; We /// want to make sure that IDE specific paths don't become interesting inside -- cgit v1.2.3