Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-expand/src/files.rs')
-rw-r--r--crates/hir-expand/src/files.rs91
1 files changed, 76 insertions, 15 deletions
diff --git a/crates/hir-expand/src/files.rs b/crates/hir-expand/src/files.rs
index 743fac50f4..fc9fa93268 100644
--- a/crates/hir-expand/src/files.rs
+++ b/crates/hir-expand/src/files.rs
@@ -1,4 +1,6 @@
//! Things to wrap other things in file ids.
+use std::borrow::Borrow;
+
use either::Either;
use span::{
AstIdNode, ErasedFileAstId, FileAstId, FileId, FileRange, HirFileId, HirFileIdRepr,
@@ -76,6 +78,13 @@ impl<FileKind: Copy, T> InFileWrapper<FileKind, T> {
pub fn as_ref(&self) -> InFileWrapper<FileKind, &T> {
self.with_value(&self.value)
}
+
+ pub fn borrow<U>(&self) -> InFileWrapper<FileKind, &U>
+ where
+ T: Borrow<U>,
+ {
+ self.with_value(self.value.borrow())
+ }
}
impl<FileKind: Copy, T: Clone> InFileWrapper<FileKind, &T> {
@@ -156,14 +165,61 @@ impl<FileId: Copy, N: AstNode> InFileWrapper<FileId, &N> {
}
// region:specific impls
+impl<SN: Borrow<SyntaxNode>> InRealFile<SN> {
+ pub fn file_range(&self) -> FileRange {
+ FileRange { file_id: self.file_id, range: self.value.borrow().text_range() }
+ }
+}
+
+impl<SN: Borrow<SyntaxNode>> InFile<SN> {
+ pub fn parent_ancestors_with_macros(
+ self,
+ db: &dyn db::ExpandDatabase,
+ ) -> impl Iterator<Item = InFile<SyntaxNode>> + '_ {
+ let succ = move |node: &InFile<SyntaxNode>| match node.value.parent() {
+ Some(parent) => Some(node.with_value(parent)),
+ None => db
+ .lookup_intern_macro_call(node.file_id.macro_file()?.macro_call_id)
+ .to_node_item(db)
+ .syntax()
+ .cloned()
+ .map(|node| node.parent())
+ .transpose(),
+ };
+ std::iter::successors(succ(&self.borrow().cloned()), succ)
+ }
+
+ pub fn ancestors_with_macros(
+ self,
+ db: &dyn db::ExpandDatabase,
+ ) -> impl Iterator<Item = InFile<SyntaxNode>> + '_ {
+ let succ = move |node: &InFile<SyntaxNode>| match node.value.parent() {
+ Some(parent) => Some(node.with_value(parent)),
+ None => db
+ .lookup_intern_macro_call(node.file_id.macro_file()?.macro_call_id)
+ .to_node_item(db)
+ .syntax()
+ .cloned()
+ .map(|node| node.parent())
+ .transpose(),
+ };
+ std::iter::successors(Some(self.borrow().cloned()), succ)
+ }
+
+ pub fn kind(&self) -> parser::SyntaxKind {
+ self.value.borrow().kind()
+ }
+
+ pub fn text_range(&self) -> TextRange {
+ self.value.borrow().text_range()
+ }
-impl InFile<&SyntaxNode> {
/// Falls back to the macro call range if the node cannot be mapped up fully.
///
/// For attributes and derives, this will point back to the attribute only.
/// For the entire item use [`InFile::original_file_range_full`].
pub fn original_file_range_rooted(self, db: &dyn db::ExpandDatabase) -> FileRange {
- self.map(SyntaxNode::text_range).original_node_file_range_rooted(db)
+ self.borrow().map(SyntaxNode::text_range).original_node_file_range_rooted(db)
}
/// Falls back to the macro call range if the node cannot be mapped up fully.
@@ -171,15 +227,7 @@ impl InFile<&SyntaxNode> {
self,
db: &dyn db::ExpandDatabase,
) -> FileRange {
- self.map(SyntaxNode::text_range).original_node_file_range_with_macro_call_body(db)
- }
-
- /// Attempts to map the syntax node back up its macro calls.
- pub fn original_file_range_opt(
- self,
- db: &dyn db::ExpandDatabase,
- ) -> Option<(FileRange, SyntaxContextId)> {
- self.map(SyntaxNode::text_range).original_node_file_range_opt(db)
+ self.borrow().map(SyntaxNode::text_range).original_node_file_range_with_macro_call_body(db)
}
pub fn original_syntax_node_rooted(
@@ -190,16 +238,19 @@ impl InFile<&SyntaxNode> {
// as we don't have node inputs otherwise and therefore can't find an `N` node in the input
let file_id = match self.file_id.repr() {
HirFileIdRepr::FileId(file_id) => {
- return Some(InRealFile { file_id, value: self.value.clone() })
+ return Some(InRealFile { file_id, value: self.value.borrow().clone() })
}
HirFileIdRepr::MacroFile(m) if m.is_attr_macro(db) => m,
_ => return None,
};
- let FileRange { file_id, range } =
- map_node_range_up_rooted(db, &db.expansion_span_map(file_id), self.value.text_range())?;
+ let FileRange { file_id, range } = map_node_range_up_rooted(
+ db,
+ &db.expansion_span_map(file_id),
+ self.value.borrow().text_range(),
+ )?;
- let kind = self.value.kind();
+ let kind = self.kind();
let value = db
.parse(file_id)
.syntax_node()
@@ -211,6 +262,16 @@ impl InFile<&SyntaxNode> {
}
}
+impl InFile<&SyntaxNode> {
+ /// Attempts to map the syntax node back up its macro calls.
+ pub fn original_file_range_opt(
+ self,
+ db: &dyn db::ExpandDatabase,
+ ) -> Option<(FileRange, SyntaxContextId)> {
+ self.borrow().map(SyntaxNode::text_range).original_node_file_range_opt(db)
+ }
+}
+
impl InMacroFile<SyntaxToken> {
pub fn upmap_once(
self,