Visitor to build all contracts.

Introduced properties

private var _current_location: Location

nitc :: ContractsVisitor :: _current_location

The current_location can corresponding of the annotation or method location.
private var _find_no_contract: Bool

nitc :: ContractsVisitor :: _find_no_contract

is no_contract annotation was found
private var _in_contract_attribute: nullable MAttribute

nitc :: ContractsVisitor :: _in_contract_attribute

The reference to the in_contract attribute.
private var _is_intro_contract: Bool

nitc :: ContractsVisitor :: _is_intro_contract

Is the contrat is an introduction or not?
private var _m_signature: MSignature

nitc :: ContractsVisitor :: _m_signature

The MSignature of the actual build contract
private var _mainmodule: MModule

nitc :: ContractsVisitor :: _mainmodule

The main module
private var _n_signature: ASignature

nitc :: ContractsVisitor :: _n_signature

The ASignature of the actual build contract
private var _toolcontext: ToolContext

nitc :: ContractsVisitor :: _toolcontext

Instance of the toolcontext
private var _visited_class: nullable AClassdef

nitc :: ContractsVisitor :: _visited_class

Actual visited class
private var _visited_module: AModule

nitc :: ContractsVisitor :: _visited_module

Actual visited module
private fun ast_builder=(ast_builder: ASTBuilder)

nitc :: ContractsVisitor :: ast_builder=

private fun build_contract(n_annotations: Array[AAnnotation], mcontract: MContract, mclassdef: MClassDef)

nitc :: ContractsVisitor :: build_contract

Define the new contract take in consideration that an old contract exist or not
private fun current_location: Location

nitc :: ContractsVisitor :: current_location

The current_location can corresponding of the annotation or method location.
private fun current_location=(current_location: Location)

nitc :: ContractsVisitor :: current_location=

The current_location can corresponding of the annotation or method location.
init defaultinit(toolcontext: ToolContext, mainmodule: MModule, visited_module: AModule, ast_builder: ASTBuilder, visited_class: nullable AClassdef)

nitc :: ContractsVisitor :: defaultinit

private fun define_signature(mcontract: MContract, nsignature: nullable ASignature, msignature: nullable MSignature)

nitc :: ContractsVisitor :: define_signature

Method use to define the signature part of the method ASignature and MSignature
private fun encapsulated_contract_call(visited_method: AMethPropdef, call_to_contracts: Array[ACallExpr]): AIfExpr

nitc :: ContractsVisitor :: encapsulated_contract_call

Return an AIfExpr with the contract encapsulated by an if to check if it's already in a contract verification.
private fun find_no_contract: Bool

nitc :: ContractsVisitor :: find_no_contract

is no_contract annotation was found
private fun find_no_contract=(find_no_contract: Bool)

nitc :: ContractsVisitor :: find_no_contract=

is no_contract annotation was found
private fun get_incontract: MAttribute

nitc :: ContractsVisitor :: get_incontract

Return the _in_contract_ attribute.
private fun in_contract_attribute: nullable MAttribute

nitc :: ContractsVisitor :: in_contract_attribute

The reference to the in_contract attribute.
private fun in_contract_attribute=(in_contract_attribute: nullable MAttribute)

nitc :: ContractsVisitor :: in_contract_attribute=

The reference to the in_contract attribute.
private fun inject_incontract_in_sys

nitc :: ContractsVisitor :: inject_incontract_in_sys

Inject the incontract attribute (_in_contract_) in the Sys class
private fun is_intro_contract: Bool

nitc :: ContractsVisitor :: is_intro_contract

Is the contrat is an introduction or not?
private fun is_intro_contract=(is_intro_contract: Bool)

nitc :: ContractsVisitor :: is_intro_contract=

Is the contrat is an introduction or not?
private fun m_signature: MSignature

nitc :: ContractsVisitor :: m_signature

The MSignature of the actual build contract
private fun m_signature=(m_signature: MSignature)

nitc :: ContractsVisitor :: m_signature=

The MSignature of the actual build contract
private fun mainmodule: MModule

nitc :: ContractsVisitor :: mainmodule

The main module
private fun mainmodule=(mainmodule: MModule)

nitc :: ContractsVisitor :: mainmodule=

The main module
private fun n_signature: ASignature

nitc :: ContractsVisitor :: n_signature

The ASignature of the actual build contract
private fun n_signature=(n_signature: ASignature)

nitc :: ContractsVisitor :: n_signature=

The ASignature of the actual build contract
private fun toolcontext: ToolContext

nitc :: ContractsVisitor :: toolcontext

Instance of the toolcontext
private fun toolcontext=(toolcontext: ToolContext)

nitc :: ContractsVisitor :: toolcontext=

Instance of the toolcontext
private fun visited_class: nullable AClassdef

nitc :: ContractsVisitor :: visited_class

Actual visited class
private fun visited_class=(visited_class: nullable AClassdef)

nitc :: ContractsVisitor :: visited_class=

Actual visited class
private fun visited_module: AModule

nitc :: ContractsVisitor :: visited_module

Actual visited module
private fun visited_module=(visited_module: AModule)

nitc :: ContractsVisitor :: visited_module=

Actual visited module

Redefined properties

redef type SELF: ContractsVisitor

nitc $ ContractsVisitor :: SELF

Type of this instance, automatically specialized in every class
redef fun visit(node: ANode)

nitc $ ContractsVisitor :: visit

What the visitor do when a node is visited

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 _current_location: Location

nitc :: ContractsVisitor :: _current_location

The current_location can corresponding of the annotation or method location.
private var _current_node: nullable ANode

nitc :: Visitor :: _current_node

The current visited node
private var _find_no_contract: Bool

nitc :: ContractsVisitor :: _find_no_contract

is no_contract annotation was found
private var _in_contract_attribute: nullable MAttribute

nitc :: ContractsVisitor :: _in_contract_attribute

The reference to the in_contract attribute.
private var _is_intro_contract: Bool

nitc :: ContractsVisitor :: _is_intro_contract

Is the contrat is an introduction or not?
private var _m_signature: MSignature

nitc :: ContractsVisitor :: _m_signature

The MSignature of the actual build contract
private var _mainmodule: MModule

nitc :: ContractsVisitor :: _mainmodule

The main module
private var _n_signature: ASignature

nitc :: ContractsVisitor :: _n_signature

The ASignature of the actual build contract
private var _toolcontext: ToolContext

nitc :: ContractsVisitor :: _toolcontext

Instance of the toolcontext
private var _visited_class: nullable AClassdef

nitc :: ContractsVisitor :: _visited_class

Actual visited class
private var _visited_module: AModule

nitc :: ContractsVisitor :: _visited_module

Actual visited module
private fun ast_builder=(ast_builder: ASTBuilder)

nitc :: ContractsVisitor :: ast_builder=

private fun build_contract(n_annotations: Array[AAnnotation], mcontract: MContract, mclassdef: MClassDef)

nitc :: ContractsVisitor :: build_contract

Define the new contract take in consideration that an old contract exist or not
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 current_location: Location

nitc :: ContractsVisitor :: current_location

The current_location can corresponding of the annotation or method location.
private fun current_location=(current_location: Location)

nitc :: ContractsVisitor :: current_location=

The current_location can corresponding of the annotation or method location.
fun current_node: nullable ANode

nitc :: Visitor :: current_node

The current visited node
fun current_node=(current_node: nullable ANode)

nitc :: Visitor :: current_node=

The current visited node
init defaultinit(toolcontext: ToolContext, mainmodule: MModule, visited_module: AModule, ast_builder: ASTBuilder, visited_class: nullable AClassdef)

nitc :: ContractsVisitor :: defaultinit

private fun define_signature(mcontract: MContract, nsignature: nullable ASignature, msignature: nullable MSignature)

nitc :: ContractsVisitor :: define_signature

Method use to define the signature part of the method ASignature and MSignature
private fun encapsulated_contract_call(visited_method: AMethPropdef, call_to_contracts: Array[ACallExpr]): AIfExpr

nitc :: ContractsVisitor :: encapsulated_contract_call

Return an AIfExpr with the contract encapsulated by an if to check if it's already in a contract verification.
fun enter_visit(e: nullable ANode)

nitc :: Visitor :: enter_visit

Ask the visitor to visit a given node.
private fun find_no_contract: Bool

nitc :: ContractsVisitor :: find_no_contract

is no_contract annotation was found
private fun find_no_contract=(find_no_contract: Bool)

nitc :: ContractsVisitor :: find_no_contract=

is no_contract annotation was found
fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
private fun get_incontract: MAttribute

nitc :: ContractsVisitor :: get_incontract

Return the _in_contract_ attribute.
fun hash: Int

core :: Object :: hash

The hash code of the object.
private fun in_contract_attribute: nullable MAttribute

nitc :: ContractsVisitor :: in_contract_attribute

The reference to the in_contract attribute.
private fun in_contract_attribute=(in_contract_attribute: nullable MAttribute)

nitc :: ContractsVisitor :: in_contract_attribute=

The reference to the in_contract attribute.
init init

core :: Object :: init

private fun inject_incontract_in_sys

nitc :: ContractsVisitor :: inject_incontract_in_sys

Inject the incontract attribute (_in_contract_) in the Sys class
fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
private fun is_intro_contract: Bool

nitc :: ContractsVisitor :: is_intro_contract

Is the contrat is an introduction or not?
private fun is_intro_contract=(is_intro_contract: Bool)

nitc :: ContractsVisitor :: is_intro_contract=

Is the contrat is an introduction or not?
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.
private fun m_signature: MSignature

nitc :: ContractsVisitor :: m_signature

The MSignature of the actual build contract
private fun m_signature=(m_signature: MSignature)

nitc :: ContractsVisitor :: m_signature=

The MSignature of the actual build contract
private fun mainmodule: MModule

nitc :: ContractsVisitor :: mainmodule

The main module
private fun mainmodule=(mainmodule: MModule)

nitc :: ContractsVisitor :: mainmodule=

The main module
private fun n_signature: ASignature

nitc :: ContractsVisitor :: n_signature

The ASignature of the actual build contract
private fun n_signature=(n_signature: ASignature)

nitc :: ContractsVisitor :: n_signature=

The ASignature of the actual build contract
private intern fun native_class_name: CString

core :: Object :: native_class_name

The class name of the object in CString format.
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 serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
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 toolcontext: ToolContext

nitc :: ContractsVisitor :: toolcontext

Instance of the toolcontext
private fun toolcontext=(toolcontext: ToolContext)

nitc :: ContractsVisitor :: toolcontext=

Instance of the toolcontext
protected abstract fun visit(e: ANode)

nitc :: Visitor :: visit

What the visitor do when a node is visited
private fun visited_class: nullable AClassdef

nitc :: ContractsVisitor :: visited_class

Actual visited class
private fun visited_class=(visited_class: nullable AClassdef)

nitc :: ContractsVisitor :: visited_class=

Actual visited class
private fun visited_module: AModule

nitc :: ContractsVisitor :: visited_module

Actual visited module
private fun visited_module=(visited_module: AModule)

nitc :: ContractsVisitor :: visited_module=

Actual visited module
package_diagram nitc::contracts::ContractsVisitor ContractsVisitor nitc::Visitor Visitor nitc::contracts::ContractsVisitor->nitc::Visitor core::Object Object nitc::Visitor->core::Object ...core::Object ... ...core::Object->core::Object

Ancestors

interface Object

core :: Object

The root of the class hierarchy.

Parents

abstract class Visitor

nitc :: Visitor

Abstract standard visitor on the AST

Class definitions

nitc $ ContractsVisitor
# Visitor to build all contracts.
private class ContractsVisitor
	super Visitor

	# Instance of the toolcontext
	var toolcontext: ToolContext

	# The main module
	# It's strore to define if the contract need to be build depending on the selected policy `--no-contract` `--full-contract` or default
	var mainmodule: MModule

	# Actual visited module
	var visited_module: AModule

	var ast_builder: ASTBuilder

	# The `ASignature` of the actual build contract
	var n_signature: ASignature is noinit

	# The `MSignature` of the actual build contract
	var m_signature: MSignature is noinit

	# The `current_location` can corresponding of the annotation or method location.
	var current_location: Location is noinit

	# Is the contrat is an introduction or not?
	# This attribute has the same value as the `is_intro` of the propdef attached to the contract.
	# Note : For MClassDef `is_intro_contract == false`. This is due to the fact that a method for checking invariants is systematically added to the root object class.
	var is_intro_contract: Bool is noinit

	# Actual visited class
	var visited_class: nullable AClassdef

	# is `no_contract` annotation was found
	var find_no_contract = false

	# The reference to the `in_contract` attribute.
	# This attribute is used to disable contract verification when you are already in a contract verification.
	# Keep the `in_contract` attribute to avoid searching at each contrat
	var in_contract_attribute: nullable MAttribute = null

	redef fun visit(node)
	do
		node.create_contracts(self)
		node.visit_all(self)
	end

	# Method use to define the signature part of the method `ASignature` and `MSignature`
	# The given `mcontract` provided `adapt_nsignature` and `adapt_msignature` to copy and adapt the given signature (`nsignature` and `msignature`)
	fun define_signature(mcontract: MContract, nsignature: nullable ASignature, msignature: nullable MSignature)
	do
		if nsignature != null and msignature != null then nsignature.ret_type = msignature.return_mtype
		self.n_signature = mcontract.adapt_nsignature(nsignature)
		self.m_signature = mcontract.adapt_msignature(msignature)
	end

	# Define the new contract take in consideration that an old contract exist or not
	private fun build_contract(n_annotations: Array[AAnnotation], mcontract: MContract, mclassdef: MClassDef)
	do
		var n_conditions = new Array[AExpr]
		# Retrieving the expression provided in the annotation
		for n_annotation in n_annotations do n_conditions.add n_annotation.construct_condition(self)
		if is_intro_contract then
			# Create new contract method
			mcontract.create_intro_contract(self, n_conditions, mclassdef)
		else
			# Create a redef of contract to take in consideration the new condition
			mcontract.create_subcontract(self, n_conditions, mclassdef)
		end
	end

	# Inject the incontract attribute (`_in_contract_`) in the `Sys` class
	# This attribute allows to check if the contract need to be executed
	private fun inject_incontract_in_sys
	do
		# If the `in_contract_attribute` already know just return
		if in_contract_attribute != null then return

		var sys_class = toolcontext.modelbuilder.get_mclass_by_name(visited_module, mainmodule, "Sys")

		# Try to get the `in_contract` property, if it has already defined in a previously visited module.
		var in_contract_property = toolcontext.modelbuilder.try_get_mproperty_by_name(visited_module, sys_class.intro, "__in_contract_")
		if in_contract_property != null then
			self.in_contract_attribute = in_contract_property.as(MAttribute)
			return
		end

		var bool_false = new AFalseExpr.make(mainmodule.bool_type)
		var n_in_contract_attribute = toolcontext.modelbuilder.create_attribute_from_name("__in_contract_", sys_class.intro, mainmodule.bool_type, public_visibility).create_setter(toolcontext.modelbuilder, true).define_default(bool_false)

		in_contract_attribute = n_in_contract_attribute.mpropdef.mproperty
	end

	# Return the `_in_contract_` attribute.
	# If the attribute `_in_contract_` does not exist it's injected with `inject_incontract_in_sys`
	private fun get_incontract: MAttribute
	do
		if self.in_contract_attribute == null then inject_incontract_in_sys
		return in_contract_attribute.as(not null)
	end

	# Return an `AIfExpr` with the contract encapsulated by an `if` to check if it's already in a contract verification.
	#
	# Example:
	# ~~~nitish
	# class A
	# 	fun bar([...]) is except([...])
	#
	# 	fun _contract_bar([...])
	#	do
	#		if not sys._in_contract_ then
	#			sys._in_contract_ = true
	#			_bar_expect([...])
	#			sys._in_contract_ = false
	#		end
	#		bar([...])
	#	end
	#
	# 	fun _bar_expect([...])
	# end
	# ~~~~
	#
	private fun encapsulated_contract_call(visited_method: AMethPropdef, call_to_contracts: Array[ACallExpr]): AIfExpr
	do
		var sys_property = toolcontext.modelbuilder.model.get_mproperties_by_name("sys").first.as(MMethod)
		var callsite_sys = ast_builder.create_callsite(toolcontext.modelbuilder, visited_method, sys_property, true)

		var incontract_attribute = get_incontract

		var callsite_get_incontract = ast_builder.create_callsite(toolcontext.modelbuilder, visited_method, incontract_attribute.getter.as(MMethod), false)
		var callsite_set_incontract = ast_builder.create_callsite(toolcontext.modelbuilder, visited_method, incontract_attribute.setter.as(MMethod), false)

		var n_condition = ast_builder.make_not(ast_builder.make_call(ast_builder.make_call(new ASelfExpr, callsite_sys, null), callsite_get_incontract, null))

		var n_if = ast_builder.make_if(n_condition, null)

		var if_then_block = n_if.n_then.as(ABlockExpr)

		if_then_block.add(ast_builder.make_call(ast_builder.make_call(new ASelfExpr, callsite_sys, null), callsite_set_incontract, [new ATrueExpr.make(mainmodule.bool_type)]))
		if_then_block.add_all(call_to_contracts)
		if_then_block.add(ast_builder.make_call(ast_builder.make_call(new ASelfExpr, callsite_sys, null), callsite_set_incontract, [new AFalseExpr.make(mainmodule.bool_type)]))

		return n_if
	end
end
src/contracts.nit:72,1--216,3