mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
internal: Remove unnecessary usages of ExpansionInfo
This commit is contained in:
parent
604479c373
commit
d252247ab7
7 changed files with 175 additions and 106 deletions
|
@ -80,6 +80,9 @@ pub trait ExpandDatabase: SourceDatabase {
|
|||
#[salsa::invoke(SpanMap::new)]
|
||||
fn span_map(&self, file_id: HirFileId) -> SpanMap;
|
||||
|
||||
#[salsa::transparent]
|
||||
#[salsa::invoke(crate::span_map::expansion_span_map)]
|
||||
fn expansion_span_map(&self, file_id: MacroFileId) -> Arc<ExpansionSpanMap>;
|
||||
#[salsa::invoke(crate::span_map::real_span_map)]
|
||||
fn real_span_map(&self, file_id: FileId) -> Arc<RealSpanMap>;
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use either::Either;
|
|||
use span::{FileId, FileRange, HirFileId, HirFileIdRepr, MacroFileId, SyntaxContextId};
|
||||
use syntax::{AstNode, SyntaxNode, SyntaxToken, TextRange, TextSize};
|
||||
|
||||
use crate::{db, ExpansionInfo, MacroFileIdExt};
|
||||
use crate::{db, map_node_range_up, span_for_offset, MacroFileIdExt};
|
||||
|
||||
/// `InFile<T>` stores a value of `T` inside a particular file/syntax tree.
|
||||
///
|
||||
|
@ -147,7 +147,7 @@ impl InFile<&SyntaxNode> {
|
|||
HirFileIdRepr::FileId(file_id) => FileRange { file_id, range: self.value.text_range() },
|
||||
HirFileIdRepr::MacroFile(mac_file) => {
|
||||
if let Some((res, ctxt)) =
|
||||
ExpansionInfo::new(db, mac_file).map_node_range_up(db, self.value.text_range())
|
||||
map_node_range_up(db, &db.expansion_span_map(mac_file), self.value.text_range())
|
||||
{
|
||||
// FIXME: Figure out an API that makes proper use of ctx, this only exists to
|
||||
// keep pre-token map rewrite behaviour.
|
||||
|
@ -163,12 +163,15 @@ impl InFile<&SyntaxNode> {
|
|||
}
|
||||
|
||||
/// Falls back to the macro call range if the node cannot be mapped up fully.
|
||||
pub fn original_file_range_full(self, db: &dyn db::ExpandDatabase) -> FileRange {
|
||||
pub fn original_file_range_with_macro_call_body(
|
||||
self,
|
||||
db: &dyn db::ExpandDatabase,
|
||||
) -> FileRange {
|
||||
match self.file_id.repr() {
|
||||
HirFileIdRepr::FileId(file_id) => FileRange { file_id, range: self.value.text_range() },
|
||||
HirFileIdRepr::MacroFile(mac_file) => {
|
||||
if let Some((res, ctxt)) =
|
||||
ExpansionInfo::new(db, mac_file).map_node_range_up(db, self.value.text_range())
|
||||
map_node_range_up(db, &db.expansion_span_map(mac_file), self.value.text_range())
|
||||
{
|
||||
// FIXME: Figure out an API that makes proper use of ctx, this only exists to
|
||||
// keep pre-token map rewrite behaviour.
|
||||
|
@ -193,7 +196,7 @@ impl InFile<&SyntaxNode> {
|
|||
Some((FileRange { file_id, range: self.value.text_range() }, SyntaxContextId::ROOT))
|
||||
}
|
||||
HirFileIdRepr::MacroFile(mac_file) => {
|
||||
ExpansionInfo::new(db, mac_file).map_node_range_up(db, self.value.text_range())
|
||||
map_node_range_up(db, &db.expansion_span_map(mac_file), self.value.text_range())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -215,7 +218,7 @@ impl InFile<&SyntaxNode> {
|
|||
}
|
||||
|
||||
let (FileRange { file_id, range }, ctx) =
|
||||
ExpansionInfo::new(db, file_id).map_node_range_up(db, self.value.text_range())?;
|
||||
map_node_range_up(db, &db.expansion_span_map(file_id), self.value.text_range())?;
|
||||
|
||||
// FIXME: Figure out an API that makes proper use of ctx, this only exists to
|
||||
// keep pre-token map rewrite behaviour.
|
||||
|
@ -246,8 +249,11 @@ impl InFile<SyntaxToken> {
|
|||
match self.file_id.repr() {
|
||||
HirFileIdRepr::FileId(file_id) => FileRange { file_id, range: self.value.text_range() },
|
||||
HirFileIdRepr::MacroFile(mac_file) => {
|
||||
let (range, ctxt) = ExpansionInfo::new(db, mac_file)
|
||||
.span_for_offset(db, self.value.text_range().start());
|
||||
let (range, ctxt) = span_for_offset(
|
||||
db,
|
||||
&db.expansion_span_map(mac_file),
|
||||
self.value.text_range().start(),
|
||||
);
|
||||
|
||||
// FIXME: Figure out an API that makes proper use of ctx, this only exists to
|
||||
// keep pre-token map rewrite behaviour.
|
||||
|
@ -269,8 +275,11 @@ impl InFile<SyntaxToken> {
|
|||
Some(FileRange { file_id, range: self.value.text_range() })
|
||||
}
|
||||
HirFileIdRepr::MacroFile(mac_file) => {
|
||||
let (range, ctxt) = ExpansionInfo::new(db, mac_file)
|
||||
.span_for_offset(db, self.value.text_range().start());
|
||||
let (range, ctxt) = span_for_offset(
|
||||
db,
|
||||
&db.expansion_span_map(mac_file),
|
||||
self.value.text_range().start(),
|
||||
);
|
||||
|
||||
// FIXME: Figure out an API that makes proper use of ctx, this only exists to
|
||||
// keep pre-token map rewrite behaviour.
|
||||
|
@ -286,7 +295,7 @@ impl InFile<SyntaxToken> {
|
|||
|
||||
impl InMacroFile<TextSize> {
|
||||
pub fn original_file_range(self, db: &dyn db::ExpandDatabase) -> (FileRange, SyntaxContextId) {
|
||||
ExpansionInfo::new(db, self.file_id).span_for_offset(db, self.value)
|
||||
span_for_offset(db, &db.expansion_span_map(self.file_id), self.value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,7 +309,7 @@ impl InFile<TextRange> {
|
|||
(FileRange { file_id, range: self.value }, SyntaxContextId::ROOT)
|
||||
}
|
||||
HirFileIdRepr::MacroFile(mac_file) => {
|
||||
match ExpansionInfo::new(db, mac_file).map_node_range_up(db, self.value) {
|
||||
match map_node_range_up(db, &db.expansion_span_map(mac_file), self.value) {
|
||||
Some(it) => it,
|
||||
None => {
|
||||
let loc = db.lookup_intern_macro_call(mac_file.macro_call_id);
|
||||
|
@ -315,7 +324,7 @@ impl InFile<TextRange> {
|
|||
match self.file_id.repr() {
|
||||
HirFileIdRepr::FileId(file_id) => FileRange { file_id, range: self.value },
|
||||
HirFileIdRepr::MacroFile(mac_file) => {
|
||||
match ExpansionInfo::new(db, mac_file).map_node_range_up(db, self.value) {
|
||||
match map_node_range_up(db, &db.expansion_span_map(mac_file), self.value) {
|
||||
Some((it, SyntaxContextId::ROOT)) => it,
|
||||
_ => {
|
||||
let loc = db.lookup_intern_macro_call(mac_file.macro_call_id);
|
||||
|
@ -335,7 +344,7 @@ impl InFile<TextRange> {
|
|||
Some((FileRange { file_id, range: self.value }, SyntaxContextId::ROOT))
|
||||
}
|
||||
HirFileIdRepr::MacroFile(mac_file) => {
|
||||
ExpansionInfo::new(db, mac_file).map_node_range_up(db, self.value)
|
||||
map_node_range_up(db, &db.expansion_span_map(mac_file), self.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -355,8 +364,11 @@ impl<N: AstNode> InFile<N> {
|
|||
return None;
|
||||
}
|
||||
|
||||
let (FileRange { file_id, range }, ctx) = ExpansionInfo::new(db, file_id)
|
||||
.map_node_range_up(db, self.value.syntax().text_range())?;
|
||||
let (FileRange { file_id, range }, ctx) = map_node_range_up(
|
||||
db,
|
||||
&db.expansion_span_map(file_id),
|
||||
self.value.syntax().text_range(),
|
||||
)?;
|
||||
|
||||
// FIXME: Figure out an API that makes proper use of ctx, this only exists to
|
||||
// keep pre-token map rewrite behaviour.
|
||||
|
|
|
@ -677,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,
|
||||
|
@ -697,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.
|
||||
|
@ -713,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.
|
||||
|
@ -822,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.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//! Span maps for real files and macro expansions.
|
||||
use span::{FileId, HirFileId, HirFileIdRepr, Span};
|
||||
use span::{FileId, HirFileId, HirFileIdRepr, MacroFileId, Span};
|
||||
use syntax::{AstNode, TextRange};
|
||||
use triomphe::Arc;
|
||||
|
||||
|
@ -94,3 +94,10 @@ pub(crate) fn real_span_map(db: &dyn ExpandDatabase, file_id: FileId) -> Arc<Rea
|
|||
tree.syntax().text_range().end(),
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn expansion_span_map(
|
||||
db: &dyn ExpandDatabase,
|
||||
file_id: MacroFileId,
|
||||
) -> Arc<ExpansionSpanMap> {
|
||||
db.parse_macro_expansion(file_id).value.1
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue