/// <summary> /// Clones the specified generic parameter. /// </summary> /// <param name="genericParameter">The generic parameter.</param> /// <param name="methodDefinition">The method definition.</param> /// <returns></returns> public static GenericParam Clone(this GenericParam genericParameter, MethodDef methodDefinition) { var newGenericParameter = new GenericParamUser(genericParameter.Number, genericParameter.Flags, genericParameter.Name); newGenericParameter.GenericParamConstraints.AddRange(genericParameter.GenericParamConstraints.Select(c => c.Clone())); return(newGenericParameter); }
internal bool RegisterGeneric(TypeSig t) { Debug.Assert(t != null, $"{nameof(t)} != null"); // This is a temporary fix. // Type visibility should be handled in a much better way which would involved some analysis. var typeDef = t.ToTypeDefOrRef().ResolveTypeDef(); if (typeDef != null && !typeDef.IsVisibleOutside()) { return(false); } // Get proper type. t = SignatureUtils.GetLeaf(t); // scrambling voids leads to peverify errors, better leave them out. if (t.ElementType == ElementType.Void) { return(false); } if (!Generics.ContainsKey(t)) { GenericParam newGenericParam; if (t.IsGenericMethodParameter) { var mVar = t.ToGenericMVar(); Debug.Assert(mVar != null, $"{nameof(mVar)} != null"); newGenericParam = new GenericParamUser(GenericCount, mVar.GenericParam.Flags, $"T{GenericCount}") { Rid = mVar.Rid }; } else if (t.IsGenericTypeParameter) { var tVar = t.ToGenericVar(); Debug.Assert(tVar != null, $"{nameof(tVar)} != null"); newGenericParam = new GenericParamUser(GenericCount, tVar.GenericParam.Flags, $"T{GenericCount}") { Rid = tVar.Rid }; } else { newGenericParam = new GenericParamUser(GenericCount, GenericParamAttributes.NoSpecialConstraint, $"T{GenericCount}"); } Generics.Add(t, newGenericParam); GenericCount++; _trueTypes.Add(t); return(true); } else { return(false); } }
GenericParam Clone(GenericParam gp) { var clone = new GenericParamUser(gp.Number, gp.Flags, gp.Name); foreach (var gpc in gp.GenericParamConstraints) { clone.GenericParamConstraints.Add(Clone(gpc)); } return(clone); }
public GenericParam Resolve(ISearchContext context) { GenericParam result = new GenericParamUser(Number, Attributes, Name); foreach (GenericParameterConstraint constraint in Constraints) { result.GenericParamConstraints.Add(context.Get(constraint)); } return(result); }
private MethodDef CreateFactoryMethodNoParameters(ITypeService service, ModuleDef module) { var instancevar = new GenericParamUser(0, GenericParamAttributes.NoSpecialConstraint, "t"); var mvar = new GenericMVar(0); var typeSpec = new TypeSpecUser(mvar); var local = new Local(mvar); var rtHandle = new Local(module.Import(typeof(RuntimeTypeHandle)).ToTypeSig()); var method = new MethodDefUser("create", new MethodSig(CallingConvention.Default, 1, mvar), MethodAttributes.Static); method.GenericParameters.Add(instancevar); var gettype = typeof(Type).GetMethod("GetTypeFromHandle"); var comparetypes = typeof(Type).GetMethod("op_Equality"); var i = new List <Instruction>(); i.Add(Instruction.Create(OpCodes.Ldtoken, typeSpec)); i.Add(Instruction.Create(OpCodes.Call, module.Import(gettype))); i.Add(Instruction.Create(OpCodes.Stloc, rtHandle)); foreach (var mr in ObjectCreationRef) { Instruction endjump = Instruction.Create(OpCodes.Nop); i.Add(Instruction.Create(OpCodes.Ldloc, rtHandle)); i.Add(Instruction.Create(OpCodes.Ldtoken, mr.DeclaringType)); i.Add(Instruction.Create(OpCodes.Call, module.Import(gettype))); i.Add(Instruction.Create(OpCodes.Call, module.Import(comparetypes))); i.Add(Instruction.Create(OpCodes.Brfalse_S, endjump)); i.Add(Instruction.Create(OpCodes.Newobj, mr)); i.Add(Instruction.Create(OpCodes.Ret)); i.Add(endjump); } i.Add(Instruction.Create(OpCodes.Ldloca_S, local)); i.Add(Instruction.Create(OpCodes.Initobj, typeSpec)); i.Add(Instruction.Create(OpCodes.Ldloc, local)); i.Add(Instruction.Create(OpCodes.Ret)); method.Body = new CilBody(true, i, new ExceptionHandler[0], new Local[] { local, rtHandle }); return(method); }
// Copies most things but not everything public static MethodDef Clone(MethodDef method) { var newMethod = new MethodDefUser(method.Name, method.MethodSig, method.ImplAttributes, method.Attributes); newMethod.Rid = method.Rid; newMethod.DeclaringType2 = method.DeclaringType; foreach (var pd in method.ParamDefs) { newMethod.ParamDefs.Add(new ParamDefUser(pd.Name, pd.Sequence, pd.Attributes)); } foreach (var gp in method.GenericParameters) { var newGp = new GenericParamUser(gp.Number, gp.Flags, gp.Name); foreach (var gpc in gp.GenericParamConstraints) { newGp.GenericParamConstraints.Add(new GenericParamConstraintUser(gpc.Constraint)); } newMethod.GenericParameters.Add(newGp); } newMethod.Body = new CilBody(); CopyBodyFromTo(method, newMethod); return(newMethod); }
// Copies most things but not everything public static MethodDef Clone(MethodDef method) { var newMethod = new MethodDefUser(method.Name, method.MethodSig, method.ImplAttributes, method.Attributes); newMethod.Rid = method.Rid; newMethod.DeclaringType2 = method.DeclaringType; foreach (var pd in method.ParamDefs) newMethod.ParamDefs.Add(new ParamDefUser(pd.Name, pd.Sequence, pd.Attributes)); foreach (var gp in method.GenericParameters) { var newGp = new GenericParamUser(gp.Number, gp.Flags, gp.Name); foreach (var gpc in gp.GenericParamConstraints) newGp.GenericParamConstraints.Add(new GenericParamConstraintUser(gpc.Constraint)); newMethod.GenericParameters.Add(newGp); } newMethod.Body = new CilBody(); CopyBodyFromTo(method, newMethod); return newMethod; }
private static void ReMethodDef(MethodDef method, ModuleDef module) { ReCustomAttributes(method, module); var newtype = ReferenceType(method.ReturnType, module); if (newtype != null) method.ReturnType = newtype; for (int i = 0; i < method.ParamDefs.Count; ++i) { var p = method.ParamDefs[i]; ReCustomAttributes(p, module); } for (int i = 0; i < method.Parameters.Count; ++i) { var p = method.Parameters[i]; if (p.HasParamDef) ReCustomAttributes(p.ParamDef, module); var newparam = ReferenceType(p.Type, module); if (newtype == null) continue; p.Type = newparam; } for (int i = 0; i < method.GenericParameters.Count; ++i) { var genep = method.GenericParameters[i]; ReCustomAttributes(genep, module); var negp = new GenericParamUser(genep.Number, genep.Flags, genep.Name); foreach (var ca in genep.CustomAttributes) { negp.CustomAttributes.Add(ca); } method.GenericParameters[i] = negp; } ReMethodSig(method.MethodSig, module); }
private MethodDef CreateFactory(ITypeService service, ModuleDef module, int paramNumber, IList <IMethodDefOrRef> methods) { var declaringTypeGeneric = new GenericParamUser(0, GenericParamAttributes.NoSpecialConstraint, "t"); var declaringTypeGenericMVar = new GenericMVar(0); var pGenericTypeSpecs = Enumerable.Range(1, paramNumber).Select((x) => new TypeSpecUser(new GenericMVar(x))).ToArray(); var returnGeneric = new GenericMVar(paramNumber + 1);//last generic is return type var typeSpec = new TypeSpecUser(declaringTypeGenericMVar); var local = new Local(declaringTypeGenericMVar); var rtHandle = new Local(module.Import(typeof(RuntimeTypeHandle)).ToTypeSig()); var methodSig = new MethodSig(CallingConvention.Default, 1, returnGeneric, //Method index Enumerable.Range(1, paramNumber) .Select(x => new GenericMVar(x)) .Concat(new TypeSig[] { module.CorLibTypes.UInt32 }) //Index .ToArray()); var method = new MethodDefUser("call", methodSig, MethodAttributes.Static); method.GenericParameters.Add(declaringTypeGeneric); for (ushort genericNum = 1; genericNum < paramNumber + 2 /*declare type / return type */; genericNum++) { method.GenericParameters.Add(new GenericParamUser(genericNum, GenericParamAttributes.NoSpecialConstraint, "p" + genericNum.ToString())); } var gettype = typeof(Type).GetMethod("GetTypeFromHandle"); var comparetypes = typeof(Type).GetMethod("op_Equality"); var i = new List <Instruction>(); i.Add(Instruction.Create(OpCodes.Ldtoken, typeSpec)); i.Add(Instruction.Create(OpCodes.Call, module.Import(gettype))); i.Add(Instruction.Create(OpCodes.Stloc, rtHandle)); var retDef = new Instruction[] { Instruction.Create(OpCodes.Ldloca_S, local), Instruction.Create(OpCodes.Initobj, new TypeSpecUser(returnGeneric)), Instruction.Create(OpCodes.Ldloc, local), Instruction.Create(OpCodes.Ret), }; foreach (var mr in methods) { Instruction endjump = Instruction.Create(OpCodes.Nop); //Calling type i.Add(Instruction.Create(OpCodes.Ldloc, rtHandle)); i.Add(Instruction.Create(OpCodes.Ldtoken, mr.DeclaringType)); i.Add(Instruction.Create(OpCodes.Call, module.Import(gettype))); i.Add(Instruction.Create(OpCodes.Call, module.Import(comparetypes))); i.Add(Instruction.Create(OpCodes.Brfalse_S, endjump)); //method index i.Add(Instruction.Create(OpCodes.Ldarg, new Parameter(paramNumber))); i.Add(Instruction.Create(OpCodes.Ldc_I4, GetIndexOfMethodInDeclaringType(mr))); i.Add(Instruction.Create(OpCodes.Ceq)); i.Add(Instruction.Create(OpCodes.Brfalse_S, endjump)); //params for (int index = 0; index < mr.MethodSig.Params.Count; index++) { i.Add(Instruction.Create(OpCodes.Ldtoken, pGenericTypeSpecs[index])); i.Add(Instruction.Create(OpCodes.Call, module.Import(gettype))); i.Add(Instruction.Create(OpCodes.Ldtoken, new TypeSpecUser(mr.MethodSig.Params[index]))); i.Add(Instruction.Create(OpCodes.Call, module.Import(gettype))); i.Add(Instruction.Create(OpCodes.Call, module.Import(comparetypes))); i.Add(Instruction.Create(OpCodes.Brfalse_S, endjump)); } for (int index = 0; index < paramNumber; index++) { i.Add(Instruction.Create(OpCodes.Ldarg, new Parameter(index))); } i.Add(Instruction.Create(OpCodes.Call, mr)); if (mr.MethodSig.RetType != module.CorLibTypes.Void) { i.Add(Instruction.Create(OpCodes.Ret)); } else { // i.AddRange(retDef); } i.Add(endjump); } i.AddRange(retDef); method.Body = new CilBody(true, i, new ExceptionHandler[0], new Local[] { local, rtHandle }); // method.Body.KeepOldMaxStack = true; return(method); }