aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/semantics.rs26
-rw-r--r--crates/ide/src/annotations.rs3
-rw-r--r--crates/ide/src/runnables.rs3
-rw-r--r--crates/ide_db/src/helpers.rs28
4 files changed, 33 insertions, 27 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 2a0a36de4..945638cc5 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -2,12 +2,10 @@
2 2
3mod source_to_def; 3mod source_to_def;
4 4
5use std::{cell::RefCell, collections::VecDeque, fmt, iter::successors}; 5use std::{cell::RefCell, fmt, iter::successors};
6 6
7use base_db::{FileId, FileRange}; 7use base_db::{FileId, FileRange};
8use either::Either;
9use hir_def::{ 8use hir_def::{
10 nameres::ModuleSource,
11 resolver::{self, HasResolver, Resolver, TypeNs}, 9 resolver::{self, HasResolver, Resolver, TypeNs},
12 AsMacroCall, FunctionId, TraitId, VariantId, 10 AsMacroCall, FunctionId, TraitId, VariantId,
13}; 11};
@@ -157,28 +155,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
157 self.imp.ancestors_at_offset_with_macros(node, offset) 155 self.imp.ancestors_at_offset_with_macros(node, offset)
158 } 156 }
159 157
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
182 /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*, 158 /// Find a AstNode by offset inside SyntaxNode, if it is inside *Macrofile*,
183 /// search up until it is of the target AstNode type 159 /// search up until it is of the target AstNode type
184 pub fn find_node_at_offset_with_macros<N: AstNode>( 160 pub fn find_node_at_offset_with_macros<N: AstNode>(
diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs
index c3422ce70..72492f826 100644
--- a/crates/ide/src/annotations.rs
+++ b/crates/ide/src/annotations.rs
@@ -2,6 +2,7 @@ use either::Either;
2use hir::{HasSource, Semantics}; 2use hir::{HasSource, Semantics};
3use ide_db::{ 3use ide_db::{
4 base_db::{FileId, FilePosition, FileRange}, 4 base_db::{FileId, FilePosition, FileRange},
5 helpers::visit_file_defs,
5 RootDatabase, 6 RootDatabase,
6}; 7};
7use syntax::{ast::NameOwner, AstNode, TextRange, TextSize}; 8use syntax::{ast::NameOwner, AstNode, TextRange, TextSize};
@@ -75,7 +76,7 @@ pub(crate) fn annotations(
75 } 76 }
76 } 77 }
77 78
78 Semantics::new(db).visit_file_defs(file_id, &mut |def| match def { 79 visit_file_defs(&Semantics::new(db), file_id, &mut |def| match def {
79 Either::Left(def) => { 80 Either::Left(def) => {
80 let node = match def { 81 let node = match def {
81 hir::ModuleDef::Const(konst) => { 82 hir::ModuleDef::Const(konst) => {
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 17454f270..0c7a8fbf8 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -8,6 +8,7 @@ use ide_assists::utils::test_related_attribute;
8use ide_db::{ 8use ide_db::{
9 base_db::{FilePosition, FileRange}, 9 base_db::{FilePosition, FileRange},
10 defs::Definition, 10 defs::Definition,
11 helpers::visit_file_defs,
11 search::SearchScope, 12 search::SearchScope,
12 RootDatabase, SymbolKind, 13 RootDatabase, SymbolKind,
13}; 14};
@@ -105,7 +106,7 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
105 let sema = Semantics::new(db); 106 let sema = Semantics::new(db);
106 107
107 let mut res = Vec::new(); 108 let mut res = Vec::new();
108 sema.visit_file_defs(file_id, &mut |def| match def { 109 visit_file_defs(&sema, file_id, &mut |def| match def {
109 Either::Left(def) => { 110 Either::Left(def) => {
110 let runnable = match def { 111 let runnable = match def {
111 hir::ModuleDef::Module(it) => runnable_mod(&sema, it), 112 hir::ModuleDef::Module(it) => runnable_mod(&sema, it),
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 @@
2pub mod insert_use; 2pub mod insert_use;
3pub mod import_assets; 3pub mod import_assets;
4 4
5use std::collections::VecDeque;
6
7use base_db::FileId;
8use either::Either;
5use hir::{Crate, Enum, ItemInNs, MacroDef, Module, ModuleDef, Name, ScopeDef, Semantics, Trait}; 9use hir::{Crate, Enum, ItemInNs, MacroDef, Module, ModuleDef, Name, ScopeDef, Semantics, Trait};
6use syntax::ast::{self, make}; 10use syntax::ast::{self, make};
7 11
@@ -39,6 +43,30 @@ pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path {
39 make::path_from_segments(segments, is_abs) 43 make::path_from_segments(segments, is_abs)
40} 44}
41 45
46/// Iterates all `ModuleDef`s and `Impl` blocks of the given file.
47pub fn visit_file_defs(
48 sema: &Semantics<RootDatabase>,
49 file_id: FileId,
50 cb: &mut dyn FnMut(Either<hir::ModuleDef, hir::Impl>),
51) {
52 let db = sema.db;
53 let module = match sema.to_module_def(file_id) {
54 Some(it) => it,
55 None => return,
56 };
57 let mut defs: VecDeque<_> = module.declarations(db).into();
58 while let Some(def) = defs.pop_front() {
59 if let ModuleDef::Module(submodule) = def {
60 if let hir::ModuleSource::Module(_) = submodule.definition_source(db).value {
61 defs.extend(submodule.declarations(db));
62 submodule.impl_defs(db).into_iter().for_each(|impl_| cb(Either::Right(impl_)));
63 }
64 }
65 cb(Either::Left(def));
66 }
67 module.impl_defs(db).into_iter().for_each(|impl_| cb(Either::Right(impl_)));
68}
69
42/// Helps with finding well-know things inside the standard library. This is 70/// Helps with finding well-know things inside the standard library. This is
43/// somewhat similar to the known paths infra inside hir, but it different; We 71/// somewhat similar to the known paths infra inside hir, but it different; We
44/// want to make sure that IDE specific paths don't become interesting inside 72/// want to make sure that IDE specific paths don't become interesting inside