Skip to content

Commit ce2cd59

Browse files
committed
Error when lines not extractable to function
1 parent ebbbd26 commit ce2cd59

File tree

2 files changed

+45
-21
lines changed

2 files changed

+45
-21
lines changed

apps/language_server/lib/language_server/experimental/code_mod/extract_function.ex

+24-21
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,30 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.ExtractFunction do
1010
"""
1111
def extract_function(zipper, start_line, end_line, function_name) do
1212
{quoted_after_extract, acc} = extract_lines(zipper, start_line, end_line, function_name)
13-
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)
23-
24-
enclosing = acc.def
25-
26-
zipper
27-
|> top_find(fn
28-
{:def, _meta, [{^enclosing, _, _}, _]} -> true
29-
_ -> false
30-
end)
31-
|> Z.insert_right(extracted)
32-
|> fix_block()
33-
|> Z.root()
13+
if Enum.empty?(acc.lines) do
14+
{:error, :not_extractable}
15+
else
16+
new_function_zipper = new_function(function_name, [], acc.lines) |> Z.zip()
17+
declared_vars = vars_declared(new_function_zipper) |> Enum.uniq()
18+
used_vars = vars_used(new_function_zipper) |> Enum.uniq()
19+
20+
args = used_vars -- declared_vars
21+
returns = declared_vars |> Enum.filter(&(&1 in acc.vars))
22+
23+
{zipper, extracted} =
24+
add_returned_vars(Z.zip(quoted_after_extract), returns, function_name, args, acc.lines)
25+
26+
enclosing = acc.def
27+
28+
zipper
29+
|> top_find(fn
30+
{:def, _meta, [{^enclosing, _, _}, _]} -> true
31+
_ -> false
32+
end)
33+
|> Z.insert_right(extracted)
34+
|> fix_block()
35+
|> Z.root()
36+
end
3437
end
3538

3639
@doc """

apps/language_server/test/experimental/code_mod/extract_function_test.exs

+21
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.ExtractFunctionTest do
204204

205205
Code.eval_string(source)
206206
end
207+
208+
@tag no: 6
209+
test "errors when extract on second line of multi-line function call", %{quoted: quoted} do
210+
{:error, :not_extractable} = ExtractFunction.extract_function(Z.zip(quoted), 11, 11, :bar)
211+
end
207212
end
208213

209214
describe "extract_lines/3" do
@@ -254,5 +259,21 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.ExtractFunctionTest do
254259
"{:vars, []}"
255260
] = lines |> Enum.map(&Sourceror.to_string(&1))
256261
end
262+
263+
@tag no: 23
264+
test "noop when second line of multi-line function call", %{quoted: quoted} do
265+
{zipper, lines} = ExtractFunction.extract_lines(Z.zip(quoted), 11, 11)
266+
267+
assert "defmodule Baz23 do\n def foo(one, two) do\n three = 3\n IO.inspect(one)\n IO.inspect(two)\n IO.inspect(three)\n four = 4\n IO.inspect(three)\n\n IO.inspect(\n four: four,\n force_format_on_new_line_with_really_long_atom: true\n )\n\n # comment\n end\nend" =
268+
Sourceror.to_string(zipper)
269+
270+
assert [
271+
"{:def, :foo}",
272+
"{:def_end, 15}",
273+
"{:lines, []}",
274+
"{:replace_with, nil}",
275+
"{:vars, []}"
276+
] = lines |> Enum.map(&Sourceror.to_string(&1))
277+
end
257278
end
258279
end

0 commit comments

Comments
 (0)