Merge: Contract implementation
[nit.git] / src / semantize / scope.nit
index 5f9c748..de85c22 100644 (file)
@@ -71,6 +71,9 @@ private class ScopeVisitor
        # The tool context used to display errors
        var toolcontext: ToolContext
 
+       # The analysed property
+       var propdef: APropdef
+
        var selfvariable = new Variable("self")
 
        init
@@ -248,10 +251,13 @@ redef class ANode
 end
 
 redef class APropdef
+       # The break escape mark associated with the return
+       var return_mark: nullable EscapeMark
+
        # Entry point of the scope analysis
        fun do_scope(toolcontext: ToolContext)
        do
-               var v = new ScopeVisitor(toolcontext)
+               var v = new ScopeVisitor(toolcontext, self)
                v.enter_visit(self)
                v.shift_scope
        end
@@ -262,6 +268,11 @@ redef class AParam
        var variable: nullable Variable
        redef fun accept_scope_visitor(v)
        do
+               if variable != null then
+                       v.register_variable(self.n_id, variable.as(not null))
+                       return
+               end
+
                super
                var nid = self.n_id
                var variable = new Variable(nid.text)
@@ -326,6 +337,21 @@ redef class ABreakExpr
        end
 end
 
+redef class AReturnExpr
+       redef fun accept_scope_visitor(v)
+       do
+               super
+
+               var escapemark = v.propdef.return_mark
+               if escapemark == null then
+                       escapemark = new EscapeMark
+                       v.propdef.return_mark = escapemark
+               end
+
+               escapemark.escapes.add(self)
+               self.escapemark = escapemark
+       end
+end
 
 redef class ADoExpr
        # The break escape mark associated with the 'do' block
@@ -335,6 +361,7 @@ redef class ADoExpr
        do
                self.break_mark = v.make_escape_mark(n_label, false)
                v.enter_visit_block(n_block, self.break_mark)
+               v.enter_visit_block(n_catch)
        end
 end
 
@@ -460,7 +487,7 @@ redef class ACallFormExpr
                        var variable = v.search_variable(name)
                        if variable != null then
                                var n: AExpr
-                               if not n_args.n_exprs.is_empty or n_args isa AParExprs then
+                               if not n_args.n_exprs.is_empty or n_args isa AParExprs or self isa ACallrefExpr then
                                        v.error(self, "Error: `{name}` is a variable, not a method.")
                                        return
                                end
@@ -501,3 +528,11 @@ redef class ACallReassignExpr
                return new AVarReassignExpr.init_avarreassignexpr(n_qid.n_id, n_assign_op, n_value)
        end
 end
+
+redef class ALambdaExpr
+       redef fun accept_scope_visitor(v)
+       do
+               # TODO
+               return
+       end
+end