X-Git-Url: http://nitlanguage.org diff --git a/src/semantize/typing.nit b/src/semantize/typing.nit index ffd68e7..1b53f65 100644 --- a/src/semantize/typing.nit +++ b/src/semantize/typing.nit @@ -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