Packages

A tool for converting to Gleam's new `assert` syntax

Current section

Files

Jump to
asset src asset.erl
Raw

src/asset.erl

-module(asset).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-define(FILEPATH, "src/asset.gleam").
-export([update_text/2, main/0]).
-export_type([error/0, edit/0, assertion_position/0, option_constructor/0, module_info/0, option_import/0, assertion_function/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.
-type error() :: {parsing_failed, glance:error()} | no_import_found.
-type edit() :: {edit, integer(), integer(), binary()}.
-type assertion_position() :: statement | expression | inside_assertion.
-type option_constructor() :: some_constructor | none_constructor.
-type module_info() :: {module_info,
binary(),
glance:span(),
gleam@option:option(option_import()),
binary()}.
-type option_import() :: {option_import,
binary(),
gleam@option:option(binary()),
gleam@option:option(binary())}.
-type assertion_function() :: be_error |
be_false |
be_none |
be_ok |
be_some |
be_true |
equal |
fail |
not_equal.
-file("src/asset.gleam", 263).
-spec pipe_args(glance:expression(), list(glance:field(glance:expression()))) -> list(glance:field(glance:expression())).
pipe_args(Left, Args) ->
[{unlabelled_field, Left} | Args].
-file("src/asset.gleam", 270).
-spec called_function(glance:expression()) -> {ok,
{gleam@option:option(binary()), binary()}} |
{error, nil}.
called_function(Function) ->
case Function of
{field_access, _, {variable, _, Module}, Name} ->
{ok, {{some, Module}, Name}};
{variable, _, Name@1} ->
{ok, {none, Name@1}};
_ ->
{error, nil}
end.
-file("src/asset.gleam", 478).
-spec replace_or_return(binary(), glance:span(), assertion_position()) -> {binary(),
list(edit())}.
replace_or_return(Text, Location, Position) ->
case Position of
expression ->
{<<""/utf8>>,
[{edit,
erlang:element(2, Location),
erlang:element(3, Location),
Text}]};
statement ->
{<<""/utf8>>,
[{edit,
erlang:element(2, Location),
erlang:element(3, Location),
Text}]};
inside_assertion ->
{Text, []}
end.
-file("src/asset.gleam", 489).
-spec wrap_assert(binary(), assertion_position()) -> binary().
wrap_assert(Assert_, Position) ->
case Position of
expression ->
<<<<"{ "/utf8, Assert_/binary>>/binary, " }"/utf8>>;
inside_assertion ->
<<<<"{ "/utf8, Assert_/binary>>/binary, " }"/utf8>>;
statement ->
Assert_
end.
-file("src/asset.gleam", 501).
-spec option_constructor(option_constructor(), module_info()) -> {binary(),
list(edit())}.
option_constructor(Constructor, Info) ->
{Import_@1, Edits} = case erlang:element(4, Info) of
none ->
Import_ = {option_import, <<"option"/utf8>>, none, none},
{Import_, [{edit, 0, 0, <<"import gleam/option\n"/utf8>>}]};
{some, I} ->
{I, []}
end,
Name@2 = case Constructor of
none_constructor ->
case erlang:element(4, Import_@1) of
none ->
<<(erlang:element(2, Import_@1))/binary, ".None"/utf8>>;
{some, Name} ->
Name
end;
some_constructor ->
case erlang:element(3, Import_@1) of
none ->
<<(erlang:element(2, Import_@1))/binary, ".Some"/utf8>>;
{some, Name@1} ->
Name@1
end
end,
{Name@2, Edits}.
-file("src/asset.gleam", 747).
-spec operator_to_string(glance:binary_operator()) -> binary().
operator_to_string(Name) ->
case Name of
add_float ->
<<"+."/utf8>>;
add_int ->
<<"+"/utf8>>;
'and' ->
<<"&&"/utf8>>;
concatenate ->
<<"<>"/utf8>>;
div_float ->
<<"/."/utf8>>;
div_int ->
<<"/"/utf8>>;
eq ->
<<"=="/utf8>>;
gt_eq_float ->
<<">=."/utf8>>;
gt_eq_int ->
<<">="/utf8>>;
gt_float ->
<<">."/utf8>>;
gt_int ->
<<">"/utf8>>;
lt_eq_float ->
<<"<=."/utf8>>;
lt_eq_int ->
<<"<="/utf8>>;
lt_float ->
<<"<=."/utf8>>;
lt_int ->
<<"<"/utf8>>;
mult_float ->
<<"*."/utf8>>;
mult_int ->
<<"*"/utf8>>;
not_eq ->
<<"!="/utf8>>;
'or' ->
<<"||"/utf8>>;
pipe ->
<<"|>"/utf8>>;
remainder_int ->
<<"%"/utf8>>;
sub_float ->
<<"-."/utf8>>;
sub_int ->
<<"-"/utf8>>
end.
-file("src/asset.gleam", 843).
-spec count_indentation(binary(), integer()) -> integer().
count_indentation(Text, Count) ->
case gleam_stdlib:string_ends_with(Text, <<" "/utf8>>) of
false ->
Count;
true ->
count_indentation(gleam@string:drop_end(Text, 1), Count + 1)
end.
-file("src/asset.gleam", 867).
-spec slice(binary(), integer(), integer()) -> binary().
slice(String, Start, End) ->
Length = case End of
-1 ->
erlang:byte_size(String) - Start;
_ ->
End - Start
end,
binary:part(String, Start, Length).
-file("src/asset.gleam", 630).
-spec do_get_src(binary(), glance:span()) -> binary().
do_get_src(Src, Location) ->
slice(Src, erlang:element(2, Location), erlang:element(3, Location)).
-file("src/asset.gleam", 592).
-spec pipe_to_call(binary(), glance:expression(), glance:expression()) -> binary().
pipe_to_call(Src, Left, Right) ->
{Function@2, Before, After, Label@1} = case Right of
{call, _, Function, Arguments} ->
{Function, [], Arguments, none};
{fn_capture, _, Label, Function@1, Arguments_before, Arguments_after} ->
{Function@1, Arguments_before, Arguments_after, Label};
_ ->
{Right, [], [], none}
end,
Piped_argument = case Label@1 of
none ->
{unlabelled_field, Left};
{some, Label@2} ->
{labelled_field, Label@2, Left}
end,
Arguments@1 = gleam@list:flatten([Before, [Piped_argument], After]),
Argument_strings = gleam@list:map(
Arguments@1,
fun(Argument) -> case Argument of
{labelled_field, Label@3, Item} ->
<<<<Label@3/binary, ": "/utf8>>/binary,
(do_get_src(Src, erlang:element(2, Item)))/binary>>;
{shorthand_field, Label@4} ->
<<Label@4/binary, ":"/utf8>>;
{unlabelled_field, Item@1} ->
do_get_src(Src, erlang:element(2, Item@1))
end end
),
<<<<<<(do_get_src(Src, erlang:element(2, Function@2)))/binary, "("/utf8>>/binary,
(gleam@string:join(Argument_strings, <<", "/utf8>>))/binary>>/binary,
")"/utf8>>.
-file("src/asset.gleam", 837).
-spec find_indent(binary(), integer()) -> integer().
find_indent(Src, Position) ->
Until_position = slice(Src, 0, Position),
count_indentation(Until_position, 0).
-file("src/asset.gleam", 862).
-spec replace_span(binary(), integer(), integer(), binary()) -> binary().
replace_span(String, Start, End, Text) ->
<<<<(slice(String, 0, Start))/binary, Text/binary>>/binary,
(slice(String, End, -1))/binary>>.
-file("src/asset.gleam", 850).
-spec apply_edits(binary(), list(edit())) -> binary().
apply_edits(Contents, Edits) ->
erlang:element(
1,
gleam@list:fold(
Edits,
{Contents, 0},
fun(Acc, Edit) ->
{Contents@1, Offset} = Acc,
Contents@2 = replace_span(
Contents@1,
erlang:element(2, Edit) + Offset,
erlang:element(3, Edit) + Offset,
erlang:element(4, Edit)
),
Edit_offset = (erlang:byte_size(erlang:element(4, Edit)) + erlang:element(
2,
Edit
))
- erlang:element(3, Edit),
Offset@1 = Offset + Edit_offset,
{Contents@2, Offset@1}
end
)
).
-file("src/asset.gleam", 908).
-spec assertion_function(module_info(), gleam@option:option(binary()), binary()) -> {ok,
assertion_function()} |
{error, nil}.
assertion_function(Info, Module, Name) ->
case Module =:= {some, erlang:element(2, Info)} of
false ->
{error, nil};
true ->
case Name of
<<"be_error"/utf8>> ->
{ok, be_error};
<<"be_false"/utf8>> ->
{ok, be_false};
<<"be_none"/utf8>> ->
{ok, be_none};
<<"be_ok"/utf8>> ->
{ok, be_ok};
<<"be_some"/utf8>> ->
{ok, be_some};
<<"be_true"/utf8>> ->
{ok, be_true};
<<"equal"/utf8>> ->
{ok, equal};
<<"fail"/utf8>> ->
{ok, fail};
<<"not_equal"/utf8>> ->
{ok, not_equal};
_ ->
{error, nil}
end
end.
-file("src/asset.gleam", 931).
-spec find_import(
list(glance:definition(glance:import())),
binary(),
module_info()
) -> {ok, module_info()} | {error, nil}.
find_import(Imports, Module, Info) ->
case Imports of
[] ->
case erlang:element(2, Info) of
<<""/utf8>> ->
{error, nil};
_ ->
{ok, Info}
end;
[Import_ | Imports@1] ->
case erlang:element(3, erlang:element(3, Import_)) of
<<"gleam/option"/utf8>> ->
Alias@1 = case erlang:element(4, erlang:element(3, Import_)) of
{some, {named, Alias}} ->
Alias;
{some, {discarded, _}} ->
<<"option"/utf8>>;
none ->
<<"option"/utf8>>
end,
Some_name = begin
_pipe = erlang:element(6, erlang:element(3, Import_)),
_pipe@2 = gleam@list:find_map(
_pipe,
fun(Value) -> case erlang:element(2, Value) of
<<"Some"/utf8>> ->
{ok,
begin
_pipe@1 = erlang:element(
3,
Value
),
gleam@option:unwrap(
_pipe@1,
<<"Some"/utf8>>
)
end};
_ ->
{error, nil}
end end
),
gleam@option:from_result(_pipe@2)
end,
None_name = begin
_pipe@3 = erlang:element(6, erlang:element(3, Import_)),
_pipe@5 = gleam@list:find_map(
_pipe@3,
fun(Value@1) -> case erlang:element(2, Value@1) of
<<"None"/utf8>> ->
{ok,
begin
_pipe@4 = erlang:element(
3,
Value@1
),
gleam@option:unwrap(
_pipe@4,
<<"None"/utf8>>
)
end};
_ ->
{error, nil}
end end
),
gleam@option:from_result(_pipe@5)
end,
find_import(
Imports@1,
Module,
begin
_record = Info,
{module_info,
erlang:element(2, _record),
erlang:element(3, _record),
{some,
{option_import,
Alias@1,
Some_name,
None_name}},
erlang:element(5, _record)}
end
);
M when M =:= Module ->
case erlang:element(4, erlang:element(3, Import_)) of
{some, {named, Alias@2}} ->
find_import(
Imports@1,
Module,
begin
_record@1 = Info,
{module_info,
Alias@2,
erlang:element(
2,
erlang:element(3, Import_)
),
erlang:element(4, _record@1),
erlang:element(5, _record@1)}
end
);
{some, {discarded, _}} ->
{error, nil};
none ->
find_import(
Imports@1,
Module,
begin
_record@2 = Info,
{module_info,
begin
_pipe@6 = gleam@string:split(
Module,
<<"/"/utf8>>
),
_pipe@7 = gleam@list:last(_pipe@6),
gleam@result:unwrap(
_pipe@7,
<<""/utf8>>
)
end,
erlang:element(
2,
erlang:element(3, Import_)
),
erlang:element(4, _record@2),
erlang:element(5, _record@2)}
end
)
end;
_ ->
find_import(Imports@1, Module, Info)
end
end.
-file("src/asset.gleam", 1046).
-spec print_error(binary(), binary(), simplifile:file_error()) -> nil.
print_error(Action, Path, Error) ->
gleam_stdlib:println_error(
<<<<<<<<<<"Failed to "/utf8, Action/binary>>/binary, " "/utf8>>/binary,
Path/binary>>/binary,
": "/utf8>>/binary,
(simplifile:describe_error(Error))/binary>>
).
-file("src/asset.gleam", 1013).
-spec collect_files(binary()) -> list({binary(), binary()}).
collect_files(Directory) ->
case simplifile_erl:read_directory(Directory) of
{error, Error} ->
print_error(<<"read directory"/utf8>>, Directory, Error),
[];
{ok, Items} ->
gleam@list:flat_map(
Items,
fun(Item) ->
Path = filepath:join(Directory, Item),
case simplifile_erl:is_directory(Path) of
{ok, true} ->
collect_files(Path);
{ok, false} ->
case filepath:extension(Path) of
{ok, <<"gleam"/utf8>>} ->
case simplifile:read(Path) of
{ok, Contents} ->
[{Path, Contents}];
{error, Error@1} ->
print_error(
<<"read file"/utf8>>,
Path,
Error@1
),
[]
end;
_ ->
[]
end;
{error, Error@2} ->
print_error(<<"read file"/utf8>>, Path, Error@2),
[]
end
end
)
end.
-file("src/asset.gleam", 1052).
-spec print_usage() -> nil.
print_usage() ->
gleam_stdlib:println(
<<"Usage: asset update [directory]
Flags:
-m <test module> Changes the target module to replace, defaults to `gleeunit/should`."/utf8>>
).
-file("src/asset.gleam", 1061).
-spec glance_error(glance:error()) -> binary().
glance_error(Error) ->
case Error of
unexpected_end_of_input ->
<<"Unexpected end of input"/utf8>>;
{unexpected_token, Token, Position} ->
<<<<<<<<"Unexpected token at position "/utf8,
(erlang:integer_to_binary(
erlang:element(2, Position)
))/binary>>/binary,
": `"/utf8>>/binary,
(glexer@token:to_source(Token))/binary>>/binary,
"`"/utf8>>
end.
-file("src/asset.gleam", 191).
-spec do_expression(
glance:expression(),
module_info(),
integer(),
assertion_position()
) -> list(edit()).
do_expression(Ast, Info, Statement_start, Position) ->
case Ast of
{binary_operator, Location, Name, Left, Right} ->
_pipe = case Name of
pipe ->
pipe(Left, Right, Location, Info, Statement_start, Position);
_ ->
{error, nil}
end,
_pipe@1 = gleam@result:map(_pipe, fun gleam@pair:second/1),
gleam@result:lazy_unwrap(
_pipe@1,
fun() -> expressions([Left, Right], Info, Statement_start) end
);
{bit_string, _, _} ->
[];
{block, _, Body} ->
statements(Body, Info);
{call, Location@1, Function, Arguments} ->
_pipe@2 = call(
Location@1,
Function,
Arguments,
Info,
Statement_start,
Position
),
_pipe@3 = gleam@result:map(_pipe@2, fun gleam@pair:second/1),
gleam@result:lazy_unwrap(
_pipe@3,
fun() ->
lists:append(
expression(Function, Info, Statement_start),
fields(Arguments, Info, Statement_start)
)
end
);
{'case', _, Subjects, Cs} ->
lists:append(
expressions(Subjects, Info, Statement_start),
clauses(Cs, Info, Statement_start)
);
{echo, _, Value} ->
optional(Value, Info, Statement_start);
{field_access, _, Container, _} ->
expression(Container, Info, Statement_start);
{float, _, _} ->
[];
{fn, _, _, _, Body@1} ->
statements(Body@1, Info);
{fn_capture, _, _, Function@1, Arguments_before, Arguments_after} ->
gleam@list:flatten(
[expression(Function@1, Info, Statement_start),
fields(Arguments_before, Info, Statement_start),
fields(Arguments_after, Info, Statement_start)]
);
{int, _, _} ->
[];
{list, _, Elements, Rest} ->
case Rest of
none ->
expressions(Elements, Info, Statement_start);
{some, Rest@1} ->
expressions([Rest@1 | Elements], Info, Statement_start)
end;
{negate_bool, _, Value@1} ->
expression(Value@1, Info, Statement_start);
{negate_int, _, Value@2} ->
expression(Value@2, Info, Statement_start);
{panic, _, Message} ->
optional(Message, Info, Statement_start);
{record_update, _, _, _, Record, Fields} ->
expressions(
[Record |
gleam@list:filter_map(
Fields,
fun(Field) ->
gleam@option:to_result(
erlang:element(3, Field),
nil
)
end
)],
Info,
Statement_start
);
{string, _, _} ->
[];
{todo, _, Message@1} ->
optional(Message@1, Info, Statement_start);
{tuple, _, Elements@1} ->
expressions(Elements@1, Info, Statement_start);
{tuple_index, _, Tuple, _} ->
expression(Tuple, Info, Statement_start);
{variable, _, _} ->
[]
end.
-file("src/asset.gleam", 183).
-spec expression(glance:expression(), module_info(), integer()) -> list(edit()).
expression(Expression, Info, Statement_start) ->
do_expression(Expression, Info, Statement_start, expression).
-file("src/asset.gleam", 119).
-spec expressions(list(glance:expression()), module_info(), integer()) -> list(edit()).
expressions(Expressions, Info, Statement_start) ->
gleam@list:flat_map(
Expressions,
fun(_capture) -> expression(_capture, Info, Statement_start) end
).
-file("src/asset.gleam", 127).
-spec statement(glance:statement(), module_info()) -> list(edit()).
statement(Statement, Info) ->
case Statement of
{assert, Location, Value, Message} ->
case Message of
none ->
expression(Value, Info, erlang:element(2, Location));
{some, Message@1} ->
expressions(
[Value, Message@1],
Info,
erlang:element(2, Location)
)
end;
{assignment, Location@1, Kind, _, _, Value@1} ->
case Kind of
{let_assert, none} ->
expression(Value@1, Info, erlang:element(2, Location@1));
'let' ->
expression(Value@1, Info, erlang:element(2, Location@1));
{let_assert, {some, Message@2}} ->
expressions(
[Value@1, Message@2],
Info,
erlang:element(2, Location@1)
)
end;
{expression, E} ->
do_expression(
E,
Info,
erlang:element(2, erlang:element(2, E)),
statement
);
{use, Location@2, _, Function} ->
expression(Function, Info, erlang:element(2, Location@2))
end.
-file("src/asset.gleam", 112).
-spec statements(list(glance:statement()), module_info()) -> list(edit()).
statements(Statements, Info) ->
gleam@list:flat_map(
Statements,
fun(_capture) -> statement(_capture, Info) end
).
-file("src/asset.gleam", 93).
-spec find_edits(list(glance:definition(glance:function_())), module_info()) -> list(edit()).
find_edits(Functions, Info) ->
_pipe = Functions,
_pipe@1 = gleam@list:flat_map(
_pipe,
fun(Definition) ->
statements(erlang:element(7, erlang:element(3, Definition)), Info)
end
),
_pipe@2 = gleam@list:prepend(
_pipe@1,
{edit,
erlang:element(2, erlang:element(3, Info)),
erlang:element(3, erlang:element(3, Info)) + 1,
<<""/utf8>>}
),
gleam@list:sort(
_pipe@2,
fun(A, B) ->
_pipe@3 = gleam@int:compare(
erlang:element(2, A),
erlang:element(2, B)
),
gleam@order:break_tie(
_pipe@3,
gleam@int:compare(erlang:element(3, A), erlang:element(3, B))
)
end
).
-file("src/asset.gleam", 42).
?DOC(
" Updates a single file to use `assert` syntax. Accepts the target module to\n"
" replace. `gleeunit/should` should be used for most cases.\n"
).
-spec update_text(binary(), binary()) -> {ok, binary()} | {error, error()}.
update_text(Contents, Target_module) ->
case glance:module(Contents) of
{error, Error} ->
{error, {parsing_failed, Error}};
{ok, Module} ->
Info = {module_info, <<""/utf8>>, {span, 0, 0}, none, Contents},
case find_import(erlang:element(2, Module), Target_module, Info) of
{error, _} ->
{error, no_import_found};
{ok, Import_} ->
Edits = find_edits(erlang:element(6, Module), Import_),
Result = apply_edits(Contents, Edits),
{ok, Result}
end
end.
-file("src/asset.gleam", 71).
-spec update_file(binary(), binary(), binary()) -> nil.
update_file(Path, Contents, Target_module) ->
case update_text(Contents, Target_module) of
{error, no_import_found} ->
gleam_stdlib:println_error(
<<<<<<"No references to `"/utf8, Target_module/binary>>/binary,
"` found in "/utf8>>/binary,
Path/binary>>
);
{error, {parsing_failed, Error}} ->
gleam_stdlib:println_error(
<<<<<<"Failed to parse file "/utf8, Path/binary>>/binary,
": "/utf8>>/binary,
(glance_error(Error))/binary>>
);
{ok, Text} ->
case simplifile:write(Path, Text) of
{error, Error@1} ->
print_error(<<"write to file"/utf8>>, Path, Error@1);
{ok, _} ->
gleam_stdlib:println_error(
<<"Successfully updated "/utf8, Path/binary>>
)
end
end.
-file("src/asset.gleam", 30).
-spec update(binary(), binary()) -> nil.
update(Directory, Module) ->
Files = collect_files(Directory),
gleam@list:each(
Files,
fun(Pair) ->
update_file(
erlang:element(1, Pair),
erlang:element(2, Pair),
Module
)
end
).
-file("src/asset.gleam", 18).
?DOC(" Call the `asset` CLI.\n").
-spec main() -> nil.
main() ->
Argv = argv:load(),
case erlang:element(4, Argv) of
[<<"update"/utf8>>] ->
update(<<"."/utf8>>, <<"gleeunit/should"/utf8>>);
[<<"update"/utf8>>, Directory] ->
update(Directory, <<"gleeunit/should"/utf8>>);
[<<"update"/utf8>>, <<"-m"/utf8>>, Module] ->
update(<<"."/utf8>>, Module);
[<<"update"/utf8>>, Directory@1, <<"-m"/utf8>>, Module@1] ->
update(Directory@1, Module@1);
_ ->
print_usage()
end.
-file("src/asset.gleam", 147).
-spec optional(
gleam@option:option(glance:expression()),
module_info(),
integer()
) -> list(edit()).
optional(Optional, Info, Statement_start) ->
case Optional of
{some, E} ->
expression(E, Info, Statement_start);
none ->
[]
end.
-file("src/asset.gleam", 158).
-spec fields(list(glance:field(glance:expression())), module_info(), integer()) -> list(edit()).
fields(Fields, Info, Statement_start) ->
gleam@list:flat_map(Fields, fun(Field) -> case Field of
{shorthand_field, _} ->
[];
{unlabelled_field, Item} ->
expression(Item, Info, Statement_start);
{labelled_field, _, Item} ->
expression(Item, Info, Statement_start)
end end).
-file("src/asset.gleam", 171).
-spec clauses(list(glance:clause()), module_info(), integer()) -> list(edit()).
clauses(Clauses, Info, Statement_start) ->
gleam@list:flat_map(
Clauses,
fun(Clause) -> case erlang:element(3, Clause) of
none ->
expression(erlang:element(4, Clause), Info, Statement_start);
{some, Guard} ->
expressions(
[erlang:element(4, Clause), Guard],
Info,
Statement_start
)
end end
).
-file("src/asset.gleam", 560).
-spec get_src(glance:expression(), module_info(), integer()) -> {binary(),
list(edit())}.
get_src(Expression, Info, Statement_start) ->
_pipe = case Expression of
{variable, _, Name} ->
{ok, {Name, []}};
{binary_operator, Location, pipe, Left, Right} ->
case pipe(
Left,
Right,
Location,
Info,
Statement_start,
inside_assertion
) of
{ok, Value} ->
{ok, Value};
{error, _} ->
case Left of
{binary_operator, _, pipe, _, _} ->
{error, nil};
_ ->
{ok,
{pipe_to_call(
erlang:element(5, Info),
Left,
Right
),
[]}}
end
end;
{call, Location@1, Function, Arguments} ->
call(
Location@1,
Function,
Arguments,
Info,
Statement_start,
inside_assertion
);
_ ->
{error, nil}
end,
gleam@result:lazy_unwrap(
_pipe,
fun() ->
{do_get_src(erlang:element(5, Info), erlang:element(2, Expression)),
[]}
end
).
-file("src/asset.gleam", 288).
-spec pipe(
glance:expression(),
glance:expression(),
glance:span(),
module_info(),
integer(),
assertion_position()
) -> {ok, {binary(), list(edit())}} | {error, nil}.
pipe(Left, Right, Location, Info, Statement_start, Position) ->
case Right of
{field_access, _, {variable, _, Module}, Name} ->
transform_assertion(
{some, Module},
Name,
Location,
pipe_args(Left, []),
Info,
Statement_start,
Position
);
{variable, _, Name@1} ->
transform_assertion(
none,
Name@1,
Location,
pipe_args(Left, []),
Info,
Statement_start,
Position
);
{call, _, Function, Arguments} ->
_pipe = Function,
_pipe@1 = called_function(_pipe),
gleam@result:'try'(
_pipe@1,
fun(Pair) ->
{Module@1, Name@2} = Pair,
transform_assertion(
Module@1,
Name@2,
Location,
pipe_args(Left, Arguments),
Info,
Statement_start,
Position
)
end
);
_ ->
{error, nil}
end.
-file("src/asset.gleam", 374).
-spec transform_assertion(
gleam@option:option(binary()),
binary(),
glance:span(),
list(glance:field(glance:expression())),
module_info(),
integer(),
assertion_position()
) -> {ok, {binary(), list(edit())}} | {error, nil}.
transform_assertion(
Module,
Name,
Location,
Arguments,
Info,
Statement_start,
Position
) ->
case assertion_function(Info, Module, Name) of
{error, _} ->
{error, nil};
{ok, be_error} ->
transform_variant_check(
Arguments,
Location,
<<"Error"/utf8>>,
Info,
Statement_start,
Position
);
{ok, be_false} ->
transform_bool_check(
Arguments,
Location,
false,
Info,
Position,
Statement_start
);
{ok, be_none} ->
case Arguments of
[{unlabelled_field, Value}] ->
Precedence = glance:precedence(eq),
{Value@1, Expr_edits} = maybe_wrap(
Value,
Info,
Precedence,
Statement_start
),
{None, Import_edits} = option_constructor(
none_constructor,
Info
),
Assert_ = <<<<<<"assert "/utf8, Value@1/binary>>/binary,
" == "/utf8>>/binary,
None/binary>>,
{Value@2, Edits} = replace_or_return(
wrap_assert(Assert_, Position),
Location,
Position
),
{ok,
{Value@2,
gleam@list:flatten(
[Import_edits, Expr_edits, Edits]
)}};
_ ->
{error, nil}
end;
{ok, be_ok} ->
transform_variant_check(
Arguments,
Location,
<<"Ok"/utf8>>,
Info,
Statement_start,
Position
);
{ok, be_some} ->
{Some, Import_edits@1} = option_constructor(some_constructor, Info),
Result = transform_variant_check(
Arguments,
Location,
Some,
Info,
Statement_start,
Position
),
gleam@result:map(
Result,
fun(Pair) ->
{erlang:element(1, Pair),
lists:append(Import_edits@1, erlang:element(2, Pair))}
end
);
{ok, be_true} ->
transform_bool_check(
Arguments,
Location,
true,
Info,
Position,
Statement_start
);
{ok, equal} ->
transform_comparison(
Arguments,
Location,
<<"=="/utf8>>,
Info,
Position,
Statement_start
);
{ok, not_equal} ->
transform_comparison(
Arguments,
Location,
<<"!="/utf8>>,
Info,
Position,
Statement_start
);
{ok, fail} ->
{ok, replace_or_return(<<"panic"/utf8>>, Location, Position)}
end.
-file("src/asset.gleam", 775).
-spec transform_variant_check(
list(glance:field(glance:expression())),
glance:span(),
binary(),
module_info(),
integer(),
assertion_position()
) -> {ok, {binary(), list(edit())}} | {error, nil}.
transform_variant_check(
Arguments,
Location,
Variant_name,
Info,
Statement_start,
Position
) ->
case Arguments of
[{unlabelled_field, Value}] ->
{Value@1, Value_edits} = get_src(Value, Info, Statement_start),
Variable_name = case Position of
expression ->
<<"value"/utf8>>;
inside_assertion ->
<<"value"/utf8>>;
statement ->
<<"_"/utf8>>
end,
Newline = case Position of
expression ->
Indent = find_indent(
erlang:element(5, Info),
Statement_start
),
<<"\n"/utf8,
(gleam@string:repeat(<<" "/utf8>>, Indent))/binary>>;
inside_assertion ->
Indent = find_indent(
erlang:element(5, Info),
Statement_start
),
<<"\n"/utf8,
(gleam@string:repeat(<<" "/utf8>>, Indent))/binary>>;
statement ->
<<""/utf8>>
end,
Assignment = <<<<<<<<<<<<"let assert "/utf8, Variant_name/binary>>/binary,
"("/utf8>>/binary,
Variable_name/binary>>/binary,
") = "/utf8>>/binary,
Value@1/binary>>/binary,
Newline/binary>>,
case Position of
expression ->
{ok,
{Variable_name,
[{edit,
Statement_start,
Statement_start,
Assignment},
{edit,
erlang:element(2, Location),
erlang:element(3, Location),
Variable_name} |
Value_edits]}};
statement ->
{ok,
{Variable_name,
[{edit,
erlang:element(2, Location),
erlang:element(3, Location),
Assignment} |
Value_edits]}};
inside_assertion ->
{ok,
{Variable_name,
[{edit,
Statement_start,
Statement_start,
Assignment} |
Value_edits]}}
end;
_ ->
{error, nil}
end.
-file("src/asset.gleam", 344).
-spec call(
glance:span(),
glance:expression(),
list(glance:field(glance:expression())),
module_info(),
integer(),
assertion_position()
) -> {ok, {binary(), list(edit())}} | {error, nil}.
call(Location, Function, Arguments, Info, Statement_start, Position) ->
_pipe = Function,
_pipe@1 = called_function(_pipe),
gleam@result:'try'(
_pipe@1,
fun(Pair) ->
{Module, Name} = Pair,
transform_assertion(
Module,
Name,
Location,
Arguments,
Info,
Statement_start,
Position
)
end
).
-file("src/asset.gleam", 528).
-spec maybe_wrap(glance:expression(), module_info(), integer(), integer()) -> {binary(),
list(edit())}.
maybe_wrap(Expression, Info, Precedence, Statement_start) ->
{Expr_src, Edits} = get_src(Expression, Info, Statement_start),
Was_transformed = case Expression of
{binary_operator, _, pipe, {binary_operator, _, pipe, _, _}, _} ->
false;
{binary_operator, _, pipe, _, _} ->
true;
_ ->
false
end,
Expr = case Expression of
{binary_operator, _, Name, _, _} when not Was_transformed ->
case glance:precedence(Name) > Precedence of
true ->
Expr_src;
false ->
<<<<"{ "/utf8, Expr_src/binary>>/binary, " }"/utf8>>
end;
_ ->
Expr_src
end,
{Expr, Edits}.
-file("src/asset.gleam", 634).
-spec transform_comparison(
list(glance:field(glance:expression())),
glance:span(),
binary(),
module_info(),
assertion_position(),
integer()
) -> {ok, {binary(), list(edit())}} | {error, nil}.
transform_comparison(
Arguments,
Location,
Operator,
Info,
Position,
Statement_start
) ->
Precedence = glance:precedence(eq),
case Arguments of
[{unlabelled_field, Left}, {unlabelled_field, Right}] ->
{Left@1, Left_edits} = maybe_wrap(
Left,
Info,
Precedence,
Statement_start
),
{Right@1, Right_edits} = maybe_wrap(
Right,
Info,
Precedence,
Statement_start
),
Assert_ = <<<<<<<<<<"assert "/utf8, Left@1/binary>>/binary,
" "/utf8>>/binary,
Operator/binary>>/binary,
" "/utf8>>/binary,
Right@1/binary>>,
{Value, Edits} = replace_or_return(
wrap_assert(Assert_, Position),
Location,
Position
),
{ok, {Value, gleam@list:flatten([Left_edits, Right_edits, Edits])}};
_ ->
{error, nil}
end.
-file("src/asset.gleam", 694).
-spec invert_value(glance:expression(), module_info(), integer()) -> {ok,
{binary(), list(edit())}} |
{error, nil}.
invert_value(Value, Info, Statement_start) ->
case Value of
{binary_operator, _, Name, Left, Right} ->
Inverted_name = case Name of
add_float ->
{error, nil};
add_int ->
{error, nil};
concatenate ->
{error, nil};
div_float ->
{error, nil};
div_int ->
{error, nil};
mult_float ->
{error, nil};
mult_int ->
{error, nil};
pipe ->
{error, nil};
remainder_int ->
{error, nil};
sub_float ->
{error, nil};
sub_int ->
{error, nil};
'and' ->
{error, nil};
'or' ->
{error, nil};
eq ->
{ok, not_eq};
gt_eq_float ->
{ok, lt_float};
gt_eq_int ->
{ok, lt_int};
gt_float ->
{ok, lt_eq_float};
gt_int ->
{ok, lt_eq_int};
lt_eq_float ->
{ok, gt_float};
lt_eq_int ->
{ok, gt_int};
lt_float ->
{ok, gt_eq_float};
lt_int ->
{ok, gt_eq_int};
not_eq ->
{ok, eq}
end,
case Inverted_name of
{ok, Name@1} ->
Precedence = glance:precedence(Name@1),
{Left@1, Left_edits} = maybe_wrap(
Left,
Info,
Precedence,
Statement_start
),
{Right@1, Right_edits} = maybe_wrap(
Right,
Info,
Precedence,
Statement_start
),
Edits = lists:append(Left_edits, Right_edits),
Operator_string = operator_to_string(Name@1),
{ok,
{<<<<<<<<Left@1/binary, " "/utf8>>/binary,
Operator_string/binary>>/binary,
" "/utf8>>/binary,
Right@1/binary>>,
Edits}};
{error, _} ->
{error, nil}
end;
_ ->
{error, nil}
end.
-file("src/asset.gleam", 660).
-spec transform_bool_check(
list(glance:field(glance:expression())),
glance:span(),
boolean(),
module_info(),
assertion_position(),
integer()
) -> {ok, {binary(), list(edit())}} | {error, nil}.
transform_bool_check(
Arguments,
Location,
Check_for,
Info,
Position,
Statement_start
) ->
case Arguments of
[{unlabelled_field, Value}] ->
{Assert_, Value_edits} = case Check_for of
false ->
case invert_value(Value, Info, Statement_start) of
{ok, {Inverted, Edits}} ->
{<<"assert "/utf8, Inverted/binary>>, Edits};
{error, _} ->
{Value@1, Edits@1} = maybe_wrap(
Value,
Info,
100,
Statement_start
),
{<<"assert !"/utf8, Value@1/binary>>, Edits@1}
end;
true ->
{Value@2, Edits@2} = get_src(Value, Info, Statement_start),
{<<"assert "/utf8, Value@2/binary>>, Edits@2}
end,
{Value@3, Edits@3} = replace_or_return(
wrap_assert(Assert_, Position),
Location,
Position
),
{ok, {Value@3, lists:append(Value_edits, Edits@3)}};
_ ->
{error, nil}
end.