Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #6
0
        // 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);
        }
Beispiel #7
0
		// 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;
		}
Beispiel #8
0
        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);
        }