Merge: Default arguments
authorJean Privat <jean@pryen.org>
Sun, 19 Apr 2015 00:07:12 +0000 (07:07 +0700)
committerJean Privat <jean@pryen.org>
Sun, 19 Apr 2015 00:07:12 +0000 (07:07 +0700)
Default arguments (aka parameters with a default value) are often a nice way to provide a complex operation with a lot of variations but allow the client to use it in a simple form when no complexity is required.
Also, it allows to extends the signature of existing operations while being API-compatible with previous versions.

This PR introduces default arguments to Nit as another tool in the toolbox of library designers.

The specification is quite simple:

* a nullable parameter can be ignored, the value of the argument will default to null

~~~nit
fun foo(a: Int, b: nullable Int) do ...
foo(1)
foo(1, null)  # equivalent thing
~~~

* default parameters can be anywhere (not necessarily at the end)

~~~nit
fun foo(a: nullable Int, b: Int) do ...
foo(1)
foo(null, 1)  # equivalent thing
~~~

* when there is multiple possible associations between arguments and parameters, arguments will be associated to the leftmost (first) parameter first.

~~~nit
fun foo(a, b: nullable Int) do ...
foo(1)
foo(1, null)  # equivalent thing
~~~

* if there is a vararg, all other parameters are mandatory (no default)

~~~nit
fun foo(a: Int..., b: nullable Int) do ...
foo(1) # Error: minimum 2 arguments (we chose that varargs require a minimum of 1 argument, but this old choice is a different issue)
foo(1, 2) # OK
foo([1]..., 2) # equivalent thing
~~~

* the last parameter of an assignment method (that is the right value of the assignment) is never default. For POLA reasons, the last argument is distinguished and syntactically mandatory, so the association with the parameter is always direct and unambiguous.

~~~nit
fun foo=(a, b: nullable Int) do ...
foo = 1
foo(null) = 1 # equivalent thing
~~~

I chose this specification because it uses the nullable facility of Nit in a nice way and is somewhat semantic: `null` means nothing to say, or keep it blank.
I prefer it over the specification of other languages that is to declare a specific default value on the declaration of parameters.

* no need not to update the grammar
* no need to specify the language of the default value (any expressions? only literal? other?)
* no need to specify when and by who the default value is evaluated (and what is the value of self? are the other parameters usable in the expression? etc.)
* no need to specify how to deal with default values on redefinitions in a OO point of view (do I inherit the default value? can I `super` the default value?)
* no need to expose the expressions used as default values in the metamodel
* no need to expose the expressions used as default values in the doc

Most of these things make the language less KISS (obviously), and less POLA because whatever spec we can choose for these points, 1) not 100% of user will find them obvious; and 2) for some cases the wanted behavior will not be the specified one.

Note that in Python, while they allow to define a specific default value on parameters, they recommend to use `null` as a default to avoid most of these aforementioned problems.

Note2: this PR was unlocked by #1269 and #1268

Pull-Request: #1280
Reviewed-by: Etienne M. Gagnon <egagnon@j-meg.com>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Ait younes Mehdi Adel <overpex@gmail.com>
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>

16 files changed:
src/compiler/abstract_compiler.nit
src/interpreter/naive_interpreter.nit
src/model/model.nit
src/modelize/modelize_property.nit
src/neo.nit
src/semantize/typing.nit
tests/base_arg_default.nit [new file with mode: 0644]
tests/base_arg_default2.nit [new file with mode: 0644]
tests/base_arg_default_autoinit.nit [new file with mode: 0644]
tests/sav/base_arg_default.res [new file with mode: 0644]
tests/sav/base_arg_default2.res [new file with mode: 0644]
tests/sav/base_arg_default2_alt1.res [new file with mode: 0644]
tests/sav/base_arg_default_alt1.res [new file with mode: 0644]
tests/sav/base_arg_default_alt2.res [new file with mode: 0644]
tests/sav/base_arg_default_autoinit.res [new file with mode: 0644]
tests/sav/base_arg_default_autoinit_alt1.res [new file with mode: 0644]

index 1b8bf6a..f8cbee8 100644 (file)
@@ -1173,6 +1173,8 @@ abstract class AbstractCompilerVisitor
                        var param = msignature.mparameters[i]
                        var j = map.map.get_or_null(i)
                        if j == null then
+                               # default value
+                               res.add(null_instance)
                                continue
                        end
                        if param.is_vararg and map.vararg_decl > 0 then
index c1bd59b..9b821e4 100644 (file)
@@ -402,6 +402,8 @@ class NaiveInterpreter
                        var param = msignature.mparameters[i]
                        var j = map.map.get_or_null(i)
                        if j == null then
+                               # default value
+                               res.add(null_instance)
                                continue
                        end
                        if param.is_vararg and map.vararg_decl > 0 then
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
index 32fab5d..f0e2911 100644 (file)
@@ -845,6 +845,7 @@ class NeoModel
                node.labels.add "MParameter"
                node["name"] = mparameter.name
                node["is_vararg"] = mparameter.is_vararg
+               node["is_default"] = mparameter.is_default
                node.out_edges.add(new NeoEdge(node, "TYPE", to_node(mparameter.mtype)))
                return node
        end
@@ -860,7 +861,8 @@ class NeoModel
                var name = node["name"].to_s
                var mtype = to_mtype(model, node.out_nodes("TYPE").first)
                var is_vararg = node["is_vararg"].as(Bool)
-               var mparameter = new MParameter(name, mtype, is_vararg)
+               var is_default = node["is_default"].as(Bool)
+               var mparameter = new MParameter(name, mtype, is_vararg, is_default)
                mentities[node.id.as(Int)] = mparameter
                return mparameter
        end
index 97e200c..e798ab2 100644 (file)
@@ -407,8 +407,18 @@ private class TypeVisitor
                                return null
                        end
                else if args.length != msignature.arity then
-                       modelbuilder.error(node, "Error: expected {msignature.arity} argument(s) for `{mproperty}{msignature}`; got {args.length}. See introduction at `{mproperty.full_name}`.")
-                       return null
+                       if msignature.arity == msignature.min_arity then
+                               modelbuilder.error(node, "Error: expected {msignature.arity} argument(s) for `{mproperty}{msignature}`; got {args.length}. See introduction at `{mproperty.full_name}`.")
+                               return null
+                       end
+                       if args.length > msignature.arity then
+                               modelbuilder.error(node, "Error: expected at most {msignature.arity} argument(s) for `{mproperty}{msignature}`; got {args.length}. See introduction at `{mproperty.full_name}`.")
+                               return null
+                       end
+                       if args.length < msignature.min_arity then
+                               modelbuilder.error(node, "Error: expected at least {msignature.min_arity} argument(s) for `{mproperty}{msignature}`; got {args.length}. See introduction at `{mproperty.full_name}`.")
+                               return null
+                       end
                end
 
                #debug("CALL {unsafe_type}.{msignature}")
@@ -416,10 +426,18 @@ private class TypeVisitor
                # Associate each parameter to a position in the arguments
                var map = new SignatureMap
 
+               var setted = args.length - msignature.min_arity
                var vararg_decl = args.length - msignature.arity
                var j = 0
                for i in [0..msignature.arity[ do
                        var param = msignature.mparameters[i]
+                       if param.is_default then
+                               if setted > 0 then
+                                       setted -= 1
+                               else
+                                       continue
+                               end
+                       end
                        var arg = args[j]
                        map.map[i] = j
                        j += 1
diff --git a/tests/base_arg_default.nit b/tests/base_arg_default.nit
new file mode 100644 (file)
index 0000000..2d1af37
--- /dev/null
@@ -0,0 +1,110 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import standard::kernel
+
+class A
+       fun foo(a, b: nullable Int, c, d: Int, e,f: nullable Int)
+       do
+               if a == null then '\n'.output else a.output
+               if b == null then '\n'.output else b.output
+               c.output
+               d.output
+               if e == null then '\n'.output else e.output
+               if f == null then '\n'.output else f.output
+               '-'.output
+               '\n'.output
+
+       end
+
+       fun bar(a,b,c: nullable Int)
+       do
+               if a == null then '\n'.output else a.output
+               if b == null then '\n'.output else b.output
+               if c == null then '\n'.output else c.output
+               '-'.output
+               '\n'.output
+       end
+
+       fun bar=(a,b,c: nullable Int)
+       do
+               if a == null then '\n'.output else a.output
+               if b == null then '\n'.output else b.output
+               if c == null then '\n'.output else c.output
+               '-'.output
+               '\n'.output
+       end
+
+       fun [](a,b,c: nullable Int): Int
+       do
+               if a == null then '\n'.output else a.output
+               if b == null then '\n'.output else b.output
+               if c == null then '\n'.output else c.output
+               '-'.output
+               '\n'.output
+               return 0
+       end
+
+       fun []=(a,b,c: nullable Int): Int
+       do
+               if a == null then '\n'.output else a.output
+               if b == null then '\n'.output else b.output
+               if c == null then '\n'.output else c.output
+               '-'.output
+               '\n'.output
+               return 0
+       end
+
+       fun +(a: nullable Int): Int
+       do
+               if a == null then '\n'.output else a.output
+               '-'.output
+               '\n'.output
+               return 0
+       end
+end
+
+var a = new A
+var x
+
+#alt1#a.foo
+#alt1#a.foo(2)
+a.foo(1,2)
+a.foo(1,2,3)
+a.foo(1,2,3,4)
+a.foo(1,2,3,4,5)
+a.foo(1,2,3,4,5,6)
+#alt1#a.foo(1,2,3,4,5,6,7)
+
+a.bar
+a.bar(1)
+a.bar(1,2)
+a.bar(1,2,3)
+#alt1#a.bar(1,2,3,4)
+
+a.bar= 10
+a.bar(1) = 20
+a.bar(1,2) = 30
+#alt1#a.bar(1,2,3) = 40
+
+#alt2# x = a[]
+x = a[1]
+x = a[1,2]
+x = a[1,2,3]
+#alt2#x = a[1,2,3,4]
+
+#alt2#a[] = 10
+a[1] = 20
+a[1,2] = 30
+#alt1#a[1,2,3] = 40
diff --git a/tests/base_arg_default2.nit b/tests/base_arg_default2.nit
new file mode 100644 (file)
index 0000000..228f5ac
--- /dev/null
@@ -0,0 +1,104 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+class A
+       fun foo(a: nullable Int, bs: Int..., c: nullable Int)
+       do
+               if a == null then '\n'.output else a.output
+               for b in bs do
+                       ' '.output
+                       b.output
+               end
+               if c == null then '\n'.output else c.output
+               '-'.output
+               '\n'.output
+
+       end
+
+       fun bar(a: nullable Int, bs: Int...)
+       do
+               if a == null then '\n'.output else a.output
+               for b in bs do
+                       ' '.output
+                       b.output
+               end
+               '-'.output
+               '\n'.output
+       end
+
+       fun bar=(a:nullable Int, bs: Int..., c: nullable Int)
+       do
+               if a == null then '\n'.output else a.output
+               for b in bs do
+                       ' '.output
+                       b.output
+               end
+               if c == null then '\n'.output else c.output
+               '-'.output
+               '\n'.output
+       end
+
+       fun [](a: nullable Int, bs: Int...): Int
+       do
+               if a == null then '\n'.output else a.output
+               for b in bs do
+                       ' '.output
+                       b.output
+               end
+               '-'.output
+               '\n'.output
+               return 0
+       end
+
+       fun []=(a: nullable Int, bs: Int..., c: nullable Int): Int
+       do
+               if a == null then '\n'.output else a.output
+               for b in bs do
+                       ' '.output
+                       b.output
+               end
+               if c == null then '\n'.output else c.output
+               '-'.output
+               '\n'.output
+               return 0
+       end
+end
+
+var a = new A
+var x
+
+#alt1#a.foo
+#alt1#a.foo(2)
+#alt1#a.foo(1,2)
+a.foo(1,2,3)
+a.foo(1,2,3,4)
+
+#alt1#a.bar
+#alt1#a.bar(1)
+a.bar(1,2)
+a.bar(1,2,3)
+
+#alt1#a.bar = 10
+#alt1#a.bar(1) = 20
+a.bar(1,2) = 30
+a.bar(1,2,3) = 40
+
+#alt1#x = a[1]
+x = a[1,2]
+x = a[1,2,3]
+
+#alt1#a[1] = 20
+a[1,2] = 30
+a[1,2,3] = 40
+a[1,2,3,4] = 50
diff --git a/tests/base_arg_default_autoinit.nit b/tests/base_arg_default_autoinit.nit
new file mode 100644 (file)
index 0000000..6ea74cf
--- /dev/null
@@ -0,0 +1,96 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import standard::kernel
+
+class A
+       var mandatory: Int
+       var optional: nullable Int
+
+       fun foo
+       do
+               '-'.output
+               '\n'.output
+               mandatory.output
+               if optional == null then
+                       ' '.output
+                       '\n'.output
+               else
+                       optional.output
+               end
+       end
+end
+
+class B
+       super A
+       var optional_b: nullable Int
+       var mandatory_b: Int
+       redef fun foo
+       do
+               super
+               if optional_b == null then
+                       ' '.output
+                       '\n'.output
+               else
+                       optional_b.output
+               end
+               mandatory_b.output
+       end
+end
+
+class C
+       super B
+       autoinit optional_b, mandatory_b, mandatory
+end
+
+var a
+
+#alt1#a = new A
+#alt1#a.foo
+
+a = new A(1)
+a.foo
+
+a = new A(1,2)
+a.foo
+
+#alt1#a = new A(1,2,3)
+#alt1#a.foo
+
+#alt1#a = new B(1)
+#alt1#a.foo
+
+a = new B(1,4)
+a.foo
+
+a = new B(1,2,4)
+a.foo
+
+a = new B(1,2,3,4)
+a.foo
+
+#alt1#a = new B(1,2,3,4,5)
+#alt1#a.foo
+
+#alt1#a = new C(1)
+#alt1#a.foo
+
+a = new C(4,1)
+a.foo
+
+a = new C(3,4,1)
+a.foo
+
+#alt1#a = new C(1,2,3,4)
+#alt1#a.foo
diff --git a/tests/sav/base_arg_default.res b/tests/sav/base_arg_default.res
new file mode 100644 (file)
index 0000000..61ea614
--- /dev/null
@@ -0,0 +1,83 @@
+
+
+1
+2
+
+
+-
+1
+
+2
+3
+
+
+-
+1
+2
+3
+4
+
+
+-
+1
+2
+3
+4
+5
+
+-
+1
+2
+3
+4
+5
+6
+-
+
+
+
+-
+1
+
+
+-
+1
+2
+
+-
+1
+2
+3
+-
+
+
+10
+-
+1
+
+20
+-
+1
+2
+30
+-
+1
+
+
+-
+1
+2
+
+-
+1
+2
+3
+-
+1
+
+20
+-
+1
+2
+30
+-
diff --git a/tests/sav/base_arg_default2.res b/tests/sav/base_arg_default2.res
new file mode 100644 (file)
index 0000000..388e53a
--- /dev/null
@@ -0,0 +1,47 @@
+1
+ 2
+3
+-
+1
+ 2
+ 3
+4
+-
+1
+ 2
+-
+1
+ 2
+ 3
+-
+1
+ 2
+30
+-
+1
+ 2
+ 3
+40
+-
+1
+ 2
+-
+1
+ 2
+ 3
+-
+1
+ 2
+30
+-
+1
+ 2
+ 3
+40
+-
+1
+ 2
+ 3
+ 4
+50
+-
diff --git a/tests/sav/base_arg_default2_alt1.res b/tests/sav/base_arg_default2_alt1.res
new file mode 100644 (file)
index 0000000..2dc6089
--- /dev/null
@@ -0,0 +1,9 @@
+alt/base_arg_default2_alt1.nit:81,3--5: Error: expected at least 3 argument(s) for `foo(a: nullable Int, bs: Int..., c: nullable Int)`; got 0. See introduction at `base_arg_default2_alt1::A::foo`.
+alt/base_arg_default2_alt1.nit:82,3--5: Error: expected at least 3 argument(s) for `foo(a: nullable Int, bs: Int..., c: nullable Int)`; got 1. See introduction at `base_arg_default2_alt1::A::foo`.
+alt/base_arg_default2_alt1.nit:83,3--5: Error: expected at least 3 argument(s) for `foo(a: nullable Int, bs: Int..., c: nullable Int)`; got 2. See introduction at `base_arg_default2_alt1::A::foo`.
+alt/base_arg_default2_alt1.nit:87,3--5: Error: expected at least 2 argument(s) for `bar(a: nullable Int, bs: Int...)`; got 0. See introduction at `base_arg_default2_alt1::A::bar`.
+alt/base_arg_default2_alt1.nit:88,3--5: Error: expected at least 2 argument(s) for `bar(a: nullable Int, bs: Int...)`; got 1. See introduction at `base_arg_default2_alt1::A::bar`.
+alt/base_arg_default2_alt1.nit:92,3--5: Error: expected at least 3 argument(s) for `bar=(a: nullable Int, bs: Int..., c: nullable Int)`; got 1. See introduction at `base_arg_default2_alt1::A::bar=`.
+alt/base_arg_default2_alt1.nit:93,3--5: Error: expected at least 3 argument(s) for `bar=(a: nullable Int, bs: Int..., c: nullable Int)`; got 2. See introduction at `base_arg_default2_alt1::A::bar=`.
+alt/base_arg_default2_alt1.nit:97,5--8: Error: expected at least 2 argument(s) for `[](a: nullable Int, bs: Int...): Int`; got 1. See introduction at `base_arg_default2_alt1::A::[]`.
+alt/base_arg_default2_alt1.nit:101,1--9: Error: expected at least 3 argument(s) for `[]=(a: nullable Int, bs: Int..., c: nullable Int): Int`; got 2. See introduction at `base_arg_default2_alt1::A::[]=`.
diff --git a/tests/sav/base_arg_default_alt1.res b/tests/sav/base_arg_default_alt1.res
new file mode 100644 (file)
index 0000000..fba2f2b
--- /dev/null
@@ -0,0 +1,6 @@
+alt/base_arg_default_alt1.nit:81,3--5: Error: expected at least 2 argument(s) for `foo(a: nullable Int, b: nullable Int, c: Int, d: Int, e: nullable Int, f: nullable Int)`; got 0. See introduction at `base_arg_default_alt1::A::foo`.
+alt/base_arg_default_alt1.nit:82,3--5: Error: expected at least 2 argument(s) for `foo(a: nullable Int, b: nullable Int, c: Int, d: Int, e: nullable Int, f: nullable Int)`; got 1. See introduction at `base_arg_default_alt1::A::foo`.
+alt/base_arg_default_alt1.nit:88,3--5: Error: expected at most 6 argument(s) for `foo(a: nullable Int, b: nullable Int, c: Int, d: Int, e: nullable Int, f: nullable Int)`; got 7. See introduction at `base_arg_default_alt1::A::foo`.
+alt/base_arg_default_alt1.nit:94,3--5: Error: expected at most 3 argument(s) for `bar(a: nullable Int, b: nullable Int, c: nullable Int)`; got 4. See introduction at `base_arg_default_alt1::A::bar`.
+alt/base_arg_default_alt1.nit:99,3--5: Error: expected at most 3 argument(s) for `bar=(a: nullable Int, b: nullable Int, c: nullable Int)`; got 4. See introduction at `base_arg_default_alt1::A::bar=`.
+alt/base_arg_default_alt1.nit:110,1--13: Error: expected at most 3 argument(s) for `[]=(a: nullable Int, b: nullable Int, c: nullable Int): Int`; got 4. See introduction at `base_arg_default_alt1::A::[]=`.
diff --git a/tests/sav/base_arg_default_alt2.res b/tests/sav/base_arg_default_alt2.res
new file mode 100644 (file)
index 0000000..ca32b19
--- /dev/null
@@ -0,0 +1 @@
+alt/base_arg_default_alt2.nit:101,7: Syntax Error: unexpected ']'.
diff --git a/tests/sav/base_arg_default_autoinit.res b/tests/sav/base_arg_default_autoinit.res
new file mode 100644 (file)
index 0000000..437e8ee
--- /dev/null
@@ -0,0 +1,31 @@
+-
+1
+-
+1
+2
+-
+1
+4
+-
+1
+2
+4
+-
+1
+2
+3
+4
+-
+1
+4
+-
+1
+3
+4
diff --git a/tests/sav/base_arg_default_autoinit_alt1.res b/tests/sav/base_arg_default_autoinit_alt1.res
new file mode 100644 (file)
index 0000000..cdf6690
--- /dev/null
@@ -0,0 +1,6 @@
+alt/base_arg_default_autoinit_alt1.nit:59,5--7: Error: expected at least 1 argument(s) for `init(mandatory: Int, optional: nullable Int)`; got 0. See introduction at `standard::Object::init`.
+alt/base_arg_default_autoinit_alt1.nit:68,5--7: Error: expected at most 2 argument(s) for `init(mandatory: Int, optional: nullable Int)`; got 3. See introduction at `standard::Object::init`.
+alt/base_arg_default_autoinit_alt1.nit:71,5--7: Error: expected at least 2 argument(s) for `init(mandatory: Int, optional: nullable Int, optional_b: nullable Int, mandatory_b: Int)`; got 1. See introduction at `standard::Object::init`.
+alt/base_arg_default_autoinit_alt1.nit:83,5--7: Error: expected at most 4 argument(s) for `init(mandatory: Int, optional: nullable Int, optional_b: nullable Int, mandatory_b: Int)`; got 5. See introduction at `standard::Object::init`.
+alt/base_arg_default_autoinit_alt1.nit:86,5--7: Error: expected at least 2 argument(s) for `init(optional_b: nullable Int, mandatory_b: Int, mandatory: Int)`; got 1. See introduction at `standard::Object::init`.
+alt/base_arg_default_autoinit_alt1.nit:95,5--7: Error: expected at most 3 argument(s) for `init(optional_b: nullable Int, mandatory_b: Int, mandatory: Int)`; got 4. See introduction at `standard::Object::init`.