Current section
Files
Jump to
Current section
Files
src/prequel@internals@checker.erl
-module(prequel@internals@checker).
-compile([no_auto_import, nowarn_unused_vars]).
-export([check_module/1]).
-spec gather_errors(
list(fun((prequel@ast:module_()) -> list(prequel@error@validation_error:validation_error()))),
prequel@ast:module_()
) -> list(prequel@error@validation_error:validation_error()).
gather_errors(Validation_steps, Module) ->
gleam@list:flat_map(Validation_steps, fun(Validate) -> Validate(Module) end).
-spec cardinality_from_attribute(prequel@ast:attribute()) -> prequel@ast:cardinality().
cardinality_from_attribute(Attribute) ->
erlang:element(4, Attribute).
-spec cardinalities_from_relationship(prequel@ast:relationship()) -> list({prequel@span:span(),
prequel@ast:cardinality()}).
cardinalities_from_relationship(Relationship) ->
{relationship, Span, _, Entity, Entities, Attributes} = Relationship,
Inner_entities = [Entity | non_empty_list:to_list(Entities)],
Cardinality_from_inner_entities = fun(Entity@1) ->
erlang:element(4, Entity@1)
end,
_pipe = [gleam@list:map(Attributes, fun cardinality_from_attribute/1),
gleam@list:map(Inner_entities, Cardinality_from_inner_entities)],
_pipe@1 = gleam@list:concat(_pipe),
gleam@list:map(_pipe@1, fun(Cardinality) -> {Span, Cardinality} end).
-spec cardinalities_from_entity(prequel@ast:entity()) -> list({prequel@span:span(),
prequel@ast:cardinality()}).
cardinalities_from_entity(Entity) ->
{entity, Span, _, _, Attributes, Inner_relationships, Children} = Entity,
Inner_relationship_cardinalities = gleam@list:flat_map(
Inner_relationships,
fun cardinalities_from_relationship/1
),
Children_cardinalities = case Children of
none ->
[];
{some, {hierarchy, _, _, _, Children@1}} ->
_pipe = non_empty_list:to_list(Children@1),
gleam@list:flat_map(_pipe, fun cardinalities_from_entity/1)
end,
_pipe@1 = [gleam@list:map(Attributes, fun cardinality_from_attribute/1)],
_pipe@2 = gleam@list:concat(_pipe@1),
_pipe@3 = gleam@list:map(
_pipe@2,
fun(Cardinality) -> {Span, Cardinality} end
),
_pipe@4 = gleam@list:append(_pipe@3, Inner_relationship_cardinalities),
gleam@list:append(_pipe@4, Children_cardinalities).
-spec cardinalities_from_module(prequel@ast:module_()) -> list({prequel@span:span(),
prequel@ast:cardinality()}).
cardinalities_from_module(Module) ->
_pipe = [gleam@list:flat_map(
erlang:element(2, Module),
fun cardinalities_from_entity/1
),
gleam@list:flat_map(
erlang:element(3, Module),
fun cardinalities_from_relationship/1
)],
gleam@list:concat(_pipe).
-spec cardinality_has_valid_bounds(prequel@ast:cardinality()) -> boolean().
cardinality_has_valid_bounds(Cardinality) ->
case Cardinality of
{bounded, _, Lower_bound, Upper_bound} when Lower_bound > Upper_bound ->
false;
{unbounded, _, _} ->
true;
{bounded, _, _, _} ->
true
end.
-spec check_cardinality_bounds(prequel@span:span(), prequel@ast:cardinality()) -> gleam@option:option(prequel@error@validation_error:validation_error()).
check_cardinality_bounds(Enclosing_definition, Cardinality) ->
case cardinality_has_valid_bounds(Cardinality) of
true ->
none;
false ->
{some,
{lower_bound_greater_than_upper_bound,
{some, <<"TODO: add hint"/utf8>>},
Enclosing_definition,
Cardinality}}
end.
-spec check_cardinalities_bounds(prequel@ast:module_()) -> list(prequel@error@validation_error:validation_error()).
check_cardinalities_bounds(Module) ->
_pipe = cardinalities_from_module(Module),
_pipe@1 = prequel@internals@extra@list:map_pairs(
_pipe,
fun check_cardinality_bounds/2
),
gleam@option:values(_pipe@1).
-spec entities_from_entity(prequel@ast:entity()) -> list(prequel@ast:entity()).
entities_from_entity(Entity) ->
case erlang:element(7, Entity) of
none ->
[];
{some, Hierarchy} ->
Children = non_empty_list:to_list(erlang:element(5, Hierarchy)),
_pipe = gleam@list:flat_map(Children, fun entities_from_entity/1),
gleam@list:append(_pipe, Children)
end.
-spec entities_from_module(prequel@ast:module_()) -> list(prequel@ast:entity()).
entities_from_module(Module) ->
Top_level_entities = erlang:element(2, Module),
Sub_entities = gleam@list:flat_map(
Top_level_entities,
fun entities_from_entity/1
),
gleam@list:append(Top_level_entities, Sub_entities).
-spec to_duplicate_entity_error(
prequel@ast:entity(),
non_empty_list:non_empty_list(prequel@ast:entity())
) -> prequel@error@validation_error:validation_error().
to_duplicate_entity_error(First_entity, Other_entities) ->
_assert_subject = gleam@list:sort(
[First_entity, erlang:element(2, Other_entities)],
fun(One, Other) ->
gleam@int:compare(
erlang:element(2, erlang:element(2, One)),
erlang:element(2, erlang:element(2, Other))
)
end
),
[First, Other@1] = case _assert_subject of
[_, _] -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"prequel/internals/checker"/utf8>>,
function => <<"to_duplicate_entity_error"/utf8>>,
line => 162})
end,
{duplicate_entity_name, {some, <<"TODO: add hint"/utf8>>}, First, Other@1}.
-spec check_all_entities_have_different_names(prequel@ast:module_()) -> list(prequel@error@validation_error:validation_error()).
check_all_entities_have_different_names(Module) ->
_pipe = entities_from_module(Module),
_pipe@1 = prequel@internals@extra@list:duplicates(
_pipe,
fun(Entity) -> erlang:element(3, Entity) end
),
prequel@internals@extra@list:map_pairs(
_pipe@1,
fun to_duplicate_entity_error/2
).
-spec relationships_from_entity(prequel@ast:entity()) -> list(prequel@ast:relationship()).
relationships_from_entity(Entity) ->
Sub_relationships = case erlang:element(7, Entity) of
{some, Hierarchy} ->
_pipe = non_empty_list:to_list(erlang:element(5, Hierarchy)),
gleam@list:flat_map(_pipe, fun relationships_from_entity/1);
none ->
[]
end,
gleam@list:append(erlang:element(6, Entity), Sub_relationships).
-spec relationships_from_module(prequel@ast:module_()) -> list(prequel@ast:relationship()).
relationships_from_module(Module) ->
Top_level_relationships = erlang:element(3, Module),
All_entities = entities_from_module(Module),
Inner_relationships = gleam@list:flat_map(
All_entities,
fun relationships_from_entity/1
),
gleam@list:append(Top_level_relationships, Inner_relationships).
-spec to_duplicate_relationship_error(
prequel@ast:relationship(),
non_empty_list:non_empty_list(prequel@ast:relationship())
) -> prequel@error@validation_error:validation_error().
to_duplicate_relationship_error(First_relationship, Other_relationships) ->
_assert_subject = gleam@list:sort(
[First_relationship, erlang:element(2, Other_relationships)],
fun(One, Other) ->
gleam@int:compare(
erlang:element(2, erlang:element(2, One)),
erlang:element(2, erlang:element(2, Other))
)
end
),
[First, Other@1] = case _assert_subject of
[_, _] -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"prequel/internals/checker"/utf8>>,
function => <<"to_duplicate_relationship_error"/utf8>>,
line => 209})
end,
{duplicate_relationship_name,
{some, <<"TODO: add hint"/utf8>>},
First,
Other@1}.
-spec check_all_relationships_have_different_names(prequel@ast:module_()) -> list(prequel@error@validation_error:validation_error()).
check_all_relationships_have_different_names(Module) ->
_pipe = relationships_from_module(Module),
_pipe@1 = prequel@internals@extra@list:duplicates(
_pipe,
fun(Relationship) -> erlang:element(3, Relationship) end
),
prequel@internals@extra@list:map_pairs(
_pipe@1,
fun to_duplicate_relationship_error/2
).
-spec check_module(prequel@ast:module_()) -> list(prequel@error@validation_error:validation_error()).
check_module(Module) ->
_pipe = [fun check_cardinalities_bounds/1,
fun check_all_entities_have_different_names/1,
fun check_all_relationships_have_different_names/1],
gather_errors(_pipe, Module).