move Semantics::visit_file_defs to ide_db::helpers

This commit is contained in:
Lukas Wirth 2021-03-15 12:18:52 +01:00
parent a1c96e04be
commit 41745f48d5
4 changed files with 33 additions and 27 deletions

View File

@ -2,12 +2,10 @@
mod source_to_def;
use std::{cell::RefCell, collections::VecDeque, fmt, iter::successors};
use std::{cell::RefCell, 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,
};
@ -157,28 +155,6 @@ 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<ModuleDef, Impl>)) {
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<N: AstNode>(

View File

@ -2,6 +2,7 @@ use either::Either;
use hir::{HasSource, Semantics};
use ide_db::{
base_db::{FileId, FilePosition, FileRange},
helpers::visit_file_defs,
RootDatabase,
};
use syntax::{ast::NameOwner, AstNode, TextRange, TextSize};
@ -75,7 +76,7 @@ pub(crate) fn annotations(
}
}
Semantics::new(db).visit_file_defs(file_id, &mut |def| match def {
visit_file_defs(&Semantics::new(db), file_id, &mut |def| match def {
Either::Left(def) => {
let node = match def {
hir::ModuleDef::Const(konst) => {

View File

@ -8,6 +8,7 @@ use ide_assists::utils::test_related_attribute;
use ide_db::{
base_db::{FilePosition, FileRange},
defs::Definition,
helpers::visit_file_defs,
search::SearchScope,
RootDatabase, SymbolKind,
};
@ -105,7 +106,7 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
let sema = Semantics::new(db);
let mut res = Vec::new();
sema.visit_file_defs(file_id, &mut |def| match def {
visit_file_defs(&sema, file_id, &mut |def| match def {
Either::Left(def) => {
let runnable = match def {
hir::ModuleDef::Module(it) => runnable_mod(&sema, it),

View File

@ -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<RootDatabase>,
file_id: FileId,
cb: &mut dyn FnMut(Either<hir::ModuleDef, hir::Impl>),
) {
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