public static Get ( ICloningContext cloningContext, Mono.Cecil.MethodDefinition constructor ) : |
||
cloningContext | ICloningContext | cloning context. |
constructor | Mono.Cecil.MethodDefinition | Constructor to multiplex. |
return |
private IReadOnlyCollection <ICloner <object, object> > InvokeForRootTypeConstructorBody(MethodBody item, MethodDefinition parent) { Contract.Requires(item != null); Contract.Requires(parent != null); Contract.Ensures(Contract.Result <IReadOnlyCollection <ICloner <object, object> > >() != null); var parentCloners = this.ClonersBySource[parent]; Contract.Assume(parentCloners != null); var constructorLogicSignatureCloner = parentCloners.SingleOrDefault(parentCloner => parentCloner is ConstructorLogicSignatureCloner) as ConstructorLogicSignatureCloner; var sourceMultiplexedConstructor = MultiplexedConstructor.Get(this.CloningContext, parent); var cloners = new List <ICloner <object, object> >(); if (constructorLogicSignatureCloner != null) { cloners.Add(new ConstructorLogicBodyCloner(constructorLogicSignatureCloner, sourceMultiplexedConstructor)); } foreach (var parentCloner in parentCloners .Where(parentCloner => parentCloner is NoOpCloner <MethodDefinition, MethodDefinition>) .Cast <NoOpCloner <MethodDefinition, MethodDefinition> >()) { // the initialization cloning includes calling redirected construction methods // so we want to do this if we have initialization items or if we have to create a logic cloner if (!sourceMultiplexedConstructor.HasInitializationItems && constructorLogicSignatureCloner == null) { continue; } var targetMultiplexedConstructor = MultiplexedConstructor.Get(this.CloningContext, parentCloner.Target); if (!targetMultiplexedConstructor.IsInitializingConstructor) { // skip non-initializing constructors because they will eventually call into an initializing constructor continue; } Contract.Assert(parentCloner.Target.HasBody); var constructorCloner = new ConstructorInitializationCloner( parentCloner, constructorLogicSignatureCloner, sourceMultiplexedConstructor, parentCloner.Target.Body); cloners.Add(constructorCloner); } return(cloners); }
/// <summary> /// Gets cloners for the given source item. /// </summary> /// <param name="item">Item to get cloners for.</param> /// <returns>Cloners for the <paramref name="item"/>.</returns> private IReadOnlyCollection <ICloner <object, object> > InvokeForRootTypeConstructor(MethodDefinition item) { Contract.Requires(item != null); Contract.Requires(item.IsConstructor && !item.IsStatic && !item.HasParameters); Contract.Ensures(Contract.Result <IReadOnlyCollection <ICloner <object, object> > >() != null); var parent = this.CloningContext.CilGraph.GetParentOf <TypeDefinition>(item); var parentCloners = this.ClonersBySource[parent]; Contract.Assume(parentCloners != null); var cloners = new List <ICloner <object, object> >(); foreach (var parentCloner in parentCloners.Cast <RootTypeCloner>()) { // add one no-op cloner per target constructor cloners.AddRange( from constructor in parentCloner.Target.Methods where constructor.IsConstructor && !constructor.IsStatic select NoOpCloner.Create(this.CloningContext, item, constructor)); // add a single constructor logic signature cloner to generate a new method, if necessary var sourceMultiplexedConstructor = MultiplexedConstructor.Get(this.CloningContext, item); // only continue if we have construction items if (!sourceMultiplexedConstructor.HasConstructionItems) { continue; } // add the constructor logic signature cloner var constructorLogicSignatureCloner = new ConstructorLogicSignatureCloner(parentCloner, sourceMultiplexedConstructor); cloners.Add(constructorLogicSignatureCloner); } return(cloners); }