# Load the imported module
var suppath = seach_module_by_amodule_name(aimport.n_name, mmodule.mgroup)
if suppath == null then
+ mmodule.is_broken = true
nmodule.mmodule = null # invalidate the module
continue # Skip error
end
var sup = load_module_path(suppath)
if sup == null then
+ mmodule.is_broken = true
nmodule.mmodule = null # invalidate the module
continue # Skip error
end
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
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)
# A Model Entity has a direct link to its model
fun model: Model is abstract
+
+ # The indication that the entity did not pass some semantic verifications.
+ #
+ # This simple flag is set by a given analysis to say that the entity is broken and unusable in
+ # an execution.
+ # When an entity status is set to broken, it is usually associated with a error message.
+ #
+ # If it is safe to do so, clients of the model SHOULD just skip broken entities in their processing.
+ # Clients that do not care about the executability (e.g. metrics) MAY still process the entity or
+ # perform specific checks to determinate the validity of the entity.
+ #
+ # Note that the broken status is not propagated to enclosing and enclosed entities.
+ # e.g. a broken method does not make the whole module broken.
+ var is_broken = false is writable
end
# Something that represents a concern
#print "new class {mclass}"
else if nclassdef isa AStdClassdef and nmodule.mclass2nclassdef.has_key(mclass) then
error(nclassdef, "Error: a class `{name}` is already defined at line {nmodule.mclass2nclassdef[mclass].location.line_start}.")
+ mclass.is_broken = true
return
else if nclassdef isa AStdClassdef and nclassdef.n_kwredef == null then
error(nclassdef, "Redef Error: `{name}` is an imported class. Add the `redef` keyword to refine it.")
+ mclass.is_broken = true
return
else if arity != 0 and mclass.arity != arity then
error(nclassdef, "Redef Error: expected {mclass.arity} formal parameter(s) for {mclass.signature_to_s}; got {arity}.")
+ mclass.is_broken = true
return
else if nkind != null and mkind != concrete_kind and mclass.kind != mkind then
error(nkind, "Redef Error: refinement changed the kind from `{mclass.kind}` to `{mkind}`.")
if mpropdef.bound == null then continue
if not check_virtual_types_circularity(npropdef, mpropdef.mproperty, mclassdef.bound_mtype, mclassdef.mmodule) then
# Invalidate the bound
+ mpropdef.is_broken = true
mpropdef.bound = mclassdef.mmodule.model.null_type
end
end
res = false
end
end
+ if not res then is_broken = true
return res
end
end
mprop.is_new = n_kwnew != null
if mprop.is_new then mclassdef.mclass.has_new_factory = true
if name == "sys" then mprop.is_toplevel = true # special case for sys allowed in `new` factories
- self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, mprop)
+ if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, mprop) then
+ mprop.is_broken = true
+ return
+ end
else
+ if mprop.is_broken then
+ return
+ end
if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, not self isa AMainMethPropdef, mprop) then return
check_redef_property_visibility(modelbuilder, self.n_visibility, mprop)
end
if is_init then
for p, n in mclassdef.mprop2npropdef do
if p != mprop and p isa MMethod and p.name == name then
- check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, p)
+ if not check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, p) then
+ mprop.is_broken = true
+ return
+ end
break
end
end
var mclassdef = mpropdef.mclassdef
var mmodule = mclassdef.mmodule
var nsig = self.n_signature
- var mysignature = self.mpropdef.msignature
+ var mysignature = mpropdef.msignature
if mysignature == null then return # Error thus skiped
# Check
if nsig != null then
if not nsig.check_signature(modelbuilder, mclassdef) then
- self.mpropdef.msignature = null # invalidate
+ mpropdef.msignature = null # invalidate
+ mpropdef.is_broken = true
return # Forward error
end
end
var ret_type = mysignature.return_mtype
if ret_type != null and precursor_ret_type == null then
modelbuilder.error(nsig.n_type.as(not null), "Redef Error: `{mpropdef.mproperty}` is a procedure, not a function.")
- self.mpropdef.msignature = null
+ mpropdef.msignature = null
+ mpropdef.is_broken = true
return
end
var node = nsig.n_params[i]
if not modelbuilder.check_sametype(node, mmodule, mclassdef.bound_mtype, myt, prt) then
modelbuilder.error(node, "Redef Error: expected `{prt}` for parameter `{mysignature.mparameters[i].name}'; got `{myt}`.")
- self.mpropdef.msignature = null
+ mpropdef.msignature = null
+ mpropdef.is_broken = true
end
end
end
ret_type = precursor_ret_type
else if not modelbuilder.check_subtype(node, mmodule, mclassdef.bound_mtype, ret_type, precursor_ret_type) then
modelbuilder.error(node, "Redef Error: expected `{precursor_ret_type}` for return type; got `{ret_type}`.")
- self.mpropdef.msignature = null
+ mpropdef.msignature = null
+ mpropdef.is_broken = true
end
end
end