/// <summary> /// Returns the type contract, if any, that has been associated with the given object. Returns null if no association exits. /// </summary> /// <param name="type">An object that might have been associated with a type contract. This can be any kind of object.</param> /// <returns></returns> /*?*/ public ITypeContract GetTypeContractFor(object type) { ITypeContract contract = this.underlyingContractProvider.GetTypeContractFor(type); if (contract != null) return contract == ContractDummy.TypeContract ? null : contract; TypeContract result = new TypeContract(); ITypeContract primaryContract = this.primaryExtractor.GetTypeContractFor(type); bool found = false; if (primaryContract != null) { found = true; ContractHelper.AddTypeContract(result, primaryContract); } if (this.oobExtractors != null) { foreach (var oobProvider in this.oobExtractors) { var oobUnit = oobProvider.Unit; ITypeReference typeReference = type as ITypeReference; if (typeReference == null || typeReference is Dummy) continue; // REVIEW: Is there anything else it could be and still find a contract for it? MappingMutator primaryToOobMapper = this.mapperForPrimaryToOob[oobProvider]; var oobType = primaryToOobMapper.Map(typeReference); if (oobType == null) continue; var oobContract = oobProvider.GetTypeContractFor(oobType); if (oobContract == null) continue; MappingMutator oobToPrimaryMapper = this.mapperForOobToPrimary[oobProvider]; oobContract = oobToPrimaryMapper.Map(oobContract); ContractHelper.AddTypeContract(result, oobContract); found = true; } } // always cache so we don't try to extract more than once if (found) { this.underlyingContractProvider.AssociateTypeWithContract(type, result); return result; } else { this.underlyingContractProvider.AssociateTypeWithContract(type, ContractDummy.TypeContract); return null; } }
/// <summary> /// Visits the specified type contract. /// </summary> /// <param name="typeContract">The type contract.</param> protected virtual ITypeContract DeepCopy(TypeContract typeContract) { typeContract.ContractFields = this.DeepCopy(typeContract.ContractFields); typeContract.ContractMethods = this.DeepCopy(typeContract.ContractMethods); typeContract.Invariants = this.DeepCopy(typeContract.Invariants); return typeContract; }
/// <summary> /// Accumulates all elements from <paramref name="sourceContract"/> into <paramref name="targetContract"/> /// </summary> /// <param name="targetContract">Contract which is target of accumulator</param> /// <param name="sourceContract">Contract which is source of accumulator</param> public static void AddTypeContract(TypeContract targetContract, ITypeContract sourceContract) { targetContract.ContractFields.AddRange(sourceContract.ContractFields); targetContract.ContractMethods.AddRange(sourceContract.ContractMethods); targetContract.Invariants.AddRange(sourceContract.Invariants); return; }