diff options
-rw-r--r-- | crates/hir/src/semantics.rs | 26 | ||||
-rw-r--r-- | crates/ide/src/annotations.rs | 3 | ||||
-rw-r--r-- | crates/ide/src/runnables.rs | 3 | ||||
-rw-r--r-- | crates/ide_db/src/helpers.rs | 28 |
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 | ||
3 | mod source_to_def; | 3 | mod source_to_def; |
4 | 4 | ||
5 | use std::{cell::RefCell, collections::VecDeque, fmt, iter::successors}; | 5 | use std::{cell::RefCell, fmt, iter::successors}; |
6 | 6 | ||
7 | use base_db::{FileId, FileRange}; | 7 | use base_db::{FileId, FileRange}; |
8 | use either::Either; | ||
9 | use hir_def::{ | 8 | use 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; | |||
2 | use hir::{HasSource, Semantics}; | 2 | use hir::{HasSource, Semantics}; |
3 | use ide_db::{ | 3 | use 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 | }; |
7 | use syntax::{ast::NameOwner, AstNode, TextRange, TextSize}; | 8 | use 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; | |||
8 | use ide_db::{ | 8 | use 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 @@ | |||
2 | pub mod insert_use; | 2 | pub mod insert_use; |
3 | pub mod import_assets; | 3 | pub mod import_assets; |
4 | 4 | ||
5 | use std::collections::VecDeque; | ||
6 | |||
7 | use base_db::FileId; | ||
8 | use either::Either; | ||
5 | use hir::{Crate, Enum, ItemInNs, MacroDef, Module, ModuleDef, Name, ScopeDef, Semantics, Trait}; | 9 | use hir::{Crate, Enum, ItemInNs, MacroDef, Module, ModuleDef, Name, ScopeDef, Semantics, Trait}; |
6 | use syntax::ast::{self, make}; | 10 | use 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. | ||
47 | pub 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 |