-module(caffeine_lang@frontend@validator). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/caffeine_lang/frontend/validator.gleam"). -export([validate_blueprints_file/1, validate_expects_file/1]). -export_type([validator_error/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. -type validator_error() :: {duplicate_extendable, binary()} | {undefined_extendable, binary(), binary()} | {duplicate_extends_reference, binary(), binary()} | {invalid_extendable_kind, binary(), binary(), binary()}. -file("src/caffeine_lang/frontend/validator.gleam", 62). -spec validate_no_duplicate_extendables_loop( list(caffeine_lang@frontend@ast:extendable()), gleam@set:set(binary()) ) -> {ok, nil} | {error, validator_error()}. validate_no_duplicate_extendables_loop(Extendables, Seen) -> case Extendables of [] -> {ok, nil}; [First | Rest] -> case gleam@set:contains(Seen, erlang:element(2, First)) of true -> {error, {duplicate_extendable, erlang:element(2, First)}}; false -> validate_no_duplicate_extendables_loop( Rest, gleam@set:insert(Seen, erlang:element(2, First)) ) end end. -file("src/caffeine_lang/frontend/validator.gleam", 56). ?DOC(" Validates that no two extendables have the same name.\n"). -spec validate_no_duplicate_extendables( list(caffeine_lang@frontend@ast:extendable()) ) -> {ok, nil} | {error, validator_error()}. validate_no_duplicate_extendables(Extendables) -> validate_no_duplicate_extendables_loop(Extendables, gleam@set:new()). -file("src/caffeine_lang/frontend/validator.gleam", 82). ?DOC(" Validates that all extendables in an expects file are Provides kind.\n"). -spec validate_extendables_are_provides( list(caffeine_lang@frontend@ast:extendable()) ) -> {ok, nil} | {error, validator_error()}. validate_extendables_are_provides(Extendables) -> case Extendables of [] -> {ok, nil}; [First | Rest] -> case erlang:element(3, First) of extendable_provides -> validate_extendables_are_provides(Rest); extendable_requires -> {error, {invalid_extendable_kind, erlang:element(2, First), <<"Provides"/utf8>>, <<"Requires"/utf8>>}} end end. -file("src/caffeine_lang/frontend/validator.gleam", 142). ?DOC(" Validates that all names in extends list exist as extendables.\n"). -spec validate_extends_exist(list(binary()), binary(), gleam@set:set(binary())) -> {ok, nil} | {error, validator_error()}. validate_extends_exist(Extends, Item_name, Extendable_names) -> case Extends of [] -> {ok, nil}; [First | Rest] -> case gleam@set:contains(Extendable_names, First) of true -> validate_extends_exist(Rest, Item_name, Extendable_names); false -> {error, {undefined_extendable, First, Item_name}} end end. -file("src/caffeine_lang/frontend/validator.gleam", 167). -spec validate_no_duplicate_extends_loop( list(binary()), binary(), gleam@set:set(binary()) ) -> {ok, nil} | {error, validator_error()}. validate_no_duplicate_extends_loop(Extends, Item_name, Seen) -> case Extends of [] -> {ok, nil}; [First | Rest] -> case gleam@set:contains(Seen, First) of true -> {error, {duplicate_extends_reference, First, Item_name}}; false -> validate_no_duplicate_extends_loop( Rest, Item_name, gleam@set:insert(Seen, First) ) end end. -file("src/caffeine_lang/frontend/validator.gleam", 160). ?DOC(" Validates that no extendable is referenced twice in the same extends list.\n"). -spec validate_no_duplicate_extends(list(binary()), binary()) -> {ok, nil} | {error, validator_error()}. validate_no_duplicate_extends(Extends, Item_name) -> validate_no_duplicate_extends_loop(Extends, Item_name, gleam@set:new()). -file("src/caffeine_lang/frontend/validator.gleam", 102). ?DOC(" Validates extends references for blueprint items.\n"). -spec validate_blueprint_items_extends( list(caffeine_lang@frontend@ast:blueprint_item()), list(caffeine_lang@frontend@ast:extendable()) ) -> {ok, nil} | {error, validator_error()}. validate_blueprint_items_extends(Items, Extendables) -> Extendable_names = begin _pipe = Extendables, _pipe@1 = gleam@list:map(_pipe, fun(E) -> erlang:element(2, E) end), gleam@set:from_list(_pipe@1) end, gleam@list:try_each( Items, fun(Item) -> gleam@result:'try'( validate_extends_exist( erlang:element(3, Item), erlang:element(2, Item), Extendable_names ), fun(_) -> validate_no_duplicate_extends( erlang:element(3, Item), erlang:element(2, Item) ) end ) end ). -file("src/caffeine_lang/frontend/validator.gleam", 22). ?DOC(false). -spec validate_blueprints_file(caffeine_lang@frontend@ast:blueprints_file()) -> {ok, caffeine_lang@frontend@ast:blueprints_file()} | {error, validator_error()}. validate_blueprints_file(File) -> Extendables = erlang:element(2, File), Items = begin _pipe = erlang:element(3, File), gleam@list:flat_map(_pipe, fun(Block) -> erlang:element(3, Block) end) end, gleam@result:'try'( validate_no_duplicate_extendables(Extendables), fun(_) -> gleam@result:'try'( validate_blueprint_items_extends(Items, Extendables), fun(_) -> {ok, File} end ) end ). -file("src/caffeine_lang/frontend/validator.gleam", 122). ?DOC(" Validates extends references for expect items.\n"). -spec validate_expect_items_extends( list(caffeine_lang@frontend@ast:expect_item()), list(caffeine_lang@frontend@ast:extendable()) ) -> {ok, nil} | {error, validator_error()}. validate_expect_items_extends(Items, Extendables) -> Extendable_names = begin _pipe = Extendables, _pipe@1 = gleam@list:map(_pipe, fun(E) -> erlang:element(2, E) end), gleam@set:from_list(_pipe@1) end, gleam@list:try_each( Items, fun(Item) -> gleam@result:'try'( validate_extends_exist( erlang:element(3, Item), erlang:element(2, Item), Extendable_names ), fun(_) -> validate_no_duplicate_extends( erlang:element(3, Item), erlang:element(2, Item) ) end ) end ). -file("src/caffeine_lang/frontend/validator.gleam", 40). ?DOC(false). -spec validate_expects_file(caffeine_lang@frontend@ast:expects_file()) -> {ok, caffeine_lang@frontend@ast:expects_file()} | {error, validator_error()}. validate_expects_file(File) -> Extendables = erlang:element(2, File), Items = begin _pipe = erlang:element(3, File), gleam@list:flat_map(_pipe, fun(Block) -> erlang:element(3, Block) end) end, gleam@result:'try'( validate_no_duplicate_extendables(Extendables), fun(_) -> gleam@result:'try'( validate_extendables_are_provides(Extendables), fun(_) -> gleam@result:'try'( validate_expect_items_extends(Items, Extendables), fun(_) -> {ok, File} end ) end ) end ).