Skip to content

Commit 8736afa

Browse files
committed
Re-implement InFile wrappers as type aliases over generic InFileWrapper
1 parent f3403ef commit 8736afa

File tree

13 files changed

+146
-102
lines changed

13 files changed

+146
-102
lines changed

crates/base-db/src/span.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ impl fmt::Debug for HirFileId {
102102
}
103103

104104
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
105-
pub struct MacroFile {
105+
pub struct MacroFileId {
106106
pub macro_call_id: MacroCallId,
107107
}
108108
/// `MacroCallId` identifies a particular macro invocation, like
@@ -113,18 +113,18 @@ crate::impl_intern_key!(MacroCallId);
113113

114114
impl MacroCallId {
115115
pub fn as_file(self) -> HirFileId {
116-
MacroFile { macro_call_id: self }.into()
116+
MacroFileId { macro_call_id: self }.into()
117117
}
118118

119-
pub fn as_macro_file(self) -> MacroFile {
120-
MacroFile { macro_call_id: self }
119+
pub fn as_macro_file(self) -> MacroFileId {
120+
MacroFileId { macro_call_id: self }
121121
}
122122
}
123123

124124
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
125125
pub enum HirFileIdRepr {
126126
FileId(FileId),
127-
MacroFile(MacroFile),
127+
MacroFile(MacroFileId),
128128
}
129129

130130
impl fmt::Debug for HirFileIdRepr {
@@ -145,8 +145,8 @@ impl From<FileId> for HirFileId {
145145
}
146146
}
147147

148-
impl From<MacroFile> for HirFileId {
149-
fn from(MacroFile { macro_call_id: MacroCallId(id) }: MacroFile) -> Self {
148+
impl From<MacroFileId> for HirFileId {
149+
fn from(MacroFileId { macro_call_id: MacroCallId(id) }: MacroFileId) -> Self {
150150
let id = id.as_u32();
151151
assert!(id < Self::MAX_FILE_ID);
152152
HirFileId(id | Self::MACRO_FILE_TAG_MASK)
@@ -163,10 +163,10 @@ impl HirFileId {
163163
}
164164

165165
#[inline]
166-
pub fn macro_file(self) -> Option<MacroFile> {
166+
pub fn macro_file(self) -> Option<MacroFileId> {
167167
match self.0 & Self::MACRO_FILE_TAG_MASK {
168168
0 => None,
169-
_ => Some(MacroFile {
169+
_ => Some(MacroFileId {
170170
macro_call_id: MacroCallId(InternId::from(self.0 ^ Self::MACRO_FILE_TAG_MASK)),
171171
}),
172172
}
@@ -184,7 +184,7 @@ impl HirFileId {
184184
pub fn repr(self) -> HirFileIdRepr {
185185
match self.0 & Self::MACRO_FILE_TAG_MASK {
186186
0 => HirFileIdRepr::FileId(FileId(self.0)),
187-
_ => HirFileIdRepr::MacroFile(MacroFile {
187+
_ => HirFileIdRepr::MacroFile(MacroFileId {
188188
macro_call_id: MacroCallId(InternId::from(self.0 ^ Self::MACRO_FILE_TAG_MASK)),
189189
}),
190190
}

crates/hir-def/src/macro_expansion_tests/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::{iter, ops::Range, sync};
1818

1919
use base_db::{fixture::WithFixture, ProcMacro, SourceDatabase};
2020
use expect_test::Expect;
21-
use hir_expand::{db::ExpandDatabase, span::SpanMapRef, HirFileIdExt, InFile, MacroFile};
21+
use hir_expand::{db::ExpandDatabase, span::SpanMapRef, HirFileIdExt, InFile, MacroFileId};
2222
use stdx::format_to;
2323
use syntax::{
2424
ast::{self, edit::IndentLevel},
@@ -94,7 +94,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
9494
})
9595
.unwrap();
9696
let macro_call_id = res.value.unwrap();
97-
let macro_file = MacroFile { macro_call_id };
97+
let macro_file = MacroFileId { macro_call_id };
9898
let mut expansion_result = db.parse_macro_expansion(macro_file);
9999
expansion_result.err = expansion_result.err.or(res.err);
100100
expansions.push((macro_call.value.clone(), expansion_result));

crates/hir-expand/src/db.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::{
2424
span::{RealSpanMap, SpanMap, SpanMapRef},
2525
tt, AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallInfo,
2626
ExpandError, ExpandResult, ExpandTo, ExpansionSpanMap, HirFileId, HirFileIdRepr, MacroCallId,
27-
MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, MacroFile, ProcMacroExpander,
27+
MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, MacroFileId, ProcMacroExpander,
2828
};
2929

3030
/// Total limit on the number of tokens produced by any macro invocation.
@@ -102,7 +102,7 @@ pub trait ExpandDatabase: SourceDatabase {
102102
// This query is LRU cached
103103
fn parse_macro_expansion(
104104
&self,
105-
macro_file: MacroFile,
105+
macro_file: MacroFileId,
106106
) -> ExpandResult<(Parse<SyntaxNode>, Arc<ExpansionSpanMap>)>;
107107
#[salsa::transparent]
108108
fn span_map(&self, file_id: HirFileId) -> SpanMap;
@@ -307,7 +307,7 @@ fn parse_or_expand_with_err(
307307

308308
fn parse_macro_expansion(
309309
db: &dyn ExpandDatabase,
310-
macro_file: MacroFile,
310+
macro_file: MacroFileId,
311311
) -> ExpandResult<(Parse<SyntaxNode>, Arc<ExpansionSpanMap>)> {
312312
let _p = profile::span("parse_macro_expansion");
313313
let mbe::ValueResult { value: tt, err } = db.macro_expand(macro_file.macro_call_id);
@@ -326,7 +326,7 @@ fn parse_macro_expansion_error(
326326
db: &dyn ExpandDatabase,
327327
macro_call_id: MacroCallId,
328328
) -> ExpandResult<Box<[SyntaxError]>> {
329-
db.parse_macro_expansion(MacroFile { macro_call_id })
329+
db.parse_macro_expansion(MacroFileId { macro_call_id })
330330
.map(|it| it.0.errors().to_vec().into_boxed_slice())
331331
}
332332

crates/hir-expand/src/files.rs

Lines changed: 97 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
use std::iter;
22

33
use base_db::{
4-
span::{HirFileId, HirFileIdRepr, MacroFile, SyntaxContextId},
5-
FileRange,
4+
span::{HirFileId, HirFileIdRepr, MacroFileId, SyntaxContextId},
5+
FileId, FileRange,
66
};
77
use either::Either;
88
use syntax::{AstNode, SyntaxNode, SyntaxToken, TextRange};
99

1010
use crate::{db, ExpansionInfo, HirFileIdExt as _};
1111

12-
// FIXME: Make an InRealFile wrapper
1312
/// `InFile<T>` stores a value of `T` inside a particular file/syntax tree.
1413
///
1514
/// Typical usages are:
@@ -18,55 +17,91 @@ use crate::{db, ExpansionInfo, HirFileIdExt as _};
1817
/// * `InFile<ast::FnDef>` -- ast node in a file
1918
/// * `InFile<TextSize>` -- offset in a file
2019
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
21-
pub struct InFile<T> {
22-
pub file_id: HirFileId,
20+
pub struct InFileWrapper<FileKind, T> {
21+
pub file_id: FileKind,
2322
pub value: T,
2423
}
24+
pub type InFile<T> = InFileWrapper<HirFileId, T>;
25+
pub type InMacroFile<T> = InFileWrapper<MacroFileId, T>;
26+
pub type InRealFile<T> = InFileWrapper<FileId, T>;
2527

26-
impl<T> InFile<T> {
27-
pub fn new(file_id: HirFileId, value: T) -> InFile<T> {
28-
InFile { file_id, value }
28+
impl<FileKind, T> InFileWrapper<FileKind, T> {
29+
pub fn new(file_id: FileKind, value: T) -> Self {
30+
Self { file_id, value }
2931
}
3032

31-
pub fn with_value<U>(&self, value: U) -> InFile<U> {
32-
InFile::new(self.file_id, value)
33+
pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> InFileWrapper<FileKind, U> {
34+
InFileWrapper::new(self.file_id, f(self.value))
3335
}
36+
}
3437

35-
pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> InFile<U> {
36-
InFile::new(self.file_id, f(self.value))
38+
impl<FileKind: Copy, T> InFileWrapper<FileKind, T> {
39+
pub fn with_value<U>(&self, value: U) -> InFileWrapper<FileKind, U> {
40+
InFileWrapper::new(self.file_id, value)
3741
}
3842

39-
pub fn as_ref(&self) -> InFile<&T> {
43+
pub fn as_ref(&self) -> InFileWrapper<FileKind, &T> {
4044
self.with_value(&self.value)
4145
}
46+
}
4247

43-
pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
44-
db.parse_or_expand(self.file_id)
48+
impl<FileKind: Copy, T: Clone> InFileWrapper<FileKind, &T> {
49+
pub fn cloned(&self) -> InFileWrapper<FileKind, T> {
50+
self.with_value(self.value.clone())
4551
}
4652
}
4753

48-
impl<T: Clone> InFile<&T> {
49-
pub fn cloned(&self) -> InFile<T> {
50-
self.with_value(self.value.clone())
54+
impl<T> From<InMacroFile<T>> for InFile<T> {
55+
fn from(InMacroFile { file_id, value }: InMacroFile<T>) -> Self {
56+
InFile { file_id: file_id.into(), value }
5157
}
5258
}
5359

54-
impl<T> InFile<Option<T>> {
55-
pub fn transpose(self) -> Option<InFile<T>> {
56-
let value = self.value?;
57-
Some(InFile::new(self.file_id, value))
60+
impl<T> From<InRealFile<T>> for InFile<T> {
61+
fn from(InRealFile { file_id, value }: InRealFile<T>) -> Self {
62+
InFile { file_id: file_id.into(), value }
5863
}
5964
}
6065

61-
impl<L, R> InFile<Either<L, R>> {
62-
pub fn transpose(self) -> Either<InFile<L>, InFile<R>> {
66+
// region:transpose impls
67+
68+
impl<FileKind, T> InFileWrapper<FileKind, Option<T>> {
69+
pub fn transpose(self) -> Option<InFileWrapper<FileKind, T>> {
70+
Some(InFileWrapper::new(self.file_id, self.value?))
71+
}
72+
}
73+
74+
impl<FileKind, L, R> InFileWrapper<FileKind, Either<L, R>> {
75+
pub fn transpose(self) -> Either<InFileWrapper<FileKind, L>, InFileWrapper<FileKind, R>> {
6376
match self.value {
64-
Either::Left(l) => Either::Left(InFile::new(self.file_id, l)),
65-
Either::Right(r) => Either::Right(InFile::new(self.file_id, r)),
77+
Either::Left(l) => Either::Left(InFileWrapper::new(self.file_id, l)),
78+
Either::Right(r) => Either::Right(InFileWrapper::new(self.file_id, r)),
6679
}
6780
}
6881
}
6982

83+
// endregion:transpose impls
84+
85+
// region:specific impls
86+
87+
impl<T> InFile<T> {
88+
pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
89+
db.parse_or_expand(self.file_id)
90+
}
91+
}
92+
93+
impl<T> InRealFile<T> {
94+
pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
95+
db.parse(self.file_id).syntax_node()
96+
}
97+
}
98+
99+
impl<T> InMacroFile<T> {
100+
pub fn file_syntax(&self, db: &dyn db::ExpandDatabase) -> SyntaxNode {
101+
db.parse_macro_expansion(self.file_id).value.0.syntax_node()
102+
}
103+
}
104+
70105
impl InFile<&SyntaxNode> {
71106
pub fn ancestors_with_macros(
72107
self,
@@ -159,11 +194,17 @@ impl InFile<&SyntaxNode> {
159194
}
160195
}
161196

162-
pub fn original_syntax_node(self, db: &dyn db::ExpandDatabase) -> Option<InFile<SyntaxNode>> {
197+
pub fn original_syntax_node(
198+
self,
199+
db: &dyn db::ExpandDatabase,
200+
) -> Option<InRealFile<SyntaxNode>> {
163201
// This kind of upmapping can only be achieved in attribute expanded files,
164202
// as we don't have node inputs otherwise and therefore can't find an `N` node in the input
165-
let Some(file_id) = self.file_id.macro_file() else {
166-
return Some(self.map(Clone::clone));
203+
let file_id = match self.file_id.repr() {
204+
HirFileIdRepr::FileId(file_id) => {
205+
return Some(InRealFile { file_id, value: self.value.clone() })
206+
}
207+
HirFileIdRepr::MacroFile(m) => m,
167208
};
168209
if !self.file_id.is_attr_macro(db) {
169210
return None;
@@ -182,7 +223,7 @@ impl InFile<&SyntaxNode> {
182223
let kind = self.value.kind();
183224
// FIXME: This heuristic is brittle and with the right macro may select completely unrelated nodes?
184225
let value = anc.ancestors().find(|it| it.kind() == kind)?;
185-
Some(InFile::new(file_id.into(), value))
226+
Some(InRealFile::new(file_id, value))
186227
}
187228
}
188229

@@ -230,29 +271,11 @@ impl InFile<SyntaxToken> {
230271
}
231272
}
232273

233-
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
234-
pub struct InMacroFile<T> {
235-
pub file_id: MacroFile,
236-
pub value: T,
237-
}
238-
239-
impl<T> From<InMacroFile<T>> for InFile<T> {
240-
fn from(macro_file: InMacroFile<T>) -> Self {
241-
InFile { file_id: macro_file.file_id.into(), value: macro_file.value }
242-
}
243-
}
244-
245-
pub fn ascend_range_up_macros(
246-
db: &dyn db::ExpandDatabase,
247-
range: InFile<TextRange>,
248-
) -> (FileRange, SyntaxContextId) {
249-
match range.file_id.repr() {
250-
HirFileIdRepr::FileId(file_id) => {
251-
(FileRange { file_id, range: range.value }, SyntaxContextId::ROOT)
252-
}
253-
HirFileIdRepr::MacroFile(m) => {
254-
ExpansionInfo::new(db, m).map_token_range_up(db, range.value)
255-
}
274+
impl InFile<TextRange> {
275+
/// Attempts to map the syntax node back up its macro calls.
276+
pub fn original_file_range(self, db: &dyn db::ExpandDatabase) -> FileRange {
277+
let (range, _ctxt) = ascend_range_up_macros(db, self);
278+
range
256279
}
257280
}
258281

@@ -261,12 +284,14 @@ impl<N: AstNode> InFile<N> {
261284
self.value.syntax().descendants().filter_map(T::cast).map(move |n| self.with_value(n))
262285
}
263286

264-
// FIXME: this should return `Option<InFileNotHirFile<N>>`
265-
pub fn original_ast_node(self, db: &dyn db::ExpandDatabase) -> Option<InFile<N>> {
287+
pub fn original_ast_node(self, db: &dyn db::ExpandDatabase) -> Option<InRealFile<N>> {
266288
// This kind of upmapping can only be achieved in attribute expanded files,
267289
// as we don't have node inputs otherwise and therefore can't find an `N` node in the input
268-
let Some(file_id) = self.file_id.macro_file() else {
269-
return Some(self);
290+
let file_id = match self.file_id.repr() {
291+
HirFileIdRepr::FileId(file_id) => {
292+
return Some(InRealFile { file_id, value: self.value })
293+
}
294+
HirFileIdRepr::MacroFile(m) => m,
270295
};
271296
if !self.file_id.is_attr_macro(db) {
272297
return None;
@@ -284,10 +309,24 @@ impl<N: AstNode> InFile<N> {
284309
// FIXME: This heuristic is brittle and with the right macro may select completely unrelated nodes?
285310
let anc = db.parse(file_id).syntax_node().covering_element(range);
286311
let value = anc.ancestors().find_map(N::cast)?;
287-
return Some(InFile::new(file_id.into(), value));
312+
Some(InRealFile::new(file_id, value))
288313
}
289314

290315
pub fn syntax(&self) -> InFile<&SyntaxNode> {
291316
self.with_value(self.value.syntax())
292317
}
293318
}
319+
320+
fn ascend_range_up_macros(
321+
db: &dyn db::ExpandDatabase,
322+
range: InFile<TextRange>,
323+
) -> (FileRange, SyntaxContextId) {
324+
match range.file_id.repr() {
325+
HirFileIdRepr::FileId(file_id) => {
326+
(FileRange { file_id, range: range.value }, SyntaxContextId::ROOT)
327+
}
328+
HirFileIdRepr::MacroFile(m) => {
329+
ExpansionInfo::new(db, m).map_token_range_up(db, range.value)
330+
}
331+
}
332+
}

0 commit comments

Comments
 (0)