1
1
//! Things to wrap other things in file ids.
2
+ use std:: borrow:: Borrow ;
3
+
2
4
use either:: Either ;
3
5
use span:: {
4
6
AstIdNode , ErasedFileAstId , FileAstId , FileId , FileRange , HirFileId , HirFileIdRepr ,
@@ -76,6 +78,13 @@ impl<FileKind: Copy, T> InFileWrapper<FileKind, T> {
76
78
pub fn as_ref ( & self ) -> InFileWrapper < FileKind , & T > {
77
79
self . with_value ( & self . value )
78
80
}
81
+
82
+ pub fn borrow < U > ( & self ) -> InFileWrapper < FileKind , & U >
83
+ where
84
+ T : Borrow < U > ,
85
+ {
86
+ self . with_value ( self . value . borrow ( ) )
87
+ }
79
88
}
80
89
81
90
impl < FileKind : Copy , T : Clone > InFileWrapper < FileKind , & T > {
@@ -156,30 +165,69 @@ impl<FileId: Copy, N: AstNode> InFileWrapper<FileId, &N> {
156
165
}
157
166
158
167
// region:specific impls
168
+ impl < SN : Borrow < SyntaxNode > > InRealFile < SN > {
169
+ pub fn file_range ( & self ) -> FileRange {
170
+ FileRange { file_id : self . file_id , range : self . value . borrow ( ) . text_range ( ) }
171
+ }
172
+ }
173
+
174
+ impl < SN : Borrow < SyntaxNode > > InFile < SN > {
175
+ pub fn parent_ancestors_with_macros (
176
+ self ,
177
+ db : & dyn db:: ExpandDatabase ,
178
+ ) -> impl Iterator < Item = InFile < SyntaxNode > > + ' _ {
179
+ let succ = move |node : & InFile < SyntaxNode > | match node. value . parent ( ) {
180
+ Some ( parent) => Some ( node. with_value ( parent) ) ,
181
+ None => db
182
+ . lookup_intern_macro_call ( node. file_id . macro_file ( ) ?. macro_call_id )
183
+ . to_node_item ( db)
184
+ . syntax ( )
185
+ . cloned ( )
186
+ . map ( |node| node. parent ( ) )
187
+ . transpose ( ) ,
188
+ } ;
189
+ std:: iter:: successors ( succ ( & self . borrow ( ) . cloned ( ) ) , succ)
190
+ }
191
+
192
+ pub fn ancestors_with_macros (
193
+ self ,
194
+ db : & dyn db:: ExpandDatabase ,
195
+ ) -> impl Iterator < Item = InFile < SyntaxNode > > + ' _ {
196
+ let succ = move |node : & InFile < SyntaxNode > | match node. value . parent ( ) {
197
+ Some ( parent) => Some ( node. with_value ( parent) ) ,
198
+ None => db
199
+ . lookup_intern_macro_call ( node. file_id . macro_file ( ) ?. macro_call_id )
200
+ . to_node_item ( db)
201
+ . syntax ( )
202
+ . cloned ( )
203
+ . map ( |node| node. parent ( ) )
204
+ . transpose ( ) ,
205
+ } ;
206
+ std:: iter:: successors ( Some ( self . borrow ( ) . cloned ( ) ) , succ)
207
+ }
208
+
209
+ pub fn kind ( & self ) -> parser:: SyntaxKind {
210
+ self . value . borrow ( ) . kind ( )
211
+ }
212
+
213
+ pub fn text_range ( & self ) -> TextRange {
214
+ self . value . borrow ( ) . text_range ( )
215
+ }
159
216
160
- impl InFile < & SyntaxNode > {
161
217
/// Falls back to the macro call range if the node cannot be mapped up fully.
162
218
///
163
219
/// For attributes and derives, this will point back to the attribute only.
164
220
/// For the entire item use [`InFile::original_file_range_full`].
165
221
pub fn original_file_range_rooted ( self , db : & dyn db:: ExpandDatabase ) -> FileRange {
166
- self . map ( SyntaxNode :: text_range) . original_node_file_range_rooted ( db)
222
+ self . borrow ( ) . map ( SyntaxNode :: text_range) . original_node_file_range_rooted ( db)
167
223
}
168
224
169
225
/// Falls back to the macro call range if the node cannot be mapped up fully.
170
226
pub fn original_file_range_with_macro_call_body (
171
227
self ,
172
228
db : & dyn db:: ExpandDatabase ,
173
229
) -> FileRange {
174
- self . map ( SyntaxNode :: text_range) . original_node_file_range_with_macro_call_body ( db)
175
- }
176
-
177
- /// Attempts to map the syntax node back up its macro calls.
178
- pub fn original_file_range_opt (
179
- self ,
180
- db : & dyn db:: ExpandDatabase ,
181
- ) -> Option < ( FileRange , SyntaxContextId ) > {
182
- self . map ( SyntaxNode :: text_range) . original_node_file_range_opt ( db)
230
+ self . borrow ( ) . map ( SyntaxNode :: text_range) . original_node_file_range_with_macro_call_body ( db)
183
231
}
184
232
185
233
pub fn original_syntax_node_rooted (
@@ -190,16 +238,19 @@ impl InFile<&SyntaxNode> {
190
238
// as we don't have node inputs otherwise and therefore can't find an `N` node in the input
191
239
let file_id = match self . file_id . repr ( ) {
192
240
HirFileIdRepr :: FileId ( file_id) => {
193
- return Some ( InRealFile { file_id, value : self . value . clone ( ) } )
241
+ return Some ( InRealFile { file_id, value : self . value . borrow ( ) . clone ( ) } )
194
242
}
195
243
HirFileIdRepr :: MacroFile ( m) if m. is_attr_macro ( db) => m,
196
244
_ => return None ,
197
245
} ;
198
246
199
- let FileRange { file_id, range } =
200
- map_node_range_up_rooted ( db, & db. expansion_span_map ( file_id) , self . value . text_range ( ) ) ?;
247
+ let FileRange { file_id, range } = map_node_range_up_rooted (
248
+ db,
249
+ & db. expansion_span_map ( file_id) ,
250
+ self . value . borrow ( ) . text_range ( ) ,
251
+ ) ?;
201
252
202
- let kind = self . value . kind ( ) ;
253
+ let kind = self . kind ( ) ;
203
254
let value = db
204
255
. parse ( file_id)
205
256
. syntax_node ( )
@@ -211,6 +262,16 @@ impl InFile<&SyntaxNode> {
211
262
}
212
263
}
213
264
265
+ impl InFile < & SyntaxNode > {
266
+ /// Attempts to map the syntax node back up its macro calls.
267
+ pub fn original_file_range_opt (
268
+ self ,
269
+ db : & dyn db:: ExpandDatabase ,
270
+ ) -> Option < ( FileRange , SyntaxContextId ) > {
271
+ self . borrow ( ) . map ( SyntaxNode :: text_range) . original_node_file_range_opt ( db)
272
+ }
273
+ }
274
+
214
275
impl InMacroFile < SyntaxToken > {
215
276
pub fn upmap_once (
216
277
self ,
0 commit comments