Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-expand/src/lib.rs')
-rw-r--r--crates/hir-expand/src/lib.rs93
1 files changed, 65 insertions, 28 deletions
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index 05f12527a4..bd25052490 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -523,6 +523,24 @@ impl MacroCallLoc {
}
}
}
+
+ pub fn include_file_id(
+ &self,
+ db: &dyn ExpandDatabase,
+ macro_call_id: MacroCallId,
+ ) -> Option<FileId> {
+ if self.def.is_include() {
+ if let Some(eager) = &self.eager {
+ if let Ok(it) =
+ builtin_fn_macro::include_input_to_file_id(db, macro_call_id, &eager.arg)
+ {
+ return Some(it);
+ }
+ }
+ }
+
+ None
+ }
}
impl MacroCallKind {
@@ -659,6 +677,10 @@ impl ExpansionInfo {
Some(self.arg.with_value(self.arg.value.as_ref()?.parent()?))
}
+ pub fn call_file(&self) -> HirFileId {
+ self.arg.file_id
+ }
+
/// Maps the passed in file range down into a macro expansion if it is the input to a macro call.
pub fn map_range_down(
&self,
@@ -679,13 +701,7 @@ impl ExpansionInfo {
offset: TextSize,
) -> (FileRange, SyntaxContextId) {
debug_assert!(self.expanded.value.text_range().contains(offset));
- let span = self.exp_map.span_at(offset);
- let anchor_offset = db
- .ast_id_map(span.anchor.file_id.into())
- .get_erased(span.anchor.ast_id)
- .text_range()
- .start();
- (FileRange { file_id: span.anchor.file_id, range: span.range + anchor_offset }, span.ctx)
+ span_for_offset(db, &self.exp_map, offset)
}
/// Maps up the text range out of the expansion hierarchy back into the original file its from.
@@ -695,27 +711,7 @@ impl ExpansionInfo {
range: TextRange,
) -> Option<(FileRange, SyntaxContextId)> {
debug_assert!(self.expanded.value.text_range().contains_range(range));
- let mut spans = self.exp_map.spans_for_range(range);
- let Span { range, anchor, ctx } = spans.next()?;
- let mut start = range.start();
- let mut end = range.end();
-
- for span in spans {
- if span.anchor != anchor || span.ctx != ctx {
- return None;
- }
- start = start.min(span.range.start());
- end = end.max(span.range.end());
- }
- let anchor_offset =
- db.ast_id_map(anchor.file_id.into()).get_erased(anchor.ast_id).text_range().start();
- Some((
- FileRange {
- file_id: anchor.file_id,
- range: TextRange::new(start, end) + anchor_offset,
- },
- ctx,
- ))
+ map_node_range_up(db, &self.exp_map, range)
}
/// Maps up the text range out of the expansion into is macro call.
@@ -804,6 +800,47 @@ impl ExpansionInfo {
}
}
+/// Maps up the text range out of the expansion hierarchy back into the original file its from.
+pub fn map_node_range_up(
+ db: &dyn ExpandDatabase,
+ exp_map: &ExpansionSpanMap,
+ range: TextRange,
+) -> Option<(FileRange, SyntaxContextId)> {
+ let mut spans = exp_map.spans_for_range(range);
+ let Span { range, anchor, ctx } = spans.next()?;
+ let mut start = range.start();
+ let mut end = range.end();
+
+ for span in spans {
+ if span.anchor != anchor || span.ctx != ctx {
+ return None;
+ }
+ start = start.min(span.range.start());
+ end = end.max(span.range.end());
+ }
+ let anchor_offset =
+ db.ast_id_map(anchor.file_id.into()).get_erased(anchor.ast_id).text_range().start();
+ Some((
+ FileRange { file_id: anchor.file_id, range: TextRange::new(start, end) + anchor_offset },
+ ctx,
+ ))
+}
+
+/// Looks up the span at the given offset.
+pub fn span_for_offset(
+ db: &dyn ExpandDatabase,
+ exp_map: &ExpansionSpanMap,
+ offset: TextSize,
+) -> (FileRange, SyntaxContextId) {
+ let span = exp_map.span_at(offset);
+ let anchor_offset = db
+ .ast_id_map(span.anchor.file_id.into())
+ .get_erased(span.anchor.ast_id)
+ .text_range()
+ .start();
+ (FileRange { file_id: span.anchor.file_id, range: span.range + anchor_offset }, span.ctx)
+}
+
/// In Rust, macros expand token trees to token trees. When we want to turn a
/// token tree into an AST node, we need to figure out what kind of AST node we
/// want: something like `foo` can be a type, an expression, or a pattern.