Current section

Files

Jump to
kivra_merlin include internal.hrl
Raw

include/internal.hrl

-include("assertions.hrl").
-include("log.hrl").
-ifdef(NOASSERT).
-define(if_asserting(Block), ok).
-else.
%% Helper for compiling away code when assertions are disabled
-define(if_asserting(Block), Block).
-endif.
%% The macro for this transform looks like this:
%% -define(QQ(Forms), {'MERLIN QUOTE MARKER', ?FILE, ?LINE, Forms}).
%% Helper macro to allow writing inline source code instead of a string of
%% source code. Its especially nice to not having to escape double quotes.
-define(STRINGIFY(Value), ??Value).
%% Helper macro to merl quote, using ?Q/1, inline code.
%% Multiple are needed as some commas are interpreted as arguments to the
%% macro, while others are ignored. Maybe because they are nested?
%%
%% These also use the parser feature of joining string literals, e.g. if you
%% write `"foo" "bar"' it gets parsed as if you had written `"foobar"'.
%% They also append a period to finish the form, as that can't be provided
%% inside a macro call. Doing that would end the macro prematurely.
-define(QUOTE(Form), ?Q(??Form ".")).
-define(QUOTE(Form1, Form2), ?Q(??Form1 "," ??Form2 ".")).
-define(QUOTE(Form1, Form2, Form3), ?Q(??Form1 "," ??Form2 "," ??Form3 ".")).
-define(QUOTE(Form1, Form2, Form3, Form4),
?Q(??Form1 "," ??Form2 "," ??Form3 "," ??Form4 ".")
).
%% Replaces forms matching `SearchPattern' using `ReplacementPattern' in
%% `Forms'.
%%
%% For example, to replace calls to `my_logger:info' with a call to
%% `my_logger:log' you would do something like:
%%
%% ```
%% ?replace(Forms, "my_logger:info(_@@Args)", "my_logger:log(info, _@Args)")
%% '''
%%
%% It's a macro and not a function because it uses merls `?Q/1' macros under
%% the hood.
-define(replace(Forms, SearchPattern, ReplacementPattern),
merlin:transform(
Forms,
fun
(Phase, Form, _) when Phase =:= enter orelse Phase =:= leaf ->
case Form of
?Q(SearchPattern) -> ?Q(ReplacementPattern);
_ -> continue
end;
(_, _, _) ->
continue
end,
'_'
)
).
-define(quickcheck(Property), ?quickcheck(Property, [])).
-define(quickcheck(Property, Options),
case
proper:quickcheck(Property, proplists:delete(comment, Options ++ [long_result]))
of
true ->
ok;
X__V ->
error(
{assertEqual, [
{module, ?MODULE},
{line, ?LINE},
{expression, ("proper:quickcheck(" ??Property ", " ??Options ")")},
{expected, true},
{value, X__V}
| case proplists:lookup(comment, Options) of
none -> [];
X__C -> [X__C]
end
]}
)
end
).