Skip to content

Commit 2a8706b

Browse files
committed
Merge pull request erlang-lager#54 from basho/adt-variable-arguments
Parse transform can't handle `Attr' as a variable
2 parents b3428c8 + 0ec0d90 commit 2a8706b

File tree

2 files changed

+153
-2
lines changed

2 files changed

+153
-2
lines changed

‎src/lager_transform.erl‎

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,25 @@ transform_statement({call, Line, {remote, _Line1, {atom, _Line2, lager},
107107
%% [Format, Args] or [Attr, Format].
108108
%% The trace attributes will be a list of tuples, so check
109109
%% for that.
110-
case Arg1 of
111-
{cons, _, {tuple, _, _}, _} ->
110+
case {element(1, Arg1), Arg1} of
111+
{_, {cons, _, {tuple, _, _}, _}} ->
112112
{concat_lists(Arg1, DefaultAttrs),
113113
Arg2, {atom, Line, none}};
114+
{Type, _} when Type == var;
115+
Type == lc;
116+
Type == call;
117+
Type == record_field ->
118+
%% crap, its not a literal. look at the second
119+
%% argument to see if it is a string
120+
case Arg2 of
121+
{string, _, _} ->
122+
{concat_lists(Arg1, DefaultAttrs),
123+
Arg2, {atom, Line, none}};
124+
_ ->
125+
%% not a string, going to have to guess
126+
%% it's the argument list
127+
{DefaultAttrs, Arg1, Arg2}
128+
end;
114129
_ ->
115130
{DefaultAttrs, Arg1, Arg2}
116131
end;
@@ -146,6 +161,22 @@ transform_statement(Stmt) ->
146161
Stmt.
147162

148163
%% concat 2 list ASTs by replacing the terminating [] in A with the contents of B
164+
concat_lists({var, Line, _Name}=Var, B) ->
165+
%% concatenating a var with a cons
166+
{call, Line, {remote, Line, {atom, Line, lists},{atom, Line, flatten}},
167+
[{cons, Line, Var, B}]};
168+
concat_lists({lc, Line, _Body, _Generator} = LC, B) ->
169+
%% concatenating a LC with a cons
170+
{call, Line, {remote, Line, {atom, Line, lists},{atom, Line, flatten}},
171+
[{cons, Line, LC, B}]};
172+
concat_lists({call, Line, _Function, _Args} = Call, B) ->
173+
%% concatenating a call with a cons
174+
{call, Line, {remote, Line, {atom, Line, lists},{atom, Line, flatten}},
175+
[{cons, Line, Call, B}]};
176+
concat_lists({record_field, Line, _Var, _Record, _Field} = Rec, B) ->
177+
%% concatenating a record_field with a cons
178+
{call, Line, {remote, Line, {atom, Line, lists},{atom, Line, flatten}},
179+
[{cons, Line, Rec, B}]};
149180
concat_lists({nil, _Line}, B) ->
150181
B;
151182
concat_lists({cons, Line, Element, Tail}, B) ->

‎test/lager_test_backend.erl‎

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
code_change/3]).
2525

2626
-record(state, {level, buffer, ignored}).
27+
-record(test, {attrs, format, args}).
2728
-compile([{parse_transform, lager_transform}]).
2829

2930
-ifdef(TEST).
@@ -180,6 +181,125 @@ lager_test_() ->
180181
ok
181182
end
182183
},
184+
{"variables inplace of literals in logging statements work",
185+
fun() ->
186+
?assertEqual(0, count()),
187+
Attr = [{a, alpha}, {b, beta}],
188+
Fmt = "format ~p",
189+
Args = [world],
190+
lager:info(Attr, "hello"),
191+
lager:info(Attr, "hello ~p", [world]),
192+
lager:info(Fmt, [world]),
193+
lager:info("hello ~p", Args),
194+
lager:info(Attr, "hello ~p", Args),
195+
lager:info([{d, delta}, {g, gamma}], Fmt, Args),
196+
?assertEqual(6, count()),
197+
{_Level, _Time, Message, Metadata} = pop(),
198+
?assertMatch([{a, alpha}, {b, beta}|_], Metadata),
199+
?assertEqual("hello", lists:flatten(Message)),
200+
{_Level, _Time2, Message2, _Metadata2} = pop(),
201+
?assertEqual("hello world", lists:flatten(Message2)),
202+
{_Level, _Time3, Message3, _Metadata3} = pop(),
203+
?assertEqual("format world", lists:flatten(Message3)),
204+
{_Level, _Time4, Message4, _Metadata4} = pop(),
205+
?assertEqual("hello world", lists:flatten(Message4)),
206+
{_Level, _Time5, Message5, _Metadata5} = pop(),
207+
?assertEqual("hello world", lists:flatten(Message5)),
208+
{_Level, _Time6, Message6, Metadata6} = pop(),
209+
?assertMatch([{d, delta}, {g, gamma}|_], Metadata6),
210+
?assertEqual("format world", lists:flatten(Message6)),
211+
ok
212+
end
213+
},
214+
{"list comprehension inplace of literals in logging statements work",
215+
fun() ->
216+
?assertEqual(0, count()),
217+
Attr = [{a, alpha}, {b, beta}],
218+
Fmt = "format ~p",
219+
Args = [world],
220+
lager:info([{K, atom_to_list(V)} || {K, V} <- Attr], "hello"),
221+
lager:info([{K, atom_to_list(V)} || {K, V} <- Attr], "hello ~p", [{atom, X} || X <- Args]),
222+
lager:info([X || X <- Fmt], [world]),
223+
lager:info("hello ~p", [{atom, X} || X <- Args]),
224+
lager:info([{K, atom_to_list(V)} || {K, V} <- Attr], "hello ~p", [{atom, X} || X <- Args]),
225+
lager:info([{d, delta}, {g, gamma}], Fmt, [{atom, X} || X <- Args]),
226+
?assertEqual(6, count()),
227+
{_Level, _Time, Message, Metadata} = pop(),
228+
?assertMatch([{a, "alpha"}, {b, "beta"}|_], Metadata),
229+
?assertEqual("hello", lists:flatten(Message)),
230+
{_Level, _Time2, Message2, _Metadata2} = pop(),
231+
?assertEqual("hello {atom,world}", lists:flatten(Message2)),
232+
{_Level, _Time3, Message3, _Metadata3} = pop(),
233+
?assertEqual("format world", lists:flatten(Message3)),
234+
{_Level, _Time4, Message4, _Metadata4} = pop(),
235+
?assertEqual("hello {atom,world}", lists:flatten(Message4)),
236+
{_Level, _Time5, Message5, _Metadata5} = pop(),
237+
?assertEqual("hello {atom,world}", lists:flatten(Message5)),
238+
{_Level, _Time6, Message6, Metadata6} = pop(),
239+
?assertMatch([{d, delta}, {g, gamma}|_], Metadata6),
240+
?assertEqual("format {atom,world}", lists:flatten(Message6)),
241+
ok
242+
end
243+
},
244+
{"function calls inplace of literals in logging statements work",
245+
fun() ->
246+
?assertEqual(0, count()),
247+
put(attrs, [{a, alpha}, {b, beta}]),
248+
put(format, "format ~p"),
249+
put(args, [world]),
250+
lager:info(get(attrs), "hello"),
251+
lager:info(get(attrs), "hello ~p", get(args)),
252+
lager:info(get(format), [world]),
253+
lager:info("hello ~p", erlang:get(args)),
254+
lager:info(fun() -> get(attrs) end(), "hello ~p", get(args)),
255+
lager:info([{d, delta}, {g, gamma}], get(format), get(args)),
256+
?assertEqual(6, count()),
257+
{_Level, _Time, Message, Metadata} = pop(),
258+
?assertMatch([{a, alpha}, {b, beta}|_], Metadata),
259+
?assertEqual("hello", lists:flatten(Message)),
260+
{_Level, _Time2, Message2, _Metadata2} = pop(),
261+
?assertEqual("hello world", lists:flatten(Message2)),
262+
{_Level, _Time3, Message3, _Metadata3} = pop(),
263+
?assertEqual("format world", lists:flatten(Message3)),
264+
{_Level, _Time4, Message4, _Metadata4} = pop(),
265+
?assertEqual("hello world", lists:flatten(Message4)),
266+
{_Level, _Time5, Message5, _Metadata5} = pop(),
267+
?assertEqual("hello world", lists:flatten(Message5)),
268+
{_Level, _Time6, Message6, Metadata6} = pop(),
269+
?assertMatch([{d, delta}, {g, gamma}|_], Metadata6),
270+
?assertEqual("format world", lists:flatten(Message6)),
271+
ok
272+
end
273+
},
274+
{"record fields inplace of literals in logging statements work",
275+
fun() ->
276+
?assertEqual(0, count()),
277+
Test = #test{attrs=[{a, alpha}, {b, beta}], format="format ~p", args=[world]},
278+
lager:info(Test#test.attrs, "hello"),
279+
lager:info(Test#test.attrs, "hello ~p", Test#test.args),
280+
lager:info(Test#test.format, [world]),
281+
lager:info("hello ~p", Test#test.args),
282+
lager:info(Test#test.attrs, "hello ~p", Test#test.args),
283+
lager:info([{d, delta}, {g, gamma}], Test#test.format, Test#test.args),
284+
?assertEqual(6, count()),
285+
{_Level, _Time, Message, Metadata} = pop(),
286+
?assertMatch([{a, alpha}, {b, beta}|_], Metadata),
287+
?assertEqual("hello", lists:flatten(Message)),
288+
{_Level, _Time2, Message2, _Metadata2} = pop(),
289+
?assertEqual("hello world", lists:flatten(Message2)),
290+
{_Level, _Time3, Message3, _Metadata3} = pop(),
291+
?assertEqual("format world", lists:flatten(Message3)),
292+
{_Level, _Time4, Message4, _Metadata4} = pop(),
293+
?assertEqual("hello world", lists:flatten(Message4)),
294+
{_Level, _Time5, Message5, _Metadata5} = pop(),
295+
?assertEqual("hello world", lists:flatten(Message5)),
296+
{_Level, _Time6, Message6, Metadata6} = pop(),
297+
?assertMatch([{d, delta}, {g, gamma}|_], Metadata6),
298+
?assertEqual("format world", lists:flatten(Message6)),
299+
ok
300+
end
301+
},
302+
183303
{"log messages below the threshold are ignored",
184304
fun() ->
185305
?assertEqual(0, count()),

0 commit comments

Comments
 (0)