Merge: doc: fixed some typos and other misc. corrections
[nit.git] / src / semantize / flow.nit
index 522a347..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")
@@ -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
+               # 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,7 +410,7 @@ redef class AWhileExpr
                var after_block = v.current_flow_context
 
                before_loop.add_loop(after_block)
-               v.merge_continues_to(after_block, self.continue_mark)
+               v.merge_continues_to(before_loop, self.continue_mark)
 
                v.current_flow_context = after_expr.when_false
                v.merge_breaks(self.break_mark)
@@ -413,7 +427,7 @@ redef class ALoopExpr
                var after_block = v.current_flow_context
 
                before_loop.add_loop(after_block)
-               v.merge_continues_to(after_block, self.continue_mark)
+               v.merge_continues_to(before_loop, self.continue_mark)
 
                v.make_unreachable_flow
                v.merge_breaks(self.break_mark)
@@ -423,7 +437,9 @@ 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,13 +448,21 @@ redef class AForExpr
                var after_block = v.current_flow_context
 
                before_loop.add_loop(after_block)
-               v.merge_continues_to(after_block, self.continue_mark)
+               v.merge_continues_to(before_loop, self.continue_mark)
 
                v.make_merge_flow(v.current_flow_context, before_loop)
                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
+
 redef class AAssertExpr
        redef fun accept_flow_visitor(v)
        do