@@ -7,7 +7,10 @@ use hir_def::{
77 DefWithBodyId , TraitId ,
88} ;
99use 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+ } ;
1114use rustc_hash:: { FxHashMap , FxHashSet } ;
1215
1316use crate :: {
@@ -333,10 +336,27 @@ impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> {
333336
334337// FIXME: Change `HasSource` trait to work with `Semantics` and remove this?
335338pub 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 } ;
338357 }
339358
359+ // Fall back to whole macro call
340360 if let Some ( expansion) = node. file_id . expansion_info ( db) {
341361 if let Some ( call_node) = expansion. call_node ( ) {
342362 return FileRange {
@@ -351,15 +371,22 @@ pub fn original_range(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> FileR
351371
352372fn original_range_and_origin (
353373 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+ } ;
357385
358386 // the input node has only one token ?
359387 let single = node. value . first_token ( ) ? == node. value . last_token ( ) ?;
360388
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| {
363390 let first = it. first_token ( ) ?;
364391 let last = it. last_token ( ) ?;
365392
@@ -380,12 +407,7 @@ fn original_range_and_origin(
380407 first. with_value ( union_range ( first. value . text_range ( ) , last. value . text_range ( ) ) ) ,
381408 first_origin,
382409 ) )
383- } ) ?;
384-
385- return Some ( (
386- FileRange { file_id : range. file_id . original_file ( db) , range : range. value } ,
387- origin,
388- ) ) ;
410+ } ) ?) ;
389411
390412 fn union_range ( a : TextRange , b : TextRange ) -> TextRange {
391413 let start = a. start ( ) . min ( b. start ( ) ) ;
0 commit comments