@@ -8,8 +8,7 @@ use hir_def::{
88} ;
99use ra_db:: { FileId , FileRange } ;
1010use ra_syntax:: {
11- algo:: { find_covering_element, skip_trivia_token} ,
12- ast, match_ast, AstNode , Direction , NodeOrToken , SyntaxElement , SyntaxNode , SyntaxToken ,
11+ algo:: skip_trivia_token, ast, match_ast, AstNode , Direction , SyntaxNode , SyntaxToken ,
1312 TextRange , TextUnit ,
1413} ;
1514use rustc_hash:: { FxHashMap , FxHashSet } ;
@@ -21,6 +20,7 @@ use crate::{
2120 Function , HirFileId , InFile , Local , MacroDef , Module , Name , Origin , Path , PathResolution ,
2221 ScopeDef , StructField , Trait , Type , TypeParam , VariantDef ,
2322} ;
23+ use hir_expand:: ExpansionInfo ;
2424use ra_prof:: profile;
2525
2626/// Primary API to get semantic information, like types, from syntax trees.
@@ -337,22 +337,12 @@ impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> {
337337
338338// FIXME: Change `HasSource` trait to work with `Semantics` and remove this?
339339pub fn original_range ( db : & impl HirDatabase , node : InFile < & SyntaxNode > ) -> FileRange {
340- let mut elem: InFile < SyntaxElement > = node. map ( |n| n. clone ( ) . into ( ) ) ;
341-
342- while let Some ( ( range, Origin :: Call ) ) = original_range_and_origin ( db, elem. as_ref ( ) ) {
340+ if let Some ( range) = original_range_opt ( db, node) {
343341 let original_file = range. file_id . original_file ( db) ;
344-
345342 if range. file_id == original_file. into ( ) {
346343 return FileRange { file_id : original_file, range : range. value } ;
347344 }
348345
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-
356346 log:: error!( "Fail to mapping up more for {:?}" , range) ;
357347 return FileRange { file_id : range. file_id . original_file ( db) , range : range. value } ;
358348 }
@@ -370,43 +360,42 @@ pub fn original_range(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> FileR
370360 FileRange { file_id : node. file_id . original_file ( db) , range : node. value . text_range ( ) }
371361}
372362
373- fn original_range_and_origin (
363+ fn original_range_opt (
374364 db : & impl HirDatabase ,
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- } ;
365+ node : InFile < & SyntaxNode > ,
366+ ) -> Option < InFile < TextRange > > {
367+ let expansion = node. file_id . expansion_info ( db) ?;
386368
387369 // the input node has only one token ?
388370 let single = skip_trivia_token ( node. value . first_token ( ) ?, Direction :: Next ) ?
389371 == skip_trivia_token ( node. value . last_token ( ) ?, Direction :: Prev ) ?;
390372
391373 Some ( node. value . descendants ( ) . find_map ( |it| {
392374 let first = skip_trivia_token ( it. first_token ( ) ?, Direction :: Next ) ?;
393- let last = skip_trivia_token ( it. last_token ( ) ?, Direction :: Prev ) ?;
394-
395- if !single && first == last {
396- return None ;
397- }
375+ let first = ascend_call_token ( db, & expansion, node. with_value ( first) ) ?;
398376
399- // Try to map first and last tokens of node, and, if success, return the union range of mapped tokens
400- let ( first, first_origin) = expansion. map_token_up ( node. with_value ( & first) ) ?;
401- let ( last, last_origin) = expansion. map_token_up ( node. with_value ( & last) ) ?;
377+ let last = skip_trivia_token ( it. last_token ( ) ?, Direction :: Prev ) ?;
378+ let last = ascend_call_token ( db, & expansion, node. with_value ( last) ) ?;
402379
403- if first. file_id != last. file_id || first_origin != last_origin {
380+ if ( !single && first == last) || ( first . file_id != last . file_id ) {
404381 return None ;
405382 }
406383
407- Some ( (
408- first. with_value ( first. value . text_range ( ) . extend_to ( & last. value . text_range ( ) ) ) ,
409- first_origin,
410- ) )
384+ Some ( first. with_value ( first. value . text_range ( ) . extend_to ( & last. value . text_range ( ) ) ) )
411385 } ) ?)
412386}
387+
388+ fn ascend_call_token (
389+ db : & impl HirDatabase ,
390+ expansion : & ExpansionInfo ,
391+ token : InFile < SyntaxToken > ,
392+ ) -> Option < InFile < SyntaxToken > > {
393+ let ( mapped, origin) = expansion. map_token_up ( token. as_ref ( ) ) ?;
394+ if origin != Origin :: Call {
395+ return None ;
396+ }
397+ if let Some ( info) = mapped. file_id . expansion_info ( db) {
398+ return ascend_call_token ( db, & info, mapped) ;
399+ }
400+ Some ( mapped)
401+ }
0 commit comments