-module(caffeine_lang@middle_end@dependency_validator). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/caffeine_lang/middle_end/dependency_validator.gleam"). -export([build_expectation_index/1, parse_dependency_path/1, validate_dependency_relations/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -file("src/caffeine_lang/middle_end/dependency_validator.gleam", 48). -spec ir_to_path( caffeine_lang@middle_end@semantic_analyzer:intermediate_representation() ) -> binary(). ir_to_path(Ir) -> <<<<<<<<<<<<(erlang:element(3, erlang:element(2, Ir)))/binary, "."/utf8>>/binary, (erlang:element(6, erlang:element(2, Ir)))/binary>>/binary, "."/utf8>>/binary, (erlang:element(4, erlang:element(2, Ir)))/binary>>/binary, "."/utf8>>/binary, (erlang:element(2, erlang:element(2, Ir)))/binary>>. -file("src/caffeine_lang/middle_end/dependency_validator.gleam", 37). ?DOC(false). -spec build_expectation_index( list(caffeine_lang@middle_end@semantic_analyzer:intermediate_representation()) ) -> gleam@dict:dict(binary(), caffeine_lang@middle_end@semantic_analyzer:intermediate_representation()). build_expectation_index(Irs) -> _pipe = Irs, _pipe@1 = gleam@list:map( _pipe, fun(Ir) -> Path = ir_to_path(Ir), {Path, Ir} end ), maps:from_list(_pipe@1). -file("src/caffeine_lang/middle_end/dependency_validator.gleam", 83). -spec extract_relations( caffeine_lang@middle_end@semantic_analyzer:intermediate_representation() ) -> gleam@dict:dict(binary(), list(binary())). extract_relations(Ir) -> _pipe = erlang:element(5, Ir), _pipe@1 = gleam@list:filter( _pipe, fun(Vt) -> erlang:element(2, Vt) =:= <<"relations"/utf8>> end ), _pipe@2 = gleam@list:first(_pipe@1), _pipe@4 = gleam@result:'try'( _pipe@2, fun(Vt@1) -> _pipe@3 = gleam@dynamic@decode:run( erlang:element(4, Vt@1), gleam@dynamic@decode:dict( {decoder, fun gleam@dynamic@decode:decode_string/1}, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_string/1} ) ) ), gleam@result:replace_error(_pipe@3, nil) end ), gleam@result:unwrap(_pipe@4, maps:new()). -file("src/caffeine_lang/middle_end/dependency_validator.gleam", 99). -spec get_all_dependency_targets(gleam@dict:dict(binary(), list(binary()))) -> list(binary()). get_all_dependency_targets(Relations) -> _pipe = Relations, _pipe@1 = maps:values(_pipe), lists:append(_pipe@1). -file("src/caffeine_lang/middle_end/dependency_validator.gleam", 153). ?DOC(false). -spec parse_dependency_path(binary()) -> {ok, {binary(), binary(), binary(), binary()}} | {error, nil}. parse_dependency_path(Path) -> case gleam@string:split(Path, <<"."/utf8>>) of [Org, Team, Service, Name] when (((Org =/= <<""/utf8>>) andalso (Team =/= <<""/utf8>>)) andalso (Service =/= <<""/utf8>>)) andalso (Name =/= <<""/utf8>>) -> {ok, {Org, Team, Service, Name}}; _ -> {error, nil} end. -file("src/caffeine_lang/middle_end/dependency_validator.gleam", 105). -spec validate_dependency_target( binary(), binary(), gleam@dict:dict(binary(), caffeine_lang@middle_end@semantic_analyzer:intermediate_representation()) ) -> {ok, nil} | {error, caffeine_lang@common@errors:compilation_error()}. validate_dependency_target(Target, Self_path, Expectation_index) -> case parse_dependency_path(Target) of {error, nil} -> {error, {semantic_analysis_dependency_validation_error, <<<<<<<<"Invalid dependency reference '"/utf8, Target/binary>>/binary, "' in '"/utf8>>/binary, Self_path/binary>>/binary, "': expected format 'org.team.service.name'"/utf8>>}}; {ok, _} -> case Target =:= Self_path of true -> {error, {semantic_analysis_dependency_validation_error, <<<<<<<<"Invalid dependency reference '"/utf8, Target/binary>>/binary, "' in '"/utf8>>/binary, Self_path/binary>>/binary, "': self-reference not allowed"/utf8>>}}; false -> case gleam_stdlib:map_get(Expectation_index, Target) of {ok, _} -> {ok, nil}; {error, nil} -> {error, {semantic_analysis_dependency_validation_error, <<<<<<<<"Invalid dependency reference '"/utf8, Target/binary>>/binary, "' in '"/utf8>>/binary, Self_path/binary>>/binary, "': target does not exist"/utf8>>}} end end end. -file("src/caffeine_lang/middle_end/dependency_validator.gleam", 58). -spec validate_ir_dependencies( caffeine_lang@middle_end@semantic_analyzer:intermediate_representation(), gleam@dict:dict(binary(), caffeine_lang@middle_end@semantic_analyzer:intermediate_representation()) ) -> {ok, nil} | {error, caffeine_lang@common@errors:compilation_error()}. validate_ir_dependencies(Ir, Expectation_index) -> case begin _pipe = erlang:element(4, Ir), gleam@list:contains(_pipe, <<"DependencyRelations"/utf8>>) end of false -> {ok, nil}; true -> Self_path = ir_to_path(Ir), Relations = extract_relations(Ir), All_targets = get_all_dependency_targets(Relations), _pipe@1 = All_targets, gleam@list:try_each( _pipe@1, fun(Target) -> validate_dependency_target( Target, Self_path, Expectation_index ) end ) end. -file("src/caffeine_lang/middle_end/dependency_validator.gleam", 17). ?DOC(false). -spec validate_dependency_relations( list(caffeine_lang@middle_end@semantic_analyzer:intermediate_representation()) ) -> {ok, list(caffeine_lang@middle_end@semantic_analyzer:intermediate_representation())} | {error, caffeine_lang@common@errors:compilation_error()}. validate_dependency_relations(Irs) -> Expectation_index = build_expectation_index(Irs), gleam@result:'try'( begin _pipe = Irs, gleam@list:try_each( _pipe, fun(Ir) -> validate_ir_dependencies(Ir, Expectation_index) end ) end, fun(_) -> {ok, Irs} end ).