Current section

Files

Jump to
elixir_script lib elixir_script passes find_functions.ex
Raw

lib/elixir_script/passes/find_functions.ex

defmodule ElixirScript.Passes.FindFunctions do
@moduledoc false
@function_types [:def, :defp, :defgen, :defgenp, :defmacro, :defmacrop]
def execute(data, _) do
new_data = Enum.map(data.data, fn { module_name, module_data } ->
%{def: functions, defp: private_functions, defgen: generators, defgenp: private_generators, defmacro: macros, defmacrop: private_macros } = get_functions_from_module(module_data.ast)
module_data = Map.put(module_data, :functions, functions ++ generators)
|> Map.put(:private_functions, private_functions ++ private_generators)
|> Map.put(:macros, macros)
|> Map.put(:private_macros, private_macros)
{module_name, module_data}
end)
%{data | data: new_data}
end
defp get_functions_from_module({:__block__, _, list}) do
Enum.reduce(list, new_function_map(), fn
({type, _, [{:when, _, [{name, _, params} | _guards] }, _] }, state) when type in @function_types and is_atom(params) ->
arity = 0
add_function_to_map(state, type, name, arity)
({type, _, [{:when, _, [{name, _, params} | _guards] }, _] }, state) when type in @function_types ->
arity = if is_nil(params), do: 0, else: length(params)
add_function_to_map(state, type, name, arity)
({type, _, [{name, _, params}, _]}, state) when type in @function_types and is_atom(params) ->
arity = 0
add_function_to_map(state, type, name, arity)
({type, _, [{name, _, params}, _]}, state) when type in @function_types ->
arity = if is_nil(params), do: 0, else: length(params)
add_function_to_map(state, type, name, arity)
({type, _, [{name, _, params}]}, state) when is_atom(params) and type in @function_types ->
arity = 0
add_function_to_map(state, type, name, arity)
({type, _, [{name, _, params}]}, state) when type in @function_types ->
arity = length(params)
add_function_to_map(state, type, name, arity)
_, state ->
state
end)
end
defp new_function_map() do
%{ def: Keyword.new, defp: Keyword.new, defgen: Keyword.new, defgenp: Keyword.new, defmacro: Keyword.new, defmacrop: Keyword.new }
end
defp get_functions_from_module(_) do
new_function_map()
end
defp add_function_to_map(map, type, name, arity) do
list = Map.get(map, type)
if {name, arity} in list do
map
else
Map.put(map, type, list ++ [{ name, arity }])
end
end
end