@@ -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,27 @@ 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
+ if range. file_id != elem. file_id {
349
+ if let Some ( root) = db. parse_or_expand ( range. file_id ) {
350
+ elem = range. with_value ( find_covering_element ( & root, range. value ) ) ;
351
+ continue ;
352
+ }
353
+ }
354
+
355
+ log:: error!( "Fail to mapping up more for {:?}" , range) ;
356
+ return FileRange { file_id : range. file_id . original_file ( db) , range : range. value } ;
338
357
}
339
358
359
+ // Fall back to whole macro call
340
360
if let Some ( expansion) = node. file_id . expansion_info ( db) {
341
361
if let Some ( call_node) = expansion. call_node ( ) {
342
362
return FileRange {
@@ -351,15 +371,22 @@ pub fn original_range(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> FileR
351
371
352
372
fn original_range_and_origin (
353
373
db : & impl HirDatabase ,
354
- node : InFile < & SyntaxNode > ,
355
- ) -> Option < ( FileRange , Origin ) > {
356
- let expansion = node. file_id . expansion_info ( db) ?;
374
+ elem : InFile < & SyntaxElement > ,
375
+ ) -> Option < ( InFile < TextRange > , Origin ) > {
376
+ let expansion = elem. file_id . expansion_info ( db) ?;
377
+
378
+ let node = match elem. as_ref ( ) . value {
379
+ NodeOrToken :: Node ( it) => elem. with_value ( it) ,
380
+ NodeOrToken :: Token ( it) => {
381
+ let ( tt, origin) = expansion. map_token_up ( elem. with_value ( it) ) ?;
382
+ return Some ( ( tt. map ( |it| it. text_range ( ) ) , origin) ) ;
383
+ }
384
+ } ;
357
385
358
386
// the input node has only one token ?
359
387
let single = node. value . first_token ( ) ? == node. value . last_token ( ) ?;
360
388
361
- // FIXME: We should handle recurside macro expansions
362
- let ( range, origin) = node. value . descendants ( ) . find_map ( |it| {
389
+ return Some ( node. value . descendants ( ) . find_map ( |it| {
363
390
let first = it. first_token ( ) ?;
364
391
let last = it. last_token ( ) ?;
365
392
@@ -380,12 +407,7 @@ fn original_range_and_origin(
380
407
first. with_value ( union_range ( first. value . text_range ( ) , last. value . text_range ( ) ) ) ,
381
408
first_origin,
382
409
) )
383
- } ) ?;
384
-
385
- return Some ( (
386
- FileRange { file_id : range. file_id . original_file ( db) , range : range. value } ,
387
- origin,
388
- ) ) ;
410
+ } ) ?) ;
389
411
390
412
fn union_range ( a : TextRange , b : TextRange ) -> TextRange {
391
413
let start = a. start ( ) . min ( b. start ( ) ) ;
0 commit comments