src: Modified compilers for the support of the new Integers
[nit.git] / src / semantize / typing.nit
index ffd68e7..1b53f65 100644 (file)
@@ -20,6 +20,7 @@ module typing
 
 import modelize
 import local_var_init
+import literal
 
 redef class ToolContext
        var typing_phase: Phase = new TypingPhase(self, [flow_phase, modelize_property_phase, local_var_init_phase])
@@ -184,12 +185,12 @@ private class TypeVisitor
        end
 
 
-       fun visit_expr_cast(node: ANode, nexpr: AExpr, ntype: AType): nullable MType
+       fun check_expr_cast(node: ANode, nexpr: AExpr, ntype: AType): nullable MType
        do
-               var sub = visit_expr(nexpr)
+               var sub = nexpr.mtype
                if sub == null then return null # Forward error
 
-               var sup = self.resolve_mtype(ntype)
+               var sup = ntype.mtype
                if sup == null then return null # Forward error
 
                if sup == sub then
@@ -217,6 +218,10 @@ private class TypeVisitor
        # Else return true.
        fun check_can_be_null(anode: ANode, mtype: MType): Bool
        do
+               if mtype isa MNullType then
+                       modelbuilder.warning(anode, "useless-null-test", "Warning: expression is always `null`.")
+                       return true
+               end
                if can_be_null(mtype) then return true
 
                if mtype isa MFormalType then
@@ -240,7 +245,7 @@ private class TypeVisitor
                if not mtype2 isa MNullType then return
 
                # Check of useless null
-               if not check_can_be_null(anode.n_expr, mtype) then return
+               if not can_be_null(mtype) then return
 
                if mtype isa MNullType then
                        # Because of type adaptation, we cannot just stop here
@@ -718,9 +723,6 @@ end
 redef class AMethPropdef
        redef fun do_typing(modelbuilder: ModelBuilder)
        do
-               var nblock = self.n_block
-               if nblock == null then return
-
                var mpropdef = self.mpropdef
                if mpropdef == null then return # skip error
 
@@ -742,6 +744,9 @@ redef class AMethPropdef
                        variable.declared_type = mtype
                end
 
+               var nblock = self.n_block
+               if nblock == null then return
+
                loop
                        v.dirty = false
                        v.visit_stmt(nblock)
@@ -1322,7 +1327,7 @@ redef class AOrElseExpr
                if t1 isa MNullType then
                        self.mtype = t2
                        return
-               else if v.check_can_be_null(n_expr, t1) then
+               else if v.can_be_null(t1) then
                        t1 = t1.as_notnull
                end
 
@@ -1338,35 +1343,41 @@ redef class AOrElseExpr
                end
                self.mtype = t
        end
-end
 
-redef class ATrueExpr
-       redef fun accept_typing(v)
+       redef fun accept_post_typing(v)
        do
-               self.mtype = v.type_bool(self)
+               var t1 = n_expr.mtype
+               if t1 == null then
+                       return
+               else
+                       v.check_can_be_null(n_expr, t1)
+               end
        end
 end
 
-redef class AFalseExpr
+redef class ATrueExpr
        redef fun accept_typing(v)
        do
                self.mtype = v.type_bool(self)
        end
 end
 
-redef class AIntExpr
+redef class AFalseExpr
        redef fun accept_typing(v)
        do
-               var mclass = v.get_mclass(self, "Int")
-               if mclass == null then return # Forward error
-               self.mtype = mclass.mclass_type
+               self.mtype = v.type_bool(self)
        end
 end
 
-redef class AByteExpr
+redef class AIntegerExpr
        redef fun accept_typing(v)
        do
-               var mclass = v.get_mclass(self, "Byte")
+               var mclass: nullable MClass = null
+               if value isa Byte then
+                       mclass = v.get_mclass(self, "Byte")
+               else if value isa Int then
+                       mclass = v.get_mclass(self, "Int")
+               end
                if mclass == null then return # Forward error
                self.mtype = mclass.mclass_type
        end
@@ -1541,7 +1552,10 @@ redef class AIsaExpr
        var cast_type: nullable MType
        redef fun accept_typing(v)
        do
-               var mtype = v.visit_expr_cast(self, self.n_expr, self.n_type)
+               v.visit_expr(n_expr)
+
+               var mtype = v.resolve_mtype(n_type)
+
                self.cast_type = mtype
 
                var variable = self.n_expr.its_variable
@@ -1555,12 +1569,24 @@ redef class AIsaExpr
 
                self.mtype = v.type_bool(self)
        end
+
+       redef fun accept_post_typing(v)
+       do
+               v.check_expr_cast(self, self.n_expr, self.n_type)
+       end
 end
 
 redef class AAsCastExpr
        redef fun accept_typing(v)
        do
-               self.mtype = v.visit_expr_cast(self, self.n_expr, self.n_type)
+               v.visit_expr(n_expr)
+
+               self.mtype = v.resolve_mtype(n_type)
+       end
+
+       redef fun accept_post_typing(v)
+       do
+               v.check_expr_cast(self, self.n_expr, self.n_type)
        end
 end
 
@@ -1575,12 +1601,19 @@ redef class AAsNotnullExpr
                        return
                end
 
-               if v.check_can_be_null(n_expr, mtype) then
+               if v.can_be_null(mtype) then
                        mtype = mtype.as_notnull
                end
 
                self.mtype = mtype
        end
+
+       redef fun accept_post_typing(v)
+       do
+               var mtype = n_expr.mtype
+               if mtype == null then return
+               v.check_can_be_null(n_expr, mtype)
+       end
 end
 
 redef class AParExpr
@@ -1712,6 +1745,18 @@ redef class AEqFormExpr
                super
                v.null_test(self)
        end
+
+       redef fun accept_post_typing(v)
+       do
+               var mtype = n_expr.mtype
+               var mtype2 = n_expr2.mtype
+
+               if mtype == null or mtype2 == null then return
+
+               if not mtype2 isa MNullType then return
+
+               v.check_can_be_null(n_expr, mtype)
+       end
 end
 
 redef class AUnaryopExpr