scope: refuse `&x` where x is a local variable
[nit.git] / src / semantize / scope.nit
index 0c70a16..2f8a1bf 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
@@ -326,6 +332,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
@@ -461,7 +482,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