Merge: Some gammar improvements
[nit.git] / src / modelize / modelize_property.nit
index 74e4932..6a34e2e 100644 (file)
@@ -38,7 +38,7 @@ end
 redef class ModelBuilder
        # Register the npropdef associated to each mpropdef
        # FIXME: why not refine the `MPropDef` class with a nullable attribute?
-       var mpropdef2npropdef: HashMap[MPropDef, APropdef] = new HashMap[MPropDef, APropdef]
+       var mpropdef2npropdef = new HashMap[MPropDef, APropdef]
 
        # Build the properties of `nclassdef`.
        # REQUIRE: all superclasses are built.
@@ -202,6 +202,7 @@ redef class ModelBuilder
                # Can we just inherit?
                if spropdefs.length == 1 and mparameters.is_empty and defined_init == null then
                        self.toolcontext.info("{mclassdef} inherits the basic constructor {longest}", 3)
+                       mclassdef.mclass.root_init = longest
                        return
                end
 
@@ -217,6 +218,7 @@ redef class ModelBuilder
                        var msignature = new MSignature(mparameters, null)
                        defined_init.new_msignature = msignature
                        self.toolcontext.info("{mclassdef} extends its basic constructor signature to {defined_init}{msignature}", 3)
+                       mclassdef.mclass.root_init = defined_init
                        return
                end
 
@@ -230,6 +232,7 @@ redef class ModelBuilder
                mpropdef.msignature = new MSignature(new Array[MParameter], null) # always an empty real signature
                nclassdef.mfree_init = mpropdef
                self.toolcontext.info("{mclassdef} gets a free constructor for attributes {mpropdef}{msignature}", 3)
+               mclassdef.mclass.root_init = mpropdef
        end
 
        # Check the visibility of `mtype` as an element of the signature of `mpropdef`.
@@ -241,7 +244,7 @@ redef class ModelBuilder
                # Extract visibility information of the main part of `mtype`
                # It is a case-by case
                var vis_type: nullable MVisibility = null # The own visibility of the type
-               var mmodule_type: nullable MModule = null # The origial module of the type
+               var mmodule_type: nullable MModule = null # The original module of the type
                mtype = mtype.as_notnullable
                if mtype isa MClassType then
                        vis_type = mtype.mclass.visibility
@@ -288,12 +291,21 @@ redef class MPropDef
 end
 
 redef class AClassdef
-       var build_properties_is_done: Bool = false
+       var build_properties_is_done = false
 
        # The free init (implicitely constructed by the class if required)
        var mfree_init: nullable MMethodDef = null
 end
 
+redef class MClass
+       # The base init of the class.
+       # Used to get the common new_msignature and initializers
+       #
+       # TODO: Where to put this information is not clear because unlike other
+       # informations, the initialisers are stable in a same class.
+       var root_init: nullable MMethodDef = null
+end
+
 redef class MClassDef
        # What is the `APropdef` associated to a `MProperty`?
        # Used to check multiple definition of a property.
@@ -440,7 +452,7 @@ redef class ASignature
                var ntype = self.n_type
                if ntype != null then
                        self.ret_type = modelbuilder.resolve_mtype(mmodule, mclassdef, ntype)
-                       if self.ret_type == null then return false # Skip errir
+                       if self.ret_type == null then return false # Skip error
                end
 
                self.is_visited = true
@@ -582,6 +594,16 @@ redef class AMethPropdef
                var mmodule = mclassdef.mmodule
                var nsig = self.n_signature
 
+               if mpropdef.mproperty.is_root_init and not mclassdef.is_intro then
+                       var root_init = mclassdef.mclass.root_init
+                       if root_init != null then
+                               # Inherit the initializers by refinement
+                               mpropdef.new_msignature = root_init.new_msignature
+                               assert mpropdef.initializers.is_empty
+                               mpropdef.initializers.add_all root_init.initializers
+                       end
+               end
+
                # Retrieve info from the signature AST
                var param_names = new Array[String] # Names of parameters from the AST
                var param_types = new Array[MType] # Types of parameters from the AST
@@ -718,12 +740,12 @@ redef class AAttrPropdef
        # Is the node tagged `noinit`?
        var noinit = false
 
-       # Is the node taggeg lazy?
+       # Is the node tagged lazy?
        var is_lazy = false
 
-       # The guard associated to a lasy attribute.
+       # The guard associated to a lazy attribute.
        # Because some engines does not have a working `isset`,
-       # this additionnal attribute is used to guard the lazy initialization.
+       # this additional attribute is used to guard the lazy initialization.
        # TODO: to remove once isset is correctly implemented
        var mlazypropdef: nullable MAttributeDef
 
@@ -830,7 +852,7 @@ redef class AAttrPropdef
        redef fun build_signature(modelbuilder)
        do
                var mpropdef = self.mpropdef
-               if mpropdef == null then return # Error thus skiped
+               if mpropdef == null then return # Error thus skipped
                var mclassdef = mpropdef.mclassdef
                var mmodule = mclassdef.mmodule
                var mtype: nullable MType = null
@@ -843,10 +865,10 @@ redef class AAttrPropdef
                        if mtype == null then return
                end
 
-               # Inherit the type from the getter (usually an abstact getter)
+               # Inherit the type from the getter (usually an abstract getter)
                if mtype == null and mreadpropdef != null and not mreadpropdef.is_intro then
                        var msignature = mreadpropdef.mproperty.intro.msignature
-                       if msignature == null then return # Error, thus skiped
+                       if msignature == null then return # Error, thus skipped
                        mtype = msignature.return_mtype
                end
 
@@ -918,12 +940,10 @@ redef class AAttrPropdef
        redef fun check_signature(modelbuilder)
        do
                var mpropdef = self.mpropdef
-               if mpropdef == null then return # Error thus skiped
-               var mclassdef = mpropdef.mclassdef
-               var mmodule = mclassdef.mmodule
+               if mpropdef == null then return # Error thus skipped
                var ntype = self.n_type
                var mtype = self.mpropdef.static_mtype
-               if mtype == null then return # Error thus skiped
+               if mtype == null then return # Error thus skipped
 
                # Lookup for signature in the precursor
                # FIXME all precursors should be considered
@@ -1046,7 +1066,7 @@ redef class ATypePropdef
        redef fun build_signature(modelbuilder)
        do
                var mpropdef = self.mpropdef
-               if mpropdef == null then return # Error thus skiped
+               if mpropdef == null then return # Error thus skipped
                var mclassdef = mpropdef.mclassdef
                var mmodule = mclassdef.mmodule
                var mtype: nullable MType = null
@@ -1062,10 +1082,10 @@ redef class ATypePropdef
        redef fun check_signature(modelbuilder)
        do
                var mpropdef = self.mpropdef
-               if mpropdef == null then return # Error thus skiped
+               if mpropdef == null then return # Error thus skipped
 
                var bound = self.mpropdef.bound
-               if bound == null then return # Error thus skiped
+               if bound == null then return # Error thus skipped
 
                modelbuilder.check_visibility(n_type, bound, mpropdef)