Current section
Files
Jump to
Current section
Files
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).