X-Git-Url: http://nitlanguage.org diff --git a/src/semantize/typing.nit b/src/semantize/typing.nit index c581f47..83bebc2 100644 --- a/src/semantize/typing.nit +++ b/src/semantize/typing.nit @@ -47,7 +47,7 @@ private class TypeVisitor # The analyzed property var mpropdef: nullable MPropDef - var selfvariable: Variable = new Variable("self") + var selfvariable = new Variable("self") # Is `self` use restricted? # * no explicit `self` @@ -272,6 +272,11 @@ private class TypeVisitor end var mproperty = self.try_get_mproperty_by_name2(node, unsafe_type, name) + if name == "new" and mproperty == null then + name = "init" + mproperty = self.try_get_mproperty_by_name2(node, unsafe_type, name) + end + if mproperty == null then #self.modelbuilder.error(node, "Type error: property {name} not found in {unsafe_type} (ie {recvtype})") if recv_is_self then @@ -377,11 +382,18 @@ private class TypeVisitor self.visit_expr_subtype(args[j], paramtype) end if vararg_rank >= 0 then - var varargs = new Array[AExpr] var paramtype = msignature.mparameters[vararg_rank].mtype - for j in [vararg_rank..vararg_rank+vararg_decl] do - varargs.add(args[j]) - self.visit_expr_subtype(args[j], paramtype) + var first = args[vararg_rank] + if vararg_decl == 0 and first isa AVarargExpr then + var mclass = get_mclass(node, "Array") + if mclass == null then return false # Forward error + var array_mtype = mclass.get_mtype([paramtype]) + self.visit_expr_subtype(first.n_expr, array_mtype) + first.mtype = first.n_expr.mtype + else + for j in [vararg_rank..vararg_rank+vararg_decl] do + self.visit_expr_subtype(args[j], paramtype) + end end end return true @@ -429,7 +441,6 @@ private class TypeVisitor fun merge_types(node: ANode, col: Array[nullable MType]): nullable MType do if col.length == 1 then return col.first - var res = new Array[nullable MType] for t1 in col do if t1 == null then continue # return null var found = true @@ -495,8 +506,8 @@ end redef class FlowContext # Store changes of types because of type evolution - private var vars: HashMap[Variable, nullable MType] = new HashMap[Variable, nullable MType] - private var cache: HashMap[Variable, nullable Array[nullable MType]] = new HashMap[Variable, nullable Array[nullable MType]] + private var vars = new HashMap[Variable, nullable MType] + private var cache = new HashMap[Variable, nullable Array[nullable MType]] # Adapt the variable to a static type # Warning1: do not modify vars directly. @@ -781,7 +792,7 @@ redef class AContinueExpr do var nexpr = self.n_expr if nexpr != null then - var mtype = v.visit_expr(nexpr) + v.visit_expr(nexpr) end self.is_typed = true end @@ -792,7 +803,7 @@ redef class ABreakExpr do var nexpr = self.n_expr if nexpr != null then - var mtype = v.visit_expr(nexpr) + v.visit_expr(nexpr) end self.is_typed = true end @@ -805,9 +816,9 @@ redef class AReturnExpr var ret_type = v.mpropdef.as(MMethodDef).msignature.return_mtype if nexpr != null then if ret_type != null then - var mtype = v.visit_expr_subtype(nexpr, ret_type) + v.visit_expr_subtype(nexpr, ret_type) else - var mtype = v.visit_expr(nexpr) + v.visit_expr(nexpr) v.error(self, "Error: Return with value in a procedure.") end else if ret_type != null then @@ -891,6 +902,9 @@ redef class AForExpr var method_key: nullable CallSite var method_finish: nullable CallSite + var method_lt: nullable CallSite + var method_successor: nullable CallSite + private fun do_type_iterator(v: TypeVisitor, mtype: MType) do if mtype isa MNullType then @@ -991,6 +1005,19 @@ redef class AForExpr end self.method_key = keydef end + + if self.variables.length == 1 and n_expr isa ARangeExpr then + var variable = variables.first + var vtype = variable.declared_type.as(not null) + + if n_expr isa AOrangeExpr then + self.method_lt = v.get_method(self, vtype, "<", false) + else + self.method_lt = v.get_method(self, vtype, "<=", false) + end + + self.method_successor = v.get_method(self, vtype, "successor", false) + end end redef fun accept_typing(v) @@ -1241,9 +1268,9 @@ redef class AIsaExpr var variable = self.n_expr.its_variable if variable != null then - var orig = self.n_expr.mtype - var from = if orig != null then orig.to_s else "invalid" - var to = if mtype != null then mtype.to_s else "invalid" + #var orig = self.n_expr.mtype + #var from = if orig != null then orig.to_s else "invalid" + #var to = if mtype != null then mtype.to_s else "invalid" #debug("adapt {variable}: {from} -> {to}") self.after_flow_context.when_true.set_var(variable, mtype) end @@ -1288,7 +1315,14 @@ redef class AAsNotnullExpr end end -redef class AProxyExpr +redef class AParExpr + redef fun accept_typing(v) + do + self.mtype = v.visit_expr(self.n_expr) + end +end + +redef class AOnceExpr redef fun accept_typing(v) do self.mtype = v.visit_expr(self.n_expr) @@ -1646,11 +1680,13 @@ redef class ANewExpr # The constructor invoked by the new. var callsite: nullable CallSite + # The designated type + var recvtype: nullable MClassType + redef fun accept_typing(v) do var recvtype = v.resolve_mtype(self.n_type) if recvtype == null then return - self.mtype = recvtype if not recvtype isa MClassType then if recvtype isa MNullableType then @@ -1660,26 +1696,34 @@ redef class ANewExpr v.error(self, "Type error: cannot instantiate the formal type {recvtype}.") return end - else - if recvtype.mclass.kind == abstract_kind then - v.error(self, "Cannot instantiate abstract class {recvtype}.") - return - else if recvtype.mclass.kind == interface_kind then - v.error(self, "Cannot instantiate interface {recvtype}.") - return - end end + self.recvtype = recvtype + var name: String var nid = self.n_id if nid != null then name = nid.text else - name = "init" + name = "new" end var callsite = v.get_method(self, recvtype, name, false) if callsite == null then return + if not callsite.mproperty.is_new then + if recvtype.mclass.kind == abstract_kind then + v.error(self, "Cannot instantiate abstract class {recvtype}.") + return + else if recvtype.mclass.kind == interface_kind then + v.error(self, "Cannot instantiate interface {recvtype}.") + return + end + self.mtype = recvtype + else + self.mtype = callsite.msignature.return_mtype + assert self.mtype != null + end + self.callsite = callsite if not callsite.mproperty.is_init_for(recvtype.mclass) then @@ -1779,6 +1823,16 @@ redef class AIssetAttrExpr end end +redef class AVarargExpr + redef fun accept_typing(v) + do + # This kind of pseudo-expression can be only processed trough a signature + # See `check_signature` + # Other cases are a syntax error. + v.error(self, "Syntax error: unexpected `...`") + end +end + ### redef class ADebugTypeExpr