A Node in the static flow graph.

A same FlowContext can be shared by more than one ANode.

Introduced properties

private var _is_already_unreachable: Bool

nitc :: FlowContext :: _is_already_unreachable

Flag to avoid repeated errors
private var _is_start: Bool

nitc :: FlowContext :: _is_start

Mark that self is the starting flow context.
private var _loops: Array[FlowContext]

nitc :: FlowContext :: _loops

Additional reachable flow that loop up to self.
private var _name: String

nitc :: FlowContext :: _name

Additional information for the flow (for debugging)
private var _node: nullable ANode

nitc :: FlowContext :: _node

The node that introduce the flow (for debugging)
private var _previous: Array[FlowContext]

nitc :: FlowContext :: _previous

The reachable previous flow
private var _vars: HashMap[Variable, nullable MType]

nitc :: FlowContext :: _vars

Store changes of types because of type evolution
private var _when_false: FlowContext

nitc :: FlowContext :: _when_false

The sub-flow to use if the associated expr is true
private var _when_true: FlowContext

nitc :: FlowContext :: _when_true

The sub-flow to use if the associated expr is true
private fun add_loop(flow: FlowContext)

nitc :: FlowContext :: add_loop

Add a previous loop flow (iff it is reachable)
private fun add_previous(flow: FlowContext)

nitc :: FlowContext :: add_previous

Add a previous flow (iff it is reachable)
private fun collect_types(variable: Variable): Array[nullable MType]

nitc :: FlowContext :: collect_types

Look in the flow and previous flow and collect all first reachable type adaptation of a local variable
fun is_already_unreachable: Bool

nitc :: FlowContext :: is_already_unreachable

Flag to avoid repeated errors
protected fun is_already_unreachable=(is_already_unreachable: Bool)

nitc :: FlowContext :: is_already_unreachable=

Flag to avoid repeated errors
private fun is_marked_unreachable=(is_marked_unreachable: Bool)

nitc :: FlowContext :: is_marked_unreachable=

fun is_start: Bool

nitc :: FlowContext :: is_start

Mark that self is the starting flow context.
protected fun is_start=(is_start: Bool)

nitc :: FlowContext :: is_start=

Mark that self is the starting flow context.
fun is_unreachable: Bool

nitc :: FlowContext :: is_unreachable

Is the flow dead?
private fun is_variable_set(variable: Variable): Bool

nitc :: FlowContext :: is_variable_set

fun loops: Array[FlowContext]

nitc :: FlowContext :: loops

Additional reachable flow that loop up to self.
protected fun loops=(loops: Array[FlowContext])

nitc :: FlowContext :: loops=

Additional reachable flow that loop up to self.
fun name: String

nitc :: FlowContext :: name

Additional information for the flow (for debugging)
protected fun name=(name: String)

nitc :: FlowContext :: name=

Additional information for the flow (for debugging)
fun node: nullable ANode

nitc :: FlowContext :: node

The node that introduce the flow (for debugging)
protected fun node=(node: nullable ANode)

nitc :: FlowContext :: node=

The node that introduce the flow (for debugging)
fun previous: Array[FlowContext]

nitc :: FlowContext :: previous

The reachable previous flow
protected fun previous=(previous: Array[FlowContext])

nitc :: FlowContext :: previous=

The reachable previous flow
private fun set_var(v: TypeVisitor, variable: Variable, mtype: nullable MType)

nitc :: FlowContext :: set_var

Adapt the variable to a static type
private fun set_vars: Set[Variable]

nitc :: FlowContext :: set_vars

private fun set_vars=(set_vars: Set[Variable])

nitc :: FlowContext :: set_vars=

private fun vars: HashMap[Variable, nullable MType]

nitc :: FlowContext :: vars

Store changes of types because of type evolution
private fun vars=(vars: HashMap[Variable, nullable MType])

nitc :: FlowContext :: vars=

Store changes of types because of type evolution
fun when_false: FlowContext

nitc :: FlowContext :: when_false

The sub-flow to use if the associated expr is true
protected fun when_false=(when_false: FlowContext)

nitc :: FlowContext :: when_false=

The sub-flow to use if the associated expr is true
fun when_true: FlowContext

nitc :: FlowContext :: when_true

The sub-flow to use if the associated expr is true
protected fun when_true=(when_true: FlowContext)

nitc :: FlowContext :: when_true=

The sub-flow to use if the associated expr is true

Redefined properties

redef type SELF: FlowContext

nitc $ FlowContext :: SELF

Type of this instance, automatically specialized in every class

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
private var _is_already_unreachable: Bool

nitc :: FlowContext :: _is_already_unreachable

Flag to avoid repeated errors
private var _is_start: Bool

nitc :: FlowContext :: _is_start

Mark that self is the starting flow context.
private var _loops: Array[FlowContext]

nitc :: FlowContext :: _loops

Additional reachable flow that loop up to self.
private var _name: String

nitc :: FlowContext :: _name

Additional information for the flow (for debugging)
private var _node: nullable ANode

nitc :: FlowContext :: _node

The node that introduce the flow (for debugging)
private var _previous: Array[FlowContext]

nitc :: FlowContext :: _previous

The reachable previous flow
private var _vars: HashMap[Variable, nullable MType]

nitc :: FlowContext :: _vars

Store changes of types because of type evolution
private var _when_false: FlowContext

nitc :: FlowContext :: _when_false

The sub-flow to use if the associated expr is true
private var _when_true: FlowContext

nitc :: FlowContext :: _when_true

The sub-flow to use if the associated expr is true
private fun add_loop(flow: FlowContext)

nitc :: FlowContext :: add_loop

Add a previous loop flow (iff it is reachable)
private fun add_previous(flow: FlowContext)

nitc :: FlowContext :: add_previous

Add a previous flow (iff it is reachable)
protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
private fun collect_types(variable: Variable): Array[nullable MType]

nitc :: FlowContext :: collect_types

Look in the flow and previous flow and collect all first reachable type adaptation of a local variable
fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
fun hash: Int

core :: Object :: hash

The hash code of the object.
init init

core :: Object :: init

fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
fun is_already_unreachable: Bool

nitc :: FlowContext :: is_already_unreachable

Flag to avoid repeated errors
protected fun is_already_unreachable=(is_already_unreachable: Bool)

nitc :: FlowContext :: is_already_unreachable=

Flag to avoid repeated errors
private fun is_marked_unreachable=(is_marked_unreachable: Bool)

nitc :: FlowContext :: is_marked_unreachable=

intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
fun is_start: Bool

nitc :: FlowContext :: is_start

Mark that self is the starting flow context.
protected fun is_start=(is_start: Bool)

nitc :: FlowContext :: is_start=

Mark that self is the starting flow context.
fun is_unreachable: Bool

nitc :: FlowContext :: is_unreachable

Is the flow dead?
private fun is_variable_set(variable: Variable): Bool

nitc :: FlowContext :: is_variable_set

fun loops: Array[FlowContext]

nitc :: FlowContext :: loops

Additional reachable flow that loop up to self.
protected fun loops=(loops: Array[FlowContext])

nitc :: FlowContext :: loops=

Additional reachable flow that loop up to self.
fun name: String

nitc :: FlowContext :: name

Additional information for the flow (for debugging)
protected fun name=(name: String)

nitc :: FlowContext :: name=

Additional information for the flow (for debugging)
private intern fun native_class_name: CString

core :: Object :: native_class_name

The class name of the object in CString format.
fun node: nullable ANode

nitc :: FlowContext :: node

The node that introduce the flow (for debugging)
protected fun node=(node: nullable ANode)

nitc :: FlowContext :: node=

The node that introduce the flow (for debugging)
intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
fun previous: Array[FlowContext]

nitc :: FlowContext :: previous

The reachable previous flow
protected fun previous=(previous: Array[FlowContext])

nitc :: FlowContext :: previous=

The reachable previous flow
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
private fun set_var(v: TypeVisitor, variable: Variable, mtype: nullable MType)

nitc :: FlowContext :: set_var

Adapt the variable to a static type
private fun set_vars: Set[Variable]

nitc :: FlowContext :: set_vars

private fun set_vars=(set_vars: Set[Variable])

nitc :: FlowContext :: set_vars=

intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
private fun vars: HashMap[Variable, nullable MType]

nitc :: FlowContext :: vars

Store changes of types because of type evolution
private fun vars=(vars: HashMap[Variable, nullable MType])

nitc :: FlowContext :: vars=

Store changes of types because of type evolution
fun when_false: FlowContext

nitc :: FlowContext :: when_false

The sub-flow to use if the associated expr is true
protected fun when_false=(when_false: FlowContext)

nitc :: FlowContext :: when_false=

The sub-flow to use if the associated expr is true
fun when_true: FlowContext

nitc :: FlowContext :: when_true

The sub-flow to use if the associated expr is true
protected fun when_true=(when_true: FlowContext)

nitc :: FlowContext :: when_true=

The sub-flow to use if the associated expr is true
package_diagram nitc::FlowContext FlowContext core::Object Object nitc::FlowContext->core::Object

Parents

interface Object

core :: Object

The root of the class hierarchy.

Class definitions

nitc $ FlowContext
# 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

nitc :: local_var_init $ FlowContext
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

nitc :: typing $ FlowContext
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