nitc :: ContractsVisitor :: _ast_builder
nitc :: ContractsVisitor :: _current_location
Thecurrent_location
can corresponding of the annotation or method location.
nitc :: ContractsVisitor :: _find_no_contract
isno_contract
annotation was found
nitc :: ContractsVisitor :: _in_contract_attribute
The reference to thein_contract
attribute.
nitc :: ContractsVisitor :: _is_intro_contract
Is the contrat is an introduction or not?nitc :: ContractsVisitor :: _m_signature
TheMSignature
of the actual build contract
nitc :: ContractsVisitor :: _n_signature
TheASignature
of the actual build contract
nitc :: ContractsVisitor :: _toolcontext
Instance of the toolcontextnitc :: ContractsVisitor :: _visited_class
Actual visited classnitc :: ContractsVisitor :: _visited_module
Actual visited modulenitc :: ContractsVisitor :: ast_builder
nitc :: ContractsVisitor :: ast_builder=
nitc :: ContractsVisitor :: build_contract
Define the new contract take in consideration that an old contract exist or notnitc :: ContractsVisitor :: current_location
Thecurrent_location
can corresponding of the annotation or method location.
nitc :: ContractsVisitor :: current_location=
Thecurrent_location
can corresponding of the annotation or method location.
nitc :: ContractsVisitor :: defaultinit
nitc :: ContractsVisitor :: define_signature
Method use to define the signature part of the methodASignature
and MSignature
nitc :: ContractsVisitor :: encapsulated_contract_call
Return anAIfExpr
with the contract encapsulated by an if
to check if it's already in a contract verification.
nitc :: ContractsVisitor :: find_no_contract
isno_contract
annotation was found
nitc :: ContractsVisitor :: find_no_contract=
isno_contract
annotation was found
nitc :: ContractsVisitor :: get_incontract
Return the_in_contract_
attribute.
nitc :: ContractsVisitor :: in_contract_attribute
The reference to thein_contract
attribute.
nitc :: ContractsVisitor :: in_contract_attribute=
The reference to thein_contract
attribute.
nitc :: ContractsVisitor :: inject_incontract_in_sys
Inject the incontract attribute (_in_contract_
) in the Sys
class
nitc :: ContractsVisitor :: is_intro_contract
Is the contrat is an introduction or not?nitc :: ContractsVisitor :: is_intro_contract=
Is the contrat is an introduction or not?nitc :: ContractsVisitor :: m_signature
TheMSignature
of the actual build contract
nitc :: ContractsVisitor :: m_signature=
TheMSignature
of the actual build contract
nitc :: ContractsVisitor :: mainmodule=
The main modulenitc :: ContractsVisitor :: n_signature
TheASignature
of the actual build contract
nitc :: ContractsVisitor :: n_signature=
TheASignature
of the actual build contract
nitc :: ContractsVisitor :: toolcontext
Instance of the toolcontextnitc :: ContractsVisitor :: toolcontext=
Instance of the toolcontextnitc :: ContractsVisitor :: visited_class
Actual visited classnitc :: ContractsVisitor :: visited_class=
Actual visited classnitc :: ContractsVisitor :: visited_module
Actual visited modulenitc :: ContractsVisitor :: visited_module=
Actual visited modulenitc $ ContractsVisitor :: SELF
Type of this instance, automatically specialized in every classnitc $ ContractsVisitor :: visit
What the visitor do when a node is visitednitc :: ContractsVisitor :: _ast_builder
nitc :: ContractsVisitor :: _current_location
Thecurrent_location
can corresponding of the annotation or method location.
nitc :: ContractsVisitor :: _find_no_contract
isno_contract
annotation was found
nitc :: ContractsVisitor :: _in_contract_attribute
The reference to thein_contract
attribute.
nitc :: ContractsVisitor :: _is_intro_contract
Is the contrat is an introduction or not?nitc :: ContractsVisitor :: _m_signature
TheMSignature
of the actual build contract
nitc :: ContractsVisitor :: _n_signature
TheASignature
of the actual build contract
nitc :: ContractsVisitor :: _toolcontext
Instance of the toolcontextnitc :: ContractsVisitor :: _visited_class
Actual visited classnitc :: ContractsVisitor :: _visited_module
Actual visited modulenitc :: ContractsVisitor :: ast_builder
nitc :: ContractsVisitor :: ast_builder=
nitc :: ContractsVisitor :: build_contract
Define the new contract take in consideration that an old contract exist or notcore :: Object :: class_factory
Implementation used byget_class
to create the specific class.
nitc :: ContractsVisitor :: current_location
Thecurrent_location
can corresponding of the annotation or method location.
nitc :: ContractsVisitor :: current_location=
Thecurrent_location
can corresponding of the annotation or method location.
nitc :: Visitor :: current_node=
The current visited nodecore :: Object :: defaultinit
nitc :: Visitor :: defaultinit
nitc :: ContractsVisitor :: defaultinit
nitc :: ContractsVisitor :: define_signature
Method use to define the signature part of the methodASignature
and MSignature
nitc :: ContractsVisitor :: encapsulated_contract_call
Return anAIfExpr
with the contract encapsulated by an if
to check if it's already in a contract verification.
nitc :: Visitor :: enter_visit
Ask the visitor to visit a given node.nitc :: ContractsVisitor :: find_no_contract
isno_contract
annotation was found
nitc :: ContractsVisitor :: find_no_contract=
isno_contract
annotation was found
nitc :: ContractsVisitor :: get_incontract
Return the_in_contract_
attribute.
nitc :: ContractsVisitor :: in_contract_attribute
The reference to thein_contract
attribute.
nitc :: ContractsVisitor :: in_contract_attribute=
The reference to thein_contract
attribute.
nitc :: ContractsVisitor :: inject_incontract_in_sys
Inject the incontract attribute (_in_contract_
) in the Sys
class
nitc :: ContractsVisitor :: is_intro_contract
Is the contrat is an introduction or not?nitc :: ContractsVisitor :: is_intro_contract=
Is the contrat is an introduction or not?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 :: ContractsVisitor :: m_signature
TheMSignature
of the actual build contract
nitc :: ContractsVisitor :: m_signature=
TheMSignature
of the actual build contract
nitc :: ContractsVisitor :: mainmodule=
The main modulenitc :: ContractsVisitor :: n_signature
TheASignature
of the actual build contract
nitc :: ContractsVisitor :: n_signature=
TheASignature
of the actual build contract
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 :: ContractsVisitor :: toolcontext
Instance of the toolcontextnitc :: ContractsVisitor :: toolcontext=
Instance of the toolcontextnitc :: ContractsVisitor :: visited_class
Actual visited classnitc :: ContractsVisitor :: visited_class=
Actual visited classnitc :: ContractsVisitor :: visited_module
Actual visited modulenitc :: ContractsVisitor :: visited_module=
Actual visited module
# 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