-module(gleamdoc@index).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleamdoc/index.gleam").
-export([package_interface_paths/3, source_location/4]).
-export_type([section/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.
?MODULEDOC(" Local package-interface indexing and source-location discovery.\n").
-type section() :: normal | dependencies | dev_dependencies.
-file("src/gleamdoc/index.gleam", 870).
-spec file_result({ok, JIZ} | {error, simplifile:file_error()}, binary()) -> {ok,
JIZ} |
{error, binary()}.
file_result(Result, Context) ->
_pipe = Result,
gleam@result:map_error(
_pipe,
fun(Error) ->
<<<<Context/binary, ": "/utf8>>/binary,
(simplifile:describe_error(Error))/binary>>
end
).
-file("src/gleamdoc/index.gleam", 884).
-spec join3(binary(), binary(), binary()) -> binary().
join3(First, Second, Third) ->
filepath:join(filepath:join(First, Second), Third).
-file("src/gleamdoc/index.gleam", 888).
-spec join4(binary(), binary(), binary(), binary()) -> binary().
join4(First, Second, Third, Fourth) ->
_pipe = join3(First, Second, Third),
filepath:join(_pipe, Fourth).
-file("src/gleamdoc/index.gleam", 285).
-spec cleanup_staging(binary()) -> {ok, nil} | {error, binary()}.
cleanup_staging(Root) ->
Staging = join4(
Root,
<<"build"/utf8>>,
<<"gleamdoc"/utf8>>,
<<"staging"/utf8>>
),
_pipe = simplifile:delete_all([Staging]),
file_result(
_pipe,
<<"Could not remove staging directory "/utf8, Staging/binary>>
).
-file("src/gleamdoc/index.gleam", 544).
-spec fingerprint_path(binary()) -> binary().
fingerprint_path(Output) ->
<<Output/binary, ".fingerprint"/utf8>>.
-file("src/gleamdoc/index.gleam", 519).
-spec write_fingerprint(binary(), list(binary())) -> {ok, nil} |
{error, binary()}.
write_fingerprint(Output, Files) ->
gleam@result:'try'(
gleamdoc_ffi:interface_fingerprint(Files),
fun(Fingerprint) ->
_pipe = simplifile:write(fingerprint_path(Output), Fingerprint),
file_result(
_pipe,
<<"Could not write cache fingerprint for "/utf8, Output/binary>>
)
end
).
-file("src/gleamdoc/index.gleam", 880).
-spec file_error(binary(), simplifile:file_error()) -> binary().
file_error(Path, Error) ->
<<<<<<"Could not read "/utf8, Path/binary>>/binary, ": "/utf8>>/binary,
(simplifile:describe_error(Error))/binary>>.
-file("src/gleamdoc/index.gleam", 509).
-spec matching_files(binary(), fun((binary()) -> boolean())) -> {ok,
list(binary())} |
{error, binary()}.
matching_files(Directory, Matches) ->
case simplifile:get_files(Directory) of
{error, Error} ->
{error, file_error(Directory, Error)};
{ok, Paths} ->
{ok, gleam@list:filter(Paths, Matches)}
end.
-file("src/gleamdoc/index.gleam", 498).
-spec dependency_interface_files(binary()) -> {ok, list(binary())} |
{error, binary()}.
dependency_interface_files(Directory) ->
matching_files(Directory, fun(Path) -> case filepath:extension(Path) of
{ok, <<"gleam"/utf8>>} ->
true;
{ok, <<"toml"/utf8>>} ->
true;
_ ->
false
end end).
-file("src/gleamdoc/index.gleam", 476).
-spec write_dependency_fingerprint(binary(), binary()) -> {ok, nil} |
{error, binary()}.
write_dependency_fingerprint(Package_directory, Output) ->
gleam@result:'try'(
dependency_interface_files(Package_directory),
fun(Files) -> write_fingerprint(Output, Files) end
).
-file("src/gleamdoc/index.gleam", 442).
-spec create_symlink(binary(), binary()) -> {ok, nil} | {error, binary()}.
create_symlink(Target, Link) ->
_pipe = simplifile_erl:create_symlink(Target, Link),
file_result(_pipe, <<"Could not create symlink "/utf8, Link/binary>>).
-file("src/gleamdoc/index.gleam", 429).
-spec link_optional_directory(binary(), binary(), binary()) -> {ok, nil} |
{error, binary()}.
link_optional_directory(Package_directory, Stage, Name) ->
Source = filepath:join(Package_directory, Name),
case simplifile_erl:is_directory(Source) of
{ok, true} ->
create_symlink(Source, filepath:join(Stage, Name));
{ok, false} ->
{ok, nil};
{error, enoent} ->
{ok, nil};
{error, Error} ->
{error, file_error(Source, Error)}
end.
-file("src/gleamdoc/index.gleam", 403).
-spec remove_requirements_section(list(binary()), list(binary()), boolean()) -> list(binary()).
remove_requirements_section(Lines, Output, Keeping) ->
case Lines of
[] ->
Output;
[Line | Rest] ->
Trimmed = gleam@string:trim(Line),
case {Trimmed =:= <<"[requirements]"/utf8>>,
Keeping,
gleam_stdlib:string_starts_with(Trimmed, <<"["/utf8>>)} of
{true, _, _} ->
remove_requirements_section(Rest, Output, false);
{false, false, true} ->
remove_requirements_section(Rest, [Line | Output], true);
{false, false, false} ->
remove_requirements_section(Rest, Output, false);
{false, true, _} ->
remove_requirements_section(Rest, [Line | Output], true)
end
end.
-file("src/gleamdoc/index.gleam", 374).
-spec prepare_manifest(binary(), binary(), list({binary(), binary()})) -> {ok,
nil} |
{error, binary()}.
prepare_manifest(Source, Destination, Requirements) ->
gleam@result:'try'(
begin
_pipe = simplifile:read(Source),
file_result(_pipe, <<"Could not read "/utf8, Source/binary>>)
end,
fun(Manifest) ->
Packages = begin
_pipe@1 = Manifest,
_pipe@2 = gleam@string:split(_pipe@1, <<"\n"/utf8>>),
_pipe@3 = remove_requirements_section(_pipe@2, [], true),
_pipe@4 = lists:reverse(_pipe@3),
_pipe@5 = gleam@string:join(_pipe@4, <<"\n"/utf8>>),
gleam@string:trim_end(_pipe@5)
end,
Requirement_lines = begin
_pipe@6 = Requirements,
_pipe@7 = gleam@list:map(
_pipe@6,
fun(Requirement) ->
{Name, Constraint} = Requirement,
<<<<<<Name/binary, " = { version = "/utf8>>/binary,
Constraint/binary>>/binary,
" }"/utf8>>
end
),
gleam@string:join(_pipe@7, <<"\n"/utf8>>)
end,
_pipe@8 = simplifile:write(
Destination,
<<<<<<Packages/binary, "\n\n[requirements]\n"/utf8>>/binary,
Requirement_lines/binary>>/binary,
"\n"/utf8>>
),
file_result(
_pipe@8,
<<"Could not write "/utf8, Destination/binary>>
)
end
).
-file("src/gleamdoc/index.gleam", 355).
-spec dependency_requirement(binary()) -> gleam@option:option({binary(),
binary()}).
dependency_requirement(Line) ->
String_pattern@1 = case gleam@regexp:from_string(
<<"^\\s*([A-Za-z0-9_]+)\\s*=\\s*(\"[^\"]+\")"/utf8>>
) of
{ok, String_pattern} -> String_pattern;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"gleamdoc/index"/utf8>>,
function => <<"dependency_requirement"/utf8>>,
line => 356,
value => _assert_fail,
start => 10611,
'end' => 10710,
pattern_start => 10622,
pattern_end => 10640})
end,
Table_pattern@1 = case gleam@regexp:from_string(
<<"^\\s*([A-Za-z0-9_]+)\\s*=\\s*\\{.*version\\s*=\\s*(\"[^\"]+\")"/utf8>>
) of
{ok, Table_pattern} -> Table_pattern;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"gleamdoc/index"/utf8>>,
function => <<"dependency_requirement"/utf8>>,
line => 358,
value => _assert_fail@1,
start => 10713,
'end' => 10845,
pattern_start => 10724,
pattern_end => 10741})
end,
case gleam@regexp:scan(String_pattern@1, Line) of
[{match, _, [{some, Name}, {some, Constraint}]} | _] ->
{some, {Name, Constraint}};
_ ->
case gleam@regexp:scan(Table_pattern@1, Line) of
[{match, _, [{some, Name@1}, {some, Constraint@1}]} | _] ->
{some, {Name@1, Constraint@1}};
_ ->
none
end
end.
-file("src/gleamdoc/index.gleam", 310).
-spec filter_config(
list(binary()),
section(),
list(binary()),
list({binary(), binary()})
) -> {list(binary()), list({binary(), binary()})}.
filter_config(Lines, Section, Output, Requirements) ->
case Lines of
[] ->
{Output, Requirements};
[Line | Rest] ->
Trimmed = gleam@string:trim(Line),
case {Trimmed, Section} of
{<<"[dependencies]"/utf8>>, _} ->
filter_config(
Rest,
dependencies,
[Line | Output],
Requirements
);
{<<"[dev-dependencies]"/utf8>>, _} ->
filter_config(Rest, dev_dependencies, Output, Requirements);
{<<"[dev_dependencies]"/utf8>>, _} ->
filter_config(Rest, dev_dependencies, Output, Requirements);
{_, dev_dependencies} ->
case gleam_stdlib:string_starts_with(Trimmed, <<"["/utf8>>) of
true ->
filter_config(
Rest,
normal,
[Line | Output],
Requirements
);
false ->
filter_config(
Rest,
dev_dependencies,
Output,
Requirements
)
end;
{_, dependencies} ->
case gleam_stdlib:string_starts_with(Trimmed, <<"["/utf8>>) of
true ->
filter_config(
Rest,
normal,
[Line | Output],
Requirements
);
false ->
case dependency_requirement(Line) of
{some, Requirement} ->
filter_config(
Rest,
dependencies,
[Line | Output],
[Requirement | Requirements]
);
none ->
filter_config(
Rest,
dependencies,
[Line | Output],
Requirements
)
end
end;
{_, normal} ->
filter_config(Rest, normal, [Line | Output], Requirements)
end
end.
-file("src/gleamdoc/index.gleam", 291).
-spec prepare_config(binary(), binary()) -> {ok, list({binary(), binary()})} |
{error, binary()}.
prepare_config(Source, Destination) ->
gleam@result:'try'(
begin
_pipe = simplifile:read(Source),
file_result(_pipe, <<"Could not read "/utf8, Source/binary>>)
end,
fun(Config) ->
{Lines, Requirements} = filter_config(
gleam@string:split(Config, <<"\n"/utf8>>),
normal,
[],
[]
),
gleam@result:'try'(
begin
_pipe@3 = simplifile:write(
Destination,
begin
_pipe@1 = Lines,
_pipe@2 = lists:reverse(_pipe@1),
gleam@string:join(_pipe@2, <<"\n"/utf8>>)
end
),
file_result(
_pipe@3,
<<"Could not write "/utf8, Destination/binary>>
)
end,
fun(_) -> {ok, lists:reverse(Requirements)} end
)
end
).
-file("src/gleamdoc/index.gleam", 447).
-spec ensure_directory(binary()) -> {ok, nil} | {error, binary()}.
ensure_directory(Path) ->
_pipe = simplifile:create_directory_all(Path),
file_result(_pipe, <<"Could not create directory "/utf8, Path/binary>>).
-file("src/gleamdoc/index.gleam", 245).
-spec prepare_stage(binary(), binary(), binary()) -> {ok, binary()} |
{error, binary()}.
prepare_stage(Root, Package_directory, Name) ->
Stage = begin
_pipe = join4(
Root,
<<"build"/utf8>>,
<<"gleamdoc"/utf8>>,
<<"staging"/utf8>>
),
filepath:join(_pipe, Name)
end,
Build_directory = filepath:join(Stage, <<"build"/utf8>>),
gleam@result:'try'(
begin
_pipe@1 = simplifile:delete_all([Stage]),
file_result(
_pipe@1,
<<"Could not reset staging directory "/utf8, Stage/binary>>
)
end,
fun(_) ->
gleam@result:'try'(
ensure_directory(Build_directory),
fun(_) ->
gleam@result:'try'(
prepare_config(
filepath:join(
Package_directory,
<<"gleam.toml"/utf8>>
),
filepath:join(Stage, <<"gleam.toml"/utf8>>)
),
fun(Requirements) ->
gleam@result:'try'(
prepare_manifest(
filepath:join(
Root,
<<"manifest.toml"/utf8>>
),
filepath:join(
Stage,
<<"manifest.toml"/utf8>>
),
Requirements
),
fun(_) ->
gleam@result:'try'(
create_symlink(
filepath:join(
Package_directory,
<<"src"/utf8>>
),
filepath:join(Stage, <<"src"/utf8>>)
),
fun(_) ->
gleam@result:'try'(
create_symlink(
join3(
Root,
<<"build"/utf8>>,
<<"packages"/utf8>>
),
filepath:join(
Build_directory,
<<"packages"/utf8>>
)
),
fun(_) ->
gleam@result:'try'(
link_optional_directory(
Package_directory,
Stage,
<<"include"/utf8>>
),
fun(_) ->
gleam@result:'try'(
link_optional_directory(
Package_directory,
Stage,
<<"priv"/utf8>>
),
fun(_) ->
{ok, Stage}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src/gleamdoc/index.gleam", 548).
-spec stale_cache_message(binary()) -> binary().
stale_cache_message(Package) ->
<<<<"The package interface cache for "/utf8, Package/binary>>/binary,
" is missing or stale. Run `gleamdoc index` to refresh it."/utf8>>.
-file("src/gleamdoc/index.gleam", 528).
-spec cache_matches_fingerprint(binary(), list(binary())) -> {ok, boolean()} |
{error, binary()}.
cache_matches_fingerprint(Output, Files) ->
case {simplifile_erl:is_file(Output),
simplifile:read(fingerprint_path(Output))} of
{{ok, true}, {ok, Stored}} ->
gleam@result:'try'(
gleamdoc_ffi:interface_fingerprint(Files),
fun(Current) -> {ok, Stored =:= Current} end
);
{{ok, false}, _} ->
{ok, false};
{{error, enoent}, _} ->
{ok, false};
{_, {error, enoent}} ->
{ok, false};
{{error, Error}, _} ->
{error, file_error(Output, Error)};
{_, {error, Error@1}} ->
{error, file_error(fingerprint_path(Output), Error@1)}
end.
-file("src/gleamdoc/index.gleam", 460).
-spec cache_is_fresh(binary(), binary()) -> {ok, boolean()} | {error, binary()}.
cache_is_fresh(Output, Package_directory) ->
gleam@result:'try'(
dependency_interface_files(Package_directory),
fun(Files) -> cache_matches_fingerprint(Output, Files) end
).
-file("src/gleamdoc/index.gleam", 160).
-spec export_dependencies(
binary(),
binary(),
binary(),
list(binary()),
boolean(),
list(binary())
) -> {ok, list(binary())} | {error, binary()}.
export_dependencies(Root, Packages_directory, Cache, Names, Refresh, Outputs) ->
case Names of
[] ->
{ok, lists:reverse(Outputs)};
[Name | Rest] ->
Package_directory = filepath:join(Packages_directory, Name),
Config = filepath:join(Package_directory, <<"gleam.toml"/utf8>>),
Output = filepath:join(Cache, <<Name/binary, ".json"/utf8>>),
case simplifile_erl:is_file(Config) of
{error, enoent} ->
export_dependencies(
Root,
Packages_directory,
Cache,
Rest,
Refresh,
Outputs
);
{error, enotdir} ->
export_dependencies(
Root,
Packages_directory,
Cache,
Rest,
Refresh,
Outputs
);
{error, Error} ->
{error, file_error(Config, Error)};
{ok, false} ->
export_dependencies(
Root,
Packages_directory,
Cache,
Rest,
Refresh,
Outputs
);
{ok, true} ->
gleam@result:'try'(
ensure_directory(Cache),
fun(_) ->
gleam@result:'try'(
cache_is_fresh(Output, Package_directory),
fun(Fresh) -> case Fresh of
true ->
export_dependencies(
Root,
Packages_directory,
Cache,
Rest,
Refresh,
[Output | Outputs]
);
false when not Refresh ->
{error, stale_cache_message(Name)};
false ->
gleam@result:'try'(
prepare_stage(
Root,
Package_directory,
Name
),
fun(Stage) ->
Stage_output = filepath:join(
Stage,
<<"package-interface.json"/utf8>>
),
gleam@result:'try'(
begin
_pipe = gleamdoc_ffi:export_package_interface(
Stage,
Stage_output
),
gleam@result:map_error(
_pipe,
fun(Message) ->
<<<<<<"Failed to index "/utf8,
Name/binary>>/binary,
":\n"/utf8>>/binary,
Message/binary>>
end
)
end,
fun(_) ->
gleam@result:'try'(
begin
_pipe@1 = simplifile:copy_file(
Stage_output,
Output
),
file_result(
_pipe@1,
<<"Could not copy "/utf8,
Stage_output/binary>>
)
end,
fun(_) ->
gleam@result:'try'(
write_dependency_fingerprint(
Package_directory,
Output
),
fun(_) ->
export_dependencies(
Root,
Packages_directory,
Cache,
Rest,
Refresh,
[Output |
Outputs]
)
end
)
end
)
end
)
end
)
end end
)
end
)
end
end.
-file("src/gleamdoc/index.gleam", 148).
-spec package_name(binary()) -> gleam@option:option(binary()).
package_name(Config) ->
Pattern@1 = case gleam@regexp:compile(
<<"^name\\s*=\\s*\"([^\"]+)\""/utf8>>,
{options, false, true}
) of
{ok, Pattern} -> Pattern;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"gleamdoc/index"/utf8>>,
function => <<"package_name"/utf8>>,
line => 149,
value => _assert_fail,
start => 4145,
'end' => 4302,
pattern_start => 4156,
pattern_end => 4167})
end,
case gleam@regexp:scan(Pattern@1, Config) of
[{match, _, [{some, Name}]} | _] ->
{some, Name};
_ ->
none
end.
-file("src/gleamdoc/index.gleam", 140).
-spec is_current_package(binary(), binary()) -> {ok, boolean()} |
{error, binary()}.
is_current_package(Root, Package) ->
Config = filepath:join(Root, <<"gleam.toml"/utf8>>),
case simplifile:read(Config) of
{error, Error} ->
{error, file_error(Config, Error)};
{ok, Content} ->
{ok, package_name(Content) =:= {some, Package}}
end.
-file("src/gleamdoc/index.gleam", 133).
-spec select_packages(list(binary()), binary()) -> list(binary()).
select_packages(Names, Package) ->
case Package of
<<""/utf8>> ->
Names;
_ ->
gleam@list:filter(Names, fun(Name) -> Name =:= Package end)
end.
-file("src/gleamdoc/index.gleam", 63).
-spec dependency_interface_paths(
binary(),
binary(),
binary(),
boolean(),
list(binary())
) -> {ok, list(binary())} | {error, binary()}.
dependency_interface_paths(Root, Cache, Package, Refresh, Outputs) ->
Packages_directory = join3(Root, <<"build"/utf8>>, <<"packages"/utf8>>),
Indexing_result = case simplifile_erl:read_directory(Packages_directory) of
{error, enoent} ->
gleam@result:'try'(
is_current_package(Root, Package),
fun(Current_package) -> case {Package, Current_package} of
{<<""/utf8>>, _} ->
{ok, lists:reverse(Outputs)};
{_, true} ->
{ok, lists:reverse(Outputs)};
{_, false} ->
{error,
<<<<"Package `"/utf8, Package/binary>>/binary,
"` is not present in build/packages."/utf8>>}
end end
);
{error, Error} ->
{error, file_error(Packages_directory, Error)};
{ok, Names} ->
Selected = select_packages(Names, Package),
case {Package, Selected} of
{<<""/utf8>>, _} ->
export_dependencies(
Root,
Packages_directory,
filepath:join(Cache, <<"packages"/utf8>>),
gleam@list:sort(Selected, fun gleam@string:compare/2),
Refresh,
Outputs
);
{_, []} ->
gleam@result:'try'(
is_current_package(Root, Package),
fun(Current_package@1) -> case Current_package@1 of
true ->
{ok, lists:reverse(Outputs)};
false ->
{error,
<<<<"Package `"/utf8, Package/binary>>/binary,
"` is not present in build/packages."/utf8>>}
end end
);
{_, _} ->
export_dependencies(
Root,
Packages_directory,
filepath:join(Cache, <<"packages"/utf8>>),
Selected,
Refresh,
Outputs
)
end
end,
case {Refresh, Indexing_result} of
{false, _} ->
Indexing_result;
{true, {error, Message}} ->
case cleanup_staging(Root) of
{ok, nil} ->
{error, Message};
{error, Cleanup_message} ->
{error,
<<<<Message/binary,
"\nAdditionally, cleanup failed: "/utf8>>/binary,
Cleanup_message/binary>>}
end;
{true, {ok, Paths}} ->
case cleanup_staging(Root) of
{ok, nil} ->
{ok, Paths};
{error, Message@1} ->
{error, Message@1}
end
end.
-file("src/gleamdoc/index.gleam", 484).
-spec current_interface_files(binary()) -> {ok, list(binary())} |
{error, binary()}.
current_interface_files(Root) ->
Source_directory = filepath:join(Root, <<"src"/utf8>>),
gleam@result:'try'(
matching_files(
Source_directory,
fun(Path) -> filepath:extension(Path) =:= {ok, <<"gleam"/utf8>>} end
),
fun(Sources) ->
{ok,
[filepath:join(Root, <<"gleam.toml"/utf8>>),
filepath:join(Root, <<"manifest.toml"/utf8>>) |
Sources]}
end
).
-file("src/gleamdoc/index.gleam", 452).
-spec current_cache_is_fresh(binary(), binary()) -> {ok, boolean()} |
{error, binary()}.
current_cache_is_fresh(Output, Root) ->
gleam@result:'try'(
current_interface_files(Root),
fun(Files) -> cache_matches_fingerprint(Output, Files) end
).
-file("src/gleamdoc/index.gleam", 468).
-spec write_current_fingerprint(binary(), binary()) -> {ok, nil} |
{error, binary()}.
write_current_fingerprint(Root, Output) ->
gleam@result:'try'(
current_interface_files(Root),
fun(Files) -> write_fingerprint(Output, Files) end
).
-file("src/gleamdoc/index.gleam", 43).
-spec prepare_current_interface(binary(), binary(), boolean()) -> {ok, nil} |
{error, binary()}.
prepare_current_interface(Root, Output, Refresh) ->
case Refresh of
true ->
gleam@result:'try'(
gleamdoc_ffi:export_package_interface(Root, Output),
fun(_) -> write_current_fingerprint(Root, Output) end
);
false ->
gleam@result:'try'(
current_cache_is_fresh(Output, Root),
fun(Fresh) -> case Fresh of
true ->
{ok, nil};
false ->
{error,
stale_cache_message(<<"current project"/utf8>>)}
end end
)
end.
-file("src/gleamdoc/index.gleam", 22).
?DOC(" Returns package-interface cache paths, refreshing them when requested.\n").
-spec package_interface_paths(boolean(), binary(), boolean()) -> {ok,
list(binary())} |
{error, binary()}.
package_interface_paths(Dependencies, Package, Refresh) ->
gleam@result:'try'(
begin
_pipe = simplifile:current_directory(),
file_result(
_pipe,
<<"Could not determine the current directory"/utf8>>
)
end,
fun(Root) ->
Cache = join3(Root, <<"build"/utf8>>, <<"gleamdoc"/utf8>>),
Current_output = filepath:join(
Cache,
<<"package-interface.json"/utf8>>
),
gleam@result:'try'(
ensure_directory(Cache),
fun(_) ->
gleam@result:'try'(
prepare_current_interface(Root, Current_output, Refresh),
fun(_) -> case Dependencies of
false ->
{ok, [Current_output]};
true ->
dependency_interface_paths(
Root,
Cache,
Package,
Refresh,
[Current_output]
)
end end
)
end
)
end
).
-file("src/gleamdoc/index.gleam", 840).
-spec line_at_offset_graphemes(list(binary()), integer(), integer(), integer()) -> integer().
line_at_offset_graphemes(Graphemes, Offset, Current_offset, Line) ->
case Graphemes of
[] ->
Line;
_ when Current_offset >= Offset ->
Line;
[Grapheme | Rest] ->
line_at_offset_graphemes(
Rest,
Offset,
Current_offset + erlang:byte_size(Grapheme),
case Grapheme of
<<"\n"/utf8>> ->
Line + 1;
<<"\r\n"/utf8>> ->
Line + 1;
_ ->
Line
end
)
end.
-file("src/gleamdoc/index.gleam", 836).
-spec line_at_offset(binary(), integer()) -> integer().
line_at_offset(Source, Offset) ->
line_at_offset_graphemes(gleam@string:to_graphemes(Source), Offset, 0, 1).
-file("src/gleamdoc/index.gleam", 862).
-spec relative_path(binary(), binary()) -> binary().
relative_path(Root, Path) ->
Prefix = <<Root/binary, "/"/utf8>>,
case gleam_stdlib:string_starts_with(Path, Prefix) of
true ->
gleam_stdlib:string_remove_prefix(Path, Prefix);
false ->
Path
end.
-file("src/gleamdoc/index.gleam", 762).
-spec find_variant_token_offset(
list({glexer@token:token(), glexer:position()}),
binary(),
integer(),
integer(),
integer(),
integer()
) -> integer().
find_variant_token_offset(
Tokens,
Name,
Start,
End,
Brace_depth,
Parenthesis_depth
) ->
case Tokens of
[] ->
-1;
[{_, {position, Offset}} | Rest] when Offset < Start ->
find_variant_token_offset(
Rest,
Name,
Start,
End,
Brace_depth,
Parenthesis_depth
);
[{_, {position, Offset@1}} | _] when Offset@1 > End ->
-1;
[{Current, {position, Offset@2}} | Rest@1] ->
case Current of
{upper_name, Token_name} when ((Brace_depth =:= 1) andalso (Parenthesis_depth =:= 0)) andalso (Token_name =:= Name) ->
Offset@2;
left_brace ->
find_variant_token_offset(
Rest@1,
Name,
Start,
End,
Brace_depth + 1,
Parenthesis_depth
);
right_brace ->
find_variant_token_offset(
Rest@1,
Name,
Start,
End,
Brace_depth - 1,
Parenthesis_depth
);
left_paren ->
find_variant_token_offset(
Rest@1,
Name,
Start,
End,
Brace_depth,
Parenthesis_depth + 1
);
right_paren ->
find_variant_token_offset(
Rest@1,
Name,
Start,
End,
Brace_depth,
Parenthesis_depth - 1
);
_ ->
find_variant_token_offset(
Rest@1,
Name,
Start,
End,
Brace_depth,
Parenthesis_depth
)
end
end.
-file("src/gleamdoc/index.gleam", 754).
-spec variant_exists(list(glance:variant()), binary()) -> boolean().
variant_exists(Variants, Name) ->
case Variants of
[] ->
false;
[{variant, Variant_name, _, _} | Rest] ->
(Variant_name =:= Name) orelse variant_exists(Rest, Name)
end.
-file("src/gleamdoc/index.gleam", 738).
-spec find_custom_type_with_variant(
list(glance:definition(glance:custom_type())),
binary()
) -> gleam@option:option(glance:custom_type()).
find_custom_type_with_variant(Definitions, Name) ->
case Definitions of
[] ->
none;
[{definition, _, Custom_type} | Rest] ->
{custom_type, _, _, _, _, _, Variants} = Custom_type,
case variant_exists(Variants, Name) of
true ->
{some, Custom_type};
false ->
find_custom_type_with_variant(Rest, Name)
end
end.
-file("src/gleamdoc/index.gleam", 704).
-spec find_variant_offset(binary(), glance:module_(), binary()) -> integer().
find_variant_offset(Source, Module, Name) ->
{module, _, Custom_types, _, _, _} = Module,
case find_custom_type_with_variant(Custom_types, Name) of
none ->
-1;
{some, {custom_type, {span, Start, End}, _, _, _, _, _}} ->
_pipe = Source,
_pipe@1 = glexer:new(_pipe),
_pipe@2 = glexer:discard_whitespace(_pipe@1),
_pipe@3 = glexer:discard_comments(_pipe@2),
_pipe@4 = glexer:lex(_pipe@3),
find_variant_token_offset(_pipe@4, Name, Start, End, 0, 0)
end.
-file("src/gleamdoc/index.gleam", 680).
-spec find_type_alias_offset(
list(glance:definition(glance:type_alias())),
binary()
) -> integer().
find_type_alias_offset(Definitions, Name) ->
case Definitions of
[] ->
-1;
[{definition,
_,
{type_alias, {span, Start, _}, Definition_name, _, _, _}} |
Rest] ->
case Definition_name =:= Name of
true ->
Start;
false ->
find_type_alias_offset(Rest, Name)
end
end.
-file("src/gleamdoc/index.gleam", 722).
-spec find_custom_type(list(glance:definition(glance:custom_type())), binary()) -> gleam@option:option(glance:custom_type()).
find_custom_type(Definitions, Name) ->
case Definitions of
[] ->
none;
[{definition, _, Custom_type} | Rest] ->
{custom_type, _, Definition_name, _, _, _, _} = Custom_type,
case Definition_name =:= Name of
true ->
{some, Custom_type};
false ->
find_custom_type(Rest, Name)
end
end.
-file("src/gleamdoc/index.gleam", 672).
-spec find_type_offset(glance:module_(), binary()) -> integer().
find_type_offset(Module, Name) ->
{module, _, Custom_types, Type_aliases, _, _} = Module,
case find_custom_type(Custom_types, Name) of
{some, {custom_type, {span, Start, _}, _, _, _, _, _}} ->
Start;
none ->
find_type_alias_offset(Type_aliases, Name)
end.
-file("src/gleamdoc/index.gleam", 648).
-spec find_constant_offset(list(glance:definition(glance:constant())), binary()) -> integer().
find_constant_offset(Definitions, Name) ->
case Definitions of
[] ->
-1;
[{definition, _, {constant, {span, Start, _}, Definition_name, _, _, _}} |
Rest] ->
case Definition_name =:= Name of
true ->
Start;
false ->
find_constant_offset(Rest, Name)
end
end.
-file("src/gleamdoc/index.gleam", 624).
-spec find_function_offset(
list(glance:definition(glance:function_())),
binary()
) -> integer().
find_function_offset(Definitions, Name) ->
case Definitions of
[] ->
-1;
[{definition,
_,
{function, {span, Start, _}, Definition_name, _, _, _, _}} |
Rest] ->
case Definition_name =:= Name of
true ->
Start;
false ->
find_function_offset(Rest, Name)
end
end.
-file("src/gleamdoc/index.gleam", 608).
-spec declaration_offset(binary(), binary(), binary()) -> integer().
declaration_offset(Source, Kind, Name) ->
case {Kind, glance:module(Source)} of
{<<"module"/utf8>>, _} ->
0;
{_, {error, _}} ->
-1;
{<<"fn"/utf8>>, {ok, {module, _, _, _, _, Functions}}} ->
find_function_offset(Functions, Name);
{<<"const"/utf8>>, {ok, {module, _, _, _, Constants, _}}} ->
find_constant_offset(Constants, Name);
{<<"type"/utf8>>, {ok, Module}} ->
find_type_offset(Module, Name);
{<<"alias"/utf8>>, {ok, {module, _, _, Type_aliases, _, _}}} ->
find_type_alias_offset(Type_aliases, Name);
{<<"variant"/utf8>>, {ok, Module@1}} ->
find_variant_offset(Source, Module@1, Name);
{_, _} ->
-1
end.
-file("src/gleamdoc/index.gleam", 600).
-spec current_project_name(binary()) -> gleam@option:option(binary()).
current_project_name(Root) ->
Config = filepath:join(Root, <<"gleam.toml"/utf8>>),
case simplifile:read(Config) of
{ok, Content} ->
package_name(Content);
{error, _} ->
none
end.
-file("src/gleamdoc/index.gleam", 570).
-spec source_location_from(binary(), binary(), binary(), binary(), binary()) -> binary().
source_location_from(Root, Package, Module, Kind, Name) ->
Dependency = begin
_pipe = join3(Root, <<"build"/utf8>>, <<"packages"/utf8>>),
filepath:join(_pipe, Package)
end,
Source_root = case current_project_name(Root) =:= {some, Package} of
true ->
filepath:join(Root, <<"src"/utf8>>);
false ->
case simplifile_erl:is_directory(Dependency) of
{ok, true} ->
filepath:join(Dependency, <<"src"/utf8>>);
_ ->
<<""/utf8>>
end
end,
Path = filepath:join(Source_root, <<Module/binary, ".gleam"/utf8>>),
case simplifile:read(Path) of
{error, _} ->
<<""/utf8>>;
{ok, Source} ->
case declaration_offset(Source, Kind, Name) of
-1 ->
<<""/utf8>>;
Offset ->
<<<<(relative_path(Root, Path))/binary, ":"/utf8>>/binary,
(erlang:integer_to_binary(
line_at_offset(Source, Offset)
))/binary>>
end
end.
-file("src/gleamdoc/index.gleam", 558).
?DOC(
" Returns the source path and declaration line for an indexed entry.\n"
"\n"
" An empty string is returned when source metadata is unavailable. Source\n"
" locations are supplementary and do not make an otherwise valid lookup fail.\n"
).
-spec source_location(binary(), binary(), binary(), binary()) -> binary().
source_location(Package, Module, Kind, Name) ->
case simplifile:current_directory() of
{error, _} ->
<<""/utf8>>;
{ok, Root} ->
source_location_from(Root, Package, Module, Kind, Name)
end.