Skip to content

Commit ec61623

Browse files
committed
Move the SpanMap definition into the span crate
1 parent 66e29be commit ec61623

File tree

8 files changed

+74
-74
lines changed

8 files changed

+74
-74
lines changed

Cargo.lock

-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/base-db/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,5 @@ profile.workspace = true
2323
stdx.workspace = true
2424
syntax.workspace = true
2525
test-utils.workspace = true
26-
tt.workspace = true
2726
vfs.workspace = true
2827
span.workspace = true

crates/hir-expand/src/db.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,20 @@ pub fn span_map(db: &dyn ExpandDatabase, file_id: HirFileId) -> SpanMap {
170170
}
171171

172172
pub fn real_span_map(db: &dyn ExpandDatabase, file_id: FileId) -> Arc<RealSpanMap> {
173-
Arc::new(RealSpanMap::from_file(db, file_id))
173+
use syntax::ast::HasModuleItem;
174+
let mut pairs = vec![(syntax::TextSize::new(0), span::ROOT_ERASED_FILE_AST_ID)];
175+
let ast_id_map = db.ast_id_map(file_id.into());
176+
let tree = db.parse(file_id).tree();
177+
pairs.extend(
178+
tree.items()
179+
.map(|item| (item.syntax().text_range().start(), ast_id_map.ast_id(&item).erase())),
180+
);
181+
182+
Arc::new(RealSpanMap::from_file(
183+
file_id,
184+
pairs.into_boxed_slice(),
185+
tree.syntax().text_range().end(),
186+
))
174187
}
175188

176189
/// This expands the given macro call, but with different arguments. This is

crates/hir-expand/src/hygiene.rs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
//!
33
//! Specifically, `ast` + `Hygiene` allows you to create a `Name`. Note that, at
44
//! this moment, this is horribly incomplete and handles only `$crate`.
5+
6+
// FIXME: Consider moving this into the span crate.
7+
58
use std::iter;
69

710
use span::{MacroCallId, Span, SyntaxContextId};

crates/hir-expand/src/quote.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,8 @@ mod tests {
259259
assert_eq!(quoted.to_string(), "hello");
260260
let t = format!("{quoted:?}");
261261
expect![[r#"
262-
SUBTREE $$ Span { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) } Span { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) }
263-
IDENT hello Span { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) }"#]].assert_eq(&t);
262+
SUBTREE $$ SpanData { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) } SpanData { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) }
263+
IDENT hello SpanData { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) }"#]].assert_eq(&t);
264264
}
265265

266266
#[test]

crates/hir-expand/src/span_map.rs

+4-68
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
//! Spanmaps allow turning absolute ranges into relative ranges for incrementality purposes as well
2-
//! as associating spans with text ranges in a particular file.
3-
4-
// FIXME: Consider moving this into the span crate
5-
6-
use base_db::FileId;
7-
use span::{ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID};
8-
use syntax::{ast::HasModuleItem, AstNode, TextRange, TextSize};
1+
//! Span maps for real files and macro expansions.
2+
use span::Span;
3+
use syntax::TextRange;
94
use triomphe::Arc;
105

11-
use crate::db::ExpandDatabase;
6+
pub use span::RealSpanMap;
127

138
pub type ExpansionSpanMap = span::SpanMap<Span>;
149

@@ -39,11 +34,6 @@ impl mbe::SpanMapper<Span> for SpanMapRef<'_> {
3934
self.span_for_range(range)
4035
}
4136
}
42-
impl mbe::SpanMapper<Span> for RealSpanMap {
43-
fn span_for(&self, range: TextRange) -> Span {
44-
self.span_for_range(range)
45-
}
46-
}
4737

4838
impl SpanMap {
4939
pub fn span_for_range(&self, range: TextRange) -> Span {
@@ -69,57 +59,3 @@ impl SpanMapRef<'_> {
6959
}
7060
}
7161
}
72-
73-
#[derive(PartialEq, Eq, Hash, Debug)]
74-
pub struct RealSpanMap {
75-
file_id: FileId,
76-
/// Invariant: Sorted vec over TextSize
77-
// FIXME: SortedVec<(TextSize, ErasedFileAstId)>?
78-
pairs: Box<[(TextSize, ErasedFileAstId)]>,
79-
end: TextSize,
80-
}
81-
82-
impl RealSpanMap {
83-
/// Creates a real file span map that returns absolute ranges (relative ranges to the root ast id).
84-
pub fn absolute(file_id: FileId) -> Self {
85-
RealSpanMap {
86-
file_id,
87-
pairs: Box::from([(TextSize::new(0), ROOT_ERASED_FILE_AST_ID)]),
88-
end: TextSize::new(!0),
89-
}
90-
}
91-
92-
pub fn from_file(db: &dyn ExpandDatabase, file_id: FileId) -> Self {
93-
let mut pairs = vec![(TextSize::new(0), ROOT_ERASED_FILE_AST_ID)];
94-
let ast_id_map = db.ast_id_map(file_id.into());
95-
let tree = db.parse(file_id).tree();
96-
pairs
97-
.extend(tree.items().map(|item| {
98-
(item.syntax().text_range().start(), ast_id_map.ast_id(&item).erase())
99-
}));
100-
RealSpanMap {
101-
file_id,
102-
pairs: pairs.into_boxed_slice(),
103-
end: tree.syntax().text_range().end(),
104-
}
105-
}
106-
107-
pub fn span_for_range(&self, range: TextRange) -> Span {
108-
assert!(
109-
range.end() <= self.end,
110-
"range {range:?} goes beyond the end of the file {:?}",
111-
self.end
112-
);
113-
let start = range.start();
114-
let idx = self
115-
.pairs
116-
.binary_search_by(|&(it, _)| it.cmp(&start).then(std::cmp::Ordering::Less))
117-
.unwrap_err();
118-
let (offset, ast_id) = self.pairs[idx - 1];
119-
Span {
120-
range: range - offset,
121-
anchor: SpanAnchor { file_id: self.file_id, ast_id },
122-
ctx: SyntaxContextId::ROOT,
123-
}
124-
}
125-
}

crates/span/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use salsa::InternId;
88

99
mod map;
1010

11-
pub use crate::map::SpanMap;
11+
pub use crate::map::{RealSpanMap, SpanMap};
1212
pub use syntax::{TextRange, TextSize};
1313
pub use vfs::FileId;
1414

crates/span/src/map.rs

+50
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ use std::hash::Hash;
55

66
use stdx::{always, itertools::Itertools};
77
use syntax::{TextRange, TextSize};
8+
use vfs::FileId;
9+
10+
use crate::{ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID};
811

912
/// Maps absolute text ranges for the corresponding file to the relevant span data.
1013
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
@@ -79,3 +82,50 @@ impl<S: Copy> SpanMap<S> {
7982
self.spans.iter().copied()
8083
}
8184
}
85+
86+
#[derive(PartialEq, Eq, Hash, Debug)]
87+
pub struct RealSpanMap {
88+
file_id: FileId,
89+
/// Invariant: Sorted vec over TextSize
90+
// FIXME: SortedVec<(TextSize, ErasedFileAstId)>?
91+
pairs: Box<[(TextSize, ErasedFileAstId)]>,
92+
end: TextSize,
93+
}
94+
95+
impl RealSpanMap {
96+
/// Creates a real file span map that returns absolute ranges (relative ranges to the root ast id).
97+
pub fn absolute(file_id: FileId) -> Self {
98+
RealSpanMap {
99+
file_id,
100+
pairs: Box::from([(TextSize::new(0), ROOT_ERASED_FILE_AST_ID)]),
101+
end: TextSize::new(!0),
102+
}
103+
}
104+
105+
pub fn from_file(
106+
file_id: FileId,
107+
pairs: Box<[(TextSize, ErasedFileAstId)]>,
108+
end: TextSize,
109+
) -> Self {
110+
Self { file_id, pairs, end }
111+
}
112+
113+
pub fn span_for_range(&self, range: TextRange) -> Span {
114+
assert!(
115+
range.end() <= self.end,
116+
"range {range:?} goes beyond the end of the file {:?}",
117+
self.end
118+
);
119+
let start = range.start();
120+
let idx = self
121+
.pairs
122+
.binary_search_by(|&(it, _)| it.cmp(&start).then(std::cmp::Ordering::Less))
123+
.unwrap_err();
124+
let (offset, ast_id) = self.pairs[idx - 1];
125+
Span {
126+
range: range - offset,
127+
anchor: SpanAnchor { file_id: self.file_id, ast_id },
128+
ctx: SyntaxContextId::ROOT,
129+
}
130+
}
131+
}

0 commit comments

Comments
 (0)