public ITypeContract Map(ITypeContract typeContract) { var result = new CodeAndContractDeepCopier(host).Copy(typeContract); var rewriter = new ActualMutator(host, targetUnit, sourceUnitIdentity); return rewriter.Rewrite(result); }
/// <summary> /// Given a method contract (<paramref name="methodContract"/> for a unspecialized/uninstantiated method reference/definition /// (<paramref name="unspec"/>), specialize and instantiate (i.e., the generics) in the contract so that it is a contract /// relative to the specialized/instantiated method reference/definition (<paramref name="mr"/>). /// </summary> /// <param name="host"></param> /// <param name="methodContract"></param> /// <param name="mr"></param> /// <param name="unspec"></param> /// <returns> /// A deep copy of <paramref name="methodContract"/>, properly specialized and instantiated. /// </returns> public static MethodContract InstantiateAndSpecializeContract(IMetadataHost host, IMethodContract methodContract, IMethodReference mr, IMethodReference unspec) { //Contract.Requires(mr is IGenericMethodInstanceReference || mr is ISpecializedMethodReference); var copier = new CodeAndContractDeepCopier(host); var mutableContract = copier.Copy(methodContract); var unspecializedTypeReferences = new List<ITypeReference>(); var specializedTypeReferences = new List<ITypeReference>(); var copyOfUnspecializedContainingType = copier.Copy(unspec.ContainingType); unspecializedTypeReferences.Add(copyOfUnspecializedContainingType); var containingType = mr.ContainingType; var gtir2 = containingType as IGenericTypeInstanceReference; var copyOfSpecializedContainingType = gtir2 != null ? copier.Copy(gtir2) : copier.Copy(containingType); specializedTypeReferences.Add(copyOfSpecializedContainingType); var unspecializedMethodDefinition = unspec as IMethodDefinition; #region Map generic type parameters var smr = mr as ISpecializedMethodReference; if (smr != null) { if (unspecializedMethodDefinition != null) { foreach (var t in unspecializedMethodDefinition.ContainingTypeDefinition.GenericParameters) { // without the cast, the copy is not object equals to references within the contract var copyOfT = copier.Copy((IGenericTypeParameterReference)t); unspecializedTypeReferences.Add(copyOfT); } var gtir = smr.ContainingType as IGenericTypeInstanceReference; if (gtir != null) { foreach (var t in gtir.GenericArguments) { var copyOfT = copier.Copy(t); specializedTypeReferences.Add(copyOfT); } } } } #endregion #region Map generic method parameters var gmir = mr as IGenericMethodInstanceReference; if (gmir != null) { var unspecialized = gmir.GenericMethod.ResolvedMethod; foreach (var t in unspecialized.GenericParameters) { var copyOfT = copier.Copy(t); unspecializedTypeReferences.Add(copyOfT); } foreach (var t in gmir.GenericArguments) { var copyOfT = copier.Copy(t); specializedTypeReferences.Add(copyOfT); } } #endregion var d = new Dictionary<uint, ITypeReference>(); IteratorHelper.Zip(unspecializedTypeReferences, specializedTypeReferences, (u, s) => d.Add(u.InternedKey, s)); var specializer = new CodeSpecializer(host, d); mutableContract = (MethodContract)specializer.Rewrite(mutableContract); mutableContract = (MethodContract)ContractHelper.CopyContractIntoNewContext(host, mutableContract, smr != null ? smr.ResolvedMethod : mr.ResolvedMethod, unspecializedMethodDefinition); return mutableContract; }
/// <summary> /// Given a type contract (<paramref name="typeContract"/> for a unspecialized/uninstantiated type reference/definition /// specialize and instantiate (i.e., the generics) in the contract so that it is a contract /// relative to the specialized/instantiated type reference/definition (<paramref name="context"/>). /// </summary> /// <param name="host"></param> /// <param name="typeContract"></param> /// <param name="context"></param> /// <returns> /// A deep copy of <paramref name="typeContract"/>, properly specialized and instantiated. /// </returns> public static TypeContract InstantiateAndSpecializeContract(IMetadataHost host, ITypeContract typeContract, ITypeReference context) { Contract.Requires(host != null); Contract.Requires(typeContract != null); Contract.Requires(context != null); var copier = new CodeAndContractDeepCopier(host); var mutableContract = copier.Copy(typeContract); var specializer = new TypeContractSpecializer(host, context); mutableContract = (TypeContract)specializer.Rewrite(mutableContract); return mutableContract; }
/// <summary> /// Returns a modified <paramref name="methodContract"/> so that instead of belonging to <paramref name="fromMethod"/> it /// is a method contract for <paramref name="toMethod"/>. /// All parameters from <paramref name="fromMethod"/> are replaced with the corresponding /// parameters from <paramref name="toMethod"/>. /// Any local definitions which are introduced in local declaration statements are modified so that the defining method /// each local points to is <paramref name="toMethod"/> instead of <paramref name="fromMethod"/> /// </summary> public static IMethodContract CopyContractIntoNewContext(IMetadataHost host, IMethodContract methodContract, IMethodDefinition toMethod, IMethodDefinition fromMethod) { var result = new CodeAndContractDeepCopier(host).Copy(methodContract); var rewriter = new RewriteContractInNewContext(host, toMethod, fromMethod); return rewriter.Rewrite(result); }