Current section

Files

Jump to
credo lib credo exs_loader.ex
Raw

lib/credo/exs_loader.ex

defmodule Credo.ExsLoader do
def parse(exs_string, safe \\ false)
def parse(exs_string, true) do
case Code.string_to_quoted(exs_string) do
{:ok, ast} ->
process_exs(ast)
_ -> %{}
end
end
def parse(exs_string, false) do
{result, _binding} = Code.eval_string(exs_string)
result
end
def parse_safe(exs_string) do
case Code.string_to_quoted(exs_string) do
{:ok, ast} ->
process_exs(ast)
_ -> %{}
end
end
defp process_exs(v) when is_atom(v)
or is_binary(v)
or is_boolean(v)
or is_float(v)
or is_integer(v)
or is_nil(v), do: v
defp process_exs(list) when is_list(list) do
Enum.map(list, &process_exs/1)
end
defp process_exs({:sigil_w, _, [{:<<>>, _, [list_as_string]}, []]}) do
list_as_string
|> String.split(~r/\s+/)
end
# TODO: support regex modifiers
defp process_exs({:sigil_r, _, [{:<<>>, _, [regex_as_string]}, []]}) do
regex_as_string
|> Regex.compile!
end
defp process_exs({:%{}, _meta, body}) do
process_map(body, %{})
end
defp process_exs({:{}, _meta, body}) do
process_tuple(body, {})
end
defp process_exs({:__aliases__, _meta, name_list}) do
Module.safe_concat(name_list)
end
defp process_exs({{:__aliases__, _meta, name_list}, options}) do
{Module.safe_concat(name_list), process_exs(options)}
end
defp process_exs({key, value}) when is_atom(key) or is_binary(key) do
{process_exs(key), process_exs(value)}
end
defp process_tuple([], acc), do: acc
defp process_tuple([head|tail], acc) do
acc = process_tuple_item(head, acc)
process_tuple(tail, acc)
end
defp process_tuple_item(value, acc) do
Tuple.append(acc, process_exs(value))
end
defp process_map([], acc), do: acc
defp process_map([head|tail], acc) do
acc = process_map_item(head, acc)
process_map(tail, acc)
end
defp process_map_item({key, value}, acc) when is_atom(key) or is_binary(key) do
Map.put acc, key, process_exs(value)
end
end