If the importation was already done (nmodule.is_importation_done
), this method does a no-op.
REQUIRE nmodule.mmodule != null
ENSURE nmodule.is_importation_done
# Analyze the module importation and fill the module_importation_hierarchy
#
# If the importation was already done (`nmodule.is_importation_done`), this method does a no-op.
#
# REQUIRE `nmodule.mmodule != null`
# ENSURE `nmodule.is_importation_done`
fun build_module_importation(nmodule: AModule)
do
if nmodule.is_importation_done then return
nmodule.is_importation_done = true
var mmodule = nmodule.mmodule.as(not null)
var stdimport = true
var imported_modules = new Array[MModule]
for aimport in nmodule.n_imports do
# Do not imports conditional
var atconditionals = aimport.get_annotations("conditional")
if atconditionals.not_empty then continue
stdimport = false
if not aimport isa AStdImport then
continue
end
# Load the imported module
var sup = search_module_by_amodule_name(aimport.n_name, mmodule.mgroup)
if sup == null then
mmodule.is_broken = true
nmodule.mmodule = null # invalidate the module
continue # Skip error
end
var ast = sup.load(self)
if ast == null then
mmodule.is_broken = true
nmodule.mmodule = null # invalidate the module
continue # Skip error
end
aimport.mmodule = sup
imported_modules.add(sup)
var mvisibility = aimport.n_visibility.mvisibility
if mvisibility == protected_visibility then
mmodule.is_broken = true
error(aimport.n_visibility, "Error: only properties can be protected.")
mmodule.is_broken = true
nmodule.mmodule = null # invalidate the module
return
end
if sup == mmodule then
error(aimport.n_name, "Error: dependency loop in module {mmodule}.")
mmodule.is_broken = true
nmodule.mmodule = null # invalidate the module
end
if sup.in_importation < mmodule then
error(aimport.n_name, "Error: dependency loop between modules {mmodule} and {sup}.")
mmodule.is_broken = true
nmodule.mmodule = null # invalidate the module
return
end
mmodule.set_visibility_for(sup, mvisibility)
end
if stdimport then
var mod_name = "core"
var sup = self.get_mmodule_by_name(nmodule, null, mod_name)
if sup == null then
mmodule.is_broken = true
nmodule.mmodule = null # invalidate the module
else # Skip error
imported_modules.add(sup)
mmodule.set_visibility_for(sup, public_visibility)
end
end
# Declare conditional importation
for aimport in nmodule.n_imports do
if not aimport isa AStdImport then continue
var atconditionals = aimport.get_annotations("conditional")
if atconditionals.is_empty then continue
var suppath = search_module_by_amodule_name(aimport.n_name, mmodule.mgroup)
if suppath == null then continue # skip error
for atconditional in atconditionals do
var nargs = atconditional.n_args
if nargs.is_empty then
error(atconditional, "Syntax Error: `conditional` expects module identifiers as arguments.")
continue
end
# The rule
var rule = new Array[MModule]
# First element is the goal, thus
rule.add suppath
# Second element is the first condition, that is to be a client of the current module
rule.add mmodule
# Other condition are to be also a client of each modules indicated as arguments of the annotation
for narg in nargs do
var id = narg.as_id
if id == null then
error(narg, "Syntax Error: `conditional` expects module identifier as arguments.")
continue
end
var mp = search_mmodule_by_name(narg, mmodule.mgroup, id)
if mp == null then continue
rule.add mp
end
conditional_importations.add rule
end
end
mmodule.set_imported_mmodules(imported_modules)
apply_conditional_importations(mmodule)
self.toolcontext.info("{mmodule} imports {mmodule.in_importation.direct_greaters.join(", ")}", 3)
# Force `core` to be public if imported
for sup in mmodule.in_importation.greaters do
if sup.name == "core" then
mmodule.set_visibility_for(sup, public_visibility)
end
end
# TODO: Correctly check for useless importation
# It is even doable?
var directs = mmodule.in_importation.direct_greaters
for nim in nmodule.n_imports do
if not nim isa AStdImport then continue
var im = nim.mmodule
if im == null then continue
if directs.has(im) then continue
# This generates so much noise that it is simpler to just comment it
#warning(nim, "Warning: possible useless importation of {im}")
end
end
src/loader.nit:921,2--1060,4