-module(internal@ast). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([files_ast/1, files_paths_with_ast/2, is_pub_member_used/4]). -export_type([file_ast/0, another_files_ast/0, module_name/0, imported_info/0, public_member/0]). -type file_ast() :: {file_ast, glance:module_()}. -type another_files_ast() :: {another_files_ast, list(file_ast())}. -type module_name() :: {module_name, binary()}. -type imported_info() :: {module_imported, module_name()} | imported_as_alias. -type public_member() :: {public_fun, binary()} | {public_const, binary()} | {public_type, binary()}. -spec files_ast(list(internal@fs:file_content())) -> list(file_ast()). files_ast(Files_contents) -> gleam@list:map( Files_contents, fun(Content) -> {file_content, Content@1} = case Content of {file_content, _} -> Content; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"internal/ast"/utf8>>, function => <<"files_ast"/utf8>>, line => 36}) end, _assert_subject = glance:module(Content@1), {ok, Ast} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"internal/ast"/utf8>>, function => <<"files_ast"/utf8>>, line => 37}) end, {file_ast, Ast} end ). -spec files_paths_with_ast( internal@fs:files_dir(), gleam@option:option(internal@fs:files_dir()) ) -> list({internal@fs:file_path(), file_ast(), another_files_ast()}). files_paths_with_ast(Dir, Test_dir) -> File_paths = internal@fs:files_paths(Dir), File_paths_idx = begin _pipe = File_paths, _pipe@1 = gleam@list:index_map(_pipe, fun(Fp, I) -> {I, Fp} end), maps:from_list(_pipe@1) end, Flle_contents = internal@fs:files_contents(File_paths), Test_file_contents = case Test_dir of {some, {files_dir, _} = Test_dir@1} -> _pipe@2 = internal@fs:files_paths(Test_dir@1), internal@fs:files_contents(_pipe@2); none -> [] end, Ast_list = begin _pipe@3 = Flle_contents, _pipe@4 = lists:append(_pipe@3, Test_file_contents), files_ast(_pipe@4) end, Ast_list_idx = begin _pipe@5 = Ast_list, _pipe@6 = gleam@list:index_map(_pipe@5, fun(Ast, I@1) -> {I@1, Ast} end), maps:from_list(_pipe@6) end, Indexes = gleam@list:range(0, erlang:length(Ast_list) - 1), gleam@list:filter_map( Indexes, fun(Index) -> case gleam@dict:get(File_paths_idx, Index) of {ok, File_path} -> _assert_subject = gleam@dict:get(Ast_list_idx, Index), {ok, File_ast} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"internal/ast"/utf8>>, function => <<"files_paths_with_ast"/utf8>>, line => 67}) end, {ok, {File_path, File_ast, {another_files_ast, gleam@list:filter_map( Indexes, fun(Idx) -> case Idx =:= Index of true -> {error, nil}; false -> gleam@dict:get( Ast_list_idx, Idx ) end end )}}}; {error, nil} -> {error, nil} end end ). -spec module_full_name_to_module_name(internal@fs:module_full_name()) -> module_name(). module_full_name_to_module_name(Module_full_name) -> {module_full_name, Module_full_name@1} = case Module_full_name of {module_full_name, _} -> Module_full_name; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"internal/ast"/utf8>>, function => <<"module_full_name_to_module_name"/utf8>>, line => 143}) end, _assert_subject = begin _pipe = gleam@string:split(Module_full_name@1, <<"/"/utf8>>), gleam@list:last(_pipe) end, {ok, Module_name} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"internal/ast"/utf8>>, function => <<"module_full_name_to_module_name"/utf8>>, line => 144}) end, {module_name, Module_name}. -spec imported_info( list(glance:definition(glance:import())), internal@fs:module_full_name(), public_member() ) -> list(imported_info()). imported_info(Imports, Module_full_name, Exported) -> gleam@list:filter_map(Imports, fun(Imp) -> case Imp of {definition, _, {import, Import_name, Module_alias, Type_aliases, Aliases}} when {module_full_name, Import_name} =:= Module_full_name -> case begin _pipe = Aliases, _pipe@1 = lists:append(_pipe, Type_aliases), gleam@list:any( _pipe@1, fun(Alias) -> {unqualified_import, Imported, _} = case Alias of {unqualified_import, _, _} -> Alias; _assert_fail -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"internal/ast"/utf8>>, function => <<"imported_info"/utf8>>, line => 95} ) end, (({public_fun, Imported} =:= Exported) orelse ({public_const, Imported} =:= Exported)) orelse ({public_type, Imported} =:= Exported) end ) end of true -> {ok, imported_as_alias}; false -> case Module_alias of {some, {named, Alias@1}} -> {ok, {module_imported, {module_name, Alias@1}}}; {some, {discarded, _}} -> {error, nil}; none -> {ok, {module_imported, module_full_name_to_module_name( Module_full_name )}} end end; _ -> {error, nil} end end). -spec is_pub_member_used( another_files_ast(), public_member(), internal@fs:module_full_name(), fun((list(glance:statement()), public_member(), module_name()) -> {ok, nil} | {error, any()}) ) -> {ok, nil} | {error, nil}. is_pub_member_used(Files_ast, Pub_member_name, Module_full_name, Check_usage) -> {another_files_ast, Files_ast@1} = case Files_ast of {another_files_ast, _} -> Files_ast; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"internal/ast"/utf8>>, function => <<"is_pub_member_used"/utf8>>, line => 125}) end, gleam@list:find_map( Files_ast@1, fun(File_ast) -> {file_ast, Ast} = case File_ast of {file_ast, _} -> File_ast; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@1, module => <<"internal/ast"/utf8>>, function => <<"is_pub_member_used"/utf8>>, line => 127}) end, {module, Imports, _, _, _, Fns} = case Ast of {module, _, _, _, _, _} -> Ast; _assert_fail@2 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@2, module => <<"internal/ast"/utf8>>, function => <<"is_pub_member_used"/utf8>>, line => 128}) end, Imported_info_list = imported_info( Imports, Module_full_name, Pub_member_name ), gleam@list:find_map( Imported_info_list, fun(Imported_info) -> case Imported_info of imported_as_alias -> {ok, nil}; {module_imported, Module_name} -> gleam@list:find_map( Fns, fun(Fun_def) -> {definition, _, {function, _, _, _, _, Statements, _}} = case Fun_def of {definition, _, {function, _, _, _, _, _, _}} -> Fun_def; _assert_fail@3 -> erlang:error( #{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@3, module => <<"internal/ast"/utf8>>, function => <<"is_pub_member_used"/utf8>>, line => 136} ) end, Check_usage( Statements, Pub_member_name, Module_name ) end ) end end ) end ).