Skip to content

Commit

Permalink
Error when lines not extractable to function
Browse files Browse the repository at this point in the history
  • Loading branch information
robmckinnon committed May 3, 2023
1 parent ebbbd26 commit ce2cd59
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,30 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.ExtractFunction do
"""
def extract_function(zipper, start_line, end_line, function_name) do
{quoted_after_extract, acc} = extract_lines(zipper, start_line, end_line, function_name)

new_function_zipper = new_function(function_name, [], acc.lines) |> Z.zip()
declared_vars = vars_declared(new_function_zipper) |> Enum.uniq()
used_vars = vars_used(new_function_zipper) |> Enum.uniq()

args = used_vars -- declared_vars
returns = declared_vars |> Enum.filter(&(&1 in acc.vars))

{zipper, extracted} =
add_returned_vars(Z.zip(quoted_after_extract), returns, function_name, args, acc.lines)

enclosing = acc.def

zipper
|> top_find(fn
{:def, _meta, [{^enclosing, _, _}, _]} -> true
_ -> false
end)
|> Z.insert_right(extracted)
|> fix_block()
|> Z.root()
if Enum.empty?(acc.lines) do
{:error, :not_extractable}
else
new_function_zipper = new_function(function_name, [], acc.lines) |> Z.zip()
declared_vars = vars_declared(new_function_zipper) |> Enum.uniq()
used_vars = vars_used(new_function_zipper) |> Enum.uniq()

args = used_vars -- declared_vars
returns = declared_vars |> Enum.filter(&(&1 in acc.vars))

{zipper, extracted} =
add_returned_vars(Z.zip(quoted_after_extract), returns, function_name, args, acc.lines)

enclosing = acc.def

zipper
|> top_find(fn
{:def, _meta, [{^enclosing, _, _}, _]} -> true
_ -> false
end)
|> Z.insert_right(extracted)
|> fix_block()
|> Z.root()
end
end

@doc """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.ExtractFunctionTest do

Code.eval_string(source)
end

@tag no: 6
test "errors when extract on second line of multi-line function call", %{quoted: quoted} do
{:error, :not_extractable} = ExtractFunction.extract_function(Z.zip(quoted), 11, 11, :bar)
end
end

describe "extract_lines/3" do
Expand Down Expand Up @@ -254,5 +259,21 @@ defmodule ElixirLS.LanguageServer.Experimental.CodeMod.ExtractFunctionTest do
"{:vars, []}"
] = lines |> Enum.map(&Sourceror.to_string(&1))
end

@tag no: 23
test "noop when second line of multi-line function call", %{quoted: quoted} do
{zipper, lines} = ExtractFunction.extract_lines(Z.zip(quoted), 11, 11)

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" =
Sourceror.to_string(zipper)

assert [
"{:def, :foo}",
"{:def_end, 15}",
"{:lines, []}",
"{:replace_with, nil}",
"{:vars, []}"
] = lines |> Enum.map(&Sourceror.to_string(&1))
end
end
end

0 comments on commit ce2cd59

Please sign in to comment.