@@ -12,7 +12,7 @@ use ide_db::{
12
12
RootDatabase ,
13
13
} ;
14
14
use itertools:: Itertools ;
15
- use stdx:: { always , never} ;
15
+ use stdx:: never;
16
16
use syntax:: { ast, AstNode , SyntaxNode } ;
17
17
18
18
use text_edit:: TextEdit ;
@@ -33,17 +33,35 @@ pub(crate) fn prepare_rename(
33
33
let source_file = sema. parse ( position. file_id ) ;
34
34
let syntax = source_file. syntax ( ) ;
35
35
36
- let mut defs = find_definitions ( & sema, syntax, position) ?;
37
-
38
- // TODO:
39
- // - `find_definitions` is implemented so that it returns a non-empty vec
40
- // in the `Ok` case. But that's not expressed by the type signature, hence `unwrap()`
41
- // here which ... wart.
42
- // - is "just take the first `name_like`" correct? If not, what do?
43
- let ( name_like, _def) = defs. next ( ) . unwrap ( ) ;
44
- let frange = sema. original_range ( name_like. syntax ( ) ) ;
45
- always ! ( frange. range. contains_inclusive( position. offset) && frange. file_id == position. file_id) ;
46
- Ok ( RangeInfo :: new ( frange. range , ( ) ) )
36
+ let res = find_definitions ( & sema, syntax, position) ?
37
+ . map ( |( name_like, def) | {
38
+ // ensure all ranges are valid
39
+
40
+ if def. range_for_rename ( & sema) . is_none ( ) {
41
+ bail ! ( "No references found at position" )
42
+ }
43
+ let frange = sema. original_range ( name_like. syntax ( ) ) ;
44
+ if frange. range . contains_inclusive ( position. offset )
45
+ && frange. file_id == position. file_id
46
+ {
47
+ Ok ( frange. range )
48
+ } else {
49
+ bail ! ( "invalid text range" )
50
+ }
51
+ } )
52
+ . reduce ( |acc, cur| match acc {
53
+ // ensure all ranges are the same
54
+ Ok ( acc_inner) if cur. is_ok ( ) && acc_inner == cur. unwrap ( ) => acc,
55
+ Err ( e) => Err ( e) ,
56
+ _ => bail ! ( "inconsistent text range" ) ,
57
+ } ) ;
58
+
59
+ match res {
60
+ // ensure at least one definition was found
61
+ // TODO this duplicates work done at the end of `find_definitions`
62
+ Some ( res) => res. map ( |range| RangeInfo :: new ( range, ( ) ) ) ,
63
+ None => bail ! ( "No references found at position" ) ,
64
+ }
47
65
}
48
66
49
67
// Feature: Rename
0 commit comments