@@ -44,7 +44,7 @@ use crate::{
44
44
db:: TokenExpander ,
45
45
mod_path:: ModPath ,
46
46
proc_macro:: ProcMacroExpander ,
47
- span:: ExpansionSpanMap ,
47
+ span:: { ExpansionSpanMap , SpanMap } ,
48
48
} ;
49
49
50
50
pub use crate :: ast_id_map:: { AstId , ErasedAstId , ErasedFileAstId } ;
@@ -172,7 +172,6 @@ pub trait HirFileIdExt {
172
172
/// For macro-expansion files, returns the file original source file the
173
173
/// expansion originated from.
174
174
fn original_file ( self , db : & dyn db:: ExpandDatabase ) -> FileId ;
175
- fn expansion_level ( self , db : & dyn db:: ExpandDatabase ) -> u32 ;
176
175
177
176
/// If this is a macro call, returns the syntax node of the call.
178
177
fn call_node ( self , db : & dyn db:: ExpandDatabase ) -> Option < InFile < SyntaxNode > > ;
@@ -218,18 +217,6 @@ impl HirFileIdExt for HirFileId {
218
217
}
219
218
}
220
219
221
- fn expansion_level ( self , db : & dyn db:: ExpandDatabase ) -> u32 {
222
- let mut level = 0 ;
223
- let mut curr = self ;
224
- while let Some ( macro_file) = curr. macro_file ( ) {
225
- let loc: MacroCallLoc = db. lookup_intern_macro_call ( macro_file. macro_call_id ) ;
226
-
227
- level += 1 ;
228
- curr = loc. kind . file_id ( ) ;
229
- }
230
- level
231
- }
232
-
233
220
fn call_node ( self , db : & dyn db:: ExpandDatabase ) -> Option < InFile < SyntaxNode > > {
234
221
let macro_file = self . macro_file ( ) ?;
235
222
let loc: MacroCallLoc = db. lookup_intern_macro_call ( macro_file. macro_call_id ) ;
@@ -330,6 +317,32 @@ impl HirFileIdExt for HirFileId {
330
317
}
331
318
}
332
319
320
+ pub trait MacroFileIdExt {
321
+ fn expansion_level ( self , db : & dyn db:: ExpandDatabase ) -> u32 ;
322
+ fn expansion_info ( self , db : & dyn db:: ExpandDatabase ) -> ExpansionInfo ;
323
+ }
324
+
325
+ impl MacroFileIdExt for MacroFileId {
326
+ fn expansion_level ( self , db : & dyn db:: ExpandDatabase ) -> u32 {
327
+ let mut level = 0 ;
328
+ let mut macro_file = self ;
329
+ loop {
330
+ let loc: MacroCallLoc = db. lookup_intern_macro_call ( macro_file. macro_call_id ) ;
331
+
332
+ level += 1 ;
333
+ macro_file = match loc. kind . file_id ( ) . repr ( ) {
334
+ HirFileIdRepr :: FileId ( _) => break level,
335
+ HirFileIdRepr :: MacroFile ( it) => it,
336
+ } ;
337
+ }
338
+ }
339
+
340
+ /// Return expansion information if it is a macro-expansion file
341
+ fn expansion_info ( self , db : & dyn db:: ExpandDatabase ) -> ExpansionInfo {
342
+ ExpansionInfo :: new ( db, self )
343
+ }
344
+ }
345
+
333
346
impl MacroDefId {
334
347
pub fn as_lazy_macro (
335
348
self ,
@@ -398,7 +411,7 @@ impl MacroCallLoc {
398
411
match file_id. repr ( ) {
399
412
HirFileIdRepr :: FileId ( file_id) => db. real_span_map ( file_id) . span_for_range ( range) ,
400
413
HirFileIdRepr :: MacroFile ( m) => {
401
- db. parse_macro_expansion ( m) . value . 1 . span_for_range ( range)
414
+ db. parse_macro_expansion ( m) . value . 1 . span_at ( range. start ( ) )
402
415
}
403
416
}
404
417
}
@@ -565,9 +578,8 @@ pub struct ExpansionInfo {
565
578
566
579
macro_def : TokenExpander ,
567
580
macro_arg : Arc < tt:: Subtree > ,
568
- exp_map : Arc < ExpansionSpanMap > ,
569
- /// [`None`] if the call is in a real file
570
- arg_map : Option < Arc < ExpansionSpanMap > > ,
581
+ pub exp_map : Arc < ExpansionSpanMap > ,
582
+ arg_map : SpanMap ,
571
583
}
572
584
573
585
impl ExpansionInfo {
@@ -582,38 +594,14 @@ impl ExpansionInfo {
582
594
/// Maps the passed in file range down into a macro expansion if it is the input to a macro call.
583
595
pub fn map_range_down < ' a > (
584
596
& ' a self ,
585
- db : & ' a dyn db:: ExpandDatabase ,
586
- FileRange { file_id, range : absolute_range } : FileRange ,
597
+ span : SpanData ,
587
598
// FIXME: use this for range mapping, so that we can resolve inline format args
588
599
_relative_token_offset : Option < TextSize > ,
589
600
// FIXME: ret ty should be wrapped in InMacroFile
590
601
) -> Option < impl Iterator < Item = InFile < SyntaxToken > > + ' a > {
591
- // search for all entries in the span map that have the given span and return the
592
- // corresponding text ranges inside the expansion
593
- // FIXME: Make this proper
594
- let span_map = & self . exp_map . span_map ;
595
- let ( start, end) = if span_map
596
- . first ( )
597
- . map_or ( false , |( _, span) | span. anchor . file_id == file_id)
598
- {
599
- ( 0 , span_map. partition_point ( |a| a. 1 . anchor . file_id == file_id) )
600
- } else {
601
- let start = span_map. partition_point ( |a| a. 1 . anchor . file_id != file_id) ;
602
- ( start, start + span_map[ start..] . partition_point ( |a| a. 1 . anchor . file_id == file_id) )
603
- } ;
604
- let tokens = span_map[ start..end]
605
- . iter ( )
606
- . filter_map ( move |( range, span) | {
607
- // we need to resolve the relative ranges here to make sure that we are in fact
608
- // considering differently anchored spans (this might occur with proc-macros)
609
- let offset = db
610
- . ast_id_map ( span. anchor . file_id . into ( ) )
611
- . get_erased ( span. anchor . ast_id )
612
- . text_range ( )
613
- . start ( ) ;
614
- let abs_range = span. range + offset;
615
- absolute_range. eq ( & abs_range) . then_some ( * range)
616
- } )
602
+ let tokens = self
603
+ . exp_map
604
+ . ranges_with_span ( span)
617
605
. flat_map ( move |range| self . expanded . value . covering_element ( range) . into_token ( ) ) ;
618
606
619
607
Some ( tokens. map ( move |token| InFile :: new ( self . expanded . file_id . into ( ) , token) ) )
@@ -626,7 +614,7 @@ impl ExpansionInfo {
626
614
range : TextRange ,
627
615
) -> ( FileRange , SyntaxContextId ) {
628
616
debug_assert ! ( self . expanded. value. text_range( ) . contains_range( range) ) ;
629
- let span = self . exp_map . span_for_range ( range) ;
617
+ let span = self . exp_map . span_at ( range. start ( ) ) ;
630
618
let anchor_offset = db
631
619
. ast_id_map ( span. anchor . file_id . into ( ) )
632
620
. get_erased ( span. anchor . ast_id )
@@ -672,15 +660,15 @@ impl ExpansionInfo {
672
660
token : TextRange ,
673
661
) -> InFile < smallvec:: SmallVec < [ TextRange ; 1 ] > > {
674
662
debug_assert ! ( self . expanded. value. text_range( ) . contains_range( token) ) ;
675
- let span = self . exp_map . span_for_range ( token) ;
663
+ let span = self . exp_map . span_at ( token. start ( ) ) ;
676
664
match & self . arg_map {
677
- None => {
665
+ SpanMap :: RealSpanMap ( _ ) => {
678
666
let file_id = span. anchor . file_id . into ( ) ;
679
667
let anchor_offset =
680
668
db. ast_id_map ( file_id) . get_erased ( span. anchor . ast_id ) . text_range ( ) . start ( ) ;
681
669
InFile { file_id, value : smallvec:: smallvec![ span. range + anchor_offset] }
682
670
}
683
- Some ( arg_map) => {
671
+ SpanMap :: ExpansionSpanMap ( arg_map) => {
684
672
let arg_range = self
685
673
. arg
686
674
. value
@@ -701,8 +689,7 @@ impl ExpansionInfo {
701
689
let loc: MacroCallLoc = db. lookup_intern_macro_call ( macro_file. macro_call_id ) ;
702
690
703
691
let arg_tt = loc. kind . arg ( db) ;
704
- let arg_map =
705
- arg_tt. file_id . macro_file ( ) . map ( |file| db. parse_macro_expansion ( file) . value . 1 ) ;
692
+ let arg_map = db. span_map ( arg_tt. file_id ) ;
706
693
707
694
let macro_def = db. macro_expander ( loc. def ) ;
708
695
let ( parse, exp_map) = db. parse_macro_expansion ( macro_file) . value ;
0 commit comments