@@ -7,7 +7,10 @@ use hir_def::{
7
7
DefWithBodyId , TraitId ,
8
8
} ;
9
9
use ra_db:: { FileId , FileRange } ;
10
- use ra_syntax:: { ast, match_ast, AstNode , SyntaxNode , SyntaxToken , TextRange , TextUnit } ;
10
+ use ra_syntax:: {
11
+ algo:: find_covering_element, ast, match_ast, AstNode , NodeOrToken , SyntaxElement , SyntaxNode ,
12
+ SyntaxToken , TextRange , TextUnit ,
13
+ } ;
11
14
use rustc_hash:: { FxHashMap , FxHashSet } ;
12
15
13
16
use crate :: {
@@ -333,10 +336,28 @@ impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> {
333
336
334
337
// FIXME: Change `HasSource` trait to work with `Semantics` and remove this?
335
338
pub fn original_range ( db : & impl HirDatabase , node : InFile < & SyntaxNode > ) -> FileRange {
336
- if let Some ( ( range, Origin :: Call ) ) = original_range_and_origin ( db, node) {
337
- return range;
339
+ let mut elem: InFile < SyntaxElement > = node. map ( |n| n. clone ( ) . into ( ) ) ;
340
+
341
+ while let Some ( ( range, Origin :: Call ) ) = original_range_and_origin ( db, elem. as_ref ( ) ) {
342
+ let original_file = range. file_id . original_file ( db) ;
343
+
344
+ if range. file_id == original_file. into ( ) {
345
+ return FileRange { file_id : original_file, range : range. value } ;
346
+ }
347
+
348
+ // Fail to mapping up more, return the original file range instead
349
+ if range. file_id != elem. file_id {
350
+ if let Some ( root) = db. parse_or_expand ( range. file_id ) {
351
+ elem = range. with_value ( find_covering_element ( & root, range. value ) ) ;
352
+ continue ;
353
+ }
354
+ }
355
+
356
+ log:: error!( "Fail to mapping up more for {:?}" , range) ;
357
+ return FileRange { file_id : range. file_id . original_file ( db) , range : range. value } ;
338
358
}
339
359
360
+ // Fall back to whole macro call
340
361
if let Some ( expansion) = node. file_id . expansion_info ( db) {
341
362
if let Some ( call_node) = expansion. call_node ( ) {
342
363
return FileRange {
@@ -351,15 +372,22 @@ pub fn original_range(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> FileR
351
372
352
373
fn original_range_and_origin (
353
374
db : & impl HirDatabase ,
354
- node : InFile < & SyntaxNode > ,
355
- ) -> Option < ( FileRange , Origin ) > {
356
- let expansion = node. file_id . expansion_info ( db) ?;
375
+ elem : InFile < & SyntaxElement > ,
376
+ ) -> Option < ( InFile < TextRange > , Origin ) > {
377
+ let expansion = elem. file_id . expansion_info ( db) ?;
378
+
379
+ let node = match elem. as_ref ( ) . value {
380
+ NodeOrToken :: Node ( it) => elem. with_value ( it) ,
381
+ NodeOrToken :: Token ( it) => {
382
+ let ( tt, origin) = expansion. map_token_up ( elem. with_value ( it) ) ?;
383
+ return Some ( ( tt. map ( |it| it. text_range ( ) ) , origin) ) ;
384
+ }
385
+ } ;
357
386
358
387
// the input node has only one token ?
359
388
let single = node. value . first_token ( ) ? == node. value . last_token ( ) ?;
360
389
361
- // FIXME: We should handle recurside macro expansions
362
- let ( range, origin) = node. value . descendants ( ) . find_map ( |it| {
390
+ return Some ( node. value . descendants ( ) . find_map ( |it| {
363
391
let first = it. first_token ( ) ?;
364
392
let last = it. last_token ( ) ?;
365
393
@@ -380,12 +408,7 @@ fn original_range_and_origin(
380
408
first. with_value ( union_range ( first. value . text_range ( ) , last. value . text_range ( ) ) ) ,
381
409
first_origin,
382
410
) )
383
- } ) ?;
384
-
385
- return Some ( (
386
- FileRange { file_id : range. file_id . original_file ( db) , range : range. value } ,
387
- origin,
388
- ) ) ;
411
+ } ) ?) ;
389
412
390
413
fn union_range ( a : TextRange , b : TextRange ) -> TextRange {
391
414
let start = a. start ( ) . min ( b. start ( ) ) ;
0 commit comments