Files
mercury/compiler/module_qual.m
Zoltan Somogyi 012751691c Rename some function symbols to avoid ambiguity.
compiler/module_qual.id_set.m:
    As above. Also give the affected type a better name.

compiler/module_qual.m:
compiler/module_qual.qual_errors.m:
compiler/module_qual.qualify_items.m:
    Conform to the change above.
2022-11-25 16:23:33 +11:00

792 lines
33 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1996-2012 The University of Melbourne.
% Copyright (C) 2015 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_qual.m.
% Main authors: stayl, fjh.
%
% The code in this module performs two tasks.
%
% - It checks for undefined types, typeclasses, insts and modes.
%
% - It module qualifies types, typeclasses, insts and modes within declaration
% items in the source code of the compilation unit. The heads of all
% declarations should be module qualified as they are read in by the parser;
% this module qualifies the bodies of those declarations.
%
% Note that we don't qualify the parts of the augmented compilation unit
% that derive from other modules' interface or optimization files, since
% those parts should be read in fully module qualified already.
%
% The algorithm we use does two passes over all the items in the compilation
% unit. The first pass records the set of modules, types, typeclasses, insts
% and modes that are visible in the compilation unit. The second uses this
% information to actually do this module's job.
%
% If any type, typeclass, inst or mode used in the module is not uniquely
% module qualifiable, i.e. if we either find zero matches for it, or we find
% two or more matches for it, we can generate an error message for it.
% We do so when we are module qualifying a compilation unit; we don't when
% we are qualifying the contents of an interface file.
%
% If the --warn-interface-imports option is set, we generate warnings about
% modules imported in the interface that are not used in the interface.
%
% Note that this module is NOT the only place in the compiler that does module
% qualification. The modes of lambda expressions are qualified in modes.m,
% and predicate and function names are qualified during typecheck, with
% the results recorded during the post_typecheck phase of the purity pass.
% This is because figuring out whether e.g. a call to predicate `p' calls
% module m1's predicate p or module m2's predicate p may require knowing
% the types of the arguments in the call.
%
% Since this module does not and cannot know about the module qualification
% of predicate names, function names and function symbols, it cannot figure out
% which modules are referred to in goals. The only goals that may appear
% in the interface section of a module are in promise declarations.
% If a promise goal contains any unqualified symbols, the second pass
% leaves the symbol unchanged, but since the eventual actual qualification
% of the symbol could refer to any of the modules imported in the interface,
% we consider them *all* of them to be "used".
%
% For the same reason (we don't know what modules predicate names,
% function names and function symbols in goals may refer to), this module
% cannot implement any equivalent of --warn-interface-imports that would
% report unnecessary imports in the *implementation* section of a module.
%
% If the --warn-unused-imports option is set, then unused_imports.m
% can generate all the warnings we would, but it can generate *better*
% messages, since unlike the code here, it can report that an imported module
% is unused *anywhere* in the module. However, even if --warn-unused-imports
% *is* set, the code in unused_imports.m won't be invoked if we stop
% compilation before its normal invocation time, due to e.g. type or more
% errors. What we should do is generate warnings here; print them if we
% stop before the unused_imports pass; throw them away if we *do* get to
% that pass. We don't (yet) do this.
%
%---------------------------------------------------------------------------%
:- module parse_tree.module_qual.
:- interface.
:- import_module libs.
:- import_module libs.globals.
:- import_module mdbcomp.
:- import_module mdbcomp.sym_name.
:- import_module parse_tree.error_spec.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_event.
:- import_module parse_tree.prog_item.
:- import_module recompilation.
:- import_module list.
:- import_module maybe.
%---------------------------------------------------------------------------%
:- type maybe_found_undef_type
---> did_not_find_undef_type
; found_undef_type.
:- type maybe_found_undef_inst
---> did_not_find_undef_inst
; found_undef_inst.
:- type maybe_found_undef_mode
---> did_not_find_undef_mode
; found_undef_mode.
:- type maybe_found_undef_typeclass
---> did_not_find_undef_typeclass
; found_undef_typeclass.
% module_qualify_aug_comp_unit(Globals, AugCompUnit0, AugCompUnit,
% EventSpecMap0, EventSpecMap, MaybeContext, EventSpecFileName, MQ_Info,
% UndefTypes, UndefInsts, UndefModes, UndefTypeClasses, !Specs):
%
% AugCompUnit is AugCompUnit0 with all items module qualified
% as much as possible; likewise for EventSpecMap0 and EventSpecMap.
%
% Errors in EventSpecMap0 will be reported as being for EventSpecFileName.
%
:- pred module_qualify_aug_comp_unit(globals::in,
aug_compilation_unit::in, aug_compilation_unit::out,
event_spec_map::in, event_spec_map::out, string::in, mq_info::out,
maybe_found_undef_type::out, maybe_found_undef_inst::out,
maybe_found_undef_mode::out, maybe_found_undef_typeclass::out,
list(error_spec)::in, list(error_spec)::out) is det.
:- pred module_qualify_aug_make_int_unit(globals::in,
aug_make_int_unit::in, aug_make_int_unit::out,
list(error_spec)::in, list(error_spec)::out) is det.
% module_qualify_parse_tree_int3(Globals, ParseTreeInt0, ParseTreeInt,
% !Specs):
%
% ParseTreeInt is ParseTreeInt0 with all items in the .int3 file
% module qualified as much as possible.
%
:- pred module_qualify_parse_tree_int3(globals::in,
parse_tree_int3::in, parse_tree_int3::out,
list(error_spec)::in, list(error_spec)::out) is det.
%---------------------------------------------------------------------------%
% When we process types, typeclasses, insts or modes, we need to know
% whether they occur in the interface of the current module. This is
% so that if we see e.g. m1.t1 in the interface, we can mark module m1
% as being used in the interface, so we can avoid generating a warning
% about m1 being unused in the interface.
%
:- type mq_in_interface
---> mq_not_used_in_interface
; mq_used_in_interface.
% This is called from make_hlds to qualify the mode of an argument
% of a lambda expression.
%
:- pred qualify_lambda_mode(mq_in_interface::in, prog_context::in,
mer_mode::in, mer_mode::out, mq_info::in, mq_info::out,
list(error_spec)::in, list(error_spec)::out) is det.
% This is called from make_hlds.m to qualify the modes in a
% clause mode annotation.
%
:- pred qualify_clause_mode_list(mq_in_interface::in, prog_context::in,
list(mer_mode)::in, list(mer_mode)::out, mq_info::in, mq_info::out,
list(error_spec)::in, list(error_spec)::out) is det.
% This is called from make_hlds to qualify an explicit type qualification.
%
:- pred qualify_type_qualification(mq_in_interface::in, prog_context::in,
mer_type::in, mer_type::out, mq_info::in, mq_info::out,
list(error_spec)::in, list(error_spec)::out) is det.
%---------------------------------------------------------------------------%
% The type partial_qualifier_info holds info need for computing which
% partial quantifiers are visible -- see get_partial_qualifiers/3.
%
:- type partial_qualifier_info.
:- pred mq_info_get_partial_qualifier_info(mq_info::in,
partial_qualifier_info::out) is det.
% Suppose we are processing a definition which defines the symbol
% foo.bar.baz.quux/1. Then we insert the following symbols
% into the symbol table:
% - if the current value of the NeedQual flag at this point
% is `may_be_unqualified',
% i.e. module `foo.bar.baz' was imported,
% then we insert the fully unqualified symbol quux/1;
% - if module `foo.bar.baz' occurs in the "imported" section,
% i.e. if module `foo.bar' was imported,
% then we insert the partially qualified symbol baz.quux/1;
% - if module `foo.bar' occurs in the "imported" section,
% i.e. if module `foo' was imported,
% then we insert the partially qualified symbol bar.baz.quux/1;
% - we always insert the fully qualified symbol foo.bar.baz.quux/1.
%
% The predicate `get_partial_qualifiers' returns all of the
% partial qualifiers for which we need to insert definitions,
% i.e. all the ones which are visible. For example,
% given as input `foo.bar.baz', it returns a list containing
% (1) `baz', iff `foo.bar' is imported, and
% (2) `bar.baz', iff `foo' is imported.
% Note that the caller will still need to handle the fully-qualified
% and fully-unqualified versions separately.
%
:- pred get_partial_qualifiers(mq_in_interface::in, module_name::in,
partial_qualifier_info::in, list(module_name)::out) is det.
%---------------------------------------------------------------------------%
% The type mq_info holds information needed for doing module qualification.
%
:- type mq_info.
:- type maybe_suppress_found_undef
---> do_not_suppress_found_undef
; suppress_found_undef.
:- pred mq_info_get_recompilation_info(mq_info::in,
maybe(recompilation_info)::out) is det.
:- pred mq_info_get_found_undef_type(mq_info::in,
maybe_found_undef_type::out) is det.
:- pred mq_info_get_found_undef_inst(mq_info::in,
maybe_found_undef_inst::out) is det.
:- pred mq_info_get_found_undef_mode(mq_info::in,
maybe_found_undef_mode::out) is det.
:- pred mq_info_get_found_undef_typeclass(mq_info::in,
maybe_found_undef_typeclass::out) is det.
:- pred mq_info_get_suppress_found_undef(mq_info::in,
maybe_suppress_found_undef::out) is det.
:- pred mq_info_set_recompilation_info(maybe(recompilation_info)::in,
mq_info::in, mq_info::out) is det.
:- pred mq_info_set_suppress_found_undef(maybe_suppress_found_undef::in,
mq_info::in, mq_info::out) is det.
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- implementation.
:- include_module parse_tree.module_qual.collect_mq_info.
:- include_module parse_tree.module_qual.id_set.
:- include_module parse_tree.module_qual.qual_errors.
:- include_module parse_tree.module_qual.qualify_items.
:- import_module libs.options.
:- import_module mdbcomp.builtin_modules.
:- import_module parse_tree.module_qual.collect_mq_info.
:- import_module parse_tree.module_qual.id_set.
:- import_module parse_tree.module_qual.qual_errors.
:- import_module parse_tree.module_qual.qualify_items.
:- import_module bool.
:- import_module io.
:- import_module map.
:- import_module one_or_more.
:- import_module pair.
:- import_module set.
%---------------------------------------------------------------------------%
module_qualify_aug_comp_unit(Globals, AugCompUnit0, AugCompUnit,
EventSpecMap0, EventSpecMap, EventSpecFileName, !:Info,
UndefTypes, UndefInsts, UndefModes, UndefTypeClasses, !Specs) :-
AugCompUnit0 = aug_compilation_unit(ParseTreeModuleSrc0,
AncestorIntSpecs, DirectInt1Specs, IndirectInt2Specs,
PlainOptSpecs, TransOptSpecs, IntForOptSpecs, TypeRepnSpecs,
ModuleVersionNumbers),
ModuleName = ParseTreeModuleSrc0 ^ ptms_module_name,
init_mq_info(Globals, ModuleName, should_report_errors, !:Info),
collect_mq_info_in_parse_tree_module_src(ParseTreeModuleSrc0, !Info),
list.foldl(collect_mq_info_in_ancestor_int_spec,
map.values(AncestorIntSpecs), !Info),
list.foldl(collect_mq_info_in_direct_int1_spec,
map.values(DirectInt1Specs), !Info),
module_qualify_parse_tree_module_src(
ParseTreeModuleSrc0, ParseTreeModuleSrc, !Info, !Specs),
AugCompUnit = aug_compilation_unit(ParseTreeModuleSrc,
AncestorIntSpecs, DirectInt1Specs, IndirectInt2Specs,
PlainOptSpecs, TransOptSpecs, IntForOptSpecs, TypeRepnSpecs,
ModuleVersionNumbers),
map.to_assoc_list(EventSpecMap0, EventSpecList0),
qualify_event_specs(mq_not_used_in_interface, EventSpecFileName,
EventSpecList0, EventSpecList, !Info, !Specs),
map.from_assoc_list(EventSpecList, EventSpecMap),
mq_info_get_found_undef_type(!.Info, UndefTypes),
mq_info_get_found_undef_inst(!.Info, UndefInsts),
mq_info_get_found_undef_mode(!.Info, UndefModes),
mq_info_get_found_undef_typeclass(!.Info, UndefTypeClasses),
maybe_report_qual_errors(Globals, !.Info, ModuleName, !Specs).
%---------------------%
module_qualify_aug_make_int_unit(Globals, AugMakeIntUnit0, AugMakeIntUnit,
!Specs) :-
AugMakeIntUnit0 = aug_make_int_unit(ParseTreeModuleSrc0,
AncestorInt0s, DirectInt3Specs, IndirectInt3Specs,
ModuleVersionNumbers),
some [!Info] (
ModuleName = ParseTreeModuleSrc0 ^ ptms_module_name,
init_mq_info(Globals, ModuleName, should_report_errors, !:Info),
collect_mq_info_in_parse_tree_module_src(ParseTreeModuleSrc0, !Info),
list.foldl(collect_mq_info_in_parse_tree_int0(rwi0_section),
map.values(AncestorInt0s), !Info),
list.foldl(collect_mq_info_in_direct_int3_spec,
map.values(DirectInt3Specs), !Info),
module_qualify_parse_tree_module_src(
ParseTreeModuleSrc0, ParseTreeModuleSrc, !Info, !Specs),
AugMakeIntUnit = aug_make_int_unit(ParseTreeModuleSrc,
AncestorInt0s, DirectInt3Specs, IndirectInt3Specs,
ModuleVersionNumbers),
maybe_report_qual_errors(Globals, !.Info, ModuleName, !Specs)
).
% Warn about any unused module imports in the interface.
% There is a special case involving type class instances that
% we need to handle here. Consider:
%
% :- module foo.
% :- interface.
%
% :- import_module bar.
% :- typeclass tc1(T) <= tc2(T).
% :- instance tc1(unit).
%
% where module bar exports the instance tc2(unit). We must import
% the module bar in the interface of the module foo in order for
% the superclass constraint on the instance tc1(unit) to be satisfied.
% However, at this stage of compilation we do not know that the
% instance tc2(unit) needs to be visible. (Knowing this would require
% a more extensive analysis of type classes and instances to be done
% in this module.)
%
% In order to prevent the import of the module bar being erroneously
% reported as unused, we make the conservative assumption that any
% imported module that exports a type class instance is used in
% the interface of the importing module, except if the importing
% module itself exports _no_ type class instances.
%
:- pred maybe_report_qual_errors(globals::in, mq_info::in, module_name::in,
list(error_spec)::in, list(error_spec)::out) is det.
maybe_report_qual_errors(Globals, Info, ModuleName, !Specs) :-
mq_info_get_as_yet_unused_interface_modules(Info, UnusedImportsMap0),
mq_info_get_exported_instances_flag(Info, ModuleExportsInstances),
(
ModuleExportsInstances = yes,
mq_info_get_imported_instance_modules(Info, InstanceImports),
map.delete_list(set.to_sorted_list(InstanceImports),
UnusedImportsMap0, UnusedImportsMap)
;
ModuleExportsInstances = no,
UnusedImportsMap = UnusedImportsMap0
),
globals.lookup_bool_option(Globals, warn_interface_imports,
WarnInterfaceImports),
(
WarnInterfaceImports = no
;
WarnInterfaceImports = yes,
map.to_assoc_list(UnusedImportsMap, UnusedImports),
list.foldl(warn_unused_interface_import(ModuleName), UnusedImports,
!Specs)
).
%---------------------%
module_qualify_parse_tree_int3(Globals, OrigParseTreeInt3, ParseTreeInt3,
!Specs) :-
ModuleName = OrigParseTreeInt3 ^ pti3_module_name,
init_mq_info(Globals, ModuleName, should_not_report_errors, Info0),
collect_mq_info_in_parse_tree_int3(int3_as_src, OrigParseTreeInt3,
Info0, Info1),
module_qualify_parse_tree_int3(OrigParseTreeInt3, ParseTreeInt3,
Info1, _Info, !Specs).
%---------------------------------------------------------------------------%
qualify_lambda_mode(InInt, Context, Mode0, Mode, !Info, !Specs) :-
ErrorContext = mqec_lambda_expr(Context),
qualify_mode(InInt, ErrorContext, Mode0, Mode, !Info, !Specs).
qualify_clause_mode_list(InInt, Context, Modes0, Modes, !Info, !Specs) :-
ErrorContext = mqec_clause_mode_annotation(Context),
qualify_mode_list(InInt, ErrorContext, Modes0, Modes, !Info, !Specs).
qualify_type_qualification(InInt, Context, Type0, Type, !Info, !Specs) :-
ErrorContext = mqec_type_qual(Context),
qualify_type(InInt, ErrorContext, Type0, Type, !Info, !Specs).
%---------------------------------------------------------------------------%
:- type partial_qualifier_info
---> partial_qualifier_info(module_id_set).
mq_info_get_partial_qualifier_info(MQInfo, QualifierInfo) :-
mq_info_get_modules(MQInfo, ModuleIdSet),
QualifierInfo = partial_qualifier_info(ModuleIdSet).
get_partial_qualifiers(InInt, ModuleName, PartialQualInfo,
PartialQualifiers) :-
PartialQualInfo = partial_qualifier_info(ModuleIdSet),
(
ModuleName = unqualified(_),
PartialQualifiers = []
;
ModuleName = qualified(Parent, Child),
get_partial_qualifiers_acc(InInt, Parent, unqualified(Child),
ModuleIdSet, [], PartialQualifiers)
).
:- pred get_partial_qualifiers_acc(mq_in_interface::in,
module_name::in, module_name::in, module_id_set::in,
list(module_name)::in, list(module_name)::out) is det.
get_partial_qualifiers_acc(InInt, ImplicitPart, ExplicitPart, ModuleIdSet,
!Qualifiers) :-
% If the ImplicitPart module was imported, rather than just being used,
% then insert the ExplicitPart module into the list of valid partial
% qualifiers.
( if
parent_module_is_imported(InInt, ImplicitPart,
ExplicitPart, ModuleIdSet)
then
!:Qualifiers = [ExplicitPart | !.Qualifiers]
else
true
),
% Recursively try to add the other possible partial qualifiers.
(
ImplicitPart = qualified(Parent, Child),
NextImplicitPart = Parent,
NextExplicitPart = add_outermost_qualifier(Child, ExplicitPart),
get_partial_qualifiers_acc(InInt, NextImplicitPart, NextExplicitPart,
ModuleIdSet, !Qualifiers)
;
ImplicitPart = unqualified(_)
).
%---------------------------------------------------------------------------%
%
% Utility predicates.
%
:- pred update_recompilation_info(
pred(recompilation_info, recompilation_info)::in(pred(in, out) is det),
mq_info::in, mq_info::out) is det.
update_recompilation_info(Pred, !Info) :-
mq_info_get_recompilation_info(!.Info, MaybeRecompInfo0),
(
MaybeRecompInfo0 = yes(RecompInfo0),
Pred(RecompInfo0, RecompInfo),
mq_info_set_recompilation_info(yes(RecompInfo), !Info)
;
MaybeRecompInfo0 = no
).
%---------------------%
% If the current item is in the interface, remove its module name from
% the list of modules not used in the interface, and if the module name
% is itself module-qualified, mark its ancestor modules as used as well.
%
:- pred mq_info_set_module_used(mq_in_interface::in, module_name::in,
mq_info::in, mq_info::out) is det.
mq_info_set_module_used(InInt, ModuleName, !Info) :-
(
InInt = mq_used_in_interface,
mq_info_get_as_yet_unused_interface_modules(!.Info, AsYetUnused0),
( if map.remove(ModuleName, _, AsYetUnused0, AsYetUnused) then
mq_info_set_as_yet_unused_interface_modules(AsYetUnused, !Info)
else
% ModuleName was not in AsYetUnused0.
true
),
(
ModuleName = qualified(ParentModule, _),
mq_info_set_module_used(InInt, ParentModule, !Info)
;
ModuleName = unqualified(_)
)
;
InInt = mq_not_used_in_interface
).
%---------------------------------------------------------------------------%
%
% Access and initialisation predicates.
%
:- type maybe_should_report_errors
---> should_not_report_errors
; should_report_errors.
% We process only the interface, so we will warn only about unused
% imports in parent's INTERFACE sections.
:- type maybe_warn_unused_imports_in_parents
---> should_not_warn_unused_imports_in_parents
; should_warn_unused_imports_in_parents.
:- type mq_sub_info
---> mq_sub_info(
% The name of the current module.
mqsi_this_module :: module_name,
mqsi_globals :: globals,
% Modules which have been imported or used, i.e. the ones
% for which there was a `:- import_module' or `:- use_module'
% declaration in this module, plus the implicitly imported
% module builtin.m. We use the contents of this field
% to decide whether to add "No module named xyz has been
% imported" to error messages when we find a reference
% to an undefined type, inst, mode, pred etc.
mqsi_imported_modules :: set(module_name),
% Modules from which `:- instance' declarations have
% been imported.
mqsi_imported_instance_modules :: set(module_name),
% Does this module export any type class instances?
mqsi_exported_instances_flag :: bool,
% Are there any undefined types, insts, modes or typeclasses?
mqsi_found_undef_type :: maybe_found_undef_type,
mqsi_found_undef_inst :: maybe_found_undef_inst,
mqsi_found_undef_mode :: maybe_found_undef_mode,
mqsi_found_undef_typeclass :: maybe_found_undef_typeclass,
% Do we want to suppress the recording of an undef type, inst,
% mode or typeclass, as such? We sometimes do, when the error
% won't prevent us from continuing on to later compiler passes.
% (We still generate error messages in such instances, of
% course.)
mqsi_suppress_found_undef :: maybe_suppress_found_undef,
% Do we want to report errors.
mqsi_should_report_errors :: maybe_should_report_errors,
mqsi_warn_parents_imports ::
maybe_warn_unused_imports_in_parents,
% The number of errors found.
mqsi_num_errors :: int
).
:- type mq_info
---> mq_info(
% Keep the size of the main mq_info structure at eight fields,
% as this allows Boehm gc to allocate memory blocks that don't
% have wasted unused space.
mqi_sub_info :: mq_sub_info,
% Sets of all modules, types, insts, modes, and typeclasses
% visible in this module.
mqi_modules :: module_id_set,
mqi_types :: type_id_set,
mqi_insts :: inst_id_set,
mqi_modes :: mode_id_set,
mqi_classes :: class_id_set,
% Map each modules known to be imported in the interface
% that is not yet known to be needed in the interface
% to the location (or sometimes, locations) of the import.
mqi_as_yet_unused_interface_modules :: module_names_contexts,
mqi_maybe_recompilation_info :: maybe(recompilation_info)
).
:- pred init_mq_info(globals::in, module_name::in,
maybe_should_report_errors::in, mq_info::out) is det.
init_mq_info(Globals, ModuleName, ReportErrors, Info) :-
set.init(InstanceModules),
ExportedInstancesFlag = no,
globals.lookup_bool_option(Globals, warn_interface_imports_in_parents,
WarnInterfaceImportsInParents),
% All the warnings generated by module_qual.*m for unused modules
% are for modules imported in the interface; see the comment at the
% top of this module.
(
WarnInterfaceImportsInParents = no,
WarnUnusedImportsInParents = should_not_warn_unused_imports_in_parents
;
WarnInterfaceImportsInParents = yes,
WarnUnusedImportsInParents = should_warn_unused_imports_in_parents
),
% This module is always implicitly imported into every module,
% and users may use the entities it defines without qualification.
% Users shouldn't write code that refers to entities defined in
% other implicitly imported modules without explicitly importing them,
% since the implicit import mechanism is to give *compiler writers*
% access to those modules, not the users directly. Therefore I (zs) think
% that if users write code that refers to entities defined in other
% implicitly imported modules, including private_builtin, but get
% the names of those entities wrong, it is ok to tell them that the
% affected module hasn't been (explicitly) imported.
set.list_to_set([mercury_public_builtin_module], ImportedOrUsedModules),
SubInfo = mq_sub_info(ModuleName, Globals, ImportedOrUsedModules,
InstanceModules, ExportedInstancesFlag,
did_not_find_undef_type, did_not_find_undef_inst,
did_not_find_undef_mode, did_not_find_undef_typeclass,
do_not_suppress_found_undef,
ReportErrors, WarnUnusedImportsInParents, 0),
id_set_init(ModuleIdSet),
id_set_init(TypeIdSet),
id_set_init(InstIdSet),
id_set_init(ModeIdSet),
id_set_init(ClassIdSet),
map.init(AsYetUnusedInterfaceModules),
globals.lookup_bool_option(Globals, smart_recompilation,
SmartRecompilation),
(
SmartRecompilation = no,
MaybeRecompInfo = no
;
SmartRecompilation = yes,
MaybeRecompInfo = yes(init_recompilation_info(ModuleName))
),
Info = mq_info(SubInfo, ModuleIdSet,
TypeIdSet, InstIdSet, ModeIdSet, ClassIdSet,
AsYetUnusedInterfaceModules, MaybeRecompInfo).
%---------------------------------------------------------------------------%
:- pred mq_info_get_modules(mq_info::in, module_id_set::out) is det.
:- pred mq_info_get_types(mq_info::in, type_id_set::out) is det.
:- pred mq_info_get_insts(mq_info::in, inst_id_set::out) is det.
:- pred mq_info_get_modes(mq_info::in, mode_id_set::out) is det.
:- pred mq_info_get_classes(mq_info::in, class_id_set::out) is det.
:- pred mq_info_get_as_yet_unused_interface_modules(mq_info::in,
module_names_contexts::out) is det.
% mq_info_get_recompilation_info is exported
:- pred mq_info_get_this_module(mq_info::in, module_name::out) is det.
:- pred mq_info_get_globals(mq_info::in, globals::out) is det.
:- pred mq_info_get_imported_modules(mq_info::in, set(module_name)::out)
is det.
:- pred mq_info_get_imported_instance_modules(mq_info::in,
set(module_name)::out) is det.
:- pred mq_info_get_exported_instances_flag(mq_info::in, bool::out) is det.
% mq_info_get_type_error_flag is exported
% mq_info_get_mode_error_flag is exported
:- pred mq_info_get_should_report_errors(mq_info::in,
maybe_should_report_errors::out) is det.
:- pred mq_info_get_should_warn_unused_imports_in_parents(mq_info::in,
maybe_warn_unused_imports_in_parents::out) is det.
mq_info_get_modules(Info, X) :-
X = Info ^ mqi_modules.
mq_info_get_types(Info, X) :-
X = Info ^ mqi_types.
mq_info_get_insts(Info, X) :-
X = Info ^ mqi_insts.
mq_info_get_modes(Info, X) :-
X = Info ^ mqi_modes.
mq_info_get_classes(Info, X) :-
X = Info ^ mqi_classes.
mq_info_get_as_yet_unused_interface_modules(Info, X) :-
X = Info ^ mqi_as_yet_unused_interface_modules.
mq_info_get_recompilation_info(Info, X) :-
X = Info ^ mqi_maybe_recompilation_info.
mq_info_get_this_module(Info, X) :-
X = Info ^ mqi_sub_info ^ mqsi_this_module.
mq_info_get_globals(Info, X) :-
X = Info ^ mqi_sub_info ^ mqsi_globals.
mq_info_get_imported_modules(Info, X) :-
X = Info ^ mqi_sub_info ^ mqsi_imported_modules.
mq_info_get_imported_instance_modules(Info, X) :-
X = Info ^ mqi_sub_info ^ mqsi_imported_instance_modules.
mq_info_get_exported_instances_flag(Info, X) :-
X = Info ^ mqi_sub_info ^ mqsi_exported_instances_flag.
mq_info_get_found_undef_type(Info, X) :-
X = Info ^ mqi_sub_info ^ mqsi_found_undef_type.
mq_info_get_found_undef_inst(Info, X) :-
X = Info ^ mqi_sub_info ^ mqsi_found_undef_inst.
mq_info_get_found_undef_mode(Info, X) :-
X = Info ^ mqi_sub_info ^ mqsi_found_undef_mode.
mq_info_get_found_undef_typeclass(Info, X) :-
X = Info ^ mqi_sub_info ^ mqsi_found_undef_typeclass.
mq_info_get_suppress_found_undef(Info, X) :-
X = Info ^ mqi_sub_info ^ mqsi_suppress_found_undef.
mq_info_get_should_report_errors(Info, X) :-
X = Info ^ mqi_sub_info ^ mqsi_should_report_errors.
mq_info_get_should_warn_unused_imports_in_parents(Info, X) :-
X = Info ^ mqi_sub_info ^ mqsi_warn_parents_imports.
:- pred mq_info_set_modules(module_id_set::in,
mq_info::in, mq_info::out) is det.
:- pred mq_info_set_types(type_id_set::in,
mq_info::in, mq_info::out) is det.
:- pred mq_info_set_insts(inst_id_set::in,
mq_info::in, mq_info::out) is det.
:- pred mq_info_set_modes(mode_id_set::in,
mq_info::in, mq_info::out) is det.
:- pred mq_info_set_classes(class_id_set::in,
mq_info::in, mq_info::out) is det.
:- pred mq_info_set_as_yet_unused_interface_modules(module_names_contexts::in,
mq_info::in, mq_info::out) is det.
% mq_info_get_recompilation_info is exported
:- pred mq_info_set_imported_modules(set(module_name)::in,
mq_info::in, mq_info::out) is det.
:- pred mq_info_set_imported_instance_modules(set(module_name)::in,
mq_info::in, mq_info::out) is det.
:- pred mq_info_set_exported_instances_flag(bool::in,
mq_info::in, mq_info::out) is det.
:- pred mq_info_set_found_undef_type(mq_info::in, mq_info::out) is det.
:- pred mq_info_set_found_undef_inst(mq_info::in, mq_info::out) is det.
:- pred mq_info_set_found_undef_mode(mq_info::in, mq_info::out) is det.
:- pred mq_info_set_found_undef_typeclass(mq_info::in, mq_info::out) is det.
mq_info_set_modules(X, !Info) :-
!Info ^ mqi_modules := X.
mq_info_set_types(X, !Info) :-
!Info ^ mqi_types := X.
mq_info_set_insts(X, !Info) :-
!Info ^ mqi_insts := X.
mq_info_set_modes(X, !Info) :-
!Info ^ mqi_modes := X.
mq_info_set_classes(X, !Info) :-
!Info ^ mqi_classes := X.
mq_info_set_as_yet_unused_interface_modules(X, !Info) :-
!Info ^ mqi_as_yet_unused_interface_modules := X.
mq_info_set_recompilation_info(X, !Info) :-
!Info ^ mqi_maybe_recompilation_info := X.
mq_info_set_imported_modules(X, !Info) :-
!Info ^ mqi_sub_info ^ mqsi_imported_modules := X.
mq_info_set_imported_instance_modules(X, !Info) :-
!Info ^ mqi_sub_info ^ mqsi_imported_instance_modules := X.
mq_info_set_exported_instances_flag(X, !Info) :-
!Info ^ mqi_sub_info ^ mqsi_exported_instances_flag := X.
mq_info_set_found_undef_type(!Info) :-
X = found_undef_type,
!Info ^ mqi_sub_info ^ mqsi_found_undef_type := X.
mq_info_set_found_undef_inst(!Info) :-
X = found_undef_inst,
!Info ^ mqi_sub_info ^ mqsi_found_undef_inst := X.
mq_info_set_found_undef_mode(!Info) :-
X = found_undef_mode,
!Info ^ mqi_sub_info ^ mqsi_found_undef_mode := X.
mq_info_set_found_undef_typeclass(!Info) :-
X = found_undef_typeclass,
!Info ^ mqi_sub_info ^ mqsi_found_undef_typeclass := X.
mq_info_set_suppress_found_undef(X, !Info) :-
!Info ^ mqi_sub_info ^ mqsi_suppress_found_undef := X.
%---------------------------------------------------------------------------%
:- pred get_mq_debug_output_stream(mq_info::in, io.text_output_stream::out,
io::di, io::uo) is det.
get_mq_debug_output_stream(Info, DebugStream, !IO) :-
mq_info_get_globals(Info, Globals),
mq_info_get_this_module(Info, ModuleName),
get_debug_output_stream(Globals, ModuleName, DebugStream, !IO).
%---------------------------------------------------------------------------%
:- pred mq_info_record_undef_mq_id(qual_id_kind::in,
mq_info::in, mq_info::out) is det.
mq_info_record_undef_mq_id(IdType, !Info) :-
mq_info_get_suppress_found_undef(!.Info, SuppressFoundUndef),
(
SuppressFoundUndef = suppress_found_undef
;
SuppressFoundUndef = do_not_suppress_found_undef,
(
IdType = qual_id_type,
mq_info_set_found_undef_type(!Info)
;
IdType = qual_id_inst,
mq_info_set_found_undef_inst(!Info)
;
IdType = qual_id_mode,
mq_info_set_found_undef_mode(!Info)
;
IdType = qual_id_class,
mq_info_set_found_undef_typeclass(!Info)
)
).
%---------------------------------------------------------------------------%
:- end_module parse_tree.module_qual.
%---------------------------------------------------------------------------%