@@ -9,14 +9,17 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.ExtractFunction do
9
9
Return zipper containing AST with extracted function.
10
10
"""
11
11
def extract_function ( zipper , start_line , end_line , function_name ) do
12
- { quoted , acc } = extract_lines ( zipper , start_line , end_line , function_name )
13
- zipper = Z . zip ( quoted )
12
+ { quoted_after_extract , acc } = extract_lines ( zipper , start_line , end_line , function_name )
14
13
15
- declares = vars_declared ( function_name , [ ] , acc . lines ) |> Enum . uniq ( )
16
- used = vars_used ( function_name , [ ] , acc . lines ) |> Enum . uniq ( )
17
- args = Enum . map ( used -- declares , fn var -> { var , [ ] , nil } end )
18
- returns = declares |> Enum . filter ( & ( & 1 in acc . vars ) )
19
- { zipper , extracted } = return_declared ( zipper , returns , function_name , args , acc . lines )
14
+ new_function_zipper = new_function ( function_name , [ ] , acc . lines ) |> Z . zip ( )
15
+ declared_vars = vars_declared ( new_function_zipper ) |> Enum . uniq ( )
16
+ used_vars = vars_used ( new_function_zipper ) |> Enum . uniq ( )
17
+
18
+ args = used_vars -- declared_vars
19
+ returns = declared_vars |> Enum . filter ( & ( & 1 in acc . vars ) )
20
+
21
+ { zipper , extracted } =
22
+ add_returned_vars ( Z . zip ( quoted_after_extract ) , returns , function_name , args , acc . lines )
20
23
21
24
enclosing = acc . def
22
25
@@ -101,11 +104,8 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.ExtractFunction do
101
104
next_remove_range ( zipper , from , to , acc )
102
105
end
103
106
104
- defp vars_declared ( function_name , args , lines ) do
105
- function_name
106
- |> new_function ( args , lines )
107
- |> Z . zip ( )
108
- |> vars_declared ( % { vars: [ ] } )
107
+ defp vars_declared ( new_function_zipper ) do
108
+ vars_declared ( new_function_zipper , % { vars: [ ] } )
109
109
end
110
110
111
111
defp vars_declared ( nil , acc ) do
@@ -124,11 +124,8 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.ExtractFunction do
124
124
|> vars_declared ( acc )
125
125
end
126
126
127
- defp vars_used ( function_name , args , lines ) do
128
- function_name
129
- |> new_function ( args , lines )
130
- |> Z . zip ( )
131
- |> vars_used ( % { vars: [ ] } )
127
+ defp vars_used ( new_function_zipper ) do
128
+ vars_used ( new_function_zipper , % { vars: [ ] } )
132
129
end
133
130
134
131
defp vars_used ( nil , acc ) do
@@ -147,53 +144,53 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.ExtractFunction do
147
144
|> vars_used ( acc )
148
145
end
149
146
150
- defp return_declared ( zipper , nil = _declares , function_name , args , lines ) do
151
- { zipper , new_function ( function_name , args , lines ) }
152
- end
153
-
154
- defp return_declared ( zipper , [ var ] , function_name , args , lines ) when is_atom ( var ) do
155
- zipper =
156
- zipper
157
- |> top_find ( fn
158
- { ^ function_name , [ ] , [ ] } -> true
159
- _ -> false
160
- end )
161
- |> Z . replace ( { := , [ ] , [ { var , [ ] , nil } , { function_name , [ ] , args } ] } )
162
-
163
- { zipper , new_function ( function_name , args , Enum . concat ( lines , [ { var , [ ] , nil } ] ) ) }
164
- end
165
-
166
- defp return_declared ( zipper , declares , function_name , args , lines ) when is_list ( declares ) do
167
- declares = Enum . reduce ( declares , { } , fn var , acc -> Tuple . append ( acc , { var , [ ] , nil } ) end )
168
-
169
- zipper =
170
- zipper
171
- |> top_find ( fn
172
- { ^ function_name , [ ] , [ ] } -> true
173
- _ -> false
174
- end )
175
- |> Z . replace (
176
- { := , [ ] ,
177
- [
178
- { :__block__ , [ ] ,
179
- [
180
- declares
181
- ] } ,
182
- { function_name , [ ] , args }
183
- ] }
184
- )
147
+ defp add_returned_vars ( zipper , _returns = [ ] , function_name , args , lines ) do
148
+ args = var_ast ( args )
149
+
150
+ {
151
+ replace_function_call ( zipper , function_name , { function_name , [ ] , args } ) ,
152
+ new_function ( function_name , args , lines )
153
+ }
154
+ end
155
+
156
+ defp add_returned_vars ( zipper , returns , function_name , args , lines ) when is_list ( returns ) do
157
+ args = var_ast ( args )
158
+ returned_vars = returned ( returns )
159
+
160
+ {
161
+ replace_function_call (
162
+ zipper ,
163
+ function_name ,
164
+ { := , [ ] , [ returned_vars , { function_name , [ ] , args } ] }
165
+ ) ,
166
+ new_function ( function_name , args , Enum . concat ( lines , [ returned_vars ] ) )
167
+ }
168
+ end
169
+
170
+ defp var_ast ( vars ) when is_list ( vars ) do
171
+ Enum . map ( vars , & var_ast / 1 )
172
+ end
185
173
186
- { zipper ,
187
- new_function (
188
- function_name ,
189
- args ,
190
- Enum . concat ( lines , [
191
- { :__block__ , [ ] ,
192
- [
193
- declares
194
- ] }
195
- ] )
196
- ) }
174
+ defp var_ast ( var ) when is_atom ( var ) do
175
+ { var , [ ] , nil }
176
+ end
177
+
178
+ defp returned ( [ var ] ) when is_atom ( var ) do
179
+ var_ast ( var )
180
+ end
181
+
182
+ defp returned ( vars ) when is_list ( vars ) do
183
+ returned = vars |> var_ast ( ) |> List . to_tuple ( )
184
+ { :__block__ , [ ] , [ returned ] }
185
+ end
186
+
187
+ defp replace_function_call ( zipper , function_name , replace_with ) do
188
+ zipper
189
+ |> top_find ( fn
190
+ { ^ function_name , [ ] , [ ] } -> true
191
+ _ -> false
192
+ end )
193
+ |> Z . replace ( replace_with )
197
194
end
198
195
199
196
defp new_function ( function_name , args , lines ) do
0 commit comments