How to fully expand all code in a Module to see what gets included by macros?

Hi, I am getting myself acquainted with larger Elixir code base and meta programming is pervasive.

I am trying to get Elixir to show me the fully expanded version of a simple Phoenix controller:

defmodule HelloWeb.PageController do
  use HelloWeb, :controller

  def index(conn, _params) do
    render conn, "index.html"
  end
end

I did it by hand and it was very interesting, but how could I’ve gone about to get Elixir to do all the expansion for me and give me back the fully expanded module?

5 Likes

At least part of the way to where you want to be can be achieved with:

{:ok, ast} = File.read!(path_to_file) |> Code.string_to_quoted()
Macro.expand(ast, __ENV__)

Unfortunately this will usually (always?) return an AST that Macro.to_string/1 can’t really do much with. I haven’t yet found a way to get from a full module through macro expansion to Elixir code again; I assume it is due to not having the right sub-set of the AST that is generated for Macro.to_string/1 to be successful with … but you can see what the resulting AST is :slight_smile: Maybe one small step forward …