mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 18:03:36 +00:00
compiler/make.deps_cache.m:
Delete a field containing no information from the key of one of the
caches. Its future role of identifying the info associated with
the rest of the key can be handled more simply by using separate fields
in make_infos.
Several of the caches that this module looks after map the same type
of keys to the same type of values. Use a single type to describe
the type of all these caches, replacing several identical earlier types.
Name these types after their structure, not their purpuse.
compiler/make.make_info.m:
Put the caches with identical types next to each other.
Improve the names of the caches' getter and setter predicates,
making some shorter, and others more meaningful. (The diff makes
the same changes to the names of the search and update predicates
in make.deps_cache.m.)
compiler/make.dependencies.m:
compiler/make.find_local_modules.m:
Conform to the changes above.
253 lines
11 KiB
Mathematica
253 lines
11 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2023 The Mercury team.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% File: make.find_local_modules.m.
|
|
%
|
|
% This module contains code to find the modules in the current directory
|
|
% that are reachable from a given module.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module make.find_local_modules.
|
|
:- interface.
|
|
|
|
:- import_module libs.
|
|
:- import_module libs.globals.
|
|
:- import_module libs.maybe_util.
|
|
:- import_module make.deps_cache.
|
|
:- import_module make.deps_set.
|
|
:- import_module make.make_info.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.sym_name.
|
|
|
|
:- import_module io.
|
|
:- import_module set.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% Find all modules in the current directory which are reachable
|
|
% (by import or include) from the given module.
|
|
%
|
|
:- pred find_reachable_local_modules(io.text_output_stream::in, globals::in,
|
|
module_name::in, maybe_succeeded::out, set(module_name)::out,
|
|
make_info::in, make_info::out, io::di, io::uo) is det.
|
|
|
|
:- pred find_transitive_module_dependencies(io.text_output_stream::in,
|
|
globals::in, transitive_dependencies_type::in,
|
|
process_modules_where::in, module_index::in,
|
|
maybe_succeeded::out, deps_set(module_index)::out,
|
|
make_info::in, make_info::out, io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module make.get_module_dep_info.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.module_dep_info.
|
|
:- import_module parse_tree.prog_data_foreign.
|
|
|
|
:- import_module dir.
|
|
:- import_module list.
|
|
:- import_module maybe.
|
|
:- import_module require.
|
|
:- import_module sparse_bitset.
|
|
:- import_module string.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
find_reachable_local_modules(ProgressStream, Globals, ModuleName, Succeeded,
|
|
Modules, !Info, !IO) :-
|
|
module_name_to_index(ModuleName, ModuleIndex, !Info),
|
|
find_transitive_module_dependencies(ProgressStream, Globals,
|
|
all_dependencies, process_only_modules_in_cur_dir, ModuleIndex,
|
|
Succeeded, Modules0, !Info, !IO),
|
|
module_index_set_to_plain_set(!.Info, Modules0, Modules).
|
|
|
|
find_transitive_module_dependencies(ProgressStream, Globals, DependenciesType,
|
|
ProcessModulesWhere, ModuleIndex, Succeeded, Modules, !Info, !IO) :-
|
|
Key = trans_deps_key(ModuleIndex, DependenciesType, ProcessModulesWhere),
|
|
( if search_trans_deps_cache(!.Info, Key, Result0) then
|
|
Result0 = deps_result(Succeeded, Modules)
|
|
else
|
|
KeepGoing = make_info_get_keep_going(!.Info),
|
|
find_transitive_module_dependencies_uncached(ProgressStream, KeepGoing,
|
|
DependenciesType, ProcessModulesWhere, Globals, ModuleIndex,
|
|
Succeeded, deps_set_init, Modules, !Info, !IO),
|
|
Result = deps_result(Succeeded, Modules),
|
|
add_to_trans_deps_cache(Key, Result, !Info)
|
|
).
|
|
|
|
:- pred find_transitive_module_dependencies_uncached(io.text_output_stream::in,
|
|
maybe_keep_going::in, transitive_dependencies_type::in,
|
|
process_modules_where::in, globals::in,
|
|
module_index::in, maybe_succeeded::out,
|
|
deps_set(module_index)::in, deps_set(module_index)::out,
|
|
make_info::in, make_info::out, io::di, io::uo) is det.
|
|
|
|
find_transitive_module_dependencies_uncached(ProgressStream, KeepGoing,
|
|
DependenciesType, ProcessModulesWhere, Globals, ModuleIndex, Succeeded,
|
|
Modules0, Modules, !Info, !IO) :-
|
|
( if
|
|
deps_set_member(ModuleIndex, Modules0)
|
|
then
|
|
Succeeded = succeeded,
|
|
Modules = Modules0
|
|
else if
|
|
Key = trans_deps_key(ModuleIndex, DependenciesType,
|
|
ProcessModulesWhere),
|
|
search_trans_deps_cache(!.Info, Key, Result0)
|
|
then
|
|
Result0 = deps_result(Succeeded, Modules1),
|
|
deps_set_union(Modules0, Modules1, Modules)
|
|
else
|
|
module_index_to_name(!.Info, ModuleIndex, ModuleName),
|
|
get_maybe_module_dep_info(ProgressStream, Globals,
|
|
ModuleName, MaybeModuleDepInfo, !Info, !IO),
|
|
(
|
|
MaybeModuleDepInfo = some_module_dep_info(ModuleDepInfo),
|
|
module_dep_info_get_source_file_dir(ModuleDepInfo, ModuleDir),
|
|
( if
|
|
(
|
|
ProcessModulesWhere = process_modules_anywhere
|
|
;
|
|
ProcessModulesWhere = process_only_modules_in_cur_dir,
|
|
ModuleDir = dir.this_directory
|
|
)
|
|
then
|
|
% XXX MDNEW Pass ModuleDir to this call, and don't allow
|
|
% later searches to look in the part of the search path
|
|
% *before* ModuleDir.
|
|
do_find_transitive_module_dependencies_uncached(ProgressStream,
|
|
KeepGoing, DependenciesType, ProcessModulesWhere, Globals,
|
|
ModuleIndex, ModuleName, ModuleDepInfo, Succeeded,
|
|
Modules0, Modules, !Info, !IO)
|
|
else
|
|
Succeeded = succeeded,
|
|
Modules = Modules0
|
|
)
|
|
;
|
|
MaybeModuleDepInfo = no_module_dep_info,
|
|
Succeeded = did_not_succeed,
|
|
Modules = Modules0
|
|
)
|
|
).
|
|
|
|
:- pred do_find_transitive_module_dependencies_uncached(
|
|
io.text_output_stream::in, maybe_keep_going::in,
|
|
transitive_dependencies_type::in, process_modules_where::in, globals::in,
|
|
module_index::in, module_name::in, module_dep_info::in,
|
|
maybe_succeeded::out,
|
|
deps_set(module_index)::in, deps_set(module_index)::out,
|
|
make_info::in, make_info::out, io::di, io::uo) is det.
|
|
|
|
do_find_transitive_module_dependencies_uncached(ProgressStream, KeepGoing,
|
|
DependenciesType, ProcessModulesWhere, Globals,
|
|
ModuleIndex, ModuleName, ModuleDepInfo, Succeeded,
|
|
Modules0, Modules, !Info, !IO) :-
|
|
module_dep_info_get_fims(ModuleDepInfo, FIMSpecs),
|
|
module_dep_info_get_module_name(ModuleDepInfo, MDI_ModuleName),
|
|
expect(unify(ModuleName, MDI_ModuleName), $pred,
|
|
"ModuleName != MDI_ModuleName"),
|
|
module_dep_info_get_int_deps(ModuleDepInfo, IntDeps),
|
|
(
|
|
% Ancestors don't need to be considered here.
|
|
% Anywhere the interface of the child module is needed,
|
|
% the ancestors must also have been imported.
|
|
DependenciesType = interface_imports,
|
|
ImportsToCheck = IntDeps,
|
|
IncludesToCheck = set.init
|
|
;
|
|
( DependenciesType = all_dependencies
|
|
; DependenciesType = all_imports
|
|
),
|
|
Ancestors = get_ancestors_set(ModuleName),
|
|
module_dep_info_get_imp_deps(ModuleDepInfo, ImpDeps),
|
|
set.map((pred(fim_spec(_, Mod)::in, Mod::out) is det),
|
|
FIMSpecs, ForeignDeps),
|
|
ImportsToCheck =
|
|
set.union_list([Ancestors, IntDeps, ImpDeps, ForeignDeps]),
|
|
(
|
|
DependenciesType = all_dependencies,
|
|
module_dep_info_get_children(ModuleDepInfo, Children),
|
|
IncludesToCheck = Children
|
|
;
|
|
DependenciesType = all_imports,
|
|
IncludesToCheck = set.init
|
|
)
|
|
),
|
|
trace [
|
|
compile_time(flag("find_trans_deps")),
|
|
run_time(env("FIND_TRANS_DEPS")),
|
|
io(!TIO)
|
|
] (
|
|
PrintIndentedModuleName =
|
|
( pred(MN::in, TIO0::di, TIO::uo) is det :-
|
|
io.format(ProgressStream, " %s\n",
|
|
[s(sym_name_to_string(MN))], TIO0, TIO)
|
|
),
|
|
ModuleNameStr = sym_name_to_string(ModuleName),
|
|
io.format(ProgressStream, "imports by %s:\n",
|
|
[s(ModuleNameStr)], !TIO),
|
|
set.foldl(PrintIndentedModuleName, ImportsToCheck, !TIO),
|
|
io.format(ProgressStream, "includes by %s:\n",
|
|
[s(ModuleNameStr)], !TIO),
|
|
set.foldl(PrintIndentedModuleName, IncludesToCheck, !TIO),
|
|
io.nl(ProgressStream, !TIO)
|
|
),
|
|
module_names_to_index_set(set.to_sorted_list(ImportsToCheck),
|
|
ImportsToCheckSet, !Info),
|
|
module_names_to_index_set(set.to_sorted_list(IncludesToCheck),
|
|
IncludesToCheckSet, !Info),
|
|
deps_set_insert(ModuleIndex, Modules0, Modules1),
|
|
OldImportingModule = make_info_get_importing_module(!.Info),
|
|
make_info_set_importing_module(yes(ioi_import(ModuleName)), !Info),
|
|
acc_module_index_trans_deps(ProgressStream, KeepGoing,
|
|
DependenciesType, ProcessModulesWhere, Globals,
|
|
deps_set_to_sorted_list(ImportsToCheckSet),
|
|
succeeded, SucceededImports, Modules1, Modules2, !Info, !IO),
|
|
make_info_set_importing_module(yes(ioi_include(ModuleName)), !Info),
|
|
acc_module_index_trans_deps(ProgressStream, KeepGoing,
|
|
DependenciesType, ProcessModulesWhere, Globals,
|
|
deps_set_to_sorted_list(IncludesToCheckSet),
|
|
succeeded, SucceededIncludes, Modules2, Modules, !Info, !IO),
|
|
make_info_set_importing_module(OldImportingModule, !Info),
|
|
Succeeded = SucceededImports `and` SucceededIncludes.
|
|
|
|
:- pred acc_module_index_trans_deps(io.text_output_stream::in,
|
|
maybe_keep_going::in, transitive_dependencies_type::in,
|
|
process_modules_where::in, globals::in, list(module_index)::in,
|
|
maybe_succeeded::in, maybe_succeeded::out,
|
|
deps_set(module_index)::in, deps_set(module_index)::out,
|
|
make_info::in, make_info::out, io::di, io::uo) is det.
|
|
|
|
acc_module_index_trans_deps(_, _, _, _, _, [], !Succeeded, !Deps, !Info, !IO).
|
|
acc_module_index_trans_deps(ProgressStream, KeepGoing, DependenciesType,
|
|
ProcessModulesWhere, Globals, [HeadModuleIndex | TailModuleIndexes],
|
|
!Succeeded, !Deps, !Info, !IO) :-
|
|
find_transitive_module_dependencies_uncached(ProgressStream, KeepGoing,
|
|
DependenciesType, ProcessModulesWhere, Globals,
|
|
HeadModuleIndex, HeadSucceeded, !Deps, !Info, !IO),
|
|
( if
|
|
( HeadSucceeded = succeeded
|
|
; KeepGoing = do_keep_going
|
|
)
|
|
then
|
|
!:Succeeded = !.Succeeded `and` HeadSucceeded,
|
|
acc_module_index_trans_deps(ProgressStream, KeepGoing,
|
|
DependenciesType, ProcessModulesWhere, Globals,
|
|
TailModuleIndexes, !Succeeded, !Deps, !Info, !IO)
|
|
else
|
|
!:Succeeded = did_not_succeed
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module make.find_local_modules.
|
|
%---------------------------------------------------------------------------%
|