nullable: convert lib, tools and tests
[nit.git] / src / syntax / control_flow.nit
index 2eddf2c..bed98a0 100644 (file)
@@ -24,7 +24,7 @@ import syntax_base
 abstract class VariableContext
        # Look for the variable from its name
        # Return null if nothing found
-       meth [](s: Symbol): Variable
+       meth [](s: Symbol): nullable Variable
        do
                if _dico.has_key(s) then
                        return _dico[s]
@@ -64,7 +64,7 @@ abstract class VariableContext
 
        # The effective static type of a given variable
        # May be different from the declaration static type
-       meth stype(v: Variable): MMType
+       meth stype(v: Variable): nullable MMType
        do
                if _stypes.has_key(v) then
                        return _stypes[v]
@@ -75,7 +75,7 @@ abstract class VariableContext
 
        # Set effective static type of a given variable
        # May be different from the declaration static type
-       meth stype=(v: Variable, t: MMType)
+       meth stype=(v: Variable, t: nullable MMType)
        do
                _stypes[v] = t
        end
@@ -87,7 +87,7 @@ abstract class VariableContext
        attr _all_variables: Set[Variable]
 
        # Updated static type of variables
-       attr _stypes: Map[Variable, MMType] = new HashMap[Variable, MMType]
+       attr _stypes: Map[Variable, nullable MMType] = new HashMap[Variable, nullable MMType]
 
        # Build a new VariableContext
        meth sub(node: PNode): SubVariableContext
@@ -144,11 +144,14 @@ abstract class VariableContext
                        if not is_set(v) and ctx.is_set(v) then
                                mark_is_set(v)
                        end
+                       var s = stype(v)
+                       var s1 = ctx.stype(v)
+                       if s1 != s then stype(v) = s1
                end
        end
 
        # Merge back two alternative flow context informations
-       meth merge2(ctx1, ctx2: VariableContext)
+       meth merge2(ctx1, ctx2, basectx: VariableContext)
        do
                if ctx1.unreash then
                        merge(ctx2)
@@ -159,7 +162,34 @@ abstract class VariableContext
                        if not is_set(v) and ctx1.is_set(v) and ctx2.is_set(v) then
                                mark_is_set(v)
                        end
+
+                       var s = stype(v)
+                       var s1 = ctx1.stype(v)
+                       var s2 = ctx2.stype(v)
+                       if s1 == s and s2 == s then
+                               # NOP
+                       else if s1 == s2 then
+                               stype(v) = s1
+                       else if s2 == null or s1 < s2 then
+                               stype(v) = s2
+                       else if s1 == null or s2 < s1 then
+                               stype(v) = s1
+                       else
+                               stype(v) = basectx.stype(v)
+                       end
+               end
+       end
+
+       redef meth to_s
+       do
+               var s = new Buffer
+               s.append(node.locate)
+               for v in _all_variables do
+                       var t = stype(v)
+                       if t == null then continue
+                       s.append(" {v}:{t}")
                end
+               return s.to_s
        end
 end