nitc :: FlowVisitor
nitc :: FlowVisitor :: _first
nitc :: FlowVisitor :: _flows
nitc :: FlowVisitor :: _toolcontext
nitc :: FlowVisitor :: defaultinit
nitc :: FlowVisitor :: first
nitc :: FlowVisitor :: first=
nitc :: FlowVisitor :: flows
nitc :: FlowVisitor :: flows=
nitc :: FlowVisitor :: make_merge_flow
nitc :: FlowVisitor :: make_sub_flow
nitc :: FlowVisitor :: merge_breaks
nitc :: FlowVisitor :: printflow
nitc :: FlowVisitor :: toolcontext
nitc :: FlowVisitor :: toolcontext=
nitc :: FlowVisitor :: visit_expr
nitc $ FlowVisitor :: SELF
Type of this instance, automatically specialized in every classnitc $ FlowVisitor :: init
nitc :: FlowVisitor :: _first
nitc :: FlowVisitor :: _flows
nitc :: FlowVisitor :: _toolcontext
core :: Object :: class_factory
Implementation used byget_class
to create the specific class.
nitc :: Visitor :: current_node=
The current visited nodecore :: Object :: defaultinit
nitc :: FlowVisitor :: defaultinit
nitc :: Visitor :: defaultinit
nitc :: Visitor :: enter_visit
Ask the visitor to visit a given node.nitc :: FlowVisitor :: first
nitc :: FlowVisitor :: first=
nitc :: FlowVisitor :: flows
nitc :: FlowVisitor :: flows=
core :: Object :: is_same_instance
Return true ifself
and other
are the same instance (i.e. same identity).
core :: Object :: is_same_serialized
Isself
the same as other
in a serialization context?
core :: Object :: is_same_type
Return true ifself
and other
have the same dynamic type.
nitc :: FlowVisitor :: make_merge_flow
nitc :: FlowVisitor :: make_sub_flow
nitc :: FlowVisitor :: merge_breaks
core :: Object :: native_class_name
The class name of the object in CString format.core :: Object :: output_class_name
Display class name on stdout (debug only).nitc :: FlowVisitor :: printflow
nitc :: FlowVisitor :: toolcontext
nitc :: FlowVisitor :: toolcontext=
nitc :: FlowVisitor :: visit_expr
# The visitor that determine flowcontext for nodes
private class FlowVisitor
super Visitor
var current_flow_context = new FlowContext
var toolcontext: ToolContext
init
do
flows.add(current_flow_context)
current_flow_context.is_start = true
end
var first: nullable ANode = null
redef fun visit(node)
do
if first == null then first = node
if current_flow_context.node == null then current_flow_context.node = node
node.accept_flow_visitor(self)
if node isa AExpr then
var flow = self.current_flow_context
node.after_flow_context = flow
# Force the creation of a specific merge after the analysis of the node.
if flow.when_true != flow or flow.when_false != flow then
self.make_sub_flow
self.current_flow_context.name = "AUTOSUB"
end
end
if first == node then
#self.printflow
end
end
fun visit_expr(node: AExpr): FlowContext
do
self.enter_visit(node)
return node.after_flow_context.as(not null)
end
var flows = new Array[FlowContext]
fun printflow
do
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
s = "\\nmain={f.node.as(AExpr).after_flow_context.object_id}"
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
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
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")
file.close
end
fun make_sub_flow: FlowContext
do
var flow = new FlowContext
flows.add(flow)
flow.node = current_node
flow.add_previous(self.current_flow_context)
self.current_flow_context = flow
return flow
end
fun make_merge_flow(flow1, flow2: FlowContext): FlowContext
do
var flow = new FlowContext
flows.add(flow)
flow.node = current_node
flow.add_previous(flow1)
flow.add_previous(flow2)
self.current_flow_context = flow
return flow
end
fun make_true_false_flow(true_flow, false_flow: FlowContext): FlowContext
do
var flow = new FlowContext
flows.add(flow)
flow.node = current_node
flow.add_previous(true_flow)
flow.add_previous(false_flow)
flow.when_true = true_flow
flow.when_false = false_flow
self.current_flow_context = flow
return flow
end
fun make_sub_true_false_flow: FlowContext
do
var orig_flow = self.current_flow_context
var true_flow = new FlowContext
flows.add(true_flow)
true_flow.node = current_node
true_flow.add_previous(orig_flow)
true_flow.name = "TRUE"
var false_flow = new FlowContext
flows.add(false_flow)
false_flow.node = current_node
false_flow.add_previous(orig_flow)
false_flow.name = "FALSE"
return make_true_false_flow(true_flow, false_flow)
end
fun make_unreachable_flow: FlowContext
do
var flow = new FlowContext
flows.add(flow)
flow.node = current_node
flow.add_previous(self.current_flow_context)
flow.is_marked_unreachable = true
self.current_flow_context = flow
return flow
end
fun merge_continues_to(before_loop: FlowContext, escapemark: nullable EscapeMark)
do
if escapemark == null then return
for b in escapemark.escapes do
var before = b.before_flow_context
if before == null then continue # Forward error
before_loop.add_loop(before)
end
end
fun merge_breaks(escapemark: nullable EscapeMark)
do
if escapemark == null then return
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)
end
end
end
src/semantize/flow.nit:33,1--184,3