Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / semantize / flow.nit
index 65f5c7b..3d27623 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
 
@@ -33,19 +34,17 @@ end
 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
@@ -78,8 +77,8 @@ private class FlowVisitor
 
        fun printflow
        do
-               var file = new OFStream.open("flow.dot")
-               file.write("digraph \{\n")
+               var file = new FileWriter.open("flow.dot")
+               file.write("digraph \{\nnode[shape=box];")
                for f in flows do
                        var s = ""
                        if f.node isa AExpr then
@@ -87,13 +86,14 @@ private class FlowVisitor
                        end
                        file.write "F{f.object_id} [label=\"{f.object_id}\\n{f.node.location}\\n{f.node.class_name}\\n{f.name}{s}\"];\n"
                        for p in f.previous do
-                               file.write "F{p.object_id} -> F{f.object_id};\n"
+                               s = ""
+                               if f.when_true == p then s = "[label=TRUE, style=dotted]"
+                               if f.when_false == p then s = "[label=FALSE, style=dotted]"
+                               if f.when_true == p and f.when_false == p then s = "[label=TRUE_FALSE, style=dotted]"
+                               file.write "F{p.object_id} -> F{f.object_id}{s};\n"
                        end
-                       if f.when_true != f then
-                               file.write "F{f.object_id} -> F{f.when_true.object_id}[label=TRUE, style=dotted];\n"
-                       end
-                       if f.when_false != f then
-                               file.write "F{f.object_id} -> F{f.when_false.object_id}[label=FALSE,style=dotted];\n"
+                       for p in f.loops do
+                               file.write "F{p.object_id} -> F{f.object_id}[label=LOOP, style=dashed, constraint=false];\n"
                        end
                end
                file.write("\}\n")
@@ -165,7 +165,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 +175,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)
@@ -263,10 +263,10 @@ redef class APropdef
 
 
        # The starting flow
-       var before_flow_context: nullable FlowContext
+       var before_flow_context: nullable FlowContext is noautoinit
 
        # The ending flow
-       var after_flow_context: nullable FlowContext
+       var after_flow_context: nullable FlowContext is noautoinit
 
        redef fun accept_flow_visitor(v)
        do
@@ -345,8 +345,22 @@ end
 redef class ADoExpr
        redef fun accept_flow_visitor(v)
        do
-               super
-               v.merge_breaks(self.escapemark)
+               # FlowContext before the block
+               var before_block = v.make_sub_flow
+
+               # Visit the bloc, then merge the breaks
+               v.enter_visit(self.n_block)
+               v.merge_breaks(self.break_mark)
+               var after_block =  v.current_flow_context
+
+               # Visit the catch if there is one
+               if self.n_catch != null then
+                       var before_catch = v.make_sub_flow
+                       v.make_merge_flow(before_block, after_block)
+                       v.enter_visit(self.n_catch)
+                       var after_catch = v.current_flow_context
+                       v.make_merge_flow(before_catch, after_catch)
+               end
        end
 end
 
@@ -396,10 +410,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(before_loop, self.continue_mark)
 
                v.current_flow_context = after_expr.when_false
-               v.merge_breaks(self.escapemark)
+               v.merge_breaks(self.break_mark)
        end
 end
 
@@ -413,17 +427,19 @@ 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(before_loop, self.continue_mark)
 
                v.make_unreachable_flow
-               v.merge_breaks(self.escapemark)
+               v.merge_breaks(self.break_mark)
        end
 end
 
 redef class AForExpr
        redef fun accept_flow_visitor(v)
        do
-               v.enter_visit(self.n_expr)
+               for g in n_groups do
+                       v.enter_visit(g.n_expr)
+               end
 
                var before_loop = v.make_sub_flow
 
@@ -432,10 +448,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(before_loop, 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
 
@@ -538,7 +562,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)