aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_expand/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_expand/src/lib.rs')
-rw-r--r--crates/ra_hir_expand/src/lib.rs39
1 files changed, 39 insertions, 0 deletions
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index 59c69b91b..0a5da7e54 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -76,6 +76,17 @@ impl HirFileId {
76 } 76 }
77 } 77 }
78 78
79 /// If this is a macro call, returns the syntax node of the call.
80 pub fn call_node(self, db: &dyn db::AstDatabase) -> Option<InFile<SyntaxNode>> {
81 match self.0 {
82 HirFileIdRepr::FileId(_) => None,
83 HirFileIdRepr::MacroFile(macro_file) => {
84 let loc = db.lookup_intern_macro(macro_file.macro_call_id);
85 Some(loc.kind.node(db))
86 }
87 }
88 }
89
79 /// Return expansion information if it is a macro-expansion file 90 /// Return expansion information if it is a macro-expansion file
80 pub fn expansion_info(self, db: &dyn db::AstDatabase) -> Option<ExpansionInfo> { 91 pub fn expansion_info(self, db: &dyn db::AstDatabase) -> Option<ExpansionInfo> {
81 match self.0 { 92 match self.0 {
@@ -176,6 +187,13 @@ impl MacroCallKind {
176 } 187 }
177 } 188 }
178 189
190 pub fn node(&self, db: &dyn db::AstDatabase) -> InFile<SyntaxNode> {
191 match self {
192 MacroCallKind::FnLike(ast_id) => ast_id.with_value(ast_id.to_node(db).syntax().clone()),
193 MacroCallKind::Attr(ast_id) => ast_id.with_value(ast_id.to_node(db).syntax().clone()),
194 }
195 }
196
179 pub fn arg(&self, db: &dyn db::AstDatabase) -> Option<SyntaxNode> { 197 pub fn arg(&self, db: &dyn db::AstDatabase) -> Option<SyntaxNode> {
180 match self { 198 match self {
181 MacroCallKind::FnLike(ast_id) => { 199 MacroCallKind::FnLike(ast_id) => {
@@ -283,3 +301,24 @@ impl<T> InFile<T> {
283 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")
284 } 302 }
285} 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}