@@ -435,6 +435,29 @@ impl MacroCallKind {
435
435
}
436
436
}
437
437
438
+ /// Returns the original file range that best describes the location of this macro call.
439
+ ///
440
+ /// Unlike `MacroCallKind::original_call_range`, this also spans the item of attributes and derives.
441
+ pub fn original_call_range_with_body ( self , db : & dyn db:: AstDatabase ) -> FileRange {
442
+ let mut kind = self ;
443
+ let file_id = loop {
444
+ match kind. file_id ( ) . 0 {
445
+ HirFileIdRepr :: MacroFile ( file) => {
446
+ kind = db. lookup_intern_macro_call ( file. macro_call_id ) . kind ;
447
+ }
448
+ HirFileIdRepr :: FileId ( file_id) => break file_id,
449
+ }
450
+ } ;
451
+
452
+ let range = match kind {
453
+ MacroCallKind :: FnLike { ast_id, .. } => ast_id. to_node ( db) . syntax ( ) . text_range ( ) ,
454
+ MacroCallKind :: Derive { ast_id, .. } => ast_id. to_node ( db) . syntax ( ) . text_range ( ) ,
455
+ MacroCallKind :: Attr { ast_id, .. } => ast_id. to_node ( db) . syntax ( ) . text_range ( ) ,
456
+ } ;
457
+
458
+ FileRange { range, file_id }
459
+ }
460
+
438
461
/// Returns the original file range that best describes the location of this macro call.
439
462
///
440
463
/// Here we try to roughly match what rustc does to improve diagnostics: fn-like macros
@@ -751,6 +774,9 @@ impl<'a> InFile<&'a SyntaxNode> {
751
774
}
752
775
753
776
/// Falls back to the macro call range if the node cannot be mapped up fully.
777
+ ///
778
+ /// For attributes and derives, this will point back to the attribute only.
779
+ /// For the entire item `InFile::use original_file_range_full`.
754
780
pub fn original_file_range ( self , db : & dyn db:: AstDatabase ) -> FileRange {
755
781
if let Some ( res) = self . original_file_range_opt ( db) {
756
782
return res;
@@ -766,6 +792,22 @@ impl<'a> InFile<&'a SyntaxNode> {
766
792
}
767
793
}
768
794
795
+ /// Falls back to the macro call range if the node cannot be mapped up fully.
796
+ pub fn original_file_range_full ( self , db : & dyn db:: AstDatabase ) -> FileRange {
797
+ if let Some ( res) = self . original_file_range_opt ( db) {
798
+ return res;
799
+ }
800
+
801
+ // Fall back to whole macro call.
802
+ match self . file_id . 0 {
803
+ HirFileIdRepr :: FileId ( file_id) => FileRange { file_id, range : self . value . text_range ( ) } ,
804
+ HirFileIdRepr :: MacroFile ( mac_file) => {
805
+ let loc = db. lookup_intern_macro_call ( mac_file. macro_call_id ) ;
806
+ loc. kind . original_call_range_with_body ( db)
807
+ }
808
+ }
809
+ }
810
+
769
811
/// Attempts to map the syntax node back up its macro calls.
770
812
pub fn original_file_range_opt ( self , db : & dyn db:: AstDatabase ) -> Option < FileRange > {
771
813
match ascend_node_border_tokens ( db, self ) {
0 commit comments