gamnit: extract Cuboid as super class to cube and intro Boxed3d::to_mesh
[nit.git] / src / model / model.nit
index f54e121..21b182e 100644 (file)
@@ -154,6 +154,14 @@ redef class MModule
        # (introduction and refinement)
        var mclassdefs = new Array[MClassDef]
 
+       private var mclassdef_sorter: MClassDefSorter is lazy do
+               return new MClassDefSorter(self)
+       end
+
+       private var mpropdef_sorter: MPropDefSorter is lazy do
+               return new MPropDefSorter(self)
+       end
+
        # Does the current module has a given class `mclass`?
        # Return true if the mmodule introduces, refines or imports a class.
        # Visibility is not considered.
@@ -201,8 +209,7 @@ redef class MModule
        # The most general is first, the most specific is last
        fun linearize_mclassdefs(mclassdefs: Array[MClassDef])
        do
-               var sorter = new MClassDefSorter(self)
-               sorter.sort(mclassdefs)
+               mclassdef_sorter.sort(mclassdefs)
        end
 
        # Sort a given array of property definitions using the linearization order of the module
@@ -210,8 +217,7 @@ redef class MModule
        # The most general is first, the most specific is last
        fun linearize_mpropdefs(mpropdefs: Array[MPropDef])
        do
-               var sorter = new MPropDefSorter(self)
-               sorter.sort(mpropdefs)
+               mpropdef_sorter.sort(mpropdefs)
        end
 
        private var flatten_mclass_hierarchy_cache: nullable POSet[MClass] = null
@@ -355,14 +361,12 @@ private class MPropDefSorter
        super Comparator
        redef type COMPARED: MPropDef
        var mmodule: MModule
+
        redef fun compare(pa, pb)
        do
                var a = pa.mclassdef
                var b = pb.mclassdef
-               var ca = a.mclass
-               var cb = b.mclass
-               if ca != cb then return mmodule.flatten_mclass_hierarchy.compare(ca, cb)
-               return mmodule.model.mclassdef_hierarchy.compare(a, b)
+               return mmodule.mclassdef_sorter.compare(a, b)
        end
 end
 
@@ -1474,8 +1478,8 @@ class MVirtualType
 
        # A VT is fixed when:
        # * the VT is (re-)defined with the annotation `is fixed`
-       # * the VT is (indirectly) bound to an enum class (see `enum_kind`) since there is no subtype possible
-       # * the receiver is an enum class since there is no subtype possible
+       # * the receiver is an enum class since there is no subtype that can
+       #   redefine this virtual type
        redef fun lookup_fixed(mmodule: MModule, resolved_receiver: MType): MType
        do
                assert not resolved_receiver.need_anchor
@@ -1489,13 +1493,10 @@ class MVirtualType
                # Recursively lookup the fixed result
                res = res.lookup_fixed(mmodule, resolved_receiver)
 
-               # 1. For a fixed VT, return the resolved bound
+               # For a fixed VT, return the resolved bound
                if prop.is_fixed then return res
 
-               # 2. For a enum boud, return the bound
-               if res isa MClassType and res.mclass.kind == enum_kind then return res
-
-               # 3. for a enum receiver return the bound
+               # For a enum receiver return the bound
                if resolved_receiver.mclass.kind == enum_kind then return res
 
                return self
@@ -1616,9 +1617,7 @@ class MParameterType
        end
 
        # A PT is fixed when:
-       # * Its bound is a enum class (see `enum_kind`).
-       #   The PT is just useless, but it is still a case.
-       # * More usually, the `resolved_receiver` is a subclass of `self.mclass`,
+       # * The `resolved_receiver` is a subclass of `self.mclass`,
        #   so it is necessarily fixed in a `super` clause, either with a normal type
        #   or with another PT.
        #   See `resolve_for` for examples about related issues.
@@ -1637,13 +1636,7 @@ class MParameterType
                #print "{class_name}: {self}/{mtype}/{anchor}?"
 
                if mtype isa MGenericType and mtype.mclass == self.mclass then
-                       var res = mtype.arguments[self.rank]
-                       if anchor != null and res.need_anchor then
-                               # Maybe the result can be resolved more if are bound to a final class
-                               var r2 = res.anchor_to(mmodule, anchor)
-                               if r2 isa MClassType and r2.mclass.kind == enum_kind then return r2
-                       end
-                       return res
+                       return mtype.arguments[self.rank]
                end
 
                # self is a parameter type of mtype (or of a super-class of mtype)