Current section
Files
Jump to
Current section
Files
src/graded@internal@extract.erl
-module(graded@internal@extract).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/graded/internal/extract.gleam").
-export([with_cross_constructors/2, with_factories/2, with_cross_factories/2, constructor_label_map/1, build_import_context/1, build_constructor_type_map/1, at/2, factory_map/1, collect_constructor_bindings/2, extract_calls/2, return_value/2]).
-export_type([local_binding/0, import_context/0, extract_result/0, constructor_binding/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 local_binding() :: {bound_function_ref,
graded@internal@types:qualified_name()} |
{bound_constructor,
gleam@dict:dict(binary(), graded@internal@types:argument_value())} |
bound_param |
{bound_closure, list(binary()), list(glance:statement())} |
{bound_choice, list(graded@internal@types:argument_value())} |
{bound_returned_operator,
graded@internal@types:qualified_name(),
list(graded@internal@types:call_argument())} |
bound_opaque.
-type import_context() :: {import_context,
gleam@dict:dict(binary(), binary()),
gleam@dict:dict(binary(), graded@internal@types:qualified_name()),
gleam@dict:dict(binary(), list(gleam@option:option(binary()))),
gleam@dict:dict({binary(), binary()}, list(gleam@option:option(binary()))),
gleam@dict:dict(binary(), gleam@dict:dict(binary(), integer())),
gleam@dict:dict({binary(), binary()}, gleam@dict:dict(binary(), integer()))}.
-type extract_result() :: {extract_result,
list(graded@internal@types:resolved_call()),
list(graded@internal@types:local_call()),
list(graded@internal@types:field_call()),
list(graded@internal@types:resolved_call()),
list(graded@internal@types:direct_operator_call()),
list(graded@internal@types:direct_pipe_op()),
gleam@dict:dict(integer(), list(graded@internal@types:call_argument()))}.
-type constructor_binding() :: {constructor_binding,
gleam@option:option(binary()),
binary(),
gleam@dict:dict(binary(), graded@internal@types:argument_value())}.
-file("src/graded/internal/extract.gleam", 75).
?DOC(false).
-spec with_cross_constructors(
import_context(),
gleam@dict:dict({binary(), binary()}, list(gleam@option:option(binary())))
) -> import_context().
with_cross_constructors(Context, Cross_constructors) ->
{import_context,
erlang:element(2, Context),
erlang:element(3, Context),
erlang:element(4, Context),
Cross_constructors,
erlang:element(6, Context),
erlang:element(7, Context)}.
-file("src/graded/internal/extract.gleam", 83).
?DOC(false).
-spec with_factories(
import_context(),
gleam@dict:dict(binary(), gleam@dict:dict(binary(), integer()))
) -> import_context().
with_factories(Context, Factories) ->
{import_context,
erlang:element(2, Context),
erlang:element(3, Context),
erlang:element(4, Context),
erlang:element(5, Context),
Factories,
erlang:element(7, Context)}.
-file("src/graded/internal/extract.gleam", 92).
?DOC(false).
-spec with_cross_factories(
import_context(),
gleam@dict:dict({binary(), binary()}, gleam@dict:dict(binary(), integer()))
) -> import_context().
with_cross_factories(Context, Cross_factories) ->
{import_context,
erlang:element(2, Context),
erlang:element(3, Context),
erlang:element(4, Context),
erlang:element(5, Context),
erlang:element(6, Context),
Cross_factories}.
-file("src/graded/internal/extract.gleam", 174).
?DOC(false).
-spec build_constructor_registry(glance:module_()) -> gleam@dict:dict(binary(), list(gleam@option:option(binary()))).
build_constructor_registry(Module) ->
gleam@list:fold(
erlang:element(3, Module),
maps:new(),
fun(Acc, Definition) ->
gleam@list:fold(
erlang:element(7, erlang:element(3, Definition)),
Acc,
fun(Acc2, Variant) ->
Labels = gleam@list:map(
erlang:element(3, Variant),
fun(Field) -> case Field of
{labelled_variant_field, _, Label} ->
{some, Label};
{unlabelled_variant_field, _} ->
none
end end
),
gleam@dict:insert(Acc2, erlang:element(2, Variant), Labels)
end
)
end
).
-file("src/graded/internal/extract.gleam", 102).
?DOC(false).
-spec constructor_label_map(glance:module_()) -> gleam@dict:dict(binary(), list(gleam@option:option(binary()))).
constructor_label_map(Module) ->
build_constructor_registry(Module).
-file("src/graded/internal/extract.gleam", 751).
?DOC(false).
-spec last_segment(binary()) -> binary().
last_segment(Module_path) ->
_pipe = Module_path,
_pipe@1 = gleam@string:split(_pipe, <<"/"/utf8>>),
_pipe@2 = gleam@list:last(_pipe@1),
gleam@result:unwrap(_pipe@2, Module_path).
-file("src/graded/internal/extract.gleam", 126).
?DOC(false).
-spec build_import_context(glance:module_()) -> import_context().
build_import_context(Module) ->
{Aliases, Unqualified} = gleam@list:fold(
erlang:element(2, Module),
{maps:new(), maps:new()},
fun(State, Definition) ->
Import_ = erlang:element(3, Definition),
Module_path = erlang:element(3, Import_),
Alias = case erlang:element(4, Import_) of
{some, {named, Name}} ->
Name;
{some, {discarded, _}} ->
last_segment(Module_path);
none ->
last_segment(Module_path)
end,
New_aliases = gleam@dict:insert(
erlang:element(1, State),
Alias,
Module_path
),
New_unqualified = gleam@list:fold(
erlang:element(6, Import_),
erlang:element(2, State),
fun(Unqualified_map, Unqualified_import) ->
Name@1 = case erlang:element(3, Unqualified_import) of
{some, Alias_name} ->
Alias_name;
none ->
erlang:element(2, Unqualified_import)
end,
gleam@dict:insert(
Unqualified_map,
Name@1,
{qualified_name,
Module_path,
erlang:element(2, Unqualified_import)}
)
end
),
{New_aliases, New_unqualified}
end
),
Constructors = build_constructor_registry(Module),
{import_context,
Aliases,
Unqualified,
Constructors,
maps:new(),
maps:new(),
maps:new()}.
-file("src/graded/internal/extract.gleam", 195).
?DOC(false).
-spec build_constructor_type_map(glance:module_()) -> gleam@dict:dict(binary(), binary()).
build_constructor_type_map(Module) ->
gleam@list:fold(
erlang:element(3, Module),
maps:new(),
fun(Acc, Definition) ->
Type_name = erlang:element(3, erlang:element(3, Definition)),
gleam@list:fold(
erlang:element(7, erlang:element(3, Definition)),
Acc,
fun(Acc2, Variant) ->
gleam@dict:insert(
Acc2,
erlang:element(2, Variant),
Type_name
)
end
)
end
).
-file("src/graded/internal/extract.gleam", 305).
?DOC(false).
-spec param_position_map(glance:function_()) -> gleam@dict:dict(binary(), integer()).
param_position_map(Function) ->
_pipe = erlang:element(5, Function),
_pipe@1 = gleam@list:index_map(
_pipe,
fun(Parameter, Index) -> {Parameter, Index} end
),
gleam@list:fold(
_pipe@1,
maps:new(),
fun(Acc, Pair) ->
{Parameter@1, Index@1} = Pair,
case erlang:element(3, Parameter@1) of
{named, Name} ->
gleam@dict:insert(Acc, Name, Index@1);
{discarded, _} ->
Acc
end
end
).
-file("src/graded/internal/extract.gleam", 811).
?DOC(false).
-spec bind_opaque(gleam@dict:dict(binary(), local_binding()), binary()) -> gleam@dict:dict(binary(), local_binding()).
bind_opaque(Env, Name) ->
gleam@dict:insert(Env, Name, bound_opaque).
-file("src/graded/internal/extract.gleam", 1044).
?DOC(false).
-spec fold_pattern_names(glance:pattern(), RET, fun((RET, binary()) -> RET)) -> RET.
fold_pattern_names(Pattern, Acc, Step) ->
case Pattern of
{pattern_variable, _, Name} ->
Step(Acc, Name);
{pattern_assignment, _, Inner, Name@1} ->
fold_pattern_names(Inner, Step(Acc, Name@1), Step);
{pattern_tuple, _, Elements} ->
gleam@list:fold(
Elements,
Acc,
fun(Inner@1, P) -> fold_pattern_names(P, Inner@1, Step) end
);
{pattern_list, _, Elements@1, Tail} ->
Head = gleam@list:fold(
Elements@1,
Acc,
fun(Inner@2, P@1) -> fold_pattern_names(P@1, Inner@2, Step) end
),
case Tail of
{some, Tail_pattern} ->
fold_pattern_names(Tail_pattern, Head, Step);
none ->
Head
end;
{pattern_variant, _, _, _, Arguments, _} ->
gleam@list:fold(Arguments, Acc, fun(Inner@3, Field) -> case Field of
{labelled_field, _, _, Item} ->
fold_pattern_names(Item, Inner@3, Step);
{shorthand_field, Label, _} ->
Step(Inner@3, Label);
{unlabelled_field, Item@1} ->
fold_pattern_names(Item@1, Inner@3, Step)
end end);
{pattern_concatenate, _, _, Prefix_name, Rest_name} ->
With_prefix = case Prefix_name of
{some, {named, N}} ->
Step(Acc, N);
_ ->
Acc
end,
case Rest_name of
{named, N@1} ->
Step(With_prefix, N@1);
{discarded, _} ->
With_prefix
end;
{pattern_bit_string, _, Segments} ->
gleam@list:fold(
Segments,
Acc,
fun(Inner@4, Segment) ->
fold_pattern_names(
erlang:element(1, Segment),
Inner@4,
Step
)
end
);
{pattern_int, _, _} ->
Acc;
{pattern_float, _, _} ->
Acc;
{pattern_string, _, _} ->
Acc;
{pattern_discard, _, _} ->
Acc
end.
-file("src/graded/internal/extract.gleam", 1035).
?DOC(false).
-spec bind_use_patterns(
list(glance:use_pattern()),
gleam@dict:dict(binary(), local_binding())
) -> gleam@dict:dict(binary(), local_binding()).
bind_use_patterns(Patterns, Env) ->
gleam@list:fold(
Patterns,
Env,
fun(Acc, Use_pattern) ->
fold_pattern_names(
erlang:element(2, Use_pattern),
Acc,
fun bind_opaque/2
)
end
).
-file("src/graded/internal/extract.gleam", 903).
?DOC(false).
-spec lookup_factory_qualified(binary(), binary(), import_context()) -> {ok,
gleam@dict:dict(binary(), integer())} |
{error, nil}.
lookup_factory_qualified(Alias, Name, Context) ->
case gleam_stdlib:map_get(erlang:element(2, Context), Alias) of
{ok, Module} ->
gleam_stdlib:map_get(erlang:element(7, Context), {Module, Name});
{error, nil} ->
{error, nil}
end.
-file("src/graded/internal/extract.gleam", 956).
?DOC(false).
-spec at(list(REL), integer()) -> {ok, REL} | {error, nil}.
at(Items, Index) ->
_pipe = Items,
_pipe@1 = gleam@list:drop(_pipe, Index),
gleam@list:first(_pipe@1).
-file("src/graded/internal/extract.gleam", 583).
?DOC(false).
-spec is_constructor_name(binary()) -> boolean().
is_constructor_name(Name) ->
graded@internal@types:is_upper_initial(Name).
-file("src/graded/internal/extract.gleam", 887).
?DOC(false).
-spec lookup_factory_bare(binary(), import_context()) -> {ok,
gleam@dict:dict(binary(), integer())} |
{error, nil}.
lookup_factory_bare(Name, Context) ->
case gleam_stdlib:map_get(erlang:element(6, Context), Name) of
{ok, Signature} ->
{ok, Signature};
{error, nil} ->
case gleam_stdlib:map_get(erlang:element(3, Context), Name) of
{ok, {qualified_name, Module, Function}} ->
gleam_stdlib:map_get(
erlang:element(7, Context),
{Module, Function}
);
{error, nil} ->
{error, nil}
end
end.
-file("src/graded/internal/extract.gleam", 1029).
?DOC(false).
-spec resolve_env(binary(), gleam@dict:dict(binary(), local_binding())) -> local_binding().
resolve_env(Name, Env) ->
_pipe = gleam_stdlib:map_get(Env, Name),
gleam@result:unwrap(_pipe, bound_opaque).
-file("src/graded/internal/extract.gleam", 964).
?DOC(false).
-spec classify_rhs_ref(
glance:expression(),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> local_binding().
classify_rhs_ref(Expression, Context, Env) ->
case classify_expression(Expression, Context, Env) of
{function_ref, Name} ->
{bound_function_ref, Name};
{local_ref, Name@1} ->
_pipe = gleam_stdlib:map_get(Env, Name@1),
gleam@result:unwrap(_pipe, bound_opaque);
{closure, Params, Body} ->
{bound_closure, Params, Body};
{choice, Options} ->
{bound_choice, Options};
{returned_operator, Callee, Args} ->
{bound_returned_operator, Callee, Args};
constructor_ref ->
bound_opaque;
other_expression ->
bound_opaque
end.
-file("src/graded/internal/extract.gleam", 940).
?DOC(false).
-spec positional_arg_values(
list(glance:field(glance:expression())),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> {ok, list(graded@internal@types:argument_value())} | {error, nil}.
positional_arg_values(Arguments, Context, Env) ->
gleam@list:try_map(Arguments, fun(Field) -> case Field of
{unlabelled_field, Item} ->
{ok, classify_expression(Item, Context, Env)};
_ ->
{error, nil}
end end).
-file("src/graded/internal/extract.gleam", 918).
?DOC(false).
-spec factory_construction(
gleam@dict:dict(binary(), integer()),
list(glance:field(glance:expression())),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> {ok, local_binding()} | {error, nil}.
factory_construction(Signature, Arguments, Context, Env) ->
gleam@result:'try'(
positional_arg_values(Arguments, Context, Env),
fun(Values) ->
Fields = gleam@dict:fold(
Signature,
maps:new(),
fun(Acc, Label, Position) -> case at(Values, Position) of
{ok, Value} ->
gleam@dict:insert(Acc, Label, Value);
{error, nil} ->
Acc
end end
),
case gleam@dict:is_empty(Fields) of
true ->
{error, nil};
false ->
{ok, {bound_constructor, Fields}}
end
end
).
-file("src/graded/internal/extract.gleam", 868).
?DOC(false).
-spec factory_or_ref(
{ok, gleam@dict:dict(binary(), integer())} | {error, nil},
glance:expression(),
list(glance:field(glance:expression())),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> local_binding().
factory_or_ref(Signature, Expression, Arguments, Context, Env) ->
case Signature of
{ok, Signature@1} ->
case factory_construction(Signature@1, Arguments, Context, Env) of
{ok, Binding} ->
Binding;
{error, nil} ->
classify_rhs_ref(Expression, Context, Env)
end;
{error, nil} ->
classify_rhs_ref(Expression, Context, Env)
end.
-file("src/graded/internal/extract.gleam", 818).
?DOC(false).
-spec classify_rhs(
glance:expression(),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> local_binding().
classify_rhs(Expression, Context, Env) ->
case Expression of
{call, _, {variable, _, Name}, Arguments} ->
case is_constructor_name(Name) of
true ->
classify_constructor(Name, none, Arguments, Context, Env);
false ->
factory_or_ref(
lookup_factory_bare(Name, Context),
Expression,
Arguments,
Context,
Env
)
end;
{call, _, {field_access, _, {variable, _, Alias}, Ctor}, Arguments@1} ->
case is_constructor_name(Ctor) of
true ->
Module = begin
_pipe = gleam_stdlib:map_get(
erlang:element(2, Context),
Alias
),
gleam@option:from_result(_pipe)
end,
classify_constructor(
Ctor,
Module,
Arguments@1,
Context,
Env
);
false ->
factory_or_ref(
lookup_factory_qualified(Alias, Ctor, Context),
Expression,
Arguments@1,
Context,
Env
)
end;
_ ->
classify_rhs_ref(Expression, Context, Env)
end.
-file("src/graded/internal/extract.gleam", 798).
?DOC(false).
-spec bind_assignment(
glance:pattern(),
glance:expression(),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> gleam@dict:dict(binary(), local_binding()).
bind_assignment(Pattern, Value, Context, Env) ->
case Pattern of
{pattern_variable, _, Name} ->
gleam@dict:insert(Env, Name, classify_rhs(Value, Context, Env));
_ ->
fold_pattern_names(Pattern, Env, fun bind_opaque/2)
end.
-file("src/graded/internal/extract.gleam", 1511).
?DOC(false).
-spec classify_block(
list(glance:statement()),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> graded@internal@types:argument_value().
classify_block(Statements, Context, Env) ->
case lists:reverse(Statements) of
[{expression, Tail} | Init_reversed] ->
Inner_env = gleam@list:fold(
lists:reverse(Init_reversed),
Env,
fun(Accumulator, Statement) -> case Statement of
{assignment, _, _, Pattern, _, Value} ->
bind_assignment(
Pattern,
Value,
Context,
Accumulator
);
{use, _, Patterns, _} ->
bind_use_patterns(Patterns, Accumulator);
_ ->
Accumulator
end end
),
classify_expression(Tail, Context, Inner_env);
_ ->
other_expression
end.
-file("src/graded/internal/extract.gleam", 1410).
?DOC(false).
-spec classify_arguments(
list(glance:field(glance:expression())),
import_context(),
gleam@dict:dict(binary(), local_binding()),
integer()
) -> list(graded@internal@types:call_argument()).
classify_arguments(Arguments, Context, Env, Position_offset) ->
gleam@list:index_map(
Arguments,
fun(Field, I) ->
{Label@2, Expression} = case Field of
{labelled_field, Label, _, Item} ->
{{some, Label}, {some, Item}};
{shorthand_field, Label@1, _} ->
{{some, Label@1}, none};
{unlabelled_field, Item@1} ->
{none, {some, Item@1}}
end,
Value = case Expression of
none ->
other_expression;
{some, Expr} ->
classify_expression(Expr, Context, Env)
end,
{call_argument, I + Position_offset, Label@2, Value}
end
).
-file("src/graded/internal/extract.gleam", 1537).
?DOC(false).
-spec classify_call_producer(
glance:expression(),
list(glance:field(glance:expression())),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> graded@internal@types:argument_value().
classify_call_producer(Function, Arguments, Context, Env) ->
Args = classify_arguments(Arguments, Context, Env, 0),
case classify_expression(Function, Context, Env) of
{function_ref, Callee} ->
{returned_operator, Callee, Args};
{local_ref, Name} ->
{returned_operator, {qualified_name, <<""/utf8>>, Name}, Args};
constructor_ref ->
other_expression;
{closure, _, _} ->
other_expression;
{choice, _} ->
other_expression;
{returned_operator, _, _} ->
other_expression;
other_expression ->
other_expression
end.
-file("src/graded/internal/extract.gleam", 1575).
?DOC(false).
-spec classify_case_options(
list(glance:clause()),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> graded@internal@types:argument_value().
classify_case_options(Clauses, Context, Env) ->
Options = gleam@list:map(
Clauses,
fun(Clause) ->
classify_expression(erlang:element(4, Clause), Context, Env)
end
),
All_function_like = (Options /= []) andalso gleam@list:all(
Options,
fun(Option) -> case Option of
{function_ref, _} ->
true;
{local_ref, _} ->
true;
{closure, _, _} ->
true;
{choice, _} ->
true;
{returned_operator, _, _} ->
true;
constructor_ref ->
false;
other_expression ->
false
end end
),
case All_function_like of
true ->
{choice, Options};
false ->
other_expression
end.
-file("src/graded/internal/extract.gleam", 1433).
?DOC(false).
-spec classify_expression(
glance:expression(),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> graded@internal@types:argument_value().
classify_expression(Expression, Context, Env) ->
case Expression of
{field_access, _, {variable, _, Alias}, Function_name} ->
case is_constructor_name(Function_name) of
true ->
constructor_ref;
false ->
case gleam_stdlib:map_get(erlang:element(2, Context), Alias) of
{ok, Module_path} ->
{function_ref,
{qualified_name, Module_path, Function_name}};
{error, nil} ->
other_expression
end
end;
{variable, _, Name} ->
case is_constructor_name(Name) of
true ->
constructor_ref;
false ->
case gleam_stdlib:map_get(erlang:element(3, Context), Name) of
{ok, Qualified_name} ->
{function_ref, Qualified_name};
{error, nil} ->
case resolve_env(Name, Env) of
{bound_function_ref, Qualified} ->
{function_ref, Qualified};
{bound_closure, Params, Body} ->
{closure, Params, Body};
{bound_choice, Options} ->
{choice, Options};
{bound_returned_operator, Callee, Args} ->
{returned_operator, Callee, Args};
_ ->
{local_ref, Name}
end
end
end;
{fn, _, Arguments, _, Body@1} ->
{closure,
gleam@list:map(
Arguments,
fun(Parameter) -> case erlang:element(2, Parameter) of
{named, Name@1} ->
Name@1;
{discarded, _} ->
<<"_"/utf8>>
end end
),
Body@1};
{'case', _, _, Clauses} ->
classify_case_options(Clauses, Context, Env);
{call, _, Function, Arguments@1} ->
classify_call_producer(Function, Arguments@1, Context, Env);
{block, _, Statements} ->
classify_block(Statements, Context, Env);
_ ->
other_expression
end.
-file("src/graded/internal/extract.gleam", 984).
?DOC(false).
-spec classify_constructor(
binary(),
gleam@option:option(binary()),
list(glance:field(glance:expression())),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> local_binding().
classify_constructor(Type_name, Module, Arguments, Context, Env) ->
Declared_labels = case Module of
none ->
_pipe = gleam_stdlib:map_get(erlang:element(4, Context), Type_name),
gleam@result:unwrap(_pipe, []);
{some, Module@1} ->
_pipe@1 = gleam_stdlib:map_get(
erlang:element(5, Context),
{Module@1, Type_name}
),
gleam@result:unwrap(_pipe@1, [])
end,
{Fields, _} = gleam@list:fold(
Arguments,
{maps:new(), Declared_labels},
fun(Acc, Field) ->
{Fields_acc, Remaining} = Acc,
case Field of
{labelled_field, Label, _, Item} ->
{gleam@dict:insert(
Fields_acc,
Label,
classify_expression(Item, Context, Env)
),
Remaining};
{shorthand_field, Label@1, _} ->
{gleam@dict:insert(Fields_acc, Label@1, other_expression),
Remaining};
{unlabelled_field, Item@1} ->
Value = classify_expression(Item@1, Context, Env),
case Remaining of
[{some, Label@2} | Rest] ->
{gleam@dict:insert(Fields_acc, Label@2, Value),
Rest};
[_ | Rest@1] ->
{Fields_acc, Rest@1};
[] ->
{Fields_acc, []}
end
end
end
),
{bound_constructor, Fields}.
-file("src/graded/internal/extract.gleam", 278).
?DOC(false).
-spec constructor_call_parts(glance:expression()) -> {ok,
{binary(),
gleam@option:option(binary()),
list(glance:field(glance:expression()))}} |
{error, nil}.
constructor_call_parts(Expression) ->
case Expression of
{call, _, {variable, _, Name}, Arguments} ->
case is_constructor_name(Name) of
true ->
{ok, {Name, none, Arguments}};
false ->
{error, nil}
end;
{call,
_,
{field_access, _, {variable, _, Alias}, Constructor},
Arguments@1} ->
case is_constructor_name(Constructor) of
true ->
{ok, {Constructor, {some, Alias}, Arguments@1}};
false ->
{error, nil}
end;
_ ->
{error, nil}
end.
-file("src/graded/internal/extract.gleam", 231).
?DOC(false).
-spec factory_signature(glance:function_(), import_context()) -> {ok,
gleam@dict:dict(binary(), integer())} |
{error, nil}.
factory_signature(Function, Context) ->
gleam@result:'try'(case gleam@list:last(erlang:element(7, Function)) of
{ok, {expression, Expression}} ->
{ok, Expression};
_ ->
{error, nil}
end, fun(Tail) ->
gleam@result:'try'(
constructor_call_parts(Tail),
fun(_use0) ->
{Constructor, Alias, Arguments} = _use0,
Module = case Alias of
{some, Alias@1} ->
_pipe = gleam_stdlib:map_get(
erlang:element(2, Context),
Alias@1
),
gleam@option:from_result(_pipe);
none ->
none
end,
Fields@1 = case classify_constructor(
Constructor,
Module,
Arguments,
Context,
maps:new()
) of
{bound_constructor, Fields} ->
Fields;
_ ->
maps:new()
end,
Param_positions = param_position_map(Function),
Field_to_param = gleam@dict:fold(
Fields@1,
maps:new(),
fun(Acc, Label, Value) -> case Value of
{local_ref, Name} ->
case gleam_stdlib:map_get(
Param_positions,
Name
) of
{ok, Position} ->
gleam@dict:insert(
Acc,
Label,
Position
);
{error, nil} ->
Acc
end;
_ ->
Acc
end end
),
case gleam@dict:is_empty(Field_to_param) of
true ->
{error, nil};
false ->
{ok, Field_to_param}
end
end
)
end).
-file("src/graded/internal/extract.gleam", 217).
?DOC(false).
-spec factory_map(glance:module_()) -> gleam@dict:dict(binary(), gleam@dict:dict(binary(), integer())).
factory_map(Module) ->
Context = build_import_context(Module),
gleam@list:fold(
erlang:element(6, Module),
maps:new(),
fun(Acc, Definition) ->
Function = erlang:element(3, Definition),
case factory_signature(Function, Context) of
{ok, Signature} ->
gleam@dict:insert(
Acc,
erlang:element(3, Function),
Signature
);
{error, nil} ->
Acc
end
end
).
-file("src/graded/internal/extract.gleam", 481).
?DOC(false).
-spec ctor_binding(
binary(),
gleam@option:option(binary()),
list(glance:field(glance:expression())),
import_context()
) -> constructor_binding().
ctor_binding(Constructor, Module, Arguments, Context) ->
Fields@1 = case classify_constructor(
Constructor,
Module,
Arguments,
Context,
maps:new()
) of
{bound_constructor, Fields} ->
Fields;
_ ->
maps:new()
end,
{constructor_binding, Module, Constructor, Fields@1}.
-file("src/graded/internal/extract.gleam", 377).
?DOC(false).
-spec ctor_in_fields(list(glance:field(glance:expression())), import_context()) -> list(constructor_binding()).
ctor_in_fields(Fields, Context) ->
gleam@list:flat_map(Fields, fun(Field) -> case Field of
{labelled_field, _, _, Item} ->
ctor_in_expression(Item, Context);
{unlabelled_field, Item@1} ->
ctor_in_expression(Item@1, Context);
{shorthand_field, _, _} ->
[]
end end).
-file("src/graded/internal/extract.gleam", 360).
?DOC(false).
-spec ctor_in_each(list(glance:expression()), import_context()) -> list(constructor_binding()).
ctor_in_each(Expressions, Context) ->
gleam@list:flat_map(
Expressions,
fun(_capture) -> ctor_in_expression(_capture, Context) end
).
-file("src/graded/internal/extract.gleam", 390).
?DOC(false).
-spec ctor_in_expression(glance:expression(), import_context()) -> list(constructor_binding()).
ctor_in_expression(Expression, Context) ->
case Expression of
{call, _, {variable, _, Name}, Arguments} ->
case is_constructor_name(Name) of
true ->
[ctor_binding(Name, none, Arguments, Context) |
ctor_in_fields(Arguments, Context)];
false ->
ctor_in_fields(Arguments, Context)
end;
{call, _, {field_access, _, {variable, _, Alias}, Ctor}, Arguments@1} ->
case is_constructor_name(Ctor) of
true ->
Module = begin
_pipe = gleam_stdlib:map_get(
erlang:element(2, Context),
Alias
),
gleam@option:from_result(_pipe)
end,
[ctor_binding(Ctor, Module, Arguments@1, Context) |
ctor_in_fields(Arguments@1, Context)];
false ->
ctor_in_fields(Arguments@1, Context)
end;
{call, _, Function, Arguments@2} ->
lists:append(
ctor_in_expression(Function, Context),
ctor_in_fields(Arguments@2, Context)
);
{block, _, Statements} ->
ctor_in_statements(Statements, Context);
{fn, _, _, _, Body} ->
ctor_in_statements(Body, Context);
{tuple, _, Elements} ->
ctor_in_each(Elements, Context);
{list, _, Elements@1, Rest} ->
lists:append(
ctor_in_each(Elements@1, Context),
ctor_in_optional(Rest, Context)
);
{binary_operator, _, _, Left, Right} ->
lists:append(
ctor_in_expression(Left, Context),
ctor_in_expression(Right, Context)
);
{'case', _, Subjects, Clauses} ->
lists:append(
ctor_in_each(Subjects, Context),
gleam@list:flat_map(
Clauses,
fun(Clause) ->
ctor_in_expression(erlang:element(4, Clause), Context)
end
)
);
{field_access, _, Container, _} ->
ctor_in_expression(Container, Context);
{tuple_index, _, Tuple, _} ->
ctor_in_expression(Tuple, Context);
{negate_int, _, Value} ->
ctor_in_expression(Value, Context);
{negate_bool, _, Value@1} ->
ctor_in_expression(Value@1, Context);
{echo, _, Expression@1, Message} ->
lists:append(
ctor_in_optional(Expression@1, Context),
ctor_in_optional(Message, Context)
);
{panic, _, Message@1} ->
ctor_in_optional(Message@1, Context);
{todo, _, Message@2} ->
ctor_in_optional(Message@2, Context);
{fn_capture, _, _, Function@1, Arguments_before, Arguments_after} ->
lists:append(
ctor_in_expression(Function@1, Context),
lists:append(
ctor_in_fields(Arguments_before, Context),
ctor_in_fields(Arguments_after, Context)
)
);
{record_update, _, _, _, Record, Fields} ->
lists:append(
ctor_in_expression(Record, Context),
gleam@list:flat_map(
Fields,
fun(Field) ->
ctor_in_optional(erlang:element(3, Field), Context)
end
)
);
{bit_string, _, Segments} ->
gleam@list:flat_map(
Segments,
fun(Segment) ->
ctor_in_expression(erlang:element(1, Segment), Context)
end
);
_ ->
[]
end.
-file("src/graded/internal/extract.gleam", 367).
?DOC(false).
-spec ctor_in_optional(
gleam@option:option(glance:expression()),
import_context()
) -> list(constructor_binding()).
ctor_in_optional(Expression, Context) ->
case Expression of
{some, E} ->
ctor_in_expression(E, Context);
none ->
[]
end.
-file("src/graded/internal/extract.gleam", 342).
?DOC(false).
-spec ctor_in_statements(list(glance:statement()), import_context()) -> list(constructor_binding()).
ctor_in_statements(Statements, Context) ->
gleam@list:flat_map(Statements, fun(Statement) -> case Statement of
{expression, Expression} ->
ctor_in_expression(Expression, Context);
{assignment, _, _, _, _, Value} ->
ctor_in_expression(Value, Context);
{use, _, _, Function} ->
ctor_in_expression(Function, Context);
{assert, _, Expression@1, Message} ->
lists:append(
ctor_in_expression(Expression@1, Context),
ctor_in_optional(Message, Context)
)
end end).
-file("src/graded/internal/extract.gleam", 333).
?DOC(false).
-spec collect_constructor_bindings(glance:module_(), import_context()) -> list(constructor_binding()).
collect_constructor_bindings(Module, Context) ->
gleam@list:flat_map(
erlang:element(6, Module),
fun(Definition) ->
ctor_in_statements(
erlang:element(7, erlang:element(3, Definition)),
Context
)
end
).
-file("src/graded/internal/extract.gleam", 1688).
?DOC(false).
-spec merge(extract_result(), extract_result()) -> extract_result().
merge(Left, Right) ->
{extract_result,
lists:append(erlang:element(2, Left), erlang:element(2, Right)),
lists:append(erlang:element(3, Left), erlang:element(3, Right)),
lists:append(erlang:element(4, Left), erlang:element(4, Right)),
lists:append(erlang:element(5, Left), erlang:element(5, Right)),
lists:append(erlang:element(6, Left), erlang:element(6, Right)),
lists:append(erlang:element(7, Left), erlang:element(7, Right)),
maps:merge(erlang:element(8, Left), erlang:element(8, Right))}.
-file("src/graded/internal/extract.gleam", 1676).
?DOC(false).
-spec empty() -> extract_result().
empty() ->
{extract_result, [], [], [], [], [], [], maps:new()}.
-file("src/graded/internal/extract.gleam", 736).
?DOC(false).
-spec qualified_reference_lookup(
binary(),
binary(),
glance:span(),
import_context()
) -> extract_result().
qualified_reference_lookup(Alias, Function_name, Span, Context) ->
case gleam_stdlib:map_get(erlang:element(2, Context), Alias) of
{ok, Module_path} ->
_record = empty(),
{extract_result,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
[{resolved_call,
{qualified_name, Module_path, Function_name},
Span}],
erlang:element(6, _record),
erlang:element(7, _record),
erlang:element(8, _record)};
{error, nil} ->
empty()
end.
-file("src/graded/internal/extract.gleam", 724).
?DOC(false).
-spec resolve_qualified_reference(
binary(),
binary(),
glance:span(),
import_context()
) -> extract_result().
resolve_qualified_reference(Alias, Function_name, Span, Context) ->
case is_constructor_name(Function_name) of
true ->
empty();
false ->
qualified_reference_lookup(Alias, Function_name, Span, Context)
end.
-file("src/graded/internal/extract.gleam", 613).
?DOC(false).
-spec bind_closure_params(
gleam@dict:dict(binary(), local_binding()),
list(glance:fn_parameter())
) -> gleam@dict:dict(binary(), local_binding()).
bind_closure_params(Env, Parameters) ->
gleam@list:fold(
Parameters,
Env,
fun(Accumulator, Parameter) -> case erlang:element(2, Parameter) of
{named, Name} ->
gleam@dict:insert(Accumulator, Name, bound_param);
{discarded, _} ->
Accumulator
end end
).
-file("src/graded/internal/extract.gleam", 1608).
?DOC(false).
-spec attach_pipe_args(
extract_result(),
glance:span(),
list(graded@internal@types:call_argument())
) -> extract_result().
attach_pipe_args(Base, Span, Pipe_args) ->
{extract_result,
erlang:element(2, Base),
erlang:element(3, Base),
erlang:element(4, Base),
erlang:element(5, Base),
erlang:element(6, Base),
erlang:element(7, Base),
gleam@dict:insert(
erlang:element(8, Base),
erlang:element(2, Span),
Pipe_args
)}.
-file("src/graded/internal/extract.gleam", 622).
?DOC(false).
-spec resolve_unqualified_call(binary(), glance:span(), import_context()) -> extract_result().
resolve_unqualified_call(Name, Span, Context) ->
case is_constructor_name(Name) of
true ->
empty();
false ->
case gleam_stdlib:map_get(erlang:element(3, Context), Name) of
{ok, Qualified_name} ->
_record = empty(),
{extract_result,
[{resolved_call, Qualified_name, Span}],
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record),
erlang:element(6, _record),
erlang:element(7, _record),
erlang:element(8, _record)};
{error, nil} ->
_record@1 = empty(),
{extract_result,
erlang:element(2, _record@1),
[{local_call, Name, Span}],
erlang:element(4, _record@1),
erlang:element(5, _record@1),
erlang:element(6, _record@1),
erlang:element(7, _record@1),
erlang:element(8, _record@1)}
end
end.
-file("src/graded/internal/extract.gleam", 588).
?DOC(false).
-spec resolve_variable_call(
binary(),
glance:span(),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> extract_result().
resolve_variable_call(Name, Span, Context, Env) ->
case resolve_env(Name, Env) of
{bound_function_ref, Qualified} ->
_record = empty(),
{extract_result,
[{resolved_call, Qualified, Span}],
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record),
erlang:element(6, _record),
erlang:element(7, _record),
erlang:element(8, _record)};
bound_param ->
empty();
{bound_returned_operator, Callee, Producer_args} ->
_record@1 = empty(),
{extract_result,
erlang:element(2, _record@1),
erlang:element(3, _record@1),
erlang:element(4, _record@1),
erlang:element(5, _record@1),
[{direct_operator_call, Callee, Producer_args, Span}],
erlang:element(7, _record@1),
erlang:element(8, _record@1)};
_ ->
resolve_unqualified_call(Name, Span, Context)
end.
-file("src/graded/internal/extract.gleam", 1621).
?DOC(false).
-spec merge_with_args(
extract_result(),
extract_result(),
glance:span(),
list(graded@internal@types:call_argument())
) -> extract_result().
merge_with_args(Call_result, Inner, Span, Args) ->
Merged = merge(Call_result, Inner),
{extract_result,
erlang:element(2, Merged),
erlang:element(3, Merged),
erlang:element(4, Merged),
erlang:element(5, Merged),
erlang:element(6, Merged),
erlang:element(7, Merged),
gleam@dict:insert(
erlang:element(8, Merged),
erlang:element(2, Span),
Args
)}.
-file("src/graded/internal/extract.gleam", 698).
?DOC(false).
-spec resolve_constructor_field_call(
binary(),
binary(),
glance:span(),
glance:span(),
gleam@dict:dict(binary(), graded@internal@types:argument_value())
) -> extract_result().
resolve_constructor_field_call(Alias, Label, Span, Receiver_span, Fields) ->
case gleam_stdlib:map_get(Fields, Label) of
{ok, {function_ref, Qualified}} ->
_record = empty(),
{extract_result,
[{resolved_call, Qualified, Span}],
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record),
erlang:element(6, _record),
erlang:element(7, _record),
erlang:element(8, _record)};
{ok, {local_ref, Local_name}} ->
_record@1 = empty(),
{extract_result,
erlang:element(2, _record@1),
[{local_call, Local_name, Span}],
erlang:element(4, _record@1),
erlang:element(5, _record@1),
erlang:element(6, _record@1),
erlang:element(7, _record@1),
erlang:element(8, _record@1)};
{ok, constructor_ref} ->
empty();
{ok, {closure, _, _}} ->
_record@2 = empty(),
{extract_result,
erlang:element(2, _record@2),
erlang:element(3, _record@2),
[{field_call, Alias, Label, Span, Receiver_span}],
erlang:element(5, _record@2),
erlang:element(6, _record@2),
erlang:element(7, _record@2),
erlang:element(8, _record@2)};
{ok, {choice, _}} ->
_record@2 = empty(),
{extract_result,
erlang:element(2, _record@2),
erlang:element(3, _record@2),
[{field_call, Alias, Label, Span, Receiver_span}],
erlang:element(5, _record@2),
erlang:element(6, _record@2),
erlang:element(7, _record@2),
erlang:element(8, _record@2)};
{ok, {returned_operator, _, _}} ->
_record@2 = empty(),
{extract_result,
erlang:element(2, _record@2),
erlang:element(3, _record@2),
[{field_call, Alias, Label, Span, Receiver_span}],
erlang:element(5, _record@2),
erlang:element(6, _record@2),
erlang:element(7, _record@2),
erlang:element(8, _record@2)};
{ok, other_expression} ->
_record@2 = empty(),
{extract_result,
erlang:element(2, _record@2),
erlang:element(3, _record@2),
[{field_call, Alias, Label, Span, Receiver_span}],
erlang:element(5, _record@2),
erlang:element(6, _record@2),
erlang:element(7, _record@2),
erlang:element(8, _record@2)};
{error, nil} ->
_record@2 = empty(),
{extract_result,
erlang:element(2, _record@2),
erlang:element(3, _record@2),
[{field_call, Alias, Label, Span, Receiver_span}],
erlang:element(5, _record@2),
erlang:element(6, _record@2),
erlang:element(7, _record@2),
erlang:element(8, _record@2)}
end.
-file("src/graded/internal/extract.gleam", 665).
?DOC(false).
-spec qualified_call_lookup(
binary(),
binary(),
glance:span(),
glance:span(),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> extract_result().
qualified_call_lookup(Alias, Function_name, Span, Receiver_span, Context, Env) ->
case gleam_stdlib:map_get(erlang:element(2, Context), Alias) of
{ok, Module_path} ->
_record = empty(),
{extract_result,
[{resolved_call,
{qualified_name, Module_path, Function_name},
Span}],
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record),
erlang:element(6, _record),
erlang:element(7, _record),
erlang:element(8, _record)};
{error, nil} ->
case resolve_env(Alias, Env) of
{bound_constructor, Fields} ->
resolve_constructor_field_call(
Alias,
Function_name,
Span,
Receiver_span,
Fields
);
_ ->
_record@1 = empty(),
{extract_result,
erlang:element(2, _record@1),
erlang:element(3, _record@1),
[{field_call, Alias, Function_name, Span, Receiver_span}],
erlang:element(5, _record@1),
erlang:element(6, _record@1),
erlang:element(7, _record@1),
erlang:element(8, _record@1)}
end
end.
-file("src/graded/internal/extract.gleam", 643).
?DOC(false).
-spec resolve_qualified_call(
binary(),
binary(),
glance:span(),
glance:span(),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> extract_result().
resolve_qualified_call(Alias, Function_name, Span, Receiver_span, Context, Env) ->
case is_constructor_name(Function_name) of
true ->
empty();
false ->
qualified_call_lookup(
Alias,
Function_name,
Span,
Receiver_span,
Context,
Env
)
end.
-file("src/graded/internal/extract.gleam", 573).
?DOC(false).
-spec use_pattern_to_fn_param(glance:use_pattern()) -> glance:fn_parameter().
use_pattern_to_fn_param(Pattern) ->
Name@1 = case erlang:element(2, Pattern) of
{pattern_variable, _, Name} ->
{named, Name};
_ ->
{discarded, <<"use"/utf8>>}
end,
{fn_parameter, Name@1, none}.
-file("src/graded/internal/extract.gleam", 553).
?DOC(false).
-spec desugar_use(
glance:span(),
list(glance:use_pattern()),
glance:expression(),
list(glance:statement())
) -> glance:expression().
desugar_use(Location, Patterns, Function, Rest) ->
Params = gleam@list:map(Patterns, fun use_pattern_to_fn_param/1),
Closure = {fn, Location, Params, none, Rest},
Closure_arg = {unlabelled_field, Closure},
case Function of
{call, Call_location, Callee, Args} ->
{call, Call_location, Callee, lists:append(Args, [Closure_arg])};
Other ->
{call, Location, Other, [Closure_arg]}
end.
-file("src/graded/internal/extract.gleam", 1634).
?DOC(false).
-spec extract_from_arguments(
list(glance:field(glance:expression())),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> extract_result().
extract_from_arguments(Arguments, Context, Env) ->
gleam@list:fold(
Arguments,
empty(),
fun(Accumulated, Field) ->
Expression = case Field of
{labelled_field, _, _, Item} ->
{some, Item};
{shorthand_field, _, _} ->
none;
{unlabelled_field, Item@1} ->
{some, Item@1}
end,
case Expression of
{some, Inner} ->
merge(
Accumulated,
extract_from_expression(Inner, Context, Env)
);
none ->
Accumulated
end
end
).
-file("src/graded/internal/extract.gleam", 1653).
?DOC(false).
-spec fold_expressions(
list(glance:expression()),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> extract_result().
fold_expressions(Expressions, Context, Env) ->
gleam@list:fold(
Expressions,
empty(),
fun(Accumulated, Expression) ->
merge(
Accumulated,
extract_from_expression(Expression, Context, Env)
)
end
).
-file("src/graded/internal/extract.gleam", 1663).
?DOC(false).
-spec merge_optional(
extract_result(),
gleam@option:option(glance:expression()),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> extract_result().
merge_optional(Base, Optional_expression, Context, Env) ->
case Optional_expression of
{some, Expression} ->
merge(Base, extract_from_expression(Expression, Context, Env));
none ->
Base
end.
-file("src/graded/internal/extract.gleam", 1395).
?DOC(false).
-spec extract_from_clause(
glance:clause(),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> extract_result().
extract_from_clause(Clause, Context, Env) ->
Body_result = extract_from_expression(
erlang:element(4, Clause),
Context,
Env
),
case erlang:element(3, Clause) of
{some, Guard} ->
merge(Body_result, extract_from_expression(Guard, Context, Env));
none ->
Body_result
end.
-file("src/graded/internal/extract.gleam", 1376).
?DOC(false).
-spec pipe_into_operator_value(
glance:expression(),
glance:span(),
import_context(),
gleam@dict:dict(binary(), local_binding()),
list(graded@internal@types:call_argument())
) -> extract_result().
pipe_into_operator_value(Expression, Span, Context, Env, Pipe_args) ->
Value = classify_expression(Expression, Context, Env),
case Value of
{closure, _, _} ->
attach_pipe_args(
begin
_record = empty(),
{extract_result,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record),
erlang:element(6, _record),
[{direct_pipe_op, Value, Span}],
erlang:element(8, _record)}
end,
Span,
Pipe_args
);
{choice, _} ->
attach_pipe_args(
begin
_record = empty(),
{extract_result,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
erlang:element(5, _record),
erlang:element(6, _record),
[{direct_pipe_op, Value, Span}],
erlang:element(8, _record)}
end,
Span,
Pipe_args
);
_ ->
extract_from_expression(Expression, Context, Env)
end.
-file("src/graded/internal/extract.gleam", 1351).
?DOC(false).
-spec pipe_into_block(
list(glance:statement()),
import_context(),
gleam@dict:dict(binary(), local_binding()),
list(graded@internal@types:call_argument())
) -> extract_result().
pipe_into_block(Statements, Context, Env, Pipe_args) ->
case lists:reverse(Statements) of
[{expression, Tail} | Init_reversed] ->
{Init_result, Inner_env} = walk_scope_with_env(
lists:reverse(Init_reversed),
Context,
Env
),
merge(
Init_result,
extract_pipe_target(Tail, Context, Inner_env, Pipe_args)
);
_ ->
walk_scope(Statements, Context, Env)
end.
-file("src/graded/internal/extract.gleam", 1261).
?DOC(false).
-spec extract_pipe_target(
glance:expression(),
import_context(),
gleam@dict:dict(binary(), local_binding()),
list(graded@internal@types:call_argument())
) -> extract_result().
extract_pipe_target(Expression, Context, Env, Pipe_args) ->
case Expression of
{field_access, Span, {variable, Receiver_span, Alias}, Function_name} ->
attach_pipe_args(
resolve_qualified_call(
Alias,
Function_name,
Span,
Receiver_span,
Context,
Env
),
Span,
Pipe_args
);
{variable, Span@1, Name} ->
attach_pipe_args(
resolve_variable_call(Name, Span@1, Context, Env),
Span@1,
Pipe_args
);
{call,
Span@2,
{field_access,
_,
{variable, Receiver_span@1, Alias@1},
Function_name@1},
Arguments} ->
merge_with_args(
resolve_qualified_call(
Alias@1,
Function_name@1,
Span@2,
Receiver_span@1,
Context,
Env
),
extract_from_arguments(Arguments, Context, Env),
Span@2,
lists:append(
Pipe_args,
classify_arguments(Arguments, Context, Env, 1)
)
);
{call, Span@3, {variable, _, Name@1}, Arguments@1} ->
merge_with_args(
resolve_variable_call(Name@1, Span@3, Context, Env),
extract_from_arguments(Arguments@1, Context, Env),
Span@3,
lists:append(
Pipe_args,
classify_arguments(Arguments@1, Context, Env, 1)
)
);
{block, _, Statements} ->
pipe_into_block(Statements, Context, Env, Pipe_args);
{fn, Span@4, _, _, _} ->
pipe_into_operator_value(
Expression,
Span@4,
Context,
Env,
Pipe_args
);
{'case', Span@5, _, _} ->
pipe_into_operator_value(
Expression,
Span@5,
Context,
Env,
Pipe_args
);
_ ->
extract_from_expression(Expression, Context, Env)
end.
-file("src/graded/internal/extract.gleam", 1097).
?DOC(false).
-spec extract_from_expression(
glance:expression(),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> extract_result().
extract_from_expression(Expression, Context, Env) ->
case Expression of
{call,
Span,
{field_access, _, {variable, Receiver_span, Alias}, Function_name},
Arguments} ->
merge_with_args(
resolve_qualified_call(
Alias,
Function_name,
Span,
Receiver_span,
Context,
Env
),
extract_from_arguments(Arguments, Context, Env),
Span,
classify_arguments(Arguments, Context, Env, 0)
);
{call, Span@1, {variable, _, Name}, Arguments@1} ->
merge_with_args(
resolve_variable_call(Name, Span@1, Context, Env),
extract_from_arguments(Arguments@1, Context, Env),
Span@1,
classify_arguments(Arguments@1, Context, Env, 0)
);
{call, _, Function_expression, Arguments@2} ->
merge(
extract_from_expression(Function_expression, Context, Env),
extract_from_arguments(Arguments@2, Context, Env)
);
{binary_operator, _, pipe, Left, Right} ->
Pipe_arg = {call_argument,
0,
none,
classify_expression(Left, Context, Env)},
merge(
extract_from_expression(Left, Context, Env),
extract_pipe_target(Right, Context, Env, [Pipe_arg])
);
{binary_operator, _, _, Left@1, Right@1} ->
merge(
extract_from_expression(Left@1, Context, Env),
extract_from_expression(Right@1, Context, Env)
);
{fn, _, Arguments@3, _, Statements} ->
walk_scope(
Statements,
Context,
bind_closure_params(Env, Arguments@3)
);
{block, _, Statements@1} ->
walk_scope(Statements@1, Context, Env);
{'case', _, Subjects, Clauses} ->
merge(
fold_expressions(Subjects, Context, Env),
gleam@list:fold(
Clauses,
empty(),
fun(Accumulated, Clause) ->
merge(
Accumulated,
extract_from_clause(Clause, Context, Env)
)
end
)
);
{tuple, _, Elements} ->
fold_expressions(Elements, Context, Env);
{list, _, Elements@1, Rest} ->
merge_optional(
fold_expressions(Elements@1, Context, Env),
Rest,
Context,
Env
);
{negate_int, _, Value} ->
extract_from_expression(Value, Context, Env);
{negate_bool, _, Value@1} ->
extract_from_expression(Value@1, Context, Env);
{record_update, _, _, _, Record, _} ->
extract_from_expression(Record, Context, Env);
{field_access, Span@2, {variable, _, Alias@1}, Function_name@1} ->
resolve_qualified_reference(
Alias@1,
Function_name@1,
Span@2,
Context
);
{field_access, _, Container, _} ->
extract_from_expression(Container, Context, Env);
{tuple_index, _, Tuple, _} ->
extract_from_expression(Tuple, Context, Env);
{fn_capture,
_,
_,
Function_expression@1,
Arguments_before,
Arguments_after} ->
merge(
extract_from_expression(Function_expression@1, Context, Env),
merge(
extract_from_arguments(Arguments_before, Context, Env),
extract_from_arguments(Arguments_after, Context, Env)
)
);
{echo, _, {some, Inner}, _} ->
extract_from_expression(Inner, Context, Env);
{echo, _, none, _} ->
empty();
{variable, Span@3, Name@1} ->
case gleam_stdlib:map_get(erlang:element(3, Context), Name@1) of
{ok, Qualified_name} ->
_record = empty(),
{extract_result,
erlang:element(2, _record),
erlang:element(3, _record),
erlang:element(4, _record),
[{resolved_call, Qualified_name, Span@3}],
erlang:element(6, _record),
erlang:element(7, _record),
erlang:element(8, _record)};
{error, nil} ->
empty()
end;
{int, _, _} ->
empty();
{float, _, _} ->
empty();
{string, _, _} ->
empty();
{panic, _, _} ->
empty();
{todo, _, _} ->
empty();
{bit_string, _, _} ->
empty()
end.
-file("src/graded/internal/extract.gleam", 758).
?DOC(false).
-spec extract_from_statement(
glance:statement(),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> {extract_result(), gleam@dict:dict(binary(), local_binding())}.
extract_from_statement(Statement, Context, Env) ->
case Statement of
{expression, Expression} ->
{extract_from_expression(Expression, Context, Env), Env};
{assignment, _, _, Pattern, _, Expression@1} ->
Result = extract_from_expression(Expression@1, Context, Env),
Next_env = bind_assignment(Pattern, Expression@1, Context, Env),
{Result, Next_env};
{use, _, Patterns, Expression@2} ->
Result@1 = extract_from_expression(Expression@2, Context, Env),
Next_env@1 = bind_use_patterns(Patterns, Env),
{Result@1, Next_env@1};
{assert, _, Expression@3, Message} ->
Expression_result = extract_from_expression(
Expression@3,
Context,
Env
),
Combined = case Message of
{some, Message_expression} ->
merge(
Expression_result,
extract_from_expression(
Message_expression,
Context,
Env
)
);
none ->
Expression_result
end,
{Combined, Env}
end.
-file("src/graded/internal/extract.gleam", 518).
?DOC(false).
-spec walk_scope_with_env(
list(glance:statement()),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> {extract_result(), gleam@dict:dict(binary(), local_binding())}.
walk_scope_with_env(Statements, Context, Env) ->
case Statements of
[] ->
{empty(), Env};
[{use, Location, Patterns, Function} | Rest] ->
{extract_from_expression(
desugar_use(Location, Patterns, Function, Rest),
Context,
Env
),
Env};
[Statement | Rest@1] ->
{Result, Next_env} = extract_from_statement(Statement, Context, Env),
{Rest_result, Final_env} = walk_scope_with_env(
Rest@1,
Context,
Next_env
),
{merge(Result, Rest_result), Final_env}
end.
-file("src/graded/internal/extract.gleam", 507).
?DOC(false).
-spec walk_scope(
list(glance:statement()),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> extract_result().
walk_scope(Statements, Context, Env) ->
erlang:element(1, walk_scope_with_env(Statements, Context, Env)).
-file("src/graded/internal/extract.gleam", 497).
?DOC(false).
-spec extract_calls(list(glance:statement()), import_context()) -> extract_result().
extract_calls(Statements, Context) ->
walk_scope(Statements, Context, maps:new()).
-file("src/graded/internal/extract.gleam", 1561).
?DOC(false).
-spec return_value(glance:function_(), import_context()) -> {ok,
graded@internal@types:argument_value()} |
{error, nil}.
return_value(Function, Context) ->
case gleam@list:last(erlang:element(7, Function)) of
{ok, {expression, Expression}} ->
{ok, classify_expression(Expression, Context, maps:new())};
_ ->
{error, nil}
end.