Skip to content

Commit fb7a22e

Browse files
authored
Print intermediate results of dbg for boolean operators (#14217)
1 parent 8a5ed11 commit fb7a22e

File tree

2 files changed

+55
-45
lines changed

2 files changed

+55
-45
lines changed

lib/elixir/lib/macro.ex

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2641,16 +2641,8 @@ defmodule Macro do
26412641
# Logic operators.
26422642
defp dbg_ast_to_debuggable({op, _meta, [_left, _right]} = ast, _env)
26432643
when op in unquote(dbg_decomposed_binary_operators) do
2644-
acc_var = unique_var(:acc, __MODULE__)
26452644
result_var = unique_var(:result, __MODULE__)
2646-
2647-
[
2648-
quote do
2649-
unquote(acc_var) = []
2650-
unquote(dbg_boolean_tree(ast, acc_var, result_var))
2651-
{:logic_op, Enum.reverse(unquote(acc_var)), unquote(result_var)}
2652-
end
2653-
]
2645+
dbg_boolean_tree(ast, result_var, [])
26542646
end
26552647

26562648
defp dbg_ast_to_debuggable({:__block__, _meta, exprs} = ast, _env) when exprs != [] do
@@ -2818,30 +2810,27 @@ defmodule Macro do
28182810
end
28192811

28202812
# This is a binary operator. We replace the left side with a recursive call to
2821-
# this function to decompose it, and then execute the operation and add it to the acc.
2822-
defp dbg_boolean_tree({op, _meta, [left, right]} = ast, acc_var, result_var)
2813+
# this function to decompose it
2814+
defp dbg_boolean_tree({op, _meta, [left, right]} = ast, result_var, nodes)
28232815
when op in unquote(dbg_decomposed_binary_operators) do
2824-
replaced_left = dbg_boolean_tree(left, acc_var, result_var)
2816+
tag = if nodes == [], do: :value, else: :multi_value
28252817

2826-
quote do
2827-
unquote(result_var) = unquote(op)(unquote(replaced_left), unquote(right))
2828-
2829-
unquote(acc_var) = [
2830-
{unquote(escape(ast)), unquote(result_var)} | unquote(acc_var)
2831-
]
2818+
node =
2819+
quote do
2820+
unquote(result_var) = unquote(op)(unquote(result_var), unquote(right))
2821+
{unquote(tag), unquote(escape(ast)), unquote(result_var)}
2822+
end
28322823

2833-
unquote(result_var)
2834-
end
2824+
dbg_boolean_tree(left, result_var, [node | nodes])
28352825
end
28362826

2837-
# This is finally an expression, so we assign "result = expr", add it to the acc, and
2838-
# return the result.
2839-
defp dbg_boolean_tree(ast, acc_var, result_var) do
2840-
quote do
2841-
unquote(result_var) = unquote(ast)
2842-
unquote(acc_var) = [{unquote(escape(ast)), unquote(result_var)} | unquote(acc_var)]
2843-
unquote(result_var)
2844-
end
2827+
defp dbg_boolean_tree(ast, result_var, nodes) do
2828+
node =
2829+
quote do
2830+
{:multi_value, unquote(escape(ast)), unquote(result_var) = unquote(ast)}
2831+
end
2832+
2833+
[node | nodes]
28452834
end
28462835

28472836
defp dbg_block({:__block__, meta, exprs}, acc_var, result_var) do
@@ -2895,15 +2884,6 @@ defmodule Macro do
28952884
{[first_formatted | rest_formatted], result}
28962885
end
28972886

2898-
defp dbg_format_ast_to_debug({:logic_op, components, value}, options) do
2899-
formatted =
2900-
Enum.map(components, fn {ast, value} ->
2901-
[dbg_format_ast(to_string_with_colors(ast, options)), " ", inspect(value, options), ?\n]
2902-
end)
2903-
2904-
{formatted, value}
2905-
end
2906-
29072887
defp dbg_format_ast_to_debug({:block, components, value}, options) do
29082888
formatted =
29092889
[
@@ -2994,12 +2974,20 @@ defmodule Macro do
29942974
{formatted, result}
29952975
end
29962976

2977+
defp dbg_format_ast_to_debug({:multi_value, code_ast, value}, options) do
2978+
{dbg_format_ast_with_value_no_newline(code_ast, value, options), value}
2979+
end
2980+
29972981
defp dbg_format_ast_to_debug({:value, code_ast, value}, options) do
29982982
{dbg_format_ast_with_value(code_ast, value, options), value}
29992983
end
30002984

2985+
defp dbg_format_ast_with_value_no_newline(ast, value, options) do
2986+
[dbg_format_ast(to_string_with_colors(ast, options)), " ", inspect(value, options)]
2987+
end
2988+
30012989
defp dbg_format_ast_with_value(ast, value, options) do
3002-
[dbg_format_ast(to_string_with_colors(ast, options)), " ", inspect(value, options), ?\n]
2990+
[dbg_format_ast_with_value_no_newline(ast, value, options), ?\n]
30032991
end
30042992

30052993
defp to_string_with_colors(ast, options) do

lib/elixir/test/elixir/macro_test.exs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -325,16 +325,22 @@ defmodule MacroTest do
325325
end
326326

327327
describe "dbg/3" do
328+
defmacrop dbg_format_no_newline(ast, options \\ quote(do: [syntax_colors: []])) do
329+
quote do
330+
ExUnit.CaptureIO.with_io(fn ->
331+
try do
332+
unquote(Macro.dbg(ast, options, __CALLER__))
333+
rescue
334+
e -> e
335+
end
336+
end)
337+
end
338+
end
339+
328340
defmacrop dbg_format(ast, options \\ quote(do: [syntax_colors: []])) do
329341
quote do
330342
{result, formatted} =
331-
ExUnit.CaptureIO.with_io(fn ->
332-
try do
333-
unquote(Macro.dbg(ast, options, __CALLER__))
334-
rescue
335-
e -> e
336-
end
337-
end)
343+
dbg_format_no_newline(unquote(ast), unquote(options))
338344

339345
# Make sure there's an empty line after the output.
340346
assert String.ends_with?(formatted, "\n\n") or
@@ -469,6 +475,22 @@ defmodule MacroTest do
469475
"""
470476
end
471477

478+
test "boolean expressions that raise" do
479+
falsy = length([]) != 0
480+
x = 0
481+
482+
{result, formatted} = dbg_format_no_newline((falsy || x) && 1 / x)
483+
484+
assert %ArithmeticError{} = result
485+
486+
assert formatted =~ "macro_test.exs"
487+
488+
assert formatted =~ """
489+
falsy #=> false
490+
falsy || x #=> 0
491+
"""
492+
end
493+
472494
test "block of code" do
473495
{result, formatted} =
474496
dbg_format(

0 commit comments

Comments
 (0)