nitc :: ModelBuilder :: build_classes
nmodule
.
# Build the classes of the module `nmodule`.
private fun build_classes(nmodule: AModule)
do
# Force building recursively
if nmodule.build_classes_is_done then return
nmodule.build_classes_is_done = true
var mmodule = nmodule.mmodule
if mmodule == null then return
for imp in mmodule.in_importation.direct_greaters do
var nimp = mmodule2node(imp)
if nimp != null then build_classes(nimp)
end
# Create all classes
# process AStdClassdef before so that non-AStdClassdef classes can be attached to existing ones, if any
for nclassdef in nmodule.n_classdefs do
if not nclassdef isa AStdClassdef then continue
self.build_a_mclass(nmodule, nclassdef)
end
for nclassdef in nmodule.n_classdefs do
if nclassdef isa AStdClassdef then continue
self.build_a_mclass(nmodule, nclassdef)
end
# Create all classdefs
for nclassdef in nmodule.n_classdefs do
if not nclassdef isa AStdClassdef then continue
self.build_a_mclassdef(nmodule, nclassdef)
end
for nclassdef in nmodule.n_classdefs do
if nclassdef isa AStdClassdef then continue
self.build_a_mclassdef(nmodule, nclassdef)
end
# Create inheritance on all classdefs
for nclassdef in nmodule.n_classdefs do
self.build_a_mclassdef_inheritance(nmodule, nclassdef)
end
# Create the mclassdef hierarchy
for mclassdef in mmodule.mclassdefs do
mclassdef.add_in_hierarchy
end
# Check inheritance
for nclassdef in nmodule.n_classdefs do
self.check_supertypes(nmodule, nclassdef)
end
# Check unchecked ntypes
for nclassdef in nmodule.n_classdefs do
if nclassdef isa AStdClassdef then
var mclassdef = nclassdef.mclassdef
var mclass
var anchor
if mclassdef == null then
mclass = null
anchor = null
else
mclass = mclassdef.mclass
anchor = mclassdef.bound_mtype
end
# check bound of formal parameter
for nfd in nclassdef.n_formaldefs do
var nfdt = nfd.n_type
if nfdt != null and nfdt.mtype != null then
var bound = resolve_mtype3(mmodule, mclass, anchor, nfdt)
if bound == null then return # Forward error
end
end
# check declared super types
for nsc in nclassdef.n_superclasses do
var ntype = nsc.n_type
if ntype.mtype != null then
var mtype = resolve_mtype3(mmodule, mclass, anchor, ntype)
if mtype == null then return # Forward error
end
end
end
end
# Check clash of ancestors
for nclassdef in nmodule.n_classdefs do
var mclassdef = nclassdef.mclassdef
if mclassdef == null then continue
var superclasses = new HashMap[MClass, MClassType]
for scd in mclassdef.in_hierarchy.greaters do
for st in scd.supertypes do
if not superclasses.has_key(st.mclass) then
superclasses[st.mclass] = st
else if superclasses[st.mclass] != st then
var st1 = superclasses[st.mclass].resolve_for(mclassdef.mclass.mclass_type, mclassdef.bound_mtype, mmodule, false)
var st2 = st.resolve_for(mclassdef.mclass.mclass_type, mclassdef.bound_mtype, mmodule, false)
if st1 != st2 then
error(nclassdef, "Error: incompatible ancestors for `{mclassdef.mclass}`; conflict: `{st1}` and `{st2}`")
end
end
end
end
end
# TODO: Check that the super-class is not intrusive
# Check that the superclasses are not already known (by transitivity)
for nclassdef in nmodule.n_classdefs do
if not nclassdef isa AStdClassdef or nclassdef.is_broken then continue
var mclassdef = nclassdef.mclassdef
if mclassdef == null then continue
# Get the direct superclasses
# Since we are a mclassdef, just look at the mclassdef hierarchy
var parents = new Array[MClass]
for sup in mclassdef.in_hierarchy.direct_greaters do
parents.add(sup.mclass)
end
# Used to track duplicates of superclasses
var seen_parents = new ArrayMap[MClass, AType]
# The Object class
var objectclass = try_get_mclass_by_name(nmodule, mmodule, "Object")
# Check each declared superclass to see if it belong to the direct superclass
for nsc in nclassdef.n_superclasses do
var ntype = nsc.n_type
var mtype = ntype.mtype
# If the supertype is `null` or don’t refer to a class, we
# already raised an error.
if not mtype isa MClassType then continue
var sc = mtype.mclass
if not parents.has(sc) or sc == objectclass then
# Skip the warning on generated code
if ntype.location.file != null and not ntype.location.file.filename.is_empty then
warning(ntype, "useless-superclass", "Warning: superfluous super-class `{mtype}` in class `{mclassdef.mclass}`.")
end
else if not seen_parents.has_key(sc) then
seen_parents[sc] = ntype
else
warning(ntype, "useless-superclass", "Warning: duplicated super-class `{mtype}` in class `{mclassdef.mclass}`.")
end
end
end
end
src/modelize/modelize_class.nit:346,2--491,4