Skip to content

Commit

Permalink
format, docs, claenup aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
ckochx committed Sep 16, 2021
1 parent 50c381c commit a0a352b
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 105 deletions.
1 change: 0 additions & 1 deletion lib/ex_factor/callers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ defmodule ExFactor.Callers do
@doc """
use `mix xref` list all the callers of a given module.
"""
# @spec callers(module()) :: list(map())
def callers(mod) do
System.cmd("mix", ["xref", "callers", "#{mod}"], env: [{"MIX_ENV", "test"}])
|> elem(0)
Expand Down
9 changes: 7 additions & 2 deletions lib/ex_factor/extractor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ defmodule ExFactor.Extractor do
"""
alias ExFactor.Neighbors
alias ExFactor.Parser
alias ExFactor.Remover

@doc """
Given a keyword list of opts, find the function in the specified source, refactor it, the docs,
Given a keyword list of opts, find the function in the specified source.
Add the function (and any accociated attrs: @doc, @spec, ) into the target module. refactor it, the docs,
specs, and any miscellaneous attrs proximate to the source function into the specified module.
"""

Expand Down Expand Up @@ -46,13 +48,16 @@ defmodule ExFactor.Extractor do
end
end

@doc """
Remove the indicated function and its spec from it's original file.
"""
def remove(opts) do
source_module = Keyword.get(opts, :source_module)
source_function = Keyword.get(opts, :source_function)
arity = Keyword.get(opts, :arity)
source_path = Keyword.get(opts, :source_path, path(source_module))

ExFactor.Remover.remove(source_path, source_function, arity)
Remover.remove(source_path, source_function, arity)
end

defp path(module) do
Expand Down
2 changes: 2 additions & 0 deletions lib/ex_factor/neighbors.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ defmodule ExFactor.Neighbors do
cond do
arity == :unmatched ->
{[], acc ++ pending ++ [el]}

length(args) == arity ->
{[], acc ++ pending ++ [el]}

true ->
{[], acc}
end
Expand Down
28 changes: 20 additions & 8 deletions lib/ex_factor/parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,22 @@ defmodule ExFactor.Parser do
[map | acc]
end

defp walk_ast({:@, fn_meta, [{:spec, _meta, [{_, _, [{name, _, args} | _]} | _]} | _]} = node, acc, _token) do
defp walk_ast(
{:@, fn_meta, [{:spec, _meta, [{_, _, [{name, _, args} | _]} | _]} | _]} = node,
acc,
_token
) do
arity = length(args)
map = merge_maps(%{name: name, ast: node, arity: arity, defn: "@spec"}, fn_meta)
[map | acc]
end

defp walk_ast({tkn, fn_meta, [{:when, _when_meta, [{name, _meta, args} | _]} | _]} = node, acc, token) when tkn == token do
defp walk_ast(
{tkn, fn_meta, [{:when, _when_meta, [{name, _meta, args} | _]} | _]} = node,
acc,
token
)
when tkn == token do
arity = length(args)
map = merge_maps(%{name: name, ast: node, arity: arity, defn: token}, fn_meta)
[map | acc]
Expand Down Expand Up @@ -116,12 +125,15 @@ defmodule ExFactor.Parser do
end

defp find_end_line(meta) do
end_expression_line = meta
|> Keyword.get(:end_of_expression, [])
|> Keyword.get(:line, :unknown)
end_line = meta
|> Keyword.get(:end, [])
|> Keyword.get(:line, :unknown)
end_expression_line =
meta
|> Keyword.get(:end_of_expression, [])
|> Keyword.get(:line, :unknown)

end_line =
meta
|> Keyword.get(:end, [])
|> Keyword.get(:line, :unknown)

cond do
end_line != :unknown -> end_line
Expand Down
10 changes: 6 additions & 4 deletions lib/ex_factor/remover.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ defmodule ExFactor.Remover do

def remove(source_path, fn_name, arity) do
{_ast, block_contents} = Parser.all_functions(source_path)
fns_to_remove = Enum.filter(block_contents, & &1.name == fn_name)
fns_to_remove = Enum.filter(block_contents, &(&1.name == fn_name))
{_ast, line_list} = Parser.read_file(source_path)

Enum.reduce(fns_to_remove, line_list, fn function, acc ->
delete_range = function.start_line..function.end_line
|> Enum.to_list()
|> Enum.reverse
delete_range =
function.start_line..function.end_line
|> Enum.to_list()
|> Enum.reverse()

delete_range
|> Enum.reduce(acc, fn idx, acc ->
Expand All @@ -30,6 +31,7 @@ defmodule ExFactor.Remover do
# @spec: #{name}/#{arity} removed by ExFactor
"""
end

defp comment(name, arity, _) do
"""
#
Expand Down
10 changes: 6 additions & 4 deletions test/ex_factor/extractor_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ defmodule ExFactor.ExtractorTest do
@somedoc "This is somedoc"
# a comment and no aliases
_docp = "here's an arbitrary module underscore"
@spec pub1(term()) :: term()
def pub1(arg1) do
:ok
end
Expand All @@ -34,6 +35,11 @@ defmodule ExFactor.ExtractorTest do
file = File.read!(target_path)
assert file =~ "def(pub1(arg1))"
assert file =~ "defmodule(ExFactor.NewMod) do"
# includes additional attrs
assert file =~ "@spec(pub1(term()) :: term())"
assert file =~ "@somedoc(\"This is somedoc\")"
# comments don't get moved
refute file =~ "# a comment and no aliases"
File.rm("test/support/source_module.ex")
File.rm("test/support/target_module.ex")
end
Expand Down Expand Up @@ -231,13 +237,9 @@ defmodule ExFactor.ExtractorTest do
"""

File.write("test/support/source_module.ex", content)

source_path = "test/support/source_module.ex"
# File.rm(target_path)

opts = [
# target_path: target_path,
# target_module: ExFactor.NewMod,
source_module: ExFactorSampleModule,
source_path: "test/support/source_module.ex",
source_function: :pub1,
Expand Down
127 changes: 64 additions & 63 deletions test/ex_factor/parser_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,17 @@ defmodule ExFactor.ParserTest do
end

test "it should report public fns with start and end lines" do
content = """
defmodule ExFactorSampleModule do
@somedoc "This is somedoc"
# no aliases
def pub1(arg1) do
:ok
end
content = """
defmodule ExFactorSampleModule do
@somedoc "This is somedoc"
# no aliases
def pub1(arg1) do
:ok
end
"""
# |> Code.string_to_quoted()
end
"""

# |> Code.string_to_quoted()

File.write("test/tmp/other_module.ex", content)

Expand All @@ -70,15 +71,15 @@ defmodule ExFactor.ParserTest do

test "it should report specs with start and end lines" do
module = """
defmodule ExFactorSampleModule do
@somedoc "This is somedoc"
# no aliases
@spec pub1(term()) :: term()
def pub1(arg1) do
:ok
end
defmodule ExFactorSampleModule do
@somedoc "This is somedoc"
# no aliases
@spec pub1(term()) :: term()
def pub1(arg1) do
:ok
end
"""
end
"""

File.write("test/tmp/other_module.ex", module)

Expand All @@ -96,26 +97,26 @@ defmodule ExFactor.ParserTest do
end

test "it should report TWO public fns" do
content =
"""
defmodule ExFactorSampleModule do
@somedoc "This is somedoc"
# no aliases
def pub1(arg1) do
:ok
end
def pub2(arg2)
do
#comment
:yes
end
content = """
defmodule ExFactorSampleModule do
@somedoc "This is somedoc"
# no aliases
def pub1(arg1) do
:ok
end
defp pub3(arg3) do
:private
def pub2(arg2)
do
#comment
:yes
end
defp pub3(arg3) do
:private
end
"""
end
"""

File.write("test/tmp/other_module.ex", content)

{_ast, [f1, f2]} = Parser.public_functions("test/tmp/other_module.ex")
Expand All @@ -130,26 +131,26 @@ defmodule ExFactor.ParserTest do

# @tag :skip
test "it should handle when clauses" do
content =
"""
defmodule ExFactorSampleModule do
@somedoc "This is somedoc"
# no aliases
def pub1(arg1) do
:ok
end
def pub2(arg2) when is_map(arg2) and not is_nil(arg2)
do
#comment
:yes
end
content = """
defmodule ExFactorSampleModule do
@somedoc "This is somedoc"
# no aliases
def pub1(arg1) do
:ok
end
defp pub3(arg3) do
:private
def pub2(arg2) when is_map(arg2) and not is_nil(arg2)
do
#comment
:yes
end
defp pub3(arg3) do
:private
end
"""
end
"""

File.write("test/tmp/other_module.ex", content)

{_ast, [f1, f2]} = Parser.public_functions("test/tmp/other_module.ex")
Expand Down Expand Up @@ -263,13 +264,13 @@ defmodule ExFactor.ParserTest do

test "it should report specs with start and end lines" do
module = """
defmodule ExFactorSampleModule do
@spec priv1(term()) :: term()
defp priv1(arg1) do
:ok
end
defmodule ExFactorSampleModule do
@spec priv1(term()) :: term()
defp priv1(arg1) do
:ok
end
"""
end
"""

File.write("test/tmp/other_module.ex", module)

Expand All @@ -288,13 +289,13 @@ defmodule ExFactor.ParserTest do

test "it should report specs with 0-arity" do
module = """
defmodule ExFactorSampleModule do
@spec priv1() :: any()
defp priv1() do
:ok
end
defmodule ExFactorSampleModule do
@spec priv1() :: any()
defp priv1() do
:ok
end
"""
end
"""

File.write("test/tmp/other_module.ex", module)

Expand Down
44 changes: 21 additions & 23 deletions test/ex_factor/remover_test.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
defmodule ExFactor.RemoverTest do
use ExUnit.Case
alias ExFactor.Remover
# alias ExFactor.Parser

setup_all do
File.mkdir_p("test/tmp")
Expand All @@ -13,31 +12,30 @@ defmodule ExFactor.RemoverTest do

describe "remove/1" do
test "it rewrites the source file and removes code blocks" do
module =
"""
defmodule ExFactorSampleModule do
@somedoc "This is somedoc"
# comments get dropped
@doc "
multiline
documentation for pub1
"
@spec pub1(term()) :: term()
def pub1(arg1) do
:ok
end
_docp = "arbitrary module-level elem"
defp priv1(arg1) do
module = """
defmodule ExFactorSampleModule do
@somedoc "This is somedoc"
# comments get dropped
@doc "
multiline
documentation for pub1
"
@spec pub1(term()) :: term()
def pub1(arg1) do
:ok
end
_docp = "arbitrary module-level elem"
defp priv1(arg1) do
:ok
end
def pub2(arg1)
do
:ok
end
def pub2(arg1)
do
:ok
end
end
"""
end
"""

File.write("test/tmp/source_module.ex", module)
Remover.remove("test/tmp/source_module.ex", :pub1, 1)
Expand Down

0 comments on commit a0a352b

Please sign in to comment.