nitc :: FlowContext
A same FlowContext
can be shared by more than one ANode
.
nitc :: FlowContext :: _is_already_unreachable
Flag to avoid repeated errorsnitc :: FlowContext :: _is_start
Mark that self is the starting flow context.nitc :: FlowContext :: _loops
Additional reachable flow that loop up to self.nitc :: FlowContext :: _name
Additional information for the flow (for debugging)nitc :: FlowContext :: _node
The node that introduce the flow (for debugging)nitc :: FlowContext :: _previous
The reachable previous flownitc :: FlowContext :: _when_false
The sub-flow to use if the associated expr is truenitc :: FlowContext :: _when_true
The sub-flow to use if the associated expr is truenitc :: FlowContext :: add_loop
Add a previous loop flow (iff it is reachable)nitc :: FlowContext :: add_previous
Add a previous flow (iff it is reachable)nitc :: FlowContext :: collect_types
Look in the flow and previous flow and collect all first reachable type adaptation of a local variablenitc :: FlowContext :: defaultinit
nitc :: FlowContext :: is_already_unreachable
Flag to avoid repeated errorsnitc :: FlowContext :: is_already_unreachable=
Flag to avoid repeated errorsnitc :: FlowContext :: is_start=
Mark that self is the starting flow context.nitc :: FlowContext :: is_variable_set
nitc :: FlowContext :: loops
Additional reachable flow that loop up to self.nitc :: FlowContext :: loops=
Additional reachable flow that loop up to self.nitc :: FlowContext :: name=
Additional information for the flow (for debugging)nitc :: FlowContext :: node
The node that introduce the flow (for debugging)nitc :: FlowContext :: node=
The node that introduce the flow (for debugging)nitc :: FlowContext :: previous=
The reachable previous flownitc :: FlowContext :: set_var
Adapt the variable to a static typenitc :: FlowContext :: when_false
The sub-flow to use if the associated expr is truenitc :: FlowContext :: when_false=
The sub-flow to use if the associated expr is truenitc :: FlowContext :: when_true
The sub-flow to use if the associated expr is truenitc :: FlowContext :: when_true=
The sub-flow to use if the associated expr is truenitc $ FlowContext :: SELF
Type of this instance, automatically specialized in every classnitc :: FlowContext :: _is_already_unreachable
Flag to avoid repeated errorsnitc :: FlowContext :: _is_start
Mark that self is the starting flow context.nitc :: FlowContext :: _loops
Additional reachable flow that loop up to self.nitc :: FlowContext :: _name
Additional information for the flow (for debugging)nitc :: FlowContext :: _node
The node that introduce the flow (for debugging)nitc :: FlowContext :: _previous
The reachable previous flownitc :: FlowContext :: _when_false
The sub-flow to use if the associated expr is truenitc :: FlowContext :: _when_true
The sub-flow to use if the associated expr is truenitc :: FlowContext :: add_loop
Add a previous loop flow (iff it is reachable)nitc :: FlowContext :: add_previous
Add a previous flow (iff it is reachable)core :: Object :: class_factory
Implementation used byget_class
to create the specific class.
nitc :: FlowContext :: collect_types
Look in the flow and previous flow and collect all first reachable type adaptation of a local variablecore :: Object :: defaultinit
nitc :: FlowContext :: defaultinit
nitc :: FlowContext :: is_already_unreachable
Flag to avoid repeated errorsnitc :: FlowContext :: is_already_unreachable=
Flag to avoid repeated errorscore :: 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 :: FlowContext :: is_start=
Mark that self is the starting flow context.nitc :: FlowContext :: is_variable_set
nitc :: FlowContext :: loops
Additional reachable flow that loop up to self.nitc :: FlowContext :: loops=
Additional reachable flow that loop up to self.nitc :: FlowContext :: name=
Additional information for the flow (for debugging)core :: Object :: native_class_name
The class name of the object in CString format.nitc :: FlowContext :: node
The node that introduce the flow (for debugging)nitc :: FlowContext :: node=
The node that introduce the flow (for debugging)core :: Object :: output_class_name
Display class name on stdout (debug only).nitc :: FlowContext :: previous=
The reachable previous flownitc :: FlowContext :: set_var
Adapt the variable to a static typenitc :: FlowContext :: when_false
The sub-flow to use if the associated expr is truenitc :: FlowContext :: when_false=
The sub-flow to use if the associated expr is truenitc :: FlowContext :: when_true
The sub-flow to use if the associated expr is truenitc :: FlowContext :: when_true=
The sub-flow to use if the associated expr is true
# A Node in the static flow graph.
# A same `FlowContext` can be shared by more than one `ANode`.
class FlowContext
# The reachable previous flow
var previous = new Array[FlowContext]
# Additional reachable flow that loop up to self.
# 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 explicitly marked unreachable?
if self.is_marked_unreachable then return true
# Are we the starting flow context?
if is_start then return false
# De we have a reachable previous?
if previous.length == 0 then return true
return false
end
# 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 debugging)
var node: nullable ANode = null
# Additional information for the flow (for debugging)
var name: String = ""
# The sub-flow to use if the associated expr is true
var when_true: FlowContext = self
# The sub-flow to use if the associated expr is true
var when_false: FlowContext = self
# Add a previous flow (iff it is reachable)
private fun add_previous(flow: FlowContext)
do
if not flow.is_unreachable and not previous.has(flow) then
previous.add(flow)
end
end
# Add a previous loop flow (iff it is reachable)
private fun add_loop(flow: FlowContext)
do
if not flow.is_unreachable and not previous.has(flow) then
loops.add(flow)
end
end
end
src/semantize/flow.nit:186,1--247,3
redef class FlowContext
private var set_vars: Set[Variable] = new HashSet[Variable]
private fun is_variable_set(variable: Variable): Bool
do
if self.set_vars.has(variable) then return true
var previous = self.previous
if previous.length == 0 then return false
if previous.length == 1 then return previous.first.is_variable_set(variable)
for p in self.previous do
if not p.is_variable_set(variable) then
return false
end
end
# Cache the result
self.set_vars.add(variable)
return true
end
end
src/semantize/local_var_init.nit:85,1--103,3
redef class FlowContext
# Store changes of types because of type evolution
private var vars = new HashMap[Variable, nullable MType]
# Adapt the variable to a static type
# Warning1: do not modify vars directly.
# Warning2: sub-flow may have cached a unadapted variable
private fun set_var(v: TypeVisitor, variable: Variable, mtype: nullable MType)
do
if variable.declared_type == mtype and not variable.is_adapted then return
if vars.has_key(variable) and vars[variable] == mtype then return
self.vars[variable] = mtype
v.dirty = true
variable.is_adapted = true
#node.debug "set {variable} to {mtype or else "X"}"
end
# Look in the flow and previous flow and collect all first reachable type adaptation of a local variable
private fun collect_types(variable: Variable): Array[nullable MType]
do
#node.debug "flow for {variable}"
var res = new Array[nullable MType]
var todo = [self]
var seen = new HashSet[FlowContext]
while not todo.is_empty do
var f = todo.pop
if f.is_unreachable then continue
if seen.has(f) then continue
seen.add f
if f.vars.has_key(variable) then
# Found something. Collect it and do not process further on this path
res.add f.vars[variable]
#f.node.debug "process {variable}: got {f.vars[variable] or else "X"}"
else
todo.add_all f.previous
todo.add_all f.loops
if f.previous.is_empty then
# Root flowcontext mean a parameter or something related
res.add variable.declared_type
#f.node.debug "root process {variable}: got {variable.declared_type or else "X"}"
end
end
end
#self.node.debug "##### end flow for {variable}: {res.join(" ")}"
return res
end
end
src/semantize/typing.nit:836,1--884,3