mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 18:03:36 +00:00
compiler/error_spec.m:
This new module contains the part of the old error_util.m that defines
the error_spec type, and some functions that can help construct pieces
of error_specs. Most modules of the compiler that deal with errors
will need to import only this part of the old error_util.m.
This change also renames the format_component type to format_piece,
which matches our long-standing naming convention for variables containing
(lists of) values of this type.
compiler/write_error_spec.m:
This new module contains the part of the old error_util.m that
writes out error specs, and converts them to strings.
This diff marks as obsolete the versions of predicates that
write out error specs to the current output stream, without
*explicitly* specifying the intended stream.
compiler/error_sort.m:
This new module contains the part of the old error_util.m that
sorts lists of error specs and error msgs.
compiler/error_type_util.m:
This new module contains the part of the old error_util.m that
convert types to format_pieces that generate readable output.
compiler/parse_tree.m:
compiler/notes/compiler_design.html:
Include and document the new modules.
compiler/error_util.m:
The code remaining in the original error_util.m consists of
general utility predicates and functions that don't fit into
any of the modules above.
Delete an unneeded pair of I/O states from the argument list
of a predicate.
compiler/file_util.m:
Move the unable_to_open_file predicate here from error_util.m,
since it belongs here. Mark another predicate that writes
to the current output stream as obsolete.
compiler/hlds_error_util.m:
Mark two predicates that wrote out error_spec to the current output
stream as obsolete, and add versions that take an explicit output stream.
compiler/Mercury.options:
Compile the modules that call the newly obsoleted predicates
with --no-warn-obsolete, for the time being.
compiler/*.m:
Conform to the changes above, mostly by updating import_module
declarations, and renaming format_component to format_piece.
173 lines
6.9 KiB
Mathematica
173 lines
6.9 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2015-2011 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: check_module_interface.m.
|
|
%
|
|
% Check whether the interface of a module exports anything.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module parse_tree.check_module_interface.
|
|
:- interface.
|
|
|
|
:- import_module libs.
|
|
:- import_module libs.globals.
|
|
:- import_module parse_tree.error_spec.
|
|
:- import_module parse_tree.prog_item.
|
|
|
|
:- import_module list.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% Given a module's source code, check whether its interface
|
|
% exports anything. If it does not, and --warn-nothing-exported is set,
|
|
% report a warning.
|
|
%
|
|
:- pred check_module_interface_for_no_exports(globals::in,
|
|
parse_tree_module_src::in,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module libs.options.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.item_util.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module bool.
|
|
:- import_module map.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
check_module_interface_for_no_exports(Globals, ParseTreeModuleSrc, !Specs) :-
|
|
globals.lookup_bool_option(Globals, warn_nothing_exported, ExportWarning),
|
|
(
|
|
ExportWarning = no
|
|
;
|
|
ExportWarning = yes,
|
|
ParseTreeModuleSrc = parse_tree_module_src(ModuleName,
|
|
ModuleNameContext, IntIncls, _ImpIncls, _InclMap,
|
|
_IntImports, _IntUses, _ImpImports, _ImpUses, _ImportUseMap,
|
|
_IntFIMs, _ImpFIMs, _IntSelfFIMLangs, _ImpSelfFIMLangs,
|
|
|
|
TypeCtorCheckedMap, InstCtorCheckedMap, ModeCtorCheckedMap,
|
|
TypeSpecs, InstModeSpecs,
|
|
|
|
IntTypeClasses, IntInstances, IntPredDecls, IntModeDecls,
|
|
IntDeclPragmas, IntPromises, _IntBadClauses,
|
|
|
|
_ImpTypeClasses, _ImpInstances, _ImpPredDecls, _ImpModeDecls,
|
|
_ImpClauses, _ImpForeignExportEnums,
|
|
_ImpDeclPragmas, _ImpImplPragmas, _ImpPromises,
|
|
_ImpInitialises, _ImpFinalises, _ImpMutables),
|
|
map.count(IntIncls, NumIntIncls),
|
|
( if
|
|
( NumIntIncls = 0
|
|
; NumIntIncls = 1
|
|
),
|
|
type_ctor_checked_map_get_src_defns(TypeCtorCheckedMap,
|
|
IntTypeDefns, _, _),
|
|
IntTypeDefns = [],
|
|
inst_ctor_checked_map_get_src_defns(InstCtorCheckedMap,
|
|
IntInstDefns, _),
|
|
IntInstDefns = [],
|
|
mode_ctor_checked_map_get_src_defns(ModeCtorCheckedMap,
|
|
IntModeDefns, _),
|
|
IntModeDefns = [],
|
|
|
|
% If some type, inst or mode definitions were invalid, then
|
|
% there are two possibilities: either some of them are in
|
|
% the interface section, or none of them are. Unfortunately,
|
|
% we don't know which is the case, so must choose an algorithm
|
|
% that works in both cases.
|
|
%
|
|
% - If some of the errors are in the interface section, then
|
|
% generating a "no exports" warning would be misleading.
|
|
%
|
|
% - If all of the errors are in the implementation section, then
|
|
% generating that warning would not be misleading, but
|
|
% it is also not quite needed. Due to those errors,
|
|
% the compilation will fail, with error messages that the
|
|
% programmer can and should fix, whether we generate
|
|
% a "no exports" warning or not. This means that the warning
|
|
% is not really needed *now*; it can be generated later,
|
|
% once the complained-about invalid definitions are fixed.
|
|
TypeSpecs = [],
|
|
InstModeSpecs = [],
|
|
|
|
IntTypeClasses = [],
|
|
IntInstances = [],
|
|
IntPredDecls = [],
|
|
IntModeDecls = [],
|
|
IntDeclPragmas = [],
|
|
IntPromises = []
|
|
then
|
|
generate_no_exports_warning(ModuleName, ModuleNameContext,
|
|
NumIntIncls, !Specs)
|
|
else
|
|
true
|
|
)
|
|
).
|
|
|
|
:- inst num_int_incls for int/0
|
|
---> 0
|
|
; 1.
|
|
|
|
:- pred generate_no_exports_warning(module_name::in, prog_context::in,
|
|
int::in(num_int_incls),
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
generate_no_exports_warning(ModuleName, Context, NumIntIncls, !Specs) :-
|
|
MainMsg = simple_msg(Context,
|
|
[always([invis_order_default_start(2),
|
|
words("Warning: the interface of module"),
|
|
qual_sym_name(ModuleName),
|
|
words("does not export anything."), nl]),
|
|
% We don't list mode declarations because they don't make sense
|
|
% without a corresponding pred or func declaration.
|
|
% We don't list decl pragmas for the same reason.
|
|
% We don't list promises because although they don't *have to be*
|
|
% about predicates and functions defined in the same module,
|
|
% they *should be*.
|
|
verbose_only(verbose_always,
|
|
[words("To be useful, a module should export something."),
|
|
words("A file should contain at least one declaration"),
|
|
words("other than"), decl("import_module"),
|
|
words("in its interface section(s)."),
|
|
words("This would normally be a"), decl("pred"), words("or"),
|
|
decl("func"), words("declaration, or a"),
|
|
decl("type"), suffix(","), decl("inst"), suffix(","),
|
|
decl("mode"), suffix(","), decl("typeclass"), words("or"),
|
|
decl("instance"), words("definition."), nl]
|
|
)]),
|
|
(
|
|
NumIntIncls = 0,
|
|
Msgs = [MainMsg]
|
|
;
|
|
NumIntIncls = 1,
|
|
InclMsg = simple_msg(Context,
|
|
[verbose_only(verbose_always,
|
|
[words("A module that includes a single submodule"),
|
|
words("is not useful, because it can be replaced"),
|
|
words("by that submodule."), nl])
|
|
]),
|
|
Msgs = [MainMsg, InclMsg]
|
|
),
|
|
Spec = error_spec($pred, severity_warning, phase_term_to_parse_tree, Msgs),
|
|
!:Specs = [Spec | !.Specs].
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module parse_tree.check_module_interface.
|
|
%---------------------------------------------------------------------------%
|