# This file is part of NIT ( http://www.nitlanguage.org ). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # The abstract concept of a contract in the model module model_contract import model import scope # The root of all contracts abstract class MContract super MMethod # Is the contract is it already applied on the given `mfacet` fun is_already_applied(mfacet: MFacet): Bool is abstract end # An expect (precondition) contract representation class MExpect super MContract redef fun is_already_applied(mfacet: MFacet): Bool do return mfacet.has_applied_expect end # The root of all contracts where the call is after the execution of the original method (`invariant` and `ensure`). abstract class BottomMContract super MContract end # A ensure (postcondition) representation class MEnsure super BottomMContract redef fun is_already_applied(mfacet: MFacet): Bool do return mfacet.has_applied_ensure end # A facet contract representation # This class is created to keep the information of which method is a contract facet class MFacet super MMethod # Is there an `expect` contract applied? var has_applied_expect: Bool = false # Is there an `ensure` contract applied? var has_applied_ensure: Bool = false end redef class MMethod # The contract facet of the method # is representing the method with a contract # This method calls contracts (expect, ensure) and the method var mcontract_facet: nullable MFacet = null # The `MExpect` contract if any var mexpect: nullable MExpect = null # The `MEnsure` contract if any var mensure: nullable MEnsure = null # Build `mensure` if is not exist and return it private fun build_ensure: MEnsure do var m_mensure = self.mensure # build a new `MEnsure` contract if m_mensure == null then m_mensure = new MEnsure(intro_mclassdef, "_ensure_{name}", intro_mclassdef.location, public_visibility) self.mensure = m_mensure return m_mensure end # Is there an ensure contract? fun has_ensure: Bool do return self.mensure != null end # Build `mexpect` if is not exist and return it private fun build_expect: MExpect do var m_mexpect = self.mexpect # build a new `MExpect` contract if m_mexpect == null then m_mexpect = new MExpect(intro_mclassdef, "_expect_{name}", intro_mclassdef.location, public_visibility) self.mexpect = m_mexpect return m_mexpect end # Is there an expect contract? fun has_expect: Bool do return self.mexpect != null end # Build `mcontract_facet` if is not exist and return it private fun build_contract_facet: MFacet do var m_mcontract_facet = self.mcontract_facet # build a new `MFacet` contract if m_mcontract_facet == null then m_mcontract_facet = new MFacet(intro_mclassdef, "_contract_{name}", intro_mclassdef.location, public_visibility) self.mcontract_facet = m_mcontract_facet return m_mcontract_facet end # Is there an contract facet? fun has_contract_facet: Bool do return self.mcontract_facet != null end end