X-Git-Url: http://nitlanguage.org diff --git a/src/semantize/typing.nit b/src/semantize/typing.nit index 7c1adf4..41b5eeb 100644 --- a/src/semantize/typing.nit +++ b/src/semantize/typing.nit @@ -43,10 +43,10 @@ private class TypeVisitor var anchor: nullable MClassType = null # The analyzed mclassdef - var mclassdef: nullable MClassDef = null + var mclassdef: MClassDef is noinit # The analyzed property - var mpropdef: nullable MPropDef + var mpropdef: MPropDef var selfvariable = new Variable("self") @@ -59,33 +59,24 @@ private class TypeVisitor init do var mpropdef = self.mpropdef + var mclassdef = mpropdef.mclassdef + self.mclassdef = mclassdef + self.anchor = mclassdef.bound_mtype - if mpropdef != null then - self.mpropdef = mpropdef - var mclassdef = mpropdef.mclassdef - self.mclassdef = mclassdef - self.anchor = mclassdef.bound_mtype - - var mclass = mclassdef.mclass + var mclass = mclassdef.mclass - var selfvariable = new Variable("self") - self.selfvariable = selfvariable - selfvariable.declared_type = mclass.mclass_type + var selfvariable = new Variable("self") + self.selfvariable = selfvariable + selfvariable.declared_type = mclass.mclass_type - var mprop = mpropdef.mproperty - if mprop isa MMethod and mprop.is_new then - is_toplevel_context = true - end + var mprop = mpropdef.mproperty + if mprop isa MMethod and mprop.is_new then + is_toplevel_context = true end end fun anchor_to(mtype: MType): MType do - var anchor = anchor - if anchor == null then - assert not mtype.need_anchor - return mtype - end return mtype.anchor_to(mmodule, anchor) end @@ -580,7 +571,16 @@ private class TypeVisitor return mtypes.first else var res = merge_types(node,mtypes) - if res == null then res = variable.declared_type + if res == null then + res = variable.declared_type + # Try to fallback to a non-null version + if res != null and can_be_null(res) then do + for t in mtypes do + if t != null and can_be_null(t) then break label + end + res = res.as_notnull + end label + end return res end end @@ -736,7 +736,7 @@ end class CallSite super MEntity - redef var location: Location + redef var location # The static type of the receiver (possibly unresolved) var recv: MType @@ -781,11 +781,13 @@ class CallSite fun dump_info(v: ASTDump): String do return "{recv}.{mpropdef}{msignature}" end + + redef fun mdoc_or_fallback do return mproperty.intro.mdoc end redef class Variable # The declared type of the variable - var declared_type: nullable MType is writable + var declared_type: nullable MType = null is writable # Was the variable type-adapted? # This is used to speedup type retrieval while it remains `false` @@ -1788,9 +1790,16 @@ redef class AIsaExpr #var to = if mtype != null then mtype.to_s else "invalid" #debug("adapt {variable}: {from} -> {to}") - # Do not adapt if there is no information gain (i.e. adapt to a supertype) - if mtype == null or orig == null or not v.is_subtype(orig, mtype) then - self.after_flow_context.when_true.set_var(v, variable, mtype) + var thentype = v.intersect_types(self, orig, mtype) + if thentype != orig then + self.after_flow_context.when_true.set_var(v, variable, thentype) + #debug "{variable}:{orig or else "?"} isa {mtype or else "?"} -> then {thentype or else "?"}" + end + + var elsetype = v.diff_types(self, orig, mtype) + if elsetype != orig then + self.after_flow_context.when_false.set_var(v, variable, elsetype) + #debug "{variable}:{orig or else "?"} isa {mtype or else "?"} -> else {elsetype or else "?"}" end end