diff: modules.m: nested modules bug fixes
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Jul 10 08:01:49 AEST 1998
Estimated hours taken: 4
compiler/modules.m:
Fix a couple of bugs in the computation of dependencies
for the `--generate-dependencies' option:
(1) it wasn't handling the case where the top-level file named
on the command line contained nested modules
(2) it wasn't including the parent module's dependencies in the
dependencies for child modules.
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.81
diff -u -r1.81 modules.m
--- modules.m 1998/07/01 04:09:39 1.81
+++ modules.m 1998/07/09 21:10:39
@@ -187,6 +187,21 @@
% The `module_imports' structure holds information about
% a module and the modules that it imports.
+% Note that we build this structure up as we go along.
+% When generating the dependencies (for `--generate-dependencies'),
+% the two fields that hold the direct imports do not include
+% the imports via ancestors when the module is first read in;
+% the ancestor imports are added later, once all the modules
+% have been read in. Similarly the indirect imports field is
+% initially set to the empty list and filled in later.
+%
+% When compiling or when making interface files, the same
+% sort of thing applies: initially all the list(module_name) fields
+% except the public children field are set to empty lists,
+% and then we add ancestor modules and imported modules
+% to their respective lists as we process the interface files
+% for those imported or ancestor modules.
+
:- type module_imports --->
module_imports(
file_name, % The source file
@@ -217,6 +232,9 @@
:- pred module_imports_get_module_name(module_imports, module_name).
:- mode module_imports_get_module_name(in, out) is det.
+:- pred module_imports_get_impl_deps(module_imports, list(module_name)).
+:- mode module_imports_get_impl_deps(in, out) is det.
+
:- pred module_imports_get_items(module_imports, item_list).
:- mode module_imports_get_items(in, out) is det.
@@ -229,6 +247,17 @@
:- pred module_imports_set_error(module_imports, module_error, module_imports).
:- mode module_imports_set_error(in, in, out) is det.
+% set the interface dependencies
+:- pred module_imports_set_int_deps(module_imports, list(module_name),
+ module_imports).
+:- mode module_imports_set_int_deps(in, in, out) is det.
+
+% set the implementation dependencies
+:- pred module_imports_set_impl_deps(module_imports, list(module_name),
+ module_imports).
+:- mode module_imports_set_impl_deps(in, in, out) is det.
+
+% set the indirect dependencies
:- pred module_imports_set_indirect_deps(module_imports, list(module_name),
module_imports).
:- mode module_imports_set_indirect_deps(in, in, out) is det.
@@ -1068,6 +1097,9 @@
module_imports_get_module_name(Module, ModuleName) :-
Module = module_imports(_, ModuleName, _, _, _, _, _, _, _, _).
+module_imports_get_impl_deps(Module, ImplDeps) :-
+ Module = module_imports(_, _, _, _, ImplDeps, _, _, _, _, _).
+
module_imports_get_items(Module, Items) :-
Module = module_imports(_, _, _, _, _, _, _, _, Items, _).
@@ -1082,6 +1114,14 @@
Module0 = module_imports(A, B, C, D, E, F, G, H, I, _),
Module = module_imports(A, B, C, D, E, F, G, H, I, Error).
+module_imports_set_int_deps(Module0, IntDeps, Module) :-
+ Module0 = module_imports(A, B, C, _, E, F, G, H, I, J),
+ Module = module_imports(A, B, C, IntDeps, E, F, G, H, I, J).
+
+module_imports_set_impl_deps(Module0, ImplDeps, Module) :-
+ Module0 = module_imports(A, B, C, D, _, F, G, H, I, J),
+ Module = module_imports(A, B, C, D, ImplDeps, F, G, H, I, J).
+
module_imports_set_indirect_deps(Module0, IndirectDeps, Module) :-
Module0 = module_imports(A, B, C, D, E, _, G, H, I, J),
Module = module_imports(A, B, C, D, E, IndirectDeps, G, H, I, J).
@@ -1735,10 +1775,12 @@
read_mod_from_file(FileName, ".m", "Reading file", no,
Items, Error, ModuleName),
{ string__append(FileName, ".m", SourceFileName) },
- { init_dependencies(SourceFileName, Error, ModuleName - Items,
- ModuleImports) },
+ { split_into_submodules(ModuleName, Items, SubModuleList) },
+ { list__map(init_dependencies(SourceFileName, Error), SubModuleList,
+ ModuleImportsList) },
{ map__init(DepsMap0) },
- { insert_into_deps_map(ModuleImports, DepsMap0, DepsMap1) },
+ { list__foldl(insert_into_deps_map, ModuleImportsList,
+ DepsMap0, DepsMap1) },
generate_dependencies(ModuleName, DepsMap1).
:- pred generate_dependencies(module_name, deps_map, io__state, io__state).
@@ -1788,6 +1830,10 @@
get_opt_deps(yes, TransOptDepsOrdering0, IntermodDirs,
".trans_opt", TransOptDepsOrdering),
+ % { relation__to_assoc_list(ImplDepsRel, ImplDepsAL) },
+ % print("ImplDepsAL:\n"),
+ % write_list(ImplDepsAL, "\n", print), nl,
+
%
% compute the indirect dependencies: they are equal to the
% composition of the implementation dependencies
@@ -1797,7 +1843,8 @@
{ relation__compose(ImplDepsRel, TransIntDepsRel,
IndirectDepsRel) },
- generate_dependencies_write_d_files(DepsList, IndirectDepsRel,
+ generate_dependencies_write_d_files(DepsList,
+ IntDepsRel, ImplDepsRel, IndirectDepsRel,
TransOptDepsOrdering, DepsMap)
).
@@ -1846,27 +1893,27 @@
% TransOptOrder gives the ordering that is used to determine
% which other modules the .trans_opt files may depend on.
:- pred generate_dependencies_write_d_files(list(deps)::in,
- relation(module_name)::in, list(module_name)::in, deps_map::in,
- io__state::di, io__state::uo) is det.
-generate_dependencies_write_d_files([], _, _TransOptOrder, _DepsMap) --> [].
+ deps_rel::in, deps_rel::in, deps_rel::in, list(module_name)::in,
+ deps_map::in, io__state::di, io__state::uo) is det.
+generate_dependencies_write_d_files([], _, _, _, _, _) --> [].
generate_dependencies_write_d_files([Dep | Deps],
- IndirectDepsRel0, TransOptOrder, DepsMap) -->
+ IntDepsRel, ImplDepsRel, IndirectDepsRel,
+ TransOptOrder, DepsMap) -->
{ Dep = deps(_, Module0) },
%
- % Look up the indirect dependencies for this module
- % from the indirect dependencies relation, and save
- % them in the module_imports structure.
+ % Look up the interface/implementation/indirect dependencies
+ % for this module from the respective dependency relations,
+ % and save them in the module_imports structure.
%
{ module_imports_get_module_name(Module0, ModuleName) },
- { relation__add_element(IndirectDepsRel0, ModuleName, ModuleKey,
- IndirectDepsRel) },
- { relation__lookup_from(IndirectDepsRel, ModuleKey,
- IndirectDepsKeysSet) },
- { set__to_sorted_list(IndirectDepsKeysSet, IndirectDepsKeys) },
- { list__map(relation__lookup_key(IndirectDepsRel), IndirectDepsKeys,
- IndirectDeps) },
- { module_imports_set_indirect_deps(Module0, IndirectDeps, Module) },
+ { get_dependencies_from_relation(IntDepsRel, ModuleName, IntDeps) },
+ { get_dependencies_from_relation(ImplDepsRel, ModuleName, ImplDeps) },
+ { get_dependencies_from_relation(IndirectDepsRel, ModuleName,
+ IndirectDeps) },
+ { module_imports_set_int_deps(Module0, IntDeps, Module1) },
+ { module_imports_set_impl_deps(Module1, ImplDeps, Module2) },
+ { module_imports_set_indirect_deps(Module2, IndirectDeps, Module) },
%
% Compute the trans-opt dependencies for this module.
@@ -1894,9 +1941,20 @@
;
[]
),
- generate_dependencies_write_d_files(Deps, IndirectDepsRel,
+ generate_dependencies_write_d_files(Deps,
+ IntDepsRel, ImplDepsRel, IndirectDepsRel,
TransOptOrder, DepsMap).
+:- pred get_dependencies_from_relation(deps_rel, module_name,
+ list(module_name)).
+:- mode get_dependencies_from_relation(in, in, out) is det.
+
+get_dependencies_from_relation(DepsRel0, ModuleName, Deps) :-
+ relation__add_element(DepsRel0, ModuleName, ModuleKey, DepsRel),
+ relation__lookup_from(DepsRel, ModuleKey, DepsKeysSet),
+ set__to_sorted_list(DepsKeysSet, DepsKeys),
+ list__map(relation__lookup_key(DepsRel), DepsKeys, Deps).
+
% This is the data structure we use to record the dependencies.
% We keep a map from module name to information about the module.
@@ -1952,34 +2010,95 @@
IntRel0, IntRel, ImplRel0, ImplRel) :-
Deps = deps(_, ModuleImports),
ModuleImports = module_imports(_FileName, ModuleName,
- ParentDeps, IntDeps, ImplDeps,
- _IndirectDeps, PublicChildren, _FactDeps, _Items, ModuleError),
+ ParentDeps, _IntDeps, _ImplDeps,
+ _IndirectDeps, _PublicChildren, _FactDeps, _Items, ModuleError),
( ModuleError \= fatal ->
- % add interface dependencies to the interface deps relation
+ %
+ % Add interface dependencies to the interface deps relation.
+ %
+ % Note that we need to do this both for the interface imports
+ % of this module and for the *implementation* imports of
+ % its ancestors. This is because if this module is defined
+ % in the implementation section of its parent, then the
+ % interface of this module may depend on things
+ % imported only by its parent's implementation.
+ %
+ % If this module was actually defined in the interface
+ % section of one of its ancestors, then it should only
+ % depend on the interface imports of that ancestor,
+ % so the dependencies added here are in fact more
+ % conservative than they need to be in that case.
+ % However, that should not be a major problem.
+ %
relation__add_element(IntRel0, ModuleName, IntModuleKey,
IntRel1),
- AddIntDep = add_dep(IntModuleKey),
- list__foldl(AddIntDep, ParentDeps, IntRel1, IntRel2),
- list__foldl(AddIntDep, IntDeps, IntRel2, IntRel3),
- list__foldl(AddIntDep, PublicChildren, IntRel3, IntRel4),
-
- % add implementation dependencies to the impl. deps relation
- % (the implementation dependencies are a superset of the
- % interface dependencies)
+ add_int_deps(IntModuleKey, ModuleImports, IntRel1, IntRel2),
+ list__foldl(add_parent_impl_deps(DepsMap, IntModuleKey),
+ ParentDeps, IntRel2, IntRel3),
+
+ %
+ % Add implementation dependencies to the impl. deps relation.
+ % (The implementation dependencies are a superset of the
+ % interface dependencies.)
+ %
+ % Note that we need to do this both for the imports
+ % of this module and for the imports of its parents,
+ % because this module may depend on things imported
+ % only by its parents.
+ %
relation__add_element(ImplRel0, ModuleName, ImplModuleKey,
ImplRel1),
- AddImplDep = add_dep(ImplModuleKey),
- list__foldl(AddImplDep, ParentDeps, ImplRel1, ImplRel2),
- list__foldl(AddImplDep, IntDeps, ImplRel2, ImplRel3),
- list__foldl(AddImplDep, PublicChildren, ImplRel3, ImplRel4),
- list__foldl(AddImplDep, ImplDeps, ImplRel4, ImplRel5)
+ add_impl_deps(ImplModuleKey, ModuleImports, ImplRel1, ImplRel2),
+ list__foldl(add_parent_impl_deps(DepsMap, ImplModuleKey),
+ ParentDeps, ImplRel2, ImplRel3)
;
- IntRel4 = IntRel0,
- ImplRel5 = ImplRel0
+ IntRel3 = IntRel0,
+ ImplRel3 = ImplRel0
),
deps_list_to_deps_rel(DepsList, DepsMap,
- IntRel4, IntRel, ImplRel5, ImplRel).
+ IntRel3, IntRel, ImplRel3, ImplRel).
+
+% add interface dependencies to the interface deps relation
+%
+:- pred add_int_deps(relation_key, module_imports, deps_rel, deps_rel).
+:- mode add_int_deps(in, in, in, out) is det.
+
+add_int_deps(ModuleKey, ModuleImports, Rel0, Rel) :-
+ ModuleImports = module_imports(_FileName, _ModuleName,
+ ParentDeps, IntDeps, _ImplDeps, _IndirectDeps, PublicChildren,
+ _FactDeps, _Items, _ModuleError),
+ AddDep = add_dep(ModuleKey),
+ list__foldl(AddDep, ParentDeps, Rel0, Rel1),
+ list__foldl(AddDep, IntDeps, Rel1, Rel2),
+ list__foldl(AddDep, PublicChildren, Rel2, Rel).
+% add direct implementation dependencies for a module to the
+% impl. deps relation
+%
+:- pred add_impl_deps(relation_key, module_imports, deps_rel, deps_rel).
+:- mode add_impl_deps(in, in, in, out) is det.
+
+add_impl_deps(ModuleKey, ModuleImports, Rel0, Rel) :-
+ % the implementation dependencies are a superset of the
+ % interface dependencies, so first we add the interface deps
+ add_int_deps(ModuleKey, ModuleImports, Rel0, Rel1),
+ % then we add the impl deps
+ module_imports_get_impl_deps(ModuleImports, ImplDeps),
+ list__foldl(add_dep(ModuleKey), ImplDeps, Rel1, Rel).
+
+% add parent implementation dependencies for the given Parent module
+% to the impl. deps relation values for the given ModuleKey.
+%
+:- pred add_parent_impl_deps(deps_map, relation_key, module_name,
+ deps_rel, deps_rel).
+:- mode add_parent_impl_deps(in, in, in, in, out) is det.
+
+add_parent_impl_deps(DepsMap, ModuleKey, Parent, Rel0, Rel) :-
+ map__lookup(DepsMap, Parent, deps(_, ParentModuleImports)),
+ add_impl_deps(ModuleKey, ParentModuleImports, Rel0, Rel).
+
+% add a single dependency to a relation
+%
:- pred add_dep(relation_key, T, relation(T), relation(T)).
:- mode add_dep(in, in, in, out) is det.
@@ -1988,6 +2107,7 @@
relation__add(Relation1, ModuleRelKey, DepRelKey, Relation).
%-----------------------------------------------------------------------------%
+
% Write out the `.dep' file, using the information collected in the
% deps_map data structure.
:- pred generate_dependencies_write_dep_file(file_name::in, module_name::in,
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list