|
| 1 | +defmodule Gradient.Debug do |
| 2 | + @moduledoc ~S""" |
| 3 | + Helpers for convenient debugging Erlang and Elixir ASTs. |
| 4 | + """ |
| 5 | + |
| 6 | + ## TODO: specify elixir_form |
| 7 | + @type elixir_form() :: any() |
| 8 | + @type erlang_form() :: Gradient.SpecifyErlAst.form() |
| 9 | + |
| 10 | + @doc ~S""" |
| 11 | + Return the Elixir AST of an Elixir module. |
| 12 | + """ |
| 13 | + @spec elixir_ast(module()) :: {:ok, [elixir_form()]} |
| 14 | + def elixir_ast(mod) do |
| 15 | + {:ok, {_, [{:debug_info, {:debug_info_v1, :elixir_erl, abstract_code}}]}} = |
| 16 | + :beam_lib.chunks(get_beam_path_as_charlist(mod), [:debug_info]) |
| 17 | + {:ok, _forms} = :elixir_erl.debug_info(:elixir_v1, :module_name, abstract_code, []) |
| 18 | + end |
| 19 | + |
| 20 | + @doc ~S""" |
| 21 | + Return the Erlang AST of an Erlang or Elixir module. |
| 22 | + """ |
| 23 | + @spec erlang_ast(module()) :: {:ok, [erlang_form()]} |
| 24 | + def erlang_ast(mod) do |
| 25 | + {:ok, _forms} = get_beam_path_as_charlist(mod) |> Gradient.ElixirFileUtils.get_forms_from_beam() |
| 26 | + end |
| 27 | + |
| 28 | + @doc ~S""" |
| 29 | + Print module as Erlang source code. |
| 30 | + """ |
| 31 | + @spec print_erlang(module()) :: :ok |
| 32 | + def print_erlang(mod) do |
| 33 | + {:ok, forms} = erlang_ast(mod) |
| 34 | + IO.puts(:erl_prettypr.format(:erl_syntax.form_list(forms))) |
| 35 | + end |
| 36 | + |
| 37 | + def get_beam_path_as_charlist(mod) when is_list(mod), do: mod |
| 38 | + def get_beam_path_as_charlist(mod) when is_atom(mod), do: :code.which(mod) |
| 39 | +end |
0 commit comments