X-Git-Url: http://nitlanguage.org diff --git a/src/semantize/typing.nit b/src/semantize/typing.nit index 1b53f65..935e1fc 100644 --- a/src/semantize/typing.nit +++ b/src/semantize/typing.nit @@ -414,26 +414,30 @@ private class TypeVisitor return null end else if args.length != msignature.arity then - 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 + # Too much argument 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}`.") + modelbuilder.error(node, "Error: expected {msignature.arity} argument(s) for `{mproperty}{msignature}`; got {args.length}. See introduction at `{mproperty.full_name}`.") return null end + # Other cases are managed later end + #debug("CALL {unsafe_type}.{msignature}") # Associate each parameter to a position in the arguments var map = new SignatureMap - var setted = args.length - msignature.min_arity + # Special case for the isolated last argument + # TODO: reify this method characteristics (where? the param, the signature, the method?) + var last_is_padded = mproperty.name.chars.last == '=' + var nbargs = args.length + if last_is_padded then + nbargs -= 1 + assert not args.last isa ANamedargExpr + map.map[msignature.arity - 1] = args.length - 1 + self.visit_expr_subtype(args.last, msignature.mparameters.last.mtype) + end # First, handle named arguments for i in [0..args.length[ do @@ -445,10 +449,6 @@ private class TypeVisitor modelbuilder.error(e.n_id, "Error: no parameter `{name}` for `{mproperty}{msignature}`.") return null end - if not param.is_default then - modelbuilder.error(e, "Error: parameter `{name}` is not optional for `{mproperty}{msignature}`.") - return null - end var idx = msignature.mparameters.index_of(param) var prev = map.map.get_or_null(idx) if prev != null then @@ -456,10 +456,12 @@ private class TypeVisitor return null end map.map[idx] = i - setted -= 1 e.mtype = self.visit_expr_subtype(e.n_expr, param.mtype) end + # Number of minimum mandatory remaining parameters + var min_arity = 0 + # Second, associate remaining parameters var vararg_decl = args.length - msignature.arity var j = 0 @@ -468,16 +470,16 @@ private class TypeVisitor if map.map.has_key(i) then continue var param = msignature.mparameters[i] - if param.is_default then - if setted > 0 then - setted -= 1 - else - continue - end - end # Search the next free argument: skip named arguments since they are already associated - while args[j] isa ANamedargExpr do j += 1 + while j < nbargs and args[j] isa ANamedargExpr do j += 1 + if j >= nbargs then + if not param.mtype isa MNullableType then + min_arity = j + 1 + end + j += 1 + continue + end var arg = args[j] map.map[i] = j j += 1 @@ -491,6 +493,16 @@ private class TypeVisitor self.visit_expr_subtype(arg, paramtype) end + if min_arity > 0 then + if last_is_padded then min_arity += 1 + if min_arity < msignature.arity then + modelbuilder.error(node, "Error: expected at least {min_arity} argument(s) for `{mproperty}{msignature}`; got {args.length}. See introduction at `{mproperty.full_name}`.") + else + modelbuilder.error(node, "Error: expected {min_arity} argument(s) for `{mproperty}{msignature}`; got {args.length}. See introduction at `{mproperty.full_name}`.") + end + return null + end + # Third, check varargs if vararg_rank >= 0 then var paramtype = msignature.mparameters[vararg_rank].mtype @@ -1377,6 +1389,16 @@ redef class AIntegerExpr mclass = v.get_mclass(self, "Byte") else if value isa Int then mclass = v.get_mclass(self, "Int") + else if value isa Int8 then + mclass = v.get_mclass(self, "Int8") + else if value isa Int16 then + mclass = v.get_mclass(self, "Int16") + else if value isa UInt16 then + mclass = v.get_mclass(self, "UInt16") + else if value isa Int32 then + mclass = v.get_mclass(self, "Int32") + else if value isa UInt32 then + mclass = v.get_mclass(self, "UInt32") end if mclass == null then return # Forward error self.mtype = mclass.mclass_type @@ -1766,14 +1788,14 @@ end redef class ACallExpr - redef fun property_name do return n_id.text - redef fun property_node do return n_id + redef fun property_name do return n_qid.n_id.text + redef fun property_node do return n_qid redef fun compute_raw_arguments do return n_args.to_a end redef class ACallAssignExpr - redef fun property_name do return n_id.text + "=" - redef fun property_node do return n_id + redef fun property_name do return n_qid.n_id.text + "=" + redef fun property_node do return n_qid redef fun compute_raw_arguments do var res = n_args.to_a @@ -1841,8 +1863,8 @@ redef class ASendReassignFormExpr end redef class ACallReassignExpr - redef fun property_name do return n_id.text - redef fun property_node do return n_id + redef fun property_name do return n_qid.n_id.text + redef fun property_node do return n_qid.n_id redef fun compute_raw_arguments do return n_args.to_a end @@ -2014,11 +2036,11 @@ redef class ANewExpr var kind = recvtype.mclass.kind var name: String - var nid = self.n_id + var nqid = self.n_qid var node: ANode - if nid != null then - name = nid.text - node = nid + if nqid != null then + name = nqid.n_id.text + node = nqid else name = "new" node = self.n_kwnew