Merge remote-tracking branch 'upstream/master' into init_auto
[nit.git] / src / model / model.nit
index 3ceb9f3..c60a8fa 100644 (file)
@@ -204,19 +204,37 @@ redef class MModule
        do
                var res = self.flatten_mclass_hierarchy_cache
                if res != null then return res
-               res = new POSet[MClass]
+                self.flatten_mclass_hierarchy_cache = new POSet[MClass]
                for m in self.in_importation.greaters do
                        for cd in m.mclassdefs do
-                               var c = cd.mclass
-                               res.add_node(c)
-                               for s in cd.supertypes do
-                                       res.add_edge(c, s.mclass)
-                               end
+                                unsafe_update_hierarchy_cache(cd)
                        end
                end
-               self.flatten_mclass_hierarchy_cache = res
-               return res
-       end
+               return self.flatten_mclass_hierarchy_cache.as(not null)
+       end
+
+        # Adds another class definition in the modue.
+        # Updates the class hierarchy cache.
+        fun add_mclassdef(mclassdef: MClassDef)
+        do
+                self.mclassdefs.add(mclassdef)
+                if self.flatten_mclass_hierarchy_cache != null then
+                        unsafe_update_hierarchy_cache(mclassdef)
+                end
+        end
+
+        # Adds a class definition inside `flatten_mclass_hierarchy_cache` without
+        # null check. The caller must have initialized the cache.
+        protected fun unsafe_update_hierarchy_cache(mclassdef: MClassDef)
+        do
+                var hierarchy = self.flatten_mclass_hierarchy_cache.as(not null)
+                # Update the cache
+                var c = mclassdef.mclass
+                hierarchy.add_node(c)
+                for s in mclassdef.supertypes do
+                        hierarchy.add_edge(c, s.mclass)
+                end
+        end
 
        # Sort a given array of classes using the linearization order of the module
        # The most general is first, the most specific is last
@@ -651,7 +669,7 @@ class MClassDef
        init
        do
                self.mclass = bound_mtype.mclass
-               mmodule.mclassdefs.add(self)
+               mmodule.add_mclassdef(self)
                mclass.mclassdefs.add(self)
                if mclass.intro_mmodule == mmodule then
                        assert not isset mclass._intro
@@ -760,6 +778,9 @@ class MClassDef
        # All property introductions and redefinitions in `self` (not inheritance).
        var mpropdefs = new Array[MPropDef]
 
+       # The special autoinit constructor
+       var auto_init: nullable MMethodDef = null is writable
+
        # All property introductions and redefinitions (not inheritance) in `self` by its associated property.
        var mpropdefs_by_property = new HashMap[MProperty, MPropDef]
 
@@ -1803,6 +1824,8 @@ class MNullableType
                if t == mtype then return self
                return t.as_nullable
        end
+
+       redef fun mdoc_or_fallback do return mtype.mdoc_or_fallback
 end
 
 # A non-null version of a formal type.
@@ -2602,19 +2625,17 @@ class MMethodDef
        # The signature attached to the property definition
        var msignature: nullable MSignature = null is writable
 
-       # The signature attached to the `new` call on a root-init
-       # This is a concatenation of the signatures of the initializers
-       #
-       # REQUIRE `mproperty.is_root_init == (new_msignature != null)`
-       var new_msignature: nullable MSignature = null is writable
-
        # List of initialisers to call in root-inits
        #
        # They could be setters or attributes
-       #
-       # REQUIRE `mproperty.is_root_init == (new_msignature != null)`
        var initializers = new Array[MProperty]
 
+       # Does the method take the responsibility to call `init`?
+       #
+       # If the method is used as an initializer, then
+       # using this information prevents to call `init` twice.
+       var is_calling_init = false is writable
+
        # Is the method definition abstract?
        var is_abstract: Bool = false is writable