Skip to content

Commit ab6c478

Browse files
committed
refactor: replaced most abstractions provided by Variable
1 parent 5c33633 commit ab6c478

File tree

8 files changed

+56
-91
lines changed

8 files changed

+56
-91
lines changed

lib/refactorex/refactor/ast.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ defmodule Refactorex.Refactor.AST do
5050
zipper
5151
|> Z.top()
5252
|> Z.traverse([], fn %{node: node} = zipper, nodes ->
53-
if finder.(node),
53+
if finder.(zipper),
5454
do: {zipper, [node | nodes]},
5555
else: {zipper, nodes}
5656
end)

lib/refactorex/refactor/constant/extract_constant.ex

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ defmodule Refactorex.Refactor.Constant.ExtractConstant do
2525
not Module.inside_one?(zipper) ->
2626
false
2727

28-
Enum.any?(Variable.list_variables(node)) ->
28+
Enum.any?(AST.find(selection, &Variable.at_one?/1)) ->
2929
:skip
3030

3131
match?(%{node: {:|>, _, [_, ^node]}}, Z.up(zipper)) ->
@@ -68,8 +68,10 @@ defmodule Refactorex.Refactor.Constant.ExtractConstant do
6868
{{:@, _, [{:behaviour, _, _}]}, i} ->
6969
i + 1
7070

71-
{{:@, _, [constant]}, i} ->
72-
if Variable.member?(constants_used, constant), do: i + 1, else: 0
71+
{{:@, _, [{name, _, _}]}, i} ->
72+
if Enum.any?(constants_used, &match?({^name, _, _}, &1)),
73+
do: i + 1,
74+
else: 0
7375

7476
_ ->
7577
0
@@ -79,7 +81,7 @@ defmodule Refactorex.Refactor.Constant.ExtractConstant do
7981

8082
defp find_constants_used(to_be_constant) do
8183
to_be_constant
82-
|> AST.find(&match?({:@, _, [{_, _, nil}]}, &1))
84+
|> AST.find(&match?({:@, _, [{_, _, nil}]}, &1.node))
8385
|> Enum.map(fn {:@, _, [constant]} -> constant end)
8486
end
8587
end

lib/refactorex/refactor/constant/inline_constant.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ defmodule Refactorex.Refactor.Constant.InlineConstant do
2727

2828
defp find_definition(%{node: {:@, _, [{id, _, _}]}} = zipper) do
2929
zipper
30-
|> AST.find(&match?({:@, _, [{^id, _, u}]} when not is_nil(u), &1))
30+
|> AST.find(&match?({:@, _, [{^id, _, u}]} when not is_nil(u), &1.node))
3131
|> List.first()
3232
end
3333
end

lib/refactorex/refactor/dataflow.ex

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
defmodule Refactorex.Refactor.Dataflow do
22
alias Sourceror.Zipper, as: Z
3-
4-
defguard is_variable(node)
5-
when is_tuple(node) and
6-
tuple_size(node) == 3 and
7-
is_atom(elem(node, 0)) and
8-
elem(node, 0) != :binary and
9-
is_nil(elem(node, 2))
3+
import Refactorex.Refactor.Variable, only: [is_variable: 1]
104

115
defstruct commands: [],
126
variables: []

lib/refactorex/refactor/function/collapse_anonymous_function.ex

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ defmodule Refactorex.Refactor.Function.CollapseAnonymousFunction do
66

77
alias Refactorex.Refactor.{
88
Block,
9+
Dataflow,
910
Variable
1011
}
1112

@@ -19,12 +20,14 @@ defmodule Refactorex.Refactor.Function.CollapseAnonymousFunction do
1920
Block.has_multiple_statements?(body) ->
2021
false
2122

22-
args != Variable.list_unpinned_variables(args) ->
23+
not Variable.plain_variables?(args) ->
24+
false
25+
26+
some_arg_not_used?(args, Dataflow.analyze(node)) ->
2327
false
2428

2529
true ->
26-
used_variables = Variable.list_unique_variables(body)
27-
Enum.all?(args, &Variable.member?(used_variables, &1))
30+
true
2831
end
2932
end
3033

@@ -38,4 +41,7 @@ defmodule Refactorex.Refactor.Function.CollapseAnonymousFunction do
3841
{:&, [], [Variable.replace_variables_by_values(body, args, new_args, node)]}
3942
)
4043
end
44+
45+
defp some_arg_not_used?(args, dataflow),
46+
do: not Enum.all?(args, &match?([_ | _], dataflow[&1]))
4147
end

lib/refactorex/refactor/function/inline_function.ex

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ defmodule Refactorex.Refactor.Function.InlineFunction do
104104
statement -> [statement]
105105
end
106106

107-
if all_simple_variables?(args) do
107+
if Variable.plain_variables?(args) do
108108
Variable.replace_variables_by_values(
109109
statements,
110110
args,
@@ -157,7 +157,4 @@ defmodule Refactorex.Refactor.Function.InlineFunction do
157157
else: zipper
158158
)
159159
end
160-
161-
defp all_simple_variables?(args),
162-
do: Enum.all?(args, &match?({_, _, nil}, &1))
163160
end

lib/refactorex/refactor/guard/extract_guard.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ defmodule Refactorex.Refactor.Guard.ExtractGuard do
77
alias Refactorex.NameCache
88

99
alias Refactorex.Refactor.{
10+
Dataflow,
1011
Guard,
11-
Module,
12-
Variable
12+
Module
1313
}
1414

1515
@guard_name "extracted_guard"
@@ -32,7 +32,7 @@ defmodule Refactorex.Refactor.Guard.ExtractGuard do
3232

3333
def refactor(%{node: node} = zipper, _) do
3434
name = next_available_guard_name(zipper)
35-
args = Variable.list_unique_variables(node)
35+
args = Dataflow.outer_variables(node)
3636

3737
zipper
3838
|> Z.replace({name, [], args})

lib/refactorex/refactor/variable.ex

Lines changed: 34 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,46 @@ defmodule Refactorex.Refactor.Variable do
66
Dataflow
77
}
88

9-
def at_one?(%{node: {name, _, nil}} = zipper) do
10-
cond do
11-
not is_atom(name) or name in ~w(binary _)a ->
12-
false
9+
defguard is_variable(node)
10+
when is_tuple(node) and
11+
tuple_size(node) == 3 and
12+
is_atom(elem(node, 0)) and
13+
elem(node, 0) not in ~w(binary _)a and
14+
is_nil(elem(node, 2))
1315

14-
match?(%{node: {:@, _, _}}, Z.up(zipper)) ->
15-
false
16+
def at_one?(%{node: node} = zipper) when is_variable(node),
17+
do: not match?(%{node: {:@, _, _}}, Z.up(zipper))
18+
19+
def at_one?(_zipper), do: false
20+
21+
def plain_variables?(nodes), do: Enum.all?(nodes, &is_variable(&1))
1622

17-
true ->
23+
def inside_declaration?(%{node: node} = zipper) do
24+
case parent = Z.up(zipper) do
25+
%{node: {id, _, [^node, _]}} when id in ~w(def defp <- when =)a ->
1826
true
27+
28+
%{node: {:->, _, [^node, _]}} ->
29+
cond do
30+
match?(%{node: {:fn, _, _}}, Z.up(parent)) -> true
31+
match?(%{node: {:case, _, _}}, AST.up(parent, 4)) -> true
32+
true -> false
33+
end
34+
35+
%{node: {_, _, [_ | _]}} ->
36+
inside_declaration?(parent)
37+
38+
%{node: [_ | _]} ->
39+
inside_declaration?(parent)
40+
41+
%{node: {_, _}} ->
42+
inside_declaration?(parent)
43+
44+
_ ->
45+
false
1946
end
2047
end
2148

22-
def at_one?(_zipper), do: false
23-
2449
def find_all_references(zipper, {name, _, _} = variable) do
2550
zipper
2651
|> Z.topmost_root()
@@ -48,65 +73,6 @@ defmodule Refactorex.Refactor.Variable do
4873
|> Z.node()
4974
end
5075

51-
def list_unique_variables(node, filter_fn \\ fn _zipper -> true end) do
52-
node
53-
|> list_variables(filter_fn)
54-
|> Enum.uniq_by(fn {name, _, _} -> name end)
55-
end
56-
57-
def list_unpinned_variables(node),
58-
do: list_variables(node, &(not match?(%{node: {:^, _, _}}, Z.up(&1))))
59-
60-
def list_variables(node, filter_fn \\ fn _zipper -> true end) do
61-
node
62-
|> Z.zip()
63-
|> Z.traverse_while([], fn
64-
%{node: node} = zipper, variables ->
65-
cond do
66-
not at_one?(zipper) ->
67-
{:cont, zipper, variables}
68-
69-
not filter_fn.(zipper) ->
70-
{:cont, zipper, variables}
71-
72-
true ->
73-
{:cont, zipper, variables ++ [node]}
74-
end
75-
end)
76-
|> elem(1)
77-
end
78-
79-
def member?(variables, {name, _, _} = _variable),
80-
do: Enum.any?(variables, &match?({^name, _, _}, &1))
81-
82-
def member?(_, _), do: false
83-
84-
def inside_declaration?(%{node: node} = zipper) do
85-
case parent = Z.up(zipper) do
86-
%{node: {id, _, [^node, _]}} when id in ~w(def defp <- when =)a ->
87-
true
88-
89-
%{node: {:->, _, [^node, _]}} ->
90-
cond do
91-
match?(%{node: {:fn, _, _}}, Z.up(parent)) -> true
92-
match?(%{node: {:case, _, _}}, AST.up(parent, 4)) -> true
93-
true -> false
94-
end
95-
96-
%{node: {_, _, [_ | _]}} ->
97-
inside_declaration?(parent)
98-
99-
%{node: [_ | _]} ->
100-
inside_declaration?(parent)
101-
102-
%{node: {_, _}} ->
103-
inside_declaration?(parent)
104-
105-
_ ->
106-
false
107-
end
108-
end
109-
11076
# find &{i} usages and replace them with arg{i}
11177
def turn_captures_into_variables(node) do
11278
node

0 commit comments

Comments
 (0)