nitc :: MMethod :: define_contract_facet
If a contract is given adapt the contract facet.
classdef
: Indicates the class where we want to introduce our facet
exist_contract
: Indicates if it is necessary to define a new facet for the contract. If exist_contract_facet and exist_contract
it's not necessary to add a facet.
Exemple:
from:
classe A
i :Int
fun add_one is ensure(old(i) + 1 == i)
end
to:
classe A
fun add_one is ensure(old(i) + 1 == i)
# The contract facet
fun contract_add_one do
add_one
ensure_add_one(old_add_one)
end
end
~~
# Define contract facet for MMethod in the given mclassdef. The facet represents the entry point with contracts (expect, ensure) of the method.
# If a contract is given adapt the contract facet.
#
# `classdef`: Indicates the class where we want to introduce our facet
# `exist_contract`: Indicates if it is necessary to define a new facet for the contract. If `exist_contract_facet and exist_contract` it's not necessary to add a facet.
#
# Exemple:
# ~~~nitish
# from:
# classe A
# i :Int
# fun add_one is ensure(old(i) + 1 == i)
# end
# to:
# classe A
# fun add_one is ensure(old(i) + 1 == i)
#
# # The contract facet
# fun contract_add_one do
# add_one
# ensure_add_one(old_add_one)
# end
# end
# ~~
private fun define_contract_facet(v: ContractsVisitor, classdef: MClassDef, mcontract: nullable MContract)
do
var exist_contract_facet = has_contract_facet
var contract_facet = build_contract_facet
# Do nothing the contract and the contract facet already exist
if mcontract != null and mcontract.is_already_applied(contract_facet) then return
var n_contract_facet: AMethPropdef
if not exist_contract_facet then
# If has no contract facet in intro just create it
if classdef != intro_mclassdef then
var n_intro_face = create_facet(v, intro_mclassdef, contract_facet, self)
n_intro_face.location = self.intro.location
n_intro_face.do_all(v.toolcontext)
end
n_contract_facet = create_facet(v, classdef, contract_facet, self)
else
# Check if the contract facet already exist in this context (in this classdef)
if classdef.mpropdefs_by_property.has_key(contract_facet) then
# get the definition
n_contract_facet = v.toolcontext.modelbuilder.mpropdef2node(classdef.mpropdefs_by_property[contract_facet]).as(AMethPropdef)
else
# create a new contract facet definition
n_contract_facet = create_facet(v, classdef, contract_facet, self)
var block = v.ast_builder.make_block
# super call to the contract facet
var args = n_contract_facet.n_signature.make_parameter_read(v.ast_builder)
var n_super_call = v.ast_builder.make_super_call(args)
# verification for add a return or not
if self.intro.msignature.return_mtype != null then
block.add(v.ast_builder.make_return(n_super_call))
else
block.add(n_super_call)
end
n_contract_facet.n_block = block
end
end
if mcontract != null then mcontract.adapt_method_to_contract(v, contract_facet, n_contract_facet)
n_contract_facet.location = v.current_location
n_contract_facet.do_all(v.toolcontext)
end
src/contracts.nit:555,2--620,4