interpreter: interpret `with` statement
[nit.git] / src / semantize / typing.nit
index 1d694e6..15d38a2 100644 (file)
@@ -597,6 +597,8 @@ end
 redef class AAttrPropdef
        redef fun do_typing(modelbuilder: ModelBuilder)
        do
+               if not has_value then return
+
                var mpropdef = self.mpropdef.as(not null)
                var v = new TypeVisitor(modelbuilder, mpropdef.mclassdef.mmodule, mpropdef)
                self.selfvariable = v.selfvariable
@@ -609,6 +611,10 @@ redef class AAttrPropdef
                var nblock = self.n_block
                if nblock != null then
                        v.visit_stmt(nblock)
+                       if not nblock.after_flow_context.is_unreachable then
+                               # We reach the end of the init without having a return, it is bad
+                               v.error(self, "Control error: Reached end of block (a 'return' with a value was expected).")
+                       end
                end
        end
 end
@@ -701,6 +707,7 @@ redef class AVardeclExpr
 
                #debug("var {variable}: {mtype}")
 
+               self.mtype = mtype
                self.is_typed = true
        end
 end
@@ -975,7 +982,7 @@ redef class AForExpr
                        is_col = true
                end
 
-               if mapit_cla != null and v.is_subtype(ittype, mapit_cla.get_mtype([objcla.mclass_type, objcla.mclass_type.as_nullable])) then
+               if mapit_cla != null and v.is_subtype(ittype, mapit_cla.get_mtype([objcla.mclass_type.as_nullable, objcla.mclass_type.as_nullable])) then
                        # Map Iterator
                        var coltype = ittype.supertype_to(v.mmodule, v.anchor, mapit_cla)
                        var variables = self.variables
@@ -1059,6 +1066,24 @@ redef class AForExpr
        end
 end
 
+redef class AWithExpr
+       var method_start: nullable CallSite
+       var method_finish: nullable CallSite
+
+       redef fun accept_typing(v: TypeVisitor)
+       do
+               var mtype = v.visit_expr(n_expr)
+               if mtype == null then return
+
+               method_start = v.get_method(self, mtype, "start", n_expr isa ASelfExpr)
+               method_finish = v.get_method(self, mtype, "finish", n_expr isa ASelfExpr)
+
+               v.visit_stmt(n_block)
+               self.mtype = n_block.mtype
+               self.is_typed = true
+       end
+end
+
 redef class AAssertExpr
        redef fun accept_typing(v)
        do
@@ -1243,7 +1268,7 @@ redef class AArrayExpr
                if mtype == null then
                        mtype = v.merge_types(self, mtypes)
                end
-               if mtype == null then
+               if mtype == null or mtype isa MNullType then
                        v.error(self, "Type Error: ambiguous array type {mtypes.join(" ")}")
                        return
                end