-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 = <>, 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.