Current section

Files

Jump to
bristow src bristow_transform.erl
Raw

src/bristow_transform.erl

-module(bristow_transform).
-export([parse_transform/2]).
parse_transform(Forms, _Options) ->
{Alias, Forms1} = gen_alias(Forms),
export_alias(Forms1, Alias).
gen_alias(Forms) ->
gen_alias(Forms, {}, [], []).
gen_alias([], _, Alias, Acc) ->
{Alias, lists:reverse(Acc)};
gen_alias([{function,_,Name,_,[{clause,_,Args,_,_}|_]} = Fun|Rest], _, Alias, Acc) ->
gen_alias(Rest, {Name, Args}, Alias, [Fun|Acc]);
gen_alias([{attribute,N,alias,Name}|Rest], {Fun, Args}, Alias, Acc) ->
gen_alias(Rest, {Fun, Args}, [{Name, length(Args)}|Alias], [{function,N,Name,length(Args),
[{clause,N,
Args,
[],
[{call,N,{atom,1,Fun},Args}]}]}|Acc]);
gen_alias([{attribute,_,alias,_}|_], {}, _, _) ->
erlang:throw("-alias must follow a function definition");
gen_alias([Def|Rest], _, Alias, Acc) ->
gen_alias(Rest, {}, Alias, [Def|Acc]).
export_alias(Forms, Alias) ->
{_, Forms1} = lists:foldl(fun
({attribute,N,export,Exports}, {A, Acc}) ->
{[], [{attribute,N,export,Exports ++ A}|Acc]};
(Other, {A, Acc}) ->
{A, [Other|Acc]}
end, {Alias, []}, Forms),
lists:reverse(Forms1).