From b2c01f446edcbc12b5dd870064cbfc6c1a47eb8b Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 6 Dec 2019 21:46:18 +0100 Subject: Implement ancestors_with_macros in a better way --- crates/ra_hir/src/source_binder.rs | 13 +------------ 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( db: &impl HirDatabase, child: InFile<&SyntaxNode>, ) -> Option { - ancestors_with_macros(db, child).find_map(|node| { + child.cloned().ancestors_with_macros(db).find_map(|node| { let n = &node.value; match_ast! { match n { @@ -89,17 +89,6 @@ fn def_with_body_from_child_node( }) } -fn ancestors_with_macros<'a>( - db: &'a (impl HirDatabase), - node: InFile<&SyntaxNode>, -) -> impl Iterator> + 'a { - let file = node.with_value(()); // keep just the file id for borrow checker purposes - let parent_node = node.file_id.call_node(db); - let parent_ancestors: Box>> = - Box::new(parent_node.into_iter().flat_map(move |n| ancestors_with_macros(db, n.as_ref()))); - node.value.ancestors().map(move |n| file.with_value(n)).chain(parent_ancestors) -} - /// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of /// original source files. It should not be used inside the HIR itself. #[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 InFile { db.parse_or_expand(self.file_id).expect("source created from invalid file") } } + +impl InFile<&T> { + pub fn cloned(&self) -> InFile { + self.with_value(self.value.clone()) + } +} + +impl InFile { + pub fn ancestors_with_macros<'a>( + self, + db: &'a impl crate::db::AstDatabase, + ) -> impl Iterator> + 'a { + std::iter::successors(Some(self), move |node| match node.value.parent() { + Some(parent) => Some(node.with_value(parent)), + None => { + let parent_node = node.file_id.call_node(db)?; + Some(parent_node) + } + }) + } +} -- cgit v1.2.3