aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/source_binder.rs13
-rw-r--r--crates/ra_hir_expand/src/lib.rs21
2 files changed, 22 insertions, 12 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index cb4345ca1..0e136b904 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -76,7 +76,7 @@ fn def_with_body_from_child_node(
76 db: &impl HirDatabase, 76 db: &impl HirDatabase,
77 child: InFile<&SyntaxNode>, 77 child: InFile<&SyntaxNode>,
78) -> Option<DefWithBody> { 78) -> Option<DefWithBody> {
79 ancestors_with_macros(db, child).find_map(|node| { 79 child.cloned().ancestors_with_macros(db).find_map(|node| {
80 let n = &node.value; 80 let n = &node.value;
81 match_ast! { 81 match_ast! {
82 match n { 82 match n {
@@ -89,17 +89,6 @@ fn def_with_body_from_child_node(
89 }) 89 })
90} 90}
91 91
92fn ancestors_with_macros<'a>(
93 db: &'a (impl HirDatabase),
94 node: InFile<&SyntaxNode>,
95) -> impl Iterator<Item = InFile<SyntaxNode>> + 'a {
96 let file = node.with_value(()); // keep just the file id for borrow checker purposes
97 let parent_node = node.file_id.call_node(db);
98 let parent_ancestors: Box<dyn Iterator<Item = InFile<SyntaxNode>>> =
99 Box::new(parent_node.into_iter().flat_map(move |n| ancestors_with_macros(db, n.as_ref())));
100 node.value.ancestors().map(move |n| file.with_value(n)).chain(parent_ancestors)
101}
102
103/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of 92/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
104/// original source files. It should not be used inside the HIR itself. 93/// original source files. It should not be used inside the HIR itself.
105#[derive(Debug)] 94#[derive(Debug)]
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index 0c1dc87e6..0a5da7e54 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -301,3 +301,24 @@ impl<T> InFile<T> {
301 db.parse_or_expand(self.file_id).expect("source created from invalid file") 301 db.parse_or_expand(self.file_id).expect("source created from invalid file")
302 } 302 }
303} 303}
304
305impl<T: Clone> InFile<&T> {
306 pub fn cloned(&self) -> InFile<T> {
307 self.with_value(self.value.clone())
308 }
309}
310
311impl InFile<SyntaxNode> {
312 pub fn ancestors_with_macros<'a>(
313 self,
314 db: &'a impl crate::db::AstDatabase,
315 ) -> impl Iterator<Item = InFile<SyntaxNode>> + 'a {
316 std::iter::successors(Some(self), move |node| match node.value.parent() {
317 Some(parent) => Some(node.with_value(parent)),
318 None => {
319 let parent_node = node.file_id.call_node(db)?;
320 Some(parent_node)
321 }
322 })
323 }
324}