model&modelize: introduce default parameters
authorJean Privat <jean@pryen.org>
Thu, 16 Apr 2015 11:11:09 +0000 (18:11 +0700)
committerJean Privat <jean@pryen.org>
Sat, 18 Apr 2015 16:05:04 +0000 (23:05 +0700)
Signed-off-by: Jean Privat <jean@pryen.org>

src/model/model.nit
src/modelize/modelize_property.nit

index cd1e570..4395cee 100644 (file)
@@ -1762,9 +1762,25 @@ class MSignature
        # Example: for "(a: Int, b: Bool..., c: Char)" #-> vararg_rank=1
        var vararg_rank: Int is noinit
 
-       # The number or parameters
+       # The number of parameters
        fun arity: Int do return mparameters.length
 
+       # The number of non-default parameters
+       #
+       # The number of default parameters is then `arity-min_arity`.
+       #
+       # Note that there cannot be both varargs and default prameters, thus
+       # if `vararg_rank != -1` then `min_arity` == `arity`
+       fun min_arity: Int
+       do
+               if vararg_rank != -1 then return arity
+               var res = 0
+               for p in mparameters do
+                       if not p.is_default then res += 1
+               end
+               return res
+       end
+
        redef fun to_s
        do
                var b = new FlatBuffer
@@ -1818,6 +1834,9 @@ class MParameter
        # Is the parameter a vararg?
        var is_vararg: Bool
 
+       # Is the parameter a default one?
+       var is_default: Bool
+
        redef fun to_s
        do
                if is_vararg then
@@ -1833,7 +1852,7 @@ class MParameter
        do
                if not self.mtype.need_anchor then return self
                var newtype = self.mtype.resolve_for(mtype, anchor, mmodule, cleanup_virtual)
-               var res = new MParameter(self.name, newtype, self.is_vararg)
+               var res = new MParameter(self.name, newtype, self.is_vararg, self.is_default)
                return res
        end
 
index c0d3890..3243f96 100644 (file)
@@ -196,7 +196,7 @@ redef class ModelBuilder
 
                                for param in sig.mparameters do
                                        var ret_type = param.mtype
-                                       var mparameter = new MParameter(param.name, ret_type, false)
+                                       var mparameter = new MParameter(param.name, ret_type, false, ret_type isa MNullableType)
                                        mparameters.add(mparameter)
                                end
                                initializers.add(npropdef.mpropdef.mproperty)
@@ -217,7 +217,7 @@ redef class ModelBuilder
                                var paramname = npropdef.mpropdef.mproperty.name.substring_from(1)
                                var ret_type = npropdef.mpropdef.static_mtype
                                if ret_type == null then return
-                               var mparameter = new MParameter(paramname, ret_type, false)
+                               var mparameter = new MParameter(paramname, ret_type, false, ret_type isa MNullableType)
                                mparameters.add(mparameter)
                                var msetter = npropdef.mwritepropdef
                                if msetter == null then
@@ -286,7 +286,13 @@ redef class ModelBuilder
                                if pd isa MMethodDef then
                                        # Get the signature resolved for the current receiver
                                        var sig = pd.msignature.resolve_for(mclassdef.mclass.mclass_type, mclassdef.bound_mtype, mclassdef.mmodule, false)
-                                       mparameters.add_all sig.mparameters
+                                       # Because the last parameter of setters is never default, try to default them for the autoinit.
+                                       for param in sig.mparameters do
+                                               if not param.is_default and param.mtype isa MNullableType then
+                                                       param = new MParameter(param.name, param.mtype, param.is_vararg, true)
+                                               end
+                                               mparameters.add(param)
+                                       end
                                else
                                        # TODO attributes?
                                        abort
@@ -942,7 +948,13 @@ redef class AMethPropdef
 
                var mparameters = new Array[MParameter]
                for i in [0..param_names.length[ do
-                       var mparameter = new MParameter(param_names[i], param_types[i], i == vararg_rank)
+                       var is_default = false
+                       if vararg_rank == -1 and param_types[i] isa MNullableType then
+                               if i < param_names.length-1 or accept_special_last_parameter then
+                                       is_default = true
+                               end
+                       end
+                       var mparameter = new MParameter(param_names[i], param_types[i], i == vararg_rank, is_default)
                        if nsig != null then nsig.n_params[i].mparameter = mparameter
                        mparameters.add(mparameter)
                end
@@ -1322,7 +1334,7 @@ redef class AAttrPropdef
                if mwritepropdef != null then
                        var name: String
                        name = n_id2.text
-                       var mparameter = new MParameter(name, mtype, false)
+                       var mparameter = new MParameter(name, mtype, false, false)
                        var msignature = new MSignature([mparameter], null)
                        mwritepropdef.msignature = msignature
                end