Current section
Files
Jump to
Current section
Files
src/builder@inspect.erl
-module(builder@inspect).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/builder/inspect.gleam").
-export([find_type_definition/3, is_prelude_type/3, find_attribute/2, filter_attributes/2]).
-export_type([type_definition/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 type_definition() :: {type_alias,
glance:definition(glance:type_alias()),
builder@module:module_()} |
{custom_type,
glance:definition(glance:custom_type()),
builder@module:module_()}.
-file("src/builder/inspect.gleam", 64).
-spec find_type_definition_in_import(
builder@context:build_context(),
binary(),
gleam@option:option(binary()),
builder@module:module_()
) -> {ok, type_definition()} | {error, nil}.
find_type_definition_in_import(Ctx, Type_name, Type_module_name, Module) ->
Import_ = begin
_pipe = erlang:element(5, Module),
gleam@list:find_map(_pipe, fun(X) -> case Type_module_name of
{some, Name} ->
Module_name@1 = case erlang:element(
4,
erlang:element(3, X)
) of
{some, Module_name} ->
case Module_name of
{named, Name@1} ->
Name@1;
{discarded, Name@2} ->
Name@2
end;
_ ->
filepath:base_name(
erlang:element(3, erlang:element(3, X))
)
end,
case Module_name@1 =:= Name of
true ->
{ok,
{erlang:element(3, erlang:element(3, X)),
Type_name}};
_ ->
{error, nil}
end;
none ->
case begin
_pipe@1 = erlang:element(5, erlang:element(3, X)),
gleam@list:find(
_pipe@1,
fun(X@1) -> case erlang:element(3, X@1) of
{some, Name@3} ->
Name@3 =:= Type_name;
_ ->
erlang:element(2, X@1) =:= Type_name
end end
)
end of
{ok, Unqualified_type} ->
{ok,
{erlang:element(3, erlang:element(3, X)),
erlang:element(2, Unqualified_type)}};
_ ->
{error, nil}
end
end end)
end,
case Import_ of
{ok, Import_@1} ->
case gleam_stdlib:map_get(
builder@context:modules(Ctx),
erlang:element(1, Import_@1)
) of
{ok, Module@1} ->
find_type_definition_do(
Ctx,
{named_type,
{span, 0, 0},
erlang:element(2, Import_@1),
none,
[]},
Module@1,
false
);
{error, _} ->
{error, nil}
end;
{error, _} ->
{error, nil}
end.
-file("src/builder/inspect.gleam", 25).
-spec find_type_definition_do(
builder@context:build_context(),
glance:type(),
builder@module:module_(),
boolean()
) -> {ok, type_definition()} | {error, nil}.
find_type_definition_do(Ctx, Type_, Module, Inspect_imports) ->
case Type_ of
{named_type, _, Name, Module_name, _} ->
case Module_name of
{some, _} ->
case Inspect_imports of
true ->
find_type_definition_in_import(
Ctx,
Name,
Module_name,
Module
);
_ ->
{error, nil}
end;
_ ->
Custom_type = begin
_pipe = erlang:element(6, Module),
gleam@list:find(
_pipe,
fun(X) ->
erlang:element(3, erlang:element(3, X)) =:= Name
end
)
end,
Type_alias = begin
_pipe@1 = erlang:element(7, Module),
gleam@list:find(
_pipe@1,
fun(X@1) ->
erlang:element(3, erlang:element(3, X@1)) =:= Name
end
)
end,
case {Custom_type, Type_alias} of
{{ok, Custom_type@1}, _} ->
{ok, {custom_type, Custom_type@1, Module}};
{_, {ok, Type_alias@1}} ->
{ok, {type_alias, Type_alias@1, Module}};
{_, _} ->
case Inspect_imports of
true ->
find_type_definition_in_import(
Ctx,
Name,
none,
Module
);
_ ->
{error, nil}
end
end
end;
_ ->
{error, nil}
end.
-file("src/builder/inspect.gleam", 17).
?DOC(
" Searches for the type definition in the current module and follows imports\n"
" to resolve qualified and unqualified type references.\n"
).
-spec find_type_definition(
builder@context:build_context(),
glance:type(),
builder@module:module_()
) -> {ok, type_definition()} | {error, nil}.
find_type_definition(Ctx, Type_, Module) ->
find_type_definition_do(Ctx, Type_, Module, true).
-file("src/builder/inspect.gleam", 134).
?DOC(
" Check if a type is a Gleam prelude type (built-in type)\n"
"\n"
" Returns True for types like Int, Float, Bool, String, Nil, BitArray, List,\n"
" Result, tuples, and functions that don't have custom definitions.\n"
).
-spec is_prelude_type(
builder@context:build_context(),
glance:type(),
builder@module:module_()
) -> boolean().
is_prelude_type(Ctx, Type_, Current_module) ->
case find_type_definition(Ctx, Type_, Current_module) of
{ok, _} ->
false;
_ ->
Check = fun(Name) -> case Name of
<<"Bool"/utf8>> ->
true;
<<"Int"/utf8>> ->
true;
<<"Float"/utf8>> ->
true;
<<"String"/utf8>> ->
true;
<<"Nil"/utf8>> ->
true;
<<"BitArray"/utf8>> ->
true;
<<"List"/utf8>> ->
true;
<<"Result"/utf8>> ->
true;
_ ->
false
end end,
case Type_ of
{tuple_type, _, _} ->
true;
{function_type, _, _, _} ->
true;
{named_type, _, Name@1, Module, _} ->
case Module of
{some, _} ->
false;
_ ->
Check(Name@1)
end;
{variable_type, _, Name@2} ->
Check(Name@2);
{hole_type, _, Name@3} ->
Check(Name@3)
end
end.
-file("src/builder/inspect.gleam", 174).
?DOC(
" Find a specific attribute by name in a definition\n"
"\n"
" Returns the attribute along with the definition it belongs to.\n"
).
-spec find_attribute(glance:definition(OCW), binary()) -> {ok,
{glance:attribute(), OCW}} |
{error, nil}.
find_attribute(Definition, Attribute_name) ->
gleam@list:find_map(
erlang:element(2, Definition),
fun(Attribute) ->
case erlang:element(2, Attribute) =:= Attribute_name of
true ->
{ok, {Attribute, erlang:element(3, Definition)}};
false ->
{error, nil}
end
end
).
-file("src/builder/inspect.gleam", 189).
?DOC(
" Filter a list of definitions to only those with a specific attribute\n"
"\n"
" Returns pairs of the matching attribute and its definition.\n"
).
-spec filter_attributes(list(glance:definition(ODA)), binary()) -> list({glance:attribute(),
ODA}).
filter_attributes(Definitions, Attribute_name) ->
gleam@list:filter_map(
Definitions,
fun(_capture) -> find_attribute(_capture, Attribute_name) end
).