@@ -5,7 +5,7 @@ use ide_db::{
5
5
EditionedFileId , RootDatabase ,
6
6
} ;
7
7
use syntax:: {
8
- ast:: { self , AstNode , AstToken , HasName } ,
8
+ ast:: { self , syntax_factory :: SyntaxFactory , AstNode , AstToken , HasName } ,
9
9
SyntaxElement , TextRange ,
10
10
} ;
11
11
@@ -43,22 +43,6 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>)
43
43
} ?;
44
44
let initializer_expr = let_stmt. initializer ( ) ?;
45
45
46
- let delete_range = delete_let. then ( || {
47
- if let Some ( whitespace) = let_stmt
48
- . syntax ( )
49
- . next_sibling_or_token ( )
50
- . and_then ( SyntaxElement :: into_token)
51
- . and_then ( ast:: Whitespace :: cast)
52
- {
53
- TextRange :: new (
54
- let_stmt. syntax ( ) . text_range ( ) . start ( ) ,
55
- whitespace. syntax ( ) . text_range ( ) . end ( ) ,
56
- )
57
- } else {
58
- let_stmt. syntax ( ) . text_range ( )
59
- }
60
- } ) ;
61
-
62
46
let wrap_in_parens = references
63
47
. into_iter ( )
64
48
. filter_map ( |FileReference { range, name, .. } | match name {
@@ -76,37 +60,55 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>)
76
60
let usage_parent_option = usage_node. and_then ( |it| it. parent ( ) ) ;
77
61
let usage_parent = match usage_parent_option {
78
62
Some ( u) => u,
79
- None => return Some ( ( range , name_ref, false ) ) ,
63
+ None => return Some ( ( name_ref, false ) ) ,
80
64
} ;
81
- Some ( ( range , name_ref, initializer_expr. needs_parens_in ( & usage_parent) ) )
65
+ Some ( ( name_ref, initializer_expr. needs_parens_in ( & usage_parent) ) )
82
66
} )
83
67
. collect :: < Option < Vec < _ > > > ( ) ?;
84
68
85
- let init_str = initializer_expr. syntax ( ) . text ( ) . to_string ( ) ;
86
- let init_in_paren = format ! ( "({init_str})" ) ;
87
-
88
69
let target = match target {
89
- ast:: NameOrNameRef :: Name ( it) => it. syntax ( ) . text_range ( ) ,
90
- ast:: NameOrNameRef :: NameRef ( it) => it. syntax ( ) . text_range ( ) ,
70
+ ast:: NameOrNameRef :: Name ( it) => it. syntax ( ) . clone ( ) ,
71
+ ast:: NameOrNameRef :: NameRef ( it) => it. syntax ( ) . clone ( ) ,
91
72
} ;
92
73
93
74
acc. add (
94
75
AssistId ( "inline_local_variable" , AssistKind :: RefactorInline ) ,
95
76
"Inline variable" ,
96
- target,
77
+ target. text_range ( ) ,
97
78
move |builder| {
98
- if let Some ( range) = delete_range {
99
- builder. delete ( range) ;
79
+ let mut editor = builder. make_editor ( & target) ;
80
+ if delete_let {
81
+ editor. delete ( let_stmt. syntax ( ) ) ;
82
+ if let Some ( whitespace) = let_stmt
83
+ . syntax ( )
84
+ . next_sibling_or_token ( )
85
+ . and_then ( SyntaxElement :: into_token)
86
+ . and_then ( ast:: Whitespace :: cast)
87
+ {
88
+ editor. delete ( whitespace. syntax ( ) ) ;
89
+ }
100
90
}
101
- for ( range, name, should_wrap) in wrap_in_parens {
102
- let replacement = if should_wrap { & init_in_paren } else { & init_str } ;
103
- if ast:: RecordExprField :: for_field_name ( & name) . is_some ( ) {
91
+
92
+ let make = SyntaxFactory :: new ( ) ;
93
+
94
+ for ( name, should_wrap) in wrap_in_parens {
95
+ let replacement = if should_wrap {
96
+ make. expr_paren ( initializer_expr. clone ( ) ) . into ( )
97
+ } else {
98
+ initializer_expr. clone ( )
99
+ } ;
100
+
101
+ if let Some ( record_field) = ast:: RecordExprField :: for_field_name ( & name) {
104
102
cov_mark:: hit!( inline_field_shorthand) ;
105
- builder. insert ( range. end ( ) , format ! ( ": {replacement}" ) ) ;
103
+ let replacement = make. record_expr_field ( name, Some ( replacement) ) ;
104
+ editor. replace ( record_field. syntax ( ) , replacement. syntax ( ) ) ;
106
105
} else {
107
- builder . replace ( range , replacement. clone ( ) )
106
+ editor . replace ( name . syntax ( ) , replacement. syntax ( ) ) ;
108
107
}
109
108
}
109
+
110
+ editor. add_mappings ( make. finish_with_mappings ( ) ) ;
111
+ builder. add_file_edits ( ctx. file_id ( ) , editor) ;
110
112
} ,
111
113
)
112
114
}
0 commit comments