Skip to content

Commit 6f11ee3

Browse files
authored
Merge pull request #54 from esl/support-nested-modules
Support nested modules
2 parents 7b9cc49 + 33e7df3 commit 6f11ee3

File tree

8 files changed

+51
-18
lines changed

8 files changed

+51
-18
lines changed

lib/gradient/ast_specifier.ex

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,8 @@ defmodule Gradient.AstSpecifier do
6464
"""
6565
@spec specify(nonempty_list(:erl_parse.abstract_form())) :: [:erl_parse.abstract_form()]
6666
def specify(forms) do
67-
with {:attribute, line, :file, {path, _}} <- hd(forms),
68-
path <- to_string(path),
69-
{:ok, code} <- File.read(path),
70-
{:ok, tokens} <- :elixir.string_to_tokens(String.to_charlist(code), line, line, path, []) do
71-
run_mappers(forms, tokens)
72-
else
73-
error ->
74-
IO.puts("Error occurred when specifying forms : #{inspect(error)}")
75-
forms
76-
end
67+
tokens = Gradient.ElixirFileUtils.load_tokens(forms)
68+
run_mappers(forms, tokens)
7769
end
7870

7971
@doc """

lib/gradient/elixir_file_utils.ex

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ defmodule Gradient.ElixirFileUtils do
33
Module used to load beam files generated from Elixir.
44
"""
55

6+
alias Gradient.Types
7+
68
@type path() :: :file.filename() | String.t()
79

810
@type abstract_forms() :: [:erl_parse.abstract_form() | :erl_parse.form_info()]
@@ -39,4 +41,18 @@ defmodule Gradient.ElixirFileUtils do
3941
{:forms_error, reason}
4042
end
4143
end
44+
45+
@spec load_tokens([:erl_parse.abstract_form()]) :: Types.tokens()
46+
def load_tokens(forms) do
47+
with [{:attribute, _, :file, {path, _}} | _] <- forms,
48+
path <- to_string(path),
49+
{:ok, code} <- File.read(path),
50+
{:ok, tokens} <- :elixir.string_to_tokens(String.to_charlist(code), 1, 1, path, []) do
51+
tokens
52+
else
53+
error ->
54+
IO.puts("Cannot load tokens: #{inspect(error)}")
55+
[]
56+
end
57+
end
4258
end
1.3 KB
Binary file not shown.
1.3 KB
Binary file not shown.
1.28 KB
Binary file not shown.

test/examples/nested_modules.ex

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
defmodule NestedModules do
2+
defmodule ModuleA do
3+
def name do
4+
:module_a
5+
end
6+
end
7+
8+
defmodule ModuleB do
9+
def name do
10+
:module_b
11+
end
12+
end
13+
14+
def name do
15+
:module
16+
end
17+
end

test/gradient/ast_specifier_test.exs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,6 +1578,19 @@ defmodule Gradient.AstSpecifierTest do
15781578
assert [_] = AstSpecifier.run_mappers(forms, [])
15791579
end
15801580

1581+
test "nested modules" do
1582+
{tokensA, astA} = load("Elixir.NestedModules.ModuleA.beam", "nested_modules.ex")
1583+
{tokensB, astB} = load("Elixir.NestedModules.ModuleB.beam", "nested_modules.ex")
1584+
{tokens, ast} = load("Elixir.NestedModules.beam", "nested_modules.ex")
1585+
1586+
assert {:function, 3, :name, 0, [{:clause, 3, [], [], [{:atom, 4, :module_a}]}]} =
1587+
List.last(AstSpecifier.run_mappers(astA, tokensA))
1588+
assert {:function, 9, :name, 0, [{:clause, 9, [], [], [{:atom, 10, :module_b}]}]} =
1589+
List.last(AstSpecifier.run_mappers(astB, tokensB))
1590+
assert {:function, 14, :name, 0, [{:clause, 14, [], [], [{:atom, 15, :module}]}]} =
1591+
List.last(AstSpecifier.run_mappers(ast, tokens))
1592+
end
1593+
15811594
# Helpers
15821595

15831596
def filter_attributes(ast, type) do

test/support/helpers.ex

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,13 @@ defmodule Gradient.TestHelpers do
88
beam_file = String.to_charlist(@examples_path <> beam_file)
99
ex_file = @examples_path <> ex_file
1010

11-
code =
12-
File.read!(ex_file)
13-
|> String.to_charlist()
14-
15-
{:ok, tokens} =
16-
code
17-
|> :elixir.string_to_tokens(1, 1, ex_file, [])
18-
1911
{:ok, {_, [abstract_code: {:raw_abstract_v1, ast}]}} =
2012
:beam_lib.chunks(beam_file, [:abstract_code])
2113

2214
ast = replace_file_path(ast, ex_file)
15+
16+
[_ | _] = tokens = Gradient.ElixirFileUtils.load_tokens(ast)
17+
2318
{tokens, ast}
2419
end
2520

0 commit comments

Comments
 (0)