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([module_path_for_source/2, build_import_context/1, extract_calls/2]).
-export_type([local_binding/0, import_context/0, extract_result/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_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())))}.
-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()),
gleam@dict:dict(integer(), list(graded@internal@types:call_argument()))}.
-file("src/graded/internal/extract.gleam", 36).
?DOC(false).
-spec module_path_for_source(binary(), binary()) -> binary().
module_path_for_source(Gleam_path, Source_directory) ->
Prefix = <<Source_directory/binary, "/"/utf8>>,
Relative = case gleam_stdlib:string_starts_with(Gleam_path, Prefix) of
true ->
gleam@string:drop_start(Gleam_path, string:length(Prefix));
false ->
Gleam_path
end,
filepath:strip_extension(Relative).
-file("src/graded/internal/extract.gleam", 119).
?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", 162).
?DOC(false).
-spec is_constructor_name(binary()) -> boolean().
is_constructor_name(Name) ->
case gleam@string:first(Name) of
{ok, Char} ->
(Char =:= string:uppercase(Char)) andalso (Char /= string:lowercase(
Char
));
{error, nil} ->
false
end.
-file("src/graded/internal/extract.gleam", 340).
?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", 78).
?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}.
-file("src/graded/internal/extract.gleam", 400).
?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", 502).
?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", 517).
?DOC(false).
-spec fold_pattern_names(glance:pattern(), LKS, fun((LKS, binary()) -> LKS)) -> LKS.
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", 508).
?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", 822).
?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};
_ ->
{local_ref, Name}
end
end
end;
_ ->
other_expression
end.
-file("src/graded/internal/extract.gleam", 442).
?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);
constructor_ref ->
bound_opaque;
other_expression ->
bound_opaque
end.
-file("src/graded/internal/extract.gleam", 459).
?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, _} ->
[]
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", 407).
?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 ->
classify_rhs_ref(Expression, 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 ->
bound_opaque
end;
_ ->
classify_rhs_ref(Expression, Context, Env)
end.
-file("src/graded/internal/extract.gleam", 387).
?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", 799).
?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", 863).
?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),
gleam@dict:insert(
erlang:element(6, Base),
erlang:element(2, Span),
Pipe_args
)}.
-file("src/graded/internal/extract.gleam", 931).
?DOC(false).
-spec empty() -> extract_result().
empty() ->
{extract_result, [], [], [], [], maps:new()}.
-file("src/graded/internal/extract.gleam", 189).
?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} ->
{extract_result,
[{resolved_call, Qualified_name, Span}],
[],
[],
[],
maps:new()};
{error, nil} ->
{extract_result,
[],
[{local_call, Name, Span}],
[],
[],
maps:new()}
end
end.
-file("src/graded/internal/extract.gleam", 170).
?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} ->
{extract_result,
[{resolved_call, Qualified, Span}],
[],
[],
[],
maps:new()};
_ ->
resolve_unqualified_call(Name, Span, Context)
end.
-file("src/graded/internal/extract.gleam", 270).
?DOC(false).
-spec resolve_constructor_field_call(
binary(),
binary(),
glance:span(),
gleam@dict:dict(binary(), graded@internal@types:argument_value())
) -> extract_result().
resolve_constructor_field_call(Alias, Label, Span, Fields) ->
case gleam_stdlib:map_get(Fields, Label) of
{ok, {function_ref, Qualified}} ->
{extract_result,
[{resolved_call, Qualified, Span}],
[],
[],
[],
maps:new()};
{ok, {local_ref, Local_name}} ->
{extract_result,
[],
[{local_call, Local_name, Span}],
[],
[],
maps:new()};
{ok, constructor_ref} ->
empty();
{ok, other_expression} ->
{extract_result,
[],
[],
[{field_call, Alias, Label, Span}],
[],
maps:new()};
{error, nil} ->
{extract_result,
[],
[],
[{field_call, Alias, Label, Span}],
[],
maps:new()}
end.
-file("src/graded/internal/extract.gleam", 234).
?DOC(false).
-spec qualified_call_lookup(
binary(),
binary(),
glance:span(),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> extract_result().
qualified_call_lookup(Alias, Function_name, Span, Context, Env) ->
case gleam_stdlib:map_get(erlang:element(2, Context), Alias) of
{ok, Module_path} ->
{extract_result,
[{resolved_call,
{qualified_name, Module_path, Function_name},
Span}],
[],
[],
[],
maps:new()};
{error, nil} ->
case resolve_env(Alias, Env) of
{bound_constructor, Fields} ->
resolve_constructor_field_call(
Alias,
Function_name,
Span,
Fields
);
_ ->
{extract_result,
[],
[],
[{field_call, Alias, Function_name, Span}],
[],
maps:new()}
end
end.
-file("src/graded/internal/extract.gleam", 221).
?DOC(false).
-spec resolve_qualified_call(
binary(),
binary(),
glance:span(),
import_context(),
gleam@dict:dict(binary(), local_binding())
) -> extract_result().
resolve_qualified_call(Alias, Function_name, Span, Context, Env) ->
case is_constructor_name(Function_name) of
true ->
empty();
false ->
qualified_call_lookup(Alias, Function_name, Span, Context, Env)
end.
-file("src/graded/internal/extract.gleam", 319).
?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} ->
{extract_result,
[],
[],
[],
[{resolved_call,
{qualified_name, Module_path, Function_name},
Span}],
maps:new()};
{error, nil} ->
empty()
end.
-file("src/graded/internal/extract.gleam", 307).
?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", 941).
?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)),
maps:merge(erlang:element(6, Left), erlang:element(6, Right))}.
-file("src/graded/internal/extract.gleam", 876).
?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),
gleam@dict:insert(
erlang:element(6, Merged),
erlang:element(2, Span),
Args
)}.
-file("src/graded/internal/extract.gleam", 570).
?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, _, Alias}, Function_name},
Arguments} ->
merge_with_args(
resolve_qualified_call(Alias, Function_name, 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, _, _, _, Statements} ->
walk_scope(Statements, Context, Env);
{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} ->
{extract_result,
[],
[],
[],
[{resolved_call, Qualified_name, Span@3}],
maps:new()};
{error, nil} ->
empty()
end;
{int, _, _} ->
empty();
{float, _, _} ->
empty();
{string, _, _} ->
empty();
{panic, _, _} ->
empty();
{todo, _, _} ->
empty();
{bit_string, _, _} ->
empty()
end.
-file("src/graded/internal/extract.gleam", 147).
?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,
gleam@list:fold(
Statements,
{empty(), Env},
fun(State, Statement) ->
{Accumulated, Current_env} = State,
{Result, Next_env} = extract_from_statement(
Statement,
Context,
Current_env
),
{merge(Accumulated, Result), Next_env}
end
)
).
-file("src/graded/internal/extract.gleam", 347).
?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", 137).
?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", 784).
?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", 889).
?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", 728).
?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, _, Alias}, Function_name} ->
attach_pipe_args(
resolve_qualified_call(Alias, Function_name, 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, _, Alias@1}, Function_name@1},
Arguments} ->
merge_with_args(
resolve_qualified_call(
Alias@1,
Function_name@1,
Span@2,
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)
)
);
_ ->
extract_from_expression(Expression, Context, Env)
end.
-file("src/graded/internal/extract.gleam", 908).
?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", 918).
?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.