File cowboy1_pt.erl of Package cowboy1
-module(cowboy1_pt).
-export([parse_transform/2]).
-record(state, {file = "" :: string(), verbose = false :: boolean(), modules = #{} :: #{module() => string()}}).
-define(COWBOY_MODULES, [cowboy, cowboy_app, cowboy_bstr, cowboy_clock, cowboy_handler, cowboy_http, cowboy_http_handler,
cowboy_loop_handler, cowboy_middleware, cowboy_protocol, cowboy_req, cowboy_rest, cowboy_router,
cowboy_spdy, cowboy_static, cowboy_sub_protocol, cowboy_sup,
cowboy_websocket, cowboy_websocket_handler]).
-spec parse_transform(Fs::list(), O::[{atom(), term()}]) -> list().
parse_transform(Fs, O) ->
{R, _} = lists:mapfoldl(fun(F, #state{modules = Ms} = S) ->
case erl_syntax:type(F) of
attribute ->
case erl_syntax:atom_value(erl_syntax:attribute_name(F)) of
file ->
{N, _} = erl_syntax_lib:analyze_file_attribute(F),
{F, S#state{file = N}};
import ->
[M|A] = erl_syntax:attribute_arguments(F),
V = erl_syntax:atom_value(M),
{case maps:find(V, Ms) of
{ok, R} ->
replace_message(erl_syntax:get_pos(M), S, V, R),
import(F, R, A);
_ -> F
end, S};
N when N =:= module; N =:= behaviour; N =:= behavior ->
[M] = erl_syntax:attribute_arguments(F),
V = erl_syntax:atom_value(M),
{case maps:find(V, Ms) of
{ok, R} ->
replace_message(erl_syntax:get_pos(M), S, V, R),
attribute1(F, N, R);
_ -> F
end, S};
N when N =:= record; N =:= spec; N =:= type -> {transform(F, S), S};
_ -> {F, S}
end;
function -> {transform(F, S), S};
_ -> {F, S}
end
end,
#state{verbose = proplists:get_bool(verbose, O),
modules = maps:from_list(lists:map(fun(M) ->
"cowboy" ++ T = atom_to_list(M),
{M, "cowboy1" ++ T}
end,
?COWBOY_MODULES))},
Fs),
R.
transform(F, #state{modules = Ms} = S) ->
FP = erl_syntax:get_pos(F),
case erl_syntax_lib:mapfold(fun(N, X) ->
case erl_syntax:type(N) of
atom ->
M = erl_syntax:atom_value(N),
case Ms of
#{M := R} -> {transform(max(erl_syntax:get_pos(N), FP), S, M, R), true};
_false -> {N, X}
end;
_ -> {N, X}
end
end, false, F) of
{T, true} -> erl_syntax:revert(T);
_ -> F
end.
transform(P, S, M, R) ->
replace_message(P, S, M, R),
erl_syntax:set_pos(erl_syntax:atom(R), P).
attribute(F, N, A) when is_atom(N), is_list(A) ->
erl_syntax:revert(erl_syntax:copy_pos(F, erl_syntax:attribute(erl_syntax:atom(N), A))).
attribute1(F, A, N) when is_list(N) -> attribute(F, A, [erl_syntax:atom(N)]).
import(F, N, A) when is_list(N) -> attribute(F, import, [erl_syntax:atom(N)|A]).
replace_message(P, #state{file = F, verbose = true}, A, R) -> io:fwrite("~ts:~p: replace ~s to ~s~n", [F, P, A, R]);
replace_message(_, _, _, _) -> ok.