public bool CreateNewObjectMethod(AssemblyDefinition assembly, MethodDefinition templateMethod, IAssemblyTracker tracker, INewTransformerInfoWrapper infoWrapper) { MethodDefinition factoryMethod = null; if ((factoryMethod = infoWrapper.GetFactoryMethod (templateMethod, assembly, tracker)) != null) { if (factoryMethod.GenericParameters.Count != 1 || factoryMethod.Parameters.Count != 1 || !factoryMethod.IsStatic) throw new ArgumentException ("Factory method to create object does not have correct signature [public static T Create<T> (ParamList)]"); TypeReference returnType = templateMethod.DeclaringType; if (templateMethod.DeclaringType.HasGenericParameters) { returnType = new GenericInstanceType (templateMethod.DeclaringType); foreach (var a in templateMethod.DeclaringType.GenericParameters.ToArray ()) { returnType.GenericParameters.Add (a); ((GenericInstanceType) returnType).GenericArguments.Add (a); } } var importedFactoryMethod = templateMethod.Module.Import (factoryMethod); var genericInstanceMethod = new GenericInstanceMethod (importedFactoryMethod); genericInstanceMethod.GenericArguments.Add (templateMethod.DeclaringType); var paramlistDef = factoryMethod.Parameters[0].ParameterType.Resolve (); var importedParamListCreateMethod = templateMethod.Module.Import (SearchParamListFactoryMethod (paramlistDef, templateMethod)); if (importedParamListCreateMethod == null) throw new ArgumentException ("Factory method: no corresponding 'create' method could have been found. [argument count]"); var newObjectMethod = new MethodDefinition ( infoWrapper.GetWrapperMethodName (templateMethod), MethodAttributes.Public | MethodAttributes.Static, returnType ); var instructions = newObjectMethod.Body.Instructions; foreach (var param in templateMethod.Parameters) { newObjectMethod.Parameters.Add (param); instructions.Add (Instruction.Create (OpCodes.Ldarg, param)); } instructions.Add(Instruction.Create (OpCodes.Call, importedParamListCreateMethod)); instructions.Add(Instruction.Create (OpCodes.Call, genericInstanceMethod)); instructions.Add (Instruction.Create (OpCodes.Ret)); newObjectMethod.Body.OptimizeMacros (); newObjectMethod.IsHideBySig = true; templateMethod.DeclaringType.Methods.Add (newObjectMethod); return true; } return false; }
private void GenerateNewObjectMethods(AssemblyDefinition assembly, TypeDefinition targetType) { foreach (var method in targetType.Methods.ToList()) { if (method.IsConstructor && !targetType.Methods.Any(m => (m.Name == _infoWrapper.GetWrapperMethodName(method) && HaveSameParameters(method, m)))) { if (_replacer.CreateNewObjectMethod(assembly, method, _tracker, _infoWrapper)) { method.IsPublic = false; method.IsPrivate = false; method.IsFamily = true; _tracker.MarkModified(assembly); } } } }
public bool CreateNewObjectMethod(AssemblyDefinition assembly, MethodDefinition templateMethod, IAssemblyTracker tracker, INewTransformerInfoWrapper infoWrapper) { MethodDefinition factoryMethod = null; if ((factoryMethod = infoWrapper.GetFactoryMethod(templateMethod, assembly, tracker)) != null) { if (factoryMethod.GenericParameters.Count != 1 || factoryMethod.Parameters.Count != 1 || !factoryMethod.IsStatic) { throw new ArgumentException("Factory method to create object does not have correct signature [public static T Create<T> (ParamList)]"); } TypeReference returnType = templateMethod.DeclaringType; if (templateMethod.DeclaringType.HasGenericParameters) { returnType = new GenericInstanceType(templateMethod.DeclaringType); foreach (var a in templateMethod.DeclaringType.GenericParameters.ToArray()) { returnType.GenericParameters.Add(a); ((GenericInstanceType)returnType).GenericArguments.Add(a); } } var importedFactoryMethod = templateMethod.Module.Import(factoryMethod); var genericInstanceMethod = new GenericInstanceMethod(importedFactoryMethod); genericInstanceMethod.GenericArguments.Add(templateMethod.DeclaringType); var paramlistDef = factoryMethod.Parameters[0].ParameterType.Resolve(); var importedParamListCreateMethod = templateMethod.Module.Import(SearchParamListFactoryMethod(paramlistDef, templateMethod)); if (importedParamListCreateMethod == null) { throw new ArgumentException("Factory method: no corresponding 'create' method could have been found. [argument count]"); } var newObjectMethod = new MethodDefinition( infoWrapper.GetWrapperMethodName(templateMethod), MethodAttributes.Public | MethodAttributes.Static, returnType ); var instructions = newObjectMethod.Body.Instructions; foreach (var param in templateMethod.Parameters) { newObjectMethod.Parameters.Add(param); instructions.Add(Instruction.Create(OpCodes.Ldarg, param)); } instructions.Add(Instruction.Create(OpCodes.Call, importedParamListCreateMethod)); instructions.Add(Instruction.Create(OpCodes.Call, genericInstanceMethod)); instructions.Add(Instruction.Create(OpCodes.Ret)); newObjectMethod.Body.OptimizeMacros(); newObjectMethod.IsHideBySig = true; templateMethod.DeclaringType.Methods.Add(newObjectMethod); return(true); } return(false); }