X-Git-Url: http://nitlanguage.org diff --git a/src/typing.nit b/src/typing.nit index 3c11789..24eafb1 100644 --- a/src/typing.nit +++ b/src/typing.nit @@ -27,6 +27,11 @@ redef class ToolContext var typing_phase: Phase = new TypingPhase(self, [flow_phase, modelize_property_phase, local_var_init_phase]) end +redef class MPropDef + # Does the MPropDef contains a call to super or a call of a super-constructor? + var has_supercall: Bool = false +end + private class TypingPhase super Phase redef fun process_npropdef(npropdef) do npropdef.do_typing(toolcontext.modelbuilder) @@ -496,12 +501,6 @@ redef class AConcreteMethPropdef assert variable != null variable.declared_type = mtype end - for i in [0..mmethoddef.msignature.mclosures.length[ do - var mclosure = mmethoddef.msignature.mclosures[i] - var variable = self.n_signature.n_closure_decls[i].variable - assert variable != null - variable.declared_type = mclosure.mtype - end v.visit_stmt(nblock) if not nblock.after_flow_context.is_unreachable and mmethoddef.msignature.return_mtype != null then @@ -825,16 +824,44 @@ redef class AForExpr private fun do_type_iterator(v: TypeVisitor, mtype: MType) do + # get obj class var objcla = v.get_mclass(self, "Object") if objcla == null then return + # check iterator method + var unsafe_type = v.anchor_to(mtype) + if v.try_get_mproperty_by_name2(self, unsafe_type, "iterator") == null then + if v.try_get_mproperty_by_name2(self, unsafe_type, "iterate") == null then + v.error(self, "Type Error: Expected method 'iterator' in type {mtype}") + else + v.modelbuilder.error(self, "NOT YET IMPLEMENTED: Do 'for' on {mtype}") + end + return + end + + var itdef = v.get_method(self, mtype, "iterator", true) + if itdef == null then + v.error(self, "Type Error: Expected method 'iterator' in type {mtype}") + return + end + self.method_iterator = itdef.mproperty + + # check that iterator return something + var ittype = itdef.msignature.return_mtype + if ittype == null then + v.error(self, "Type Error: Expected method 'iterator' to return an Iterator or MapIterator type") + return + end + + # get iterator type + var colit_cla = v.try_get_mclass(self, "Iterator") + var mapit_cla = v.try_get_mclass(self, "MapIterator") var is_col = false var is_map = false - var colcla = v.try_get_mclass(self, "Collection") - if colcla != null and v.is_subtype(mtype, colcla.get_mtype([objcla.mclass_type.as_nullable])) then - var coltype = mtype.supertype_to(v.mmodule, v.anchor, colcla) - self.coltype = coltype + if colit_cla != null and v.is_subtype(ittype, colit_cla.get_mtype([objcla.mclass_type.as_nullable])) then + # Iterator + var coltype = ittype.supertype_to(v.mmodule, v.anchor, colit_cla) var variables = self.variables if variables.length != 1 then v.error(self, "Type Error: Expected one variable") @@ -844,10 +871,9 @@ redef class AForExpr is_col = true end - var mapcla = v.try_get_mclass(self, "Map") - if mapcla != null and v.is_subtype(mtype, mapcla.get_mtype([objcla.mclass_type.as_nullable, objcla.mclass_type.as_nullable])) then - var coltype = mtype.supertype_to(v.mmodule, v.anchor, mapcla) - self.coltype = coltype + if mapit_cla != null and v.is_subtype(ittype, mapit_cla.get_mtype([objcla.mclass_type, objcla.mclass_type.as_nullable])) then + # Map Iterator + var coltype = ittype.supertype_to(v.mmodule, v.anchor, mapit_cla) var variables = self.variables if variables.length != 2 then v.error(self, "Type Error: Expected two variables") @@ -858,57 +884,46 @@ redef class AForExpr is_map = true end - if is_col or is_map then - # get iterator method - var coltype = self.coltype.as(not null) - var itdef = v.get_method(self, coltype, "iterator", true) - if itdef == null then - v.error(self, "Type Error: Expected method 'iterator' in type {coltype}") - return - end - self.method_iterator = itdef.mproperty + if not is_col and not is_map then + v.error(self, "Type Error: Expected method 'iterator' to return an Iterator of MapIterator type") + return + end - # get iterator type - var ittype = itdef.msignature.return_mtype - if ittype == null then - v.error(self, "Type Error: Expected method 'iterator' to return an Iterator type") - return - end + # anchor formal and virtual types + if mtype.need_anchor then mtype = v.anchor_to(mtype) - # get methods is_ok, next, item - var ikdef = v.get_method(self, ittype, "is_ok", false) - if ikdef == null then - v.error(self, "Type Error: Expected method 'is_ok' in Iterator type {ittype}") - return - end - self.method_is_ok = ikdef.mproperty + self.coltype = mtype.as(MClassType) - var itemdef = v.get_method(self, ittype, "item", false) - if itemdef == null then - v.error(self, "Type Error: Expected method 'item' in Iterator type {ittype}") - return - end - self.method_item = itemdef.mproperty + # get methods is_ok, next, item + var ikdef = v.get_method(self, ittype, "is_ok", false) + if ikdef == null then + v.error(self, "Type Error: Expected method 'is_ok' in Iterator type {ittype}") + return + end + self.method_is_ok = ikdef.mproperty - var nextdef = v.get_method(self, ittype, "next", false) - if nextdef == null then - v.error(self, "Type Error: Expected method 'next' in Iterator type {ittype}") - return - end - self.method_next = nextdef.mproperty + var itemdef = v.get_method(self, ittype, "item", false) + if itemdef == null then + v.error(self, "Type Error: Expected method 'item' in Iterator type {ittype}") + return + end + self.method_item = itemdef.mproperty - if is_map then - var keydef = v.get_method(self, ittype, "key", false) - if keydef == null then - v.error(self, "Type Error: Expected method 'key' in Iterator type {ittype}") - return - end - self.method_key = keydef.mproperty - end + var nextdef = v.get_method(self, ittype, "next", false) + if nextdef == null then + v.error(self, "Type Error: Expected method 'next' in Iterator type {ittype}") return end + self.method_next = nextdef.mproperty - v.modelbuilder.error(self, "NOT YET IMPLEMENTED: Do 'for' on {mtype}") + if is_map then + var keydef = v.get_method(self, ittype, "key", false) + if keydef == null then + v.error(self, "Type Error: Expected method 'key' in Iterator type {ittype}") + return + end + self.method_key = keydef.mproperty + end end redef fun accept_typing(v) @@ -942,6 +957,15 @@ redef class AOrExpr end end +redef class AImpliesExpr + redef fun accept_typing(v) + do + v.visit_expr_bool(n_expr) + v.visit_expr_bool(n_expr2) + self.mtype = v.type_bool(self) + end +end + redef class AAndExpr redef fun accept_typing(v) do @@ -976,21 +1000,16 @@ redef class AOrElseExpr var t = v.merge_types(self, [t1, t2]) if t == null then - v.error(self, "Type Error: ambiguous type {t1} vs {t2}") + t = v.mmodule.object_type + if t2 isa MNullableType then + t = t.as_nullable + end + #v.error(self, "Type Error: ambiguous type {t1} vs {t2}") end self.mtype = t end end -redef class AEeExpr - redef fun accept_typing(v) - do - v.visit_expr(n_expr) - v.visit_expr(n_expr2) - self.mtype = v.type_bool(self) - end -end - redef class ATrueExpr redef fun accept_typing(v) do @@ -1209,14 +1228,6 @@ redef class ASendExpr else self.is_typed = true end - - if self.n_closure_defs.length == msignature.mclosures.length then - for i in [0..self.n_closure_defs.length[ do - self.n_closure_defs[i].accept_typing(v, msignature.mclosures[i]) - end - else - debug("closure: got {self.n_closure_defs.length}, want {msignature.mclosures.length}") - end end # The name of the property @@ -1443,6 +1454,7 @@ redef class ASuperExpr end self.mtype = msignature.return_mtype self.is_typed = true + v.mpropdef.has_supercall = true end private fun process_superinit(v: TypeVisitor) @@ -1627,50 +1639,6 @@ end ### -redef class AClosureCallExpr - redef fun accept_typing(v) - do - var variable = self.variable - if variable == null then return # Skip error - - var recvtype = v.nclassdef.mclassdef.bound_mtype - var msignature = variable.declared_type.as(not null) - msignature = v.resolve_for(msignature, recvtype, false).as(MSignature) - - var args = n_args.to_a - v.check_signature(self, args, variable.name, msignature) - - self.is_typed = true - self.mtype = msignature.return_mtype - end -end - -redef class AClosureDef - var mclosure: nullable MParameter - - private fun accept_typing(v: TypeVisitor, mparameter: MParameter) - do - var variables = self.variables - if variables == null then return - - self.mclosure = mparameter - var msignature = mparameter.mtype.as(MSignature) - - if msignature.arity != variables.length then - v.error(self, "Type error: closure {mparameter.name} expects {msignature.arity} parameters, {variables.length} given") - return - end - - for i in [0..variables.length[ do - variables[i].declared_type = msignature.mparameters[i].mtype - end - - v.visit_stmt(self.n_expr) - end -end - -### - redef class ADebugTypeExpr redef fun accept_typing(v) do