Files
mercury/compiler/module_deps_graph.m
Zoltan Somogyi d967f36545 Improve error messages about unexpected module names, again.
When you get this message, the error may be in the module name that it
reports to be wrong, but it may be in the places that set the compiler's
expectations of what the name of the module should be. This latter is
very likely the case when one moves a module of the Mercury compiler
from one package to another. In such cases, the problems are the old modules
that continue to refer to the renamed module by its old name.

This diff improves the error message by indicating *precisely* the locations
that refer to the old name, since these are the locations that establish the
expectation that is not met.

compiler/module_imports.m:
    Change the module_and_imports structure to record, for each imported
    or used module, and for each child module, the location of the relevant
    ":- import_module" or ":- include_module" declaration(s).

compiler/deps_map.m:
    When tracing references from module A to module B.C (either because
    A imports B.C, or because A = B and A includes C), record the location
    of the ":- import_module" or ":- include_module" declaration as a source
    of the expectation that any file that contains module C will have
    B.C as module C's fully qualified name. Since a module is usually imported
    by more than one other module, there may be several sources of such
    expectations.

compiler/parse_module.m:
    Change the wording of the error message to reflect the change in what
    the context denotes.

compiler/get_dependencies.m:
compiler/prog_item.m:
    When returning the sets of modules imported, used or included by some
    entities such as item blocks, return the contexts of those
    imports/uses/includes as well.

compiler/compile_target_code.m:
compiler/hlds_module.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make.program_target.m:
compiler/mercury_compile_main.m:
compiler/module_deps_graph.m:
compiler/module_qual.m:
compiler/modules.m:
compiler/write_deps_file.m:
    Conform to the changes above.

tests/invalid/bad_module_name.err_exp:
    Expect the updated error message.
2017-12-12 13:47:14 +11:00

150 lines
6.1 KiB
Mathematica

%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 2014 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: module_deps_graph.m.
%
% XXX document me.
% The contents of this module used to be in the old giant version of modules.m.
% If you want to understand it and clean it up, you will also want to look at
% deps_map.m, whose functionality seems to be quite related.
%
%-----------------------------------------------------------------------------%
:- module parse_tree.module_deps_graph.
:- interface.
:- import_module mdbcomp.
:- import_module mdbcomp.sym_name.
:- import_module parse_tree.module_imports.
:- import_module digraph.
%-----------------------------------------------------------------------------%
% (Module1 -> Module2) means Module1 is imported by Module2.
:- type deps_graph == digraph(module_name).
:- type lookup_module_and_imports == (func(module_name) = module_and_imports).
:- mode lookup_module_and_imports == in(func(in) = out is det).
:- pred add_module_and_imports_to_deps_graph(module_and_imports::in,
lookup_module_and_imports::lookup_module_and_imports,
deps_graph::in, deps_graph::out, deps_graph::in, deps_graph::out) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module list.
:- import_module multi_map.
:- import_module set.
:- type deps_graph_key == digraph_key(module_name).
%-----------------------------------------------------------------------------%
add_module_and_imports_to_deps_graph(ModuleImports, LookupModuleImports,
!IntDepsGraph, !ImpDepsGraph) :-
% Add interface dependencies to the interface deps graph.
%
% 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.
% XXX Actually, I (zs) think it is, because I suspect that after some
% source code changes, it can lead to the unnecessary recompilation
% of not just a few, but many modules.
ModuleName = ModuleImports ^ mai_module_name,
ParentDeps = ModuleImports ^ mai_parent_deps,
digraph.add_vertex(ModuleName, IntModuleKey, !IntDepsGraph),
add_int_deps(IntModuleKey, ModuleImports, !IntDepsGraph),
add_parent_imp_deps_set(LookupModuleImports, IntModuleKey, ParentDeps,
!IntDepsGraph),
% Add implementation dependencies to the implementation deps graph.
% (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.
digraph.add_vertex(ModuleName, ImpModuleKey, !ImpDepsGraph),
add_imp_deps(ImpModuleKey, ModuleImports, !ImpDepsGraph),
add_parent_imp_deps_set(LookupModuleImports, ImpModuleKey, ParentDeps,
!ImpDepsGraph).
% Add interface dependencies to the interface deps graph.
%
:- pred add_int_deps(deps_graph_key::in, module_and_imports::in,
deps_graph::in, deps_graph::out) is det.
add_int_deps(ModuleKey, ModuleImports, !DepsGraph) :-
AddDep = add_dep(ModuleKey),
set.fold(AddDep, ModuleImports ^ mai_parent_deps, !DepsGraph),
list.foldl(AddDep, multi_map.keys(ModuleImports ^ mai_int_deps),
!DepsGraph).
% Add direct implementation dependencies for a module to the
% implementation deps graph.
%
:- pred add_imp_deps(deps_graph_key::in, module_and_imports::in,
deps_graph::in, deps_graph::out) is det.
add_imp_deps(ModuleKey, ModuleImports, !DepsGraph) :-
% The implementation dependencies are a superset of the
% interface dependencies, so first we add the interface deps.
add_int_deps(ModuleKey, ModuleImports, !DepsGraph),
% then we add the impl deps
module_and_imports_get_imp_deps(ModuleImports, ImpDeps),
list.foldl(add_dep(ModuleKey), multi_map.keys(ImpDeps), !DepsGraph).
% Add parent implementation dependencies for the given Parent module
% to the implementation deps graph values for the given ModuleKey.
%
:- pred add_parent_imp_deps(
lookup_module_and_imports::lookup_module_and_imports,
deps_graph_key::in, module_name::in, deps_graph::in, deps_graph::out)
is det.
add_parent_imp_deps(LookupModuleImports, ModuleKey, Parent, !DepsGraph) :-
ParentModuleImports = LookupModuleImports(Parent),
add_imp_deps(ModuleKey, ParentModuleImports, !DepsGraph).
:- pred add_parent_imp_deps_set(
lookup_module_and_imports::lookup_module_and_imports,
deps_graph_key::in, set(module_name)::in, deps_graph::in, deps_graph::out)
is det.
add_parent_imp_deps_set(LookupModuleImports, ModuleKey, Parents,
!DepsGraph) :-
set.fold(add_parent_imp_deps(LookupModuleImports, ModuleKey), Parents,
!DepsGraph).
% Add a single dependency to a graph.
%
:- pred add_dep(digraph_key(T)::in, T::in, digraph(T)::in, digraph(T)::out)
is det.
add_dep(ModuleKey, Dep, !DepsGraph) :-
digraph.add_vertex(Dep, DepKey, !DepsGraph),
digraph.add_edge(ModuleKey, DepKey, !DepsGraph).
%-----------------------------------------------------------------------------%
:- end_module parse_tree.module_deps_graph.
%-----------------------------------------------------------------------------%