Merge: new `with` statement
[nit.git] / src / semantize / flow.nit
index 4717d9b..8dad3b7 100644 (file)
@@ -20,6 +20,7 @@ module flow
 import scope
 
 redef class ToolContext
+       # Run `APropdef::do_flow` on each propdef
        var flow_phase: Phase = new FlowPhase(self, [scope_phase])
 end
 
@@ -29,23 +30,21 @@ private class FlowPhase
        redef fun process_npropdef(npropdef) do npropdef.do_flow(toolcontext)
 end
 
-# The visitor that derermine flowcontext for nodes
+# The visitor that determine flowcontext for nodes
 private class FlowVisitor
        super Visitor
 
-       var current_flow_context: FlowContext
+       var current_flow_context = new FlowContext
 
        var toolcontext: ToolContext
 
-       init(toolcontext: ToolContext)
+       init
        do
-               self.toolcontext = toolcontext
-               current_flow_context = new FlowContext
                flows.add(current_flow_context)
                current_flow_context.is_start = true
        end
 
-       var first: nullable ANode
+       var first: nullable ANode = null
 
        redef fun visit(node)
        do
@@ -74,11 +73,11 @@ private class FlowVisitor
                return node.after_flow_context.as(not null)
        end
 
-       var flows: Array[FlowContext] = new Array[FlowContext]
+       var flows = new Array[FlowContext]
 
        fun printflow
        do
-               var file = new OFStream.open("flow.dot")
+               var file = new FileWriter.open("flow.dot")
                file.write("digraph \{\n")
                for f in flows do
                        var s = ""
@@ -165,7 +164,7 @@ private class FlowVisitor
        fun merge_continues_to(before_loop: FlowContext, escapemark: nullable EscapeMark)
        do
                if escapemark == null then return
-               for b in escapemark.continues do
+               for b in escapemark.escapes do
                        var before = b.before_flow_context
                        if before == null then continue # Forward error
                        before_loop.add_loop(before)
@@ -175,7 +174,7 @@ private class FlowVisitor
        fun merge_breaks(escapemark: nullable EscapeMark)
        do
                if escapemark == null then return
-               for b in escapemark.breaks do
+               for b in escapemark.escapes do
                        var before = b.before_flow_context
                        if before == null then continue # Forward error
                        self.make_merge_flow(self.current_flow_context, before)
@@ -187,18 +186,18 @@ end
 # A same `FlowContext` can be shared by more than one `ANode`.
 class FlowContext
        # The reachable previous flow
-       var previous: Array[FlowContext] = new Array[FlowContext]
+       var previous = new Array[FlowContext]
 
        # Additional reachable flow that loop up to self.
-       # Loops apears in `loop`, `while`, `for`, and with `continue`
-       var loops: Array[FlowContext] = new Array[FlowContext]
+       # Loops appears in `loop`, `while`, `for`, and with `continue`
+       var loops = new Array[FlowContext]
 
        private var is_marked_unreachable: Bool = false
 
        # Is the flow dead?
        fun is_unreachable: Bool
        do
-               # Are we explicitely marked unreachable?
+               # Are we explicitly marked unreachable?
                if self.is_marked_unreachable then return true
 
                # Are we the starting flow context?
@@ -209,17 +208,17 @@ class FlowContext
                return false
        end
 
-       # Flag to avoid repeaed errors
+       # Flag to avoid repeated errors
        var is_already_unreachable: Bool = false
 
        # Mark that self is the starting flow context.
        # Such a context is reachable even if there is no previous flow
        var is_start: Bool = false
 
-       # The node that introduce the flow (for debuging)
+       # The node that introduce the flow (for debugging)
        var node: nullable ANode = null
 
-       # Additional information for the flor (for debuging)
+       # Additional information for the flow (for debugging)
        var name: String = ""
 
        # The sub-flow to use if the associated expr is true
@@ -319,22 +318,7 @@ redef class AReturnExpr
        end
 end
 
-redef class AContinueExpr
-       # The flow just before it become unreachable
-       fun before_flow_context: nullable FlowContext
-       do
-               var after = self.after_flow_context
-               if after == null then return null
-               return after.previous.first
-       end
-       redef fun accept_flow_visitor(v)
-       do
-               super
-               v.make_unreachable_flow
-       end
-end
-
-redef class ABreakExpr
+redef class AEscapeExpr
        # The flow just before it become unreachable
        fun before_flow_context: nullable FlowContext
        do
@@ -361,7 +345,7 @@ redef class ADoExpr
        redef fun accept_flow_visitor(v)
        do
                super
-               v.merge_breaks(self.escapemark)
+               v.merge_breaks(self.break_mark)
        end
 end
 
@@ -411,10 +395,10 @@ redef class AWhileExpr
                var after_block = v.current_flow_context
 
                before_loop.add_loop(after_block)
-               v.merge_continues_to(after_block, self.escapemark)
+               v.merge_continues_to(after_block, self.continue_mark)
 
                v.current_flow_context = after_expr.when_false
-               v.merge_breaks(self.escapemark)
+               v.merge_breaks(self.break_mark)
        end
 end
 
@@ -428,10 +412,10 @@ redef class ALoopExpr
                var after_block = v.current_flow_context
 
                before_loop.add_loop(after_block)
-               v.merge_continues_to(after_block, self.escapemark)
+               v.merge_continues_to(after_block, self.continue_mark)
 
                v.make_unreachable_flow
-               v.merge_breaks(self.escapemark)
+               v.merge_breaks(self.break_mark)
        end
 end
 
@@ -447,10 +431,18 @@ redef class AForExpr
                var after_block = v.current_flow_context
 
                before_loop.add_loop(after_block)
-               v.merge_continues_to(after_block, self.escapemark)
+               v.merge_continues_to(after_block, self.continue_mark)
 
                v.make_merge_flow(v.current_flow_context, before_loop)
-               v.merge_breaks(self.escapemark)
+               v.merge_breaks(self.break_mark)
+       end
+end
+
+redef class AWithExpr
+       redef fun accept_flow_visitor(v)
+       do
+               super
+               v.merge_breaks(self.break_mark)
        end
 end
 
@@ -553,7 +545,15 @@ redef class AIsaExpr
        end
 end
 
-redef class AProxyExpr
+redef class AParExpr
+       redef fun accept_flow_visitor(v)
+       do
+               var after_expr = v.visit_expr(self.n_expr)
+               v.current_flow_context = after_expr
+       end
+end
+
+redef class AOnceExpr
        redef fun accept_flow_visitor(v)
        do
                var after_expr = v.visit_expr(self.n_expr)