-module(testament@internal@parse). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/testament/internal/parse.gleam"). -export([is_doc/1, is_doctest_line/1, split_imports_and_code/2, fold_doc_state/2, parse_markdown_snippets/1, get_doc_tests_imports_and_code/1]). -export_type([doc_state/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(false). -type doc_state() :: {doc_state, boolean(), list(glexer@token:token()), list(list(glexer@token:token()))}. -file("src/testament/internal/parse.gleam", 85). ?DOC(false). -spec is_doc(glexer@token:token()) -> boolean(). is_doc(Line) -> case Line of {comment_doc, _} -> true; {comment_module, _} -> true; _ -> false end. -file("src/testament/internal/parse.gleam", 93). ?DOC(false). -spec is_doctest_line(glexer@token:token()) -> boolean(). is_doctest_line(Line) -> case Line of {comment_doc, <<":"/utf8, _/binary>>} -> true; {comment_module, <<":"/utf8, _/binary>>} -> true; _ -> false end. -file("src/testament/internal/parse.gleam", 109). ?DOC(false). -spec split_imports_and_code({list(binary()), list(binary())}, binary()) -> {list(binary()), list(binary())}. split_imports_and_code(Code, Line) -> case gleam_stdlib:string_starts_with(Line, <<"import"/utf8>>) of true -> gleam@pair:map_first( Code, fun(_capture) -> gleam@list:prepend(_capture, Line) end ); false -> gleam@pair:map_second( Code, fun(_capture@1) -> lists:append(_capture@1, [Line]) end ) end. -file("src/testament/internal/parse.gleam", 119). ?DOC(false). -spec fold_doc_state(doc_state(), glexer@token:token()) -> doc_state(). fold_doc_state(State, Line) -> case {State, Line} of {{doc_state, false, Lines, _}, {comment_doc, <<":"/utf8, _/binary>>}} -> {doc_state, true, [Line | Lines], erlang:element(4, State)}; {{doc_state, false, Lines, _}, {comment_module, <<":"/utf8, _/binary>>}} -> {doc_state, true, [Line | Lines], erlang:element(4, State)}; {{doc_state, true, Lines@1, _}, {comment_doc, <<":"/utf8, _/binary>>}} -> {doc_state, erlang:element(2, State), [Line | Lines@1], erlang:element(4, State)}; {{doc_state, true, Lines@1, _}, {comment_module, <<":"/utf8, _/binary>>}} -> {doc_state, erlang:element(2, State), [Line | Lines@1], erlang:element(4, State)}; {{doc_state, true, Lines@2, Bodies}, _} -> {doc_state, false, [], gleam@list:prepend(Bodies, lists:reverse(Lines@2))}; {_, _} -> State end. -file("src/testament/internal/parse.gleam", 76). ?DOC(false). -spec collect_test_lines(list(glexer@token:token())) -> list(list(glexer@token:token())). collect_test_lines(Tokens) -> State = gleam@list:fold( Tokens, {doc_state, false, [], []}, fun fold_doc_state/2 ), case erlang:element(3, State) of [] -> erlang:element(4, State); _ -> gleam@list:prepend( erlang:element(4, State), lists:reverse(erlang:element(3, State)) ) end. -file("src/testament/internal/parse.gleam", 140). ?DOC(false). -spec prep_imports(list({list(binary()), binary()})) -> {list(binary()), list(binary())}. prep_imports(Blocks) -> _pipe = Blocks, _pipe@3 = gleam@list:fold(_pipe, {[], []}, fun(Acc, Block) -> _pipe@1 = Acc, _pipe@2 = gleam@pair:map_first( _pipe@1, fun(_capture) -> lists:append(_capture, gleam@pair:first(Block)) end ), gleam@pair:map_second( _pipe@2, fun(_capture@1) -> gleam@list:prepend(_capture@1, gleam@pair:second(Block)) end ) end), gleam@pair:map_first(_pipe@3, fun gleam@list:unique/1). -file("src/testament/internal/parse.gleam", 19). ?DOC(false). -spec parse_markdown_snippets(binary()) -> {list(binary()), list(binary())}. parse_markdown_snippets(Content) -> Rg@1 = case gleam@regexp:compile( <<"^```gleam(?:\\s*(\\w+))?([\\s\\S]*?)^```$"/utf8>>, {options, false, true} ) of {ok, Rg} -> Rg; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => (<<"failed to compile markdown regex"/utf8>>), file => <>, module => <<"testament/internal/parse"/utf8>>, function => <<"parse_markdown_snippets"/utf8>>, line => 20, value => _assert_fail, start => 371, 'end' => 502, pattern_start => 382, pattern_end => 388}) end, _pipe = Rg@1, _pipe@1 = gleam@regexp:scan(_pipe, Content), _pipe@2 = testament@internal@stream:new(_pipe@1), _pipe@13 = testament@internal@stream:map( _pipe@2, fun(Match) -> _pipe@3 = erlang:element(2, Match), _pipe@4 = gleam@string:replace( _pipe@3, <<"```gleam"/utf8>>, <<""/utf8>> ), _pipe@5 = gleam@string:replace(_pipe@4, <<"```"/utf8>>, <<""/utf8>>), _pipe@6 = gleam@string:trim(_pipe@5), _pipe@7 = glexer:new(_pipe@6), _pipe@8 = glexer:discard_comments(_pipe@7), _pipe@9 = glexer:lex(_pipe@8), _pipe@10 = glexer:to_source(_pipe@9), _pipe@11 = gleam@string:split(_pipe@10, <<"\n"/utf8>>), _pipe@12 = gleam@list:fold( _pipe@11, {[], []}, fun split_imports_and_code/2 ), gleam@pair:map_second( _pipe@12, fun(_capture) -> gleam@string:join(_capture, <<"\n"/utf8>>) end ) end ), _pipe@14 = testament@internal@stream:to_list(_pipe@13), prep_imports(_pipe@14). -file("src/testament/internal/parse.gleam", 47). ?DOC(false). -spec get_doc_tests_imports_and_code(binary()) -> {list(binary()), list(binary())}. get_doc_tests_imports_and_code(Code) -> Prefix_len = string:length(<<":"/utf8>>), _pipe = Code, _pipe@1 = glexer:new(_pipe), _pipe@2 = glexer:discard_whitespace(_pipe@1), _pipe@3 = glexer:lex(_pipe@2), _pipe@4 = testament@internal@stream:new(_pipe@3), _pipe@5 = testament@internal@stream:map(_pipe@4, fun gleam@pair:first/1), _pipe@6 = testament@internal@stream:filter(_pipe@5, fun is_doc/1), _pipe@7 = testament@internal@stream:to_list(_pipe@6), _pipe@8 = collect_test_lines(_pipe@7), _pipe@9 = testament@internal@stream:new(_pipe@8), _pipe@19 = testament@internal@stream:map( _pipe@9, fun(Tokens) -> _pipe@10 = Tokens, _pipe@11 = testament@internal@stream:new(_pipe@10), _pipe@12 = testament@internal@stream:filter( _pipe@11, fun is_doctest_line/1 ), _pipe@13 = testament@internal@stream:map( _pipe@12, fun glexer@token:to_source/1 ), _pipe@14 = testament@internal@stream:map( _pipe@13, fun(_capture) -> gleam_stdlib:crop_string(_capture, <<":"/utf8>>) end ), _pipe@15 = testament@internal@stream:map( _pipe@14, fun(_capture@1) -> gleam@string:drop_start(_capture@1, Prefix_len) end ), _pipe@16 = testament@internal@stream:map( _pipe@15, fun gleam@string:trim/1 ), _pipe@17 = testament@internal@stream:to_list(_pipe@16), _pipe@18 = gleam@list:fold( _pipe@17, {[], []}, fun split_imports_and_code/2 ), gleam@pair:map_second( _pipe@18, fun(_capture@2) -> gleam@string:join(_capture@2, <<"\n"/utf8>>) end ) end ), _pipe@20 = testament@internal@stream:to_list(_pipe@19), prep_imports(_pipe@20).