diff options
author | Florian Diebold <[email protected]> | 2019-12-06 20:46:18 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-12-06 20:53:31 +0000 |
commit | b2c01f446edcbc12b5dd870064cbfc6c1a47eb8b (patch) | |
tree | d21f398d8a0ef3898fda2ce044f0c3c402032cb8 | |
parent | c80dc0ad3aee717f9d15c11d300d0eb1c10f1cc8 (diff) |
Implement ancestors_with_macros in a better way
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/lib.rs | 21 |
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 | ||
92 | fn 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 | |||
305 | impl<T: Clone> InFile<&T> { | ||
306 | pub fn cloned(&self) -> InFile<T> { | ||
307 | self.with_value(self.value.clone()) | ||
308 | } | ||
309 | } | ||
310 | |||
311 | impl 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 | } | ||