Current section

Files

Jump to
util src alias.erl
Raw

src/alias.erl

%%% vim:ts=2:sw=2:et
%%%-----------------------------------------------------------------------------
%%% Created 2021-06-01
%%%-----------------------------------------------------------------------------
-module(alias).
-moduledoc """
Creation of module aliases
Author: Serge Aleynikov <saleyn@gmail.com>
Copyright: 2021 Serge Aleynikov
""".
-export([create/2, create/3]).
-doc """
Create a module `Alias` for the given `OrigMod` module. This function is useful
for creating in-memory Elixir wrapper modules without needing to maintain
persistent files with such wrappers. `IncFuns` argument can be `all` or a list
of `{Fun, Arity}` values which only export a subset of functions from the
`OrigMod`.
""".
create(Alias, OrigMod) ->
create(Alias, OrigMod, all).
create(Alias, OrigMod, IncFuns) when IncFuns == all; is_list(IncFuns) ->
Exports = [T || T <- OrigMod:module_info(exports)
, element(1, T) /= module_info
, IncFuns==all orelse lists:member(T, IncFuns)],
AST = [{attribute, ?LINE, module, Alias}
,{attribute, ?LINE, export, Exports}
|[begin
% AST of a function call from the OrigMod module
Remote = {remote, ?LINE, {atom, ?LINE, OrigMod}, {atom, ?LINE, Fun}},
Args = [{var, ?LINE, list_to_atom("A" ++ integer_to_list(N))}
|| N <- lists:seq(1, Arity)],
{function, ?LINE, Fun, Arity, [{clause, ?LINE, Args, [], [{call, ?LINE, Remote, Args}]}]}
end || {Fun, Arity} <- Exports]
],
{ok, Alias, Bin} = compile:forms(AST),
{module, Alias} = code:load_binary(Alias, "/dev/null", Bin),
{ok, Alias}.