Hi there,
Is there any way to change/edit the code/ast of a module before it compiles? I am trying to use the Interceptor library to add logging functionality to a module. In order to work, this library requires all functions to be traced to either be wrapped in a special do
block or to be annotated.
Now, I would like for the user to be able to just write his regular code without having to worry about this wrapping/annotation at all. As such, my question is if it would be possible to leverage some metaprogramming, module callbacks or something else to automatically make the necessary changes to the code at compile time.
For example, let’s say I want to trace all functions, could I make something such that the code below:
defmodule Stack do
use GenServer
require Interceptor, as: I
def start_link(default) when is_list(default) do
GenServer.start_link(__MODULE__, default)
end
@impl true
def init(stack) do
{:ok, stack}
end
@impl true
def handle_call(:pop, _from, [head | tail]) do
{:reply, head, tail}
end
@impl true
def handle_cast({:push, element}, state) do
{:noreply, [element | state]}
end
end
Either gets manipulated to look like this:
defmodule Stack do
use GenServer
require Interceptor, as: I
I.Intercept do
def start_link(default) when is_list(default) do
GenServer.start_link(__MODULE__, default)
end
@impl true
def init(stack) do
{:ok, stack}
end
@impl true
def handle_call(:pop, _from, [head | tail]) do
{:reply, head, tail}
end
@impl true
def handle_cast({:push, element}, state) do
{:noreply, [element | state]}
end
end
end
Or gets manipulated to look like this:
defmodule Stack do
use GenServer
require Interceptor, as: I
@intercept true
def start_link(default) when is_list(default) do
GenServer.start_link(__MODULE__, default)
end
@impl true
@intercept true
def init(stack) do
{:ok, stack}
end
@impl true
@intercept true
def handle_call(:pop, _from, [head | tail]) do
{:reply, head, tail}
end
@impl true
@intercept true
def handle_cast({:push, element}, state) do
{:noreply, [element | state]}
end
end
Any help would be greatly appreciated!