@@ -81,7 +81,8 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext) -> Option
81
81
82
82
let anchor = if self_param. is_some ( ) { Anchor :: Method } else { Anchor :: Freestanding } ;
83
83
let insert_after = node_to_insert_after ( & body, anchor) ?;
84
- let module = ctx. sema . scope ( & insert_after) ?. module ( ) ;
84
+ let semantics_scope = ctx. sema . scope ( & insert_after) ?;
85
+ let module = semantics_scope. module ( ) ;
85
86
86
87
let ret_ty = body. return_ty ( ctx) ?;
87
88
let control_flow = body. external_control_flow ( ctx, & container_info) ?;
@@ -105,8 +106,10 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext) -> Option
105
106
let params =
106
107
body. extracted_function_params ( ctx, & container_info, locals_used. iter ( ) . copied ( ) ) ;
107
108
109
+ let name = make_function_name ( & semantics_scope) ;
110
+
108
111
let fun = Function {
109
- name : make :: name_ref ( "fun_name" ) ,
112
+ name,
110
113
self_param,
111
114
params,
112
115
control_flow,
@@ -155,6 +158,21 @@ pub(crate) fn extract_function(acc: &mut Assists, ctx: &AssistContext) -> Option
155
158
)
156
159
}
157
160
161
+ fn make_function_name ( semantics_scope : & hir:: SemanticsScope ) -> ast:: NameRef {
162
+ let mut names_in_scope = vec ! [ ] ;
163
+ semantics_scope. process_all_names ( & mut |name, _| names_in_scope. push ( name. to_string ( ) ) ) ;
164
+
165
+ let default_name = "fun_name" ;
166
+
167
+ let mut name = default_name. to_string ( ) ;
168
+ let mut counter = 0 ;
169
+ while names_in_scope. contains ( & name) {
170
+ counter += 1 ;
171
+ name = format ! ( "{}{}" , & default_name, counter)
172
+ }
173
+ make:: name_ref ( & name)
174
+ }
175
+
158
176
/// Try to guess what user wants to extract
159
177
///
160
178
/// We have basically have two cases:
@@ -4709,6 +4727,56 @@ fn $0fun_name() {
4709
4727
/* a comment */
4710
4728
let x = 0;
4711
4729
}
4730
+ "# ,
4731
+ ) ;
4732
+ }
4733
+
4734
+ #[ test]
4735
+ fn it_should_not_generate_duplicate_function_names ( ) {
4736
+ check_assist (
4737
+ extract_function,
4738
+ r#"
4739
+ fn fun_name() {
4740
+ $0let x = 0;$0
4741
+ }
4742
+ "# ,
4743
+ r#"
4744
+ fn fun_name() {
4745
+ fun_name1();
4746
+ }
4747
+
4748
+ fn $0fun_name1() {
4749
+ let x = 0;
4750
+ }
4751
+ "# ,
4752
+ ) ;
4753
+ }
4754
+
4755
+ #[ test]
4756
+ fn should_increment_suffix_until_it_finds_space ( ) {
4757
+ check_assist (
4758
+ extract_function,
4759
+ r#"
4760
+ fn fun_name1() {
4761
+ let y = 0;
4762
+ }
4763
+
4764
+ fn fun_name() {
4765
+ $0let x = 0;$0
4766
+ }
4767
+ "# ,
4768
+ r#"
4769
+ fn fun_name1() {
4770
+ let y = 0;
4771
+ }
4772
+
4773
+ fn fun_name() {
4774
+ fun_name2();
4775
+ }
4776
+
4777
+ fn $0fun_name2() {
4778
+ let x = 0;
4779
+ }
4712
4780
"# ,
4713
4781
) ;
4714
4782
}
0 commit comments