-
Notifications
You must be signed in to change notification settings - Fork 13
/
io_inspect.ex
93 lines (76 loc) · 2.33 KB
/
io_inspect.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
defmodule Recode.Task.IOInspect do
@shortdoc "There should be no calls to IO.inspect."
@moduledoc """
Calls to `IO.inspect/2` should only appear in debug sessions.
This task rewrites the code when `mix recode` runs with `autocorrect: true`.
"""
use Recode.Task, corrector: true, category: :warning
alias Recode.Issue
alias Recode.Task.IOInspect
alias Rewrite.Source
alias Sourceror.Zipper
@impl Recode.Task
def run(source, opts) do
source
|> Source.get(:quoted)
|> Zipper.zip()
|> Zipper.traverse([], fn zipper, issues ->
traverse(zipper, issues, opts[:autocorrect])
end)
|> update(source, opts[:autocorrect])
end
defp update({zipper, _issues}, source, true) do
Source.update(source, IOInspect, :quoted, Zipper.root(zipper))
end
defp update({_zipper, []}, source, false), do: source
defp update({_zipper, issues}, source, false) do
Source.add_issues(source, issues)
end
defp traverse(
%Zipper{
node: {:|>, _, [arg, {{:., _, [{:__aliases__, _, [:IO]}, :inspect]}, _, _}]}
} = zipper,
issues,
true
) do
{Zipper.replace(zipper, arg), issues}
end
defp traverse(
%Zipper{node: {{:., _, [{:__aliases__, meta, [:IO]}, :inspect]}, _, args}} = zipper,
issues,
autocorrect
)
when is_list(args) do
handle(zipper, issues, meta, autocorrect)
end
defp traverse(
%Zipper{
node: {:&, meta, [{:/, _, [{{:., _, [{:__aliases__, _, [:IO]}, :inspect]}, _, _}, _]}]}
} = zipper,
issues,
autocorrect
) do
handle_up(zipper, issues, meta, autocorrect)
end
defp traverse(zipper, issues, _autocorrect) do
{zipper, issues}
end
defp handle(zipper, issues, _meta, true) do
{Zipper.remove(zipper), issues}
end
defp handle(zipper, issues, meta, false) do
issue = Issue.new(IOInspect, @shortdoc, meta)
{zipper, [issue | issues]}
end
defp handle_up(zipper, issues, meta, true) do
up = Zipper.up(zipper)
upup = Zipper.up(up)
case upup do
%Zipper{node: {:|>, _, [arg, _]}} -> {Zipper.replace(upup, arg), issues}
_else -> handle(up, issues, meta, true)
end
end
defp handle_up(zipper, issues, meta, false) do
zipper |> Zipper.next() |> Zipper.next() |> handle(issues, meta, false)
end
end