-
Notifications
You must be signed in to change notification settings - Fork 15
/
add_use.exs
69 lines (54 loc) · 1.65 KB
/
add_use.exs
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
# A little demo for a task to add `use ...` to an existing module.
# Run with: mix run scripts/add_use.exs
alias Recode.AST
alias Recode.Formatter
alias Rewrite.Project
alias Rewrite.Source
alias Recode.Traverse
alias Sourceror.Zipper
defmodule AddUse do
@moduledoc false
use Recode.Task
@impl Recode.Task
def run(source, opts) do
use = opts |> Keyword.get(:use) |> gen_use()
ast =
source
|> Source.ast()
# get a zipper from the source
|> Zipper.zip()
# move to the right moudle (the source could contain multiple modules)
|> Traverse.to_defmodule!(opts[:module])
# insert the new code after current position or after @moduledoc
|> insert(use)
# return the root AST
|> Zipper.root()
Source.update(source, __MODULE__, ast: ast)
end
defp insert(zipper, ast) do
zipper =
case Traverse.to(zipper, {:@, :moduledoc}) do
{:ok, zipper} -> zipper
:error -> zipper
end
Zipper.insert_right(zipper, ast)
end
defp gen_use(module) when is_atom(module), do: gen_use({module, []})
defp gen_use({module, opts}) do
AST.gen(:use, module, opts)
end
end
project = "{config,lib,test}/**/*.{ex,exs}" |> Path.wildcard() |> Project.read!()
module = MyCode.Happy
use = {Foo.Bar, baz: 2}
source =
project
|> Project.source_by_module!(module)
|> AddUse.run(module: module, use: use)
project = Project.update(project, source)
config = [verbose: true]
Formatter.format(:project, {project, config}, [])
Formatter.format(:results, {project, config}, [])
IO.puts("The new code:" <> Source.code(source))
# If we want to write the changes to disk
# Project.save(project)