|
defmodule Codex.KinoHelpers do |
|
def trace(mfa) do |
|
{:ok, tracer} = Entrace.start_link() |
|
trace_frame = Kino.Frame.new() |
|
trace(tracer, trace_frame, mfa) |
|
trace_frame |
|
end |
|
|
|
def trace(tracer, trace_frame, mfa) do |
|
Entrace.stop(tracer, mfa) |
|
|
|
Entrace.trace(tracer, mfa, fn %Entrace.Trace{} = t -> |
|
IO.inspect(t) |
|
|
|
{_mod, _fun, args} = t.mfa |
|
|
|
[stack_item | _rest] = t.stacktrace |
|
|
|
columns = [ |
|
Kino.Text.new(format_stacktrace_item(stack_item)), |
|
Kino.Tree.new(args) |
|
] |
|
|
|
columns = |
|
if t.returned_at != nil do |
|
{:return, ret} = t.return_value |
|
columns ++ [format_return(ret)] |
|
else |
|
columns |
|
end |
|
|
|
stack = |
|
for {mod, fun, arity, [file: _file, line: _line]} <- t.stacktrace do |
|
[func: format_mfa({mod, fun, arity})] |
|
end |
|
|
|
Kino.Frame.append( |
|
trace_frame, |
|
Kino.Layout.tabs( |
|
Summary: Kino.Layout.grid(columns, columns: Enum.count(columns)), |
|
Stacktrace: Kino.DataTable.new(stack) |
|
) |
|
) |
|
end) |
|
end |
|
|
|
def format_stacktrace_item({:elixir, :eval_external_handler, _, _}) do |
|
"(eval)" |
|
end |
|
|
|
def format_stacktrace_item({mod, fun, arity, [file: file, line: line]}) do |
|
format_mfa({mod, fun, arity}) <> " " <> "#{file}:#{line}" |
|
end |
|
|
|
def format_mfa({mod, fun, arity}) do |
|
"Elixir." <> mod_name = Atom.to_string(mod) |
|
"&#{mod_name}.#{fun}/#{arity}" |
|
end |
|
|
|
def format_mfa(bad_mfa) do |
|
inspect(bad_mfa) |
|
end |
|
|
|
defp format_return(v) when is_binary(v) or is_number(v) or is_atom(v) do |
|
Kino.Inspect.new(v) |
|
end |
|
|
|
defp format_return(v) do |
|
Kino.Tree.new(v) |
|
end |
|
end |