X-Git-Url: http://nitlanguage.org diff --git a/src/semantize/typing.nit b/src/semantize/typing.nit index 453dd1f..b9acd5e 100644 --- a/src/semantize/typing.nit +++ b/src/semantize/typing.nit @@ -181,7 +181,6 @@ private class TypeVisitor return self.visit_expr_subtype(nexpr, self.type_bool(nexpr)) end - fun check_expr_cast(node: ANode, nexpr: AExpr, ntype: AType): nullable MType do var sub = nexpr.mtype @@ -424,7 +423,6 @@ private class TypeVisitor return build_callsite_by_name(node, recvtype, name, recv_is_self) end - # Visit the expressions of args and check their conformity with the corresponding type in signature # The point of this method is to handle varargs correctly # Note: The signature must be correctly adapted @@ -445,7 +443,6 @@ private class TypeVisitor # Other cases are managed later end - #debug("CALL {unsafe_type}.{msignature}") # Associate each parameter to a position in the arguments @@ -1177,7 +1174,6 @@ redef class AVarReassignExpr end end - redef class AContinueExpr redef fun accept_typing(v) do @@ -1503,7 +1499,6 @@ redef class AAndExpr end end - redef class ANotExpr redef fun accept_typing(v) do @@ -1989,7 +1984,9 @@ redef class ASendExpr var args = compute_raw_arguments - callsite.check_signature(v, node, args) + if not self isa ACallrefExpr then + callsite.check_signature(v, node, args) + end if callsite.mproperty.is_init then var vmpropdef = v.mpropdef @@ -2072,7 +2069,6 @@ redef class AUnaryopExpr redef fun compute_raw_arguments do return new Array[AExpr] end - redef class ACallExpr redef fun property_name do return n_qid.n_id.text redef fun property_node do return n_qid @@ -2165,6 +2161,77 @@ redef class AInitExpr redef fun compute_raw_arguments do return n_args.to_a end +redef class ACallrefExpr + 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 + + redef fun accept_typing(v) + do + super # do the job as if it was a real call + var res = callsite.mproperty + + var msignature = callsite.mpropdef.msignature + var recv = callsite.recv + assert msignature != null + var arity = msignature.mparameters.length + + var routine_type_name = "ProcRef" + if msignature.return_mtype != null then + routine_type_name = "FunRef" + end + + var target_routine_class = "{routine_type_name}{arity}" + var routine_mclass = v.get_mclass(self, target_routine_class) + + if routine_mclass == null then + v.error(self, "Error: missing functional types, try `import functional`") + return + end + + var types_list = new Array[MType] + for param in msignature.mparameters do + if param.is_vararg then + types_list.push(v.mmodule.array_type(param.mtype)) + else + types_list.push(param.mtype) + end + end + if msignature.return_mtype != null then + types_list.push(msignature.return_mtype.as(not null)) + end + + # Why we need an anchor : + # + # ~~~~nitish + # class A[E] + # def toto(x: E) do print "{x}" + # end + # + # var a = new A[Int] + # var f = &a.toto # without anchor : ProcRef1[E] + # # with anchor : ProcRef[Int] + # ~~~~ + # However, we can only anchor if we can resolve every formal + # parameter, here's an example where we can't. + # ~~~~nitish + # class A[E] + # fun bar: A[E] do return self + # fun foo: Fun0[A[E]] do return &bar # here we can't anchor + # end + # var f1 = a1.foo # when this expression will be evaluated, + # # `a1` will anchor `&bar` returned by `foo`. + # print f1.call + # ~~~~ + var routine_type = routine_mclass.get_mtype(types_list) + if not recv.need_anchor then + routine_type = routine_type.anchor_to(v.mmodule, recv.as(MClassType)) + end + is_typed = true + self.mtype = routine_type + end +end + redef class AExprs fun to_a: Array[AExpr] do return self.n_exprs.to_a end @@ -2449,7 +2516,6 @@ redef class AAttrExpr end end - redef class AAttrAssignExpr redef fun accept_typing(v) do