Current section
Files
Jump to
Current section
Files
src/stacky.erl
-module(stacky).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([erlang_module_name/1, gleam_module_name/1, stack_index/1, function_name/1, function_arity/1, erlang_file_name/1, erlang_line_number/1, frame_to_string/1, trace_to_string/1, print_frame/1, print_frame_with/2, print_trace/1, print_trace_with/2, frame/2, trace/0, main/0]).
-export_type([stack_trace/0, stack_frame/0, stack_index/0, erlang_module_name/0, function_name/0, function_arity/0, erlang_file_name/0, erlang_line_number/0]).
-type stack_trace() :: {stack_trace, list(stack_frame())}.
-type stack_frame() :: {stack_frame,
stack_index(),
erlang_module_name(),
function_name(),
function_arity(),
erlang_file_name(),
erlang_line_number()}.
-type stack_index() :: {stack_index, integer()}.
-type erlang_module_name() :: {erlang_module_name, binary()}.
-type function_name() :: {function_name, binary()}.
-type function_arity() :: {function_arity, integer()}.
-type erlang_file_name() :: {erlang_file_name, binary()}.
-type erlang_line_number() :: {erlang_line_number, integer()}.
-spec erlang_module_name(stack_frame()) -> binary().
erlang_module_name(Stack_frame) ->
{erlang_module_name, Erlang_module_name} = erlang:element(3, Stack_frame),
Erlang_module_name.
-spec gleam_module_name(stack_frame()) -> binary().
gleam_module_name(Stack_frame) ->
Erlang_module_name = begin
_pipe = Stack_frame,
erlang_module_name(_pipe)
end,
_assert_subject = gleam@regex:from_string(<<"@@"/utf8>>),
{ok, Double_at_re} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"stacky"/utf8>>,
function => <<"gleam_module_name"/utf8>>,
line => 180})
end,
_assert_subject@1 = gleam@regex:from_string(<<"@"/utf8>>),
{ok, Single_at_re} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"stacky"/utf8>>,
function => <<"gleam_module_name"/utf8>>,
line => 181})
end,
Has_double_ats = begin
_pipe@1 = Erlang_module_name,
_pipe@2 = gleam@regex:scan(Double_at_re, _pipe@1),
gleam@list:is_empty(_pipe@2)
end
=:= false,
Has_ats = begin
_pipe@3 = Erlang_module_name,
_pipe@4 = gleam@regex:scan(Single_at_re, _pipe@3),
gleam@list:is_empty(_pipe@4)
end
=:= false,
case {Has_double_ats, Has_ats} of
{true, _} ->
<<"gleam entrypoint module | "/utf8, Erlang_module_name/binary>>;
{false, false} ->
Erlang_module_name;
{false, true} ->
_pipe@5 = Erlang_module_name,
gleam@string:replace(_pipe@5, <<"@"/utf8>>, <<"/"/utf8>>)
end.
-spec stack_index(stack_frame()) -> integer().
stack_index(Stack_frame) ->
{stack_index, Stack_index} = erlang:element(2, Stack_frame),
Stack_index.
-spec function_name(stack_frame()) -> binary().
function_name(Stack_frame) ->
{function_name, Function_name} = erlang:element(4, Stack_frame),
Function_name.
-spec function_arity(stack_frame()) -> integer().
function_arity(Stack_frame) ->
{function_arity, Function_arity} = erlang:element(5, Stack_frame),
Function_arity.
-spec erlang_file_name(stack_frame()) -> binary().
erlang_file_name(Stack_frame) ->
{erlang_file_name, Erlang_file_name} = erlang:element(6, Stack_frame),
Erlang_file_name.
-spec erlang_line_number(stack_frame()) -> integer().
erlang_line_number(Stack_frame) ->
{erlang_line_number, Erlang_line_number} = erlang:element(7, Stack_frame),
Erlang_line_number.
-spec frame_to_string(stack_frame()) -> binary().
frame_to_string(Stack_frame) ->
Stack_index = begin
_pipe = Stack_frame,
_pipe@1 = stack_index(_pipe),
gleam@int:to_string(_pipe@1)
end,
Erlang_module_name = begin
_pipe@2 = Stack_frame,
gleam_module_name(_pipe@2)
end,
Function_name = begin
_pipe@3 = Stack_frame,
function_name(_pipe@3)
end,
Function_arity = begin
_pipe@4 = Stack_frame,
_pipe@5 = function_arity(_pipe@4),
gleam@int:to_string(_pipe@5)
end,
Erlang_file_name = begin
_pipe@6 = Stack_frame,
erlang_file_name(_pipe@6)
end,
Erlang_line_number = begin
_pipe@7 = Stack_frame,
_pipe@8 = erlang_line_number(_pipe@7),
gleam@int:to_string(_pipe@8)
end,
Line = <<<<<<<<<<<<<<"#"/utf8, Stack_index/binary>>/binary, " - "/utf8>>/binary,
Erlang_module_name/binary>>/binary,
"."/utf8>>/binary,
Function_name/binary>>/binary,
" - /"/utf8>>/binary,
Function_arity/binary>>,
<<Line/binary, (case Erlang_file_name of
<<"unknown"/utf8>> ->
<<""/utf8>>;
_ ->
<<<<<<" - "/utf8, Erlang_file_name/binary>>/binary, ":"/utf8>>/binary,
Erlang_line_number/binary>>
end)/binary>>.
-spec trace_to_string(stack_trace()) -> binary().
trace_to_string(Stack_frame) ->
{stack_trace, Stack_trace} = Stack_frame,
_pipe = Stack_trace,
_pipe@2 = gleam@list:map(
_pipe,
fun(Stack_frame@1) -> _pipe@1 = Stack_frame@1,
frame_to_string(_pipe@1) end
),
gleam@string:join(_pipe@2, <<"\n"/utf8>>).
-spec print_frame(stack_frame()) -> nil.
print_frame(Stack_frame) ->
gleam_erlang_ffi:sleep(100),
_pipe = Stack_frame,
_pipe@1 = frame_to_string(_pipe),
gleam@io:println(_pipe@1),
gleam_erlang_ffi:sleep(100).
-spec print_frame_with(stack_frame(), any()) -> nil.
print_frame_with(Stack_frame, C) ->
gleam_erlang_ffi:sleep(100),
_pipe = Stack_frame,
_pipe@1 = frame_to_string(_pipe),
gleam@io:print(_pipe@1),
gleam@io:print(<<"\nwith context: "/utf8>>),
pprint:debug(C),
gleam_erlang_ffi:sleep(100).
-spec print_trace(stack_trace()) -> nil.
print_trace(Stack_trace) ->
gleam_erlang_ffi:sleep(100),
_pipe = Stack_trace,
_pipe@1 = trace_to_string(_pipe),
gleam@io:println(_pipe@1),
gleam_erlang_ffi:sleep(100).
-spec print_trace_with(stack_trace(), any()) -> nil.
print_trace_with(Stack_trace, C) ->
gleam_erlang_ffi:sleep(100),
_pipe = Stack_trace,
_pipe@1 = trace_to_string(_pipe),
gleam@io:print(_pipe@1),
gleam@io:print(<<"\nwith context: "/utf8>>),
pprint:debug(C),
gleam_erlang_ffi:sleep(100).
-spec list_at(list(GMO), integer()) -> {ok, GMO} | {error, nil}.
list_at(List, Index) ->
case Index >= 0 of
true ->
_pipe = List,
_pipe@1 = gleam@list:drop(_pipe, Index),
gleam@list:first(_pipe@1);
false ->
{error, nil}
end.
-spec frame(stack_trace(), integer()) -> stack_frame().
frame(Stacktrace, Index) ->
{stack_trace, Stacktrace@1} = Stacktrace,
case begin
_pipe = Stacktrace@1,
list_at(_pipe, Index)
end of
{ok, Stackframe} ->
Stackframe;
{error, _} ->
Panic_msg = <<<<"No stack frame at index "/utf8,
(gleam@int:to_string(Index))/binary>>/binary,
"."/utf8>>,
erlang:error(#{gleam_error => panic,
message => Panic_msg,
module => <<"stacky"/utf8>>,
function => <<"frame"/utf8>>,
line => 52})
end.
-spec trace() -> stack_trace().
trace() ->
Erlang_stack_trace = stacky_ffi:stacky_erlang_stacktrace(),
_pipe = Erlang_stack_trace,
_pipe@1 = gleam@list:map(
_pipe,
fun(Frame) ->
{Stack_index,
{Erlang_module_name,
Function_name,
Function_arity,
Erlang_file_name,
Erlang_line_number}} = Frame,
{stack_frame,
{stack_index, Stack_index},
{erlang_module_name, Erlang_module_name},
{function_name, Function_name},
{function_arity, Function_arity},
{erlang_file_name, Erlang_file_name},
{erlang_line_number, Erlang_line_number}}
end
),
{stack_trace, _pipe@1}.
-spec main() -> nil.
main() ->
gleam@io:println(<<"\nFor example stack traces, run:\n"/utf8>>),
gleam@io:println(
<<" gleam run --module stacky/internal/example\n"/utf8>>
),
gleam@io:println(<<"...or...\n"/utf8>>),
gleam@io:println(
<<" gleam run --module stacky/internal/sub_dir/example_in_sub_dir\n"/utf8>>
),
gleam@io:println(<<"...or...\n"/utf8>>),
gleam@io:println(<<" gleam run --module my_gleam_module\n"/utf8>>).