Esempio n. 1
0
        protected override void ScanCore(MemberImportingOptions options, List <MemberImporter> importList)
        {
            //Property
            var originalProp = (PropertyDefinition)Member;

            propClone = originalProp.Clone(Session);

            //Registers importing of custom attributes
            if (propClone.HasCustomAttributes)
            {
                importList.Add(new CustomAttributesImporter(propClone, propClone, Session).Scan(options));
                propClone.CustomAttributes.Clear();
            }

            //Registers importing of get and set methods
            if (propClone.GetMethod != null)
            {
                var importer = new MethodImporter(propClone.GetMethod, Destination, Session, false).Scan(options);
                importer.ImportFinished += m => {
                    var get = (MethodDefinition)m;
                    get.IsGetter        = true;
                    propClone.GetMethod = get;
                };
                importList.Add(importer);
            }
            if (propClone.SetMethod != null)
            {
                var importer = new MethodImporter(propClone.SetMethod, Destination, Session, false).Scan(options);
                importer.ImportFinished += m =>
                {
                    var set = (MethodDefinition)m;
                    set.IsSetter        = true;
                    propClone.SetMethod = set;
                };
                importList.Add(importer);
            }

            //Imports other methods
            if (originalProp.HasOtherMethods)
            {
                foreach (var m in originalProp.OtherMethods)
                {
                    var importer = new MethodImporter(m, Destination, Session, false).Scan(options);
                    importer.ImportFinished += x => {
                        var method = (MethodDefinition)x;
                        method.IsOther = true;
                        propClone.OtherMethods.Add(method);
                    };
                    importList.Add(importer);
                }
            }

            //Imports the parameters
            foreach (var p in originalProp.Parameters)
            {
                //Creates a new parameter
                var param = new ParameterDefinition(p.Name, p.Attributes, p.ParameterType)
                {
                    Constant      = p.Constant,
                    MarshalInfo   = p.MarshalInfo,
                    MetadataToken = new MetadataToken(p.MetadataToken.TokenType, GlobalContainer.GetFreeRID(Session.DestinationModule))
                };
                propClone.Parameters.Add(param);

                //Queues importing of custom attributes
                if (p.HasCustomAttributes)
                {
                    importList.Add(new CustomAttributesImporter(p, param, Session).Scan(options));
                    param.CustomAttributes.Clear();
                }

                //Queues importing of type
                var typeImporter = Helpers.CreateTypeImporter(p.ParameterType, Session, importList, options);
                typeImporter.ImportFinished += t => param.ParameterType = (TypeReference)t;
            }
        }
Esempio n. 2
0
        public void Inject(ICSharpCode.ILSpy.TreeNodes.ILSpyTreeNode node, string name, Mono.Cecil.IMetadataTokenProvider member)
        {
            //Type
            var type = (TypeDefinition)((IMemberTreeNode)node).Member;

            //Event type
            var eventType = type.Module.Import((TypeReference)member, type);

            //Creates the event
            var evt = new EventDefinition(name, EventAttributes.None, eventType)
            {
                MetadataToken = new MetadataToken(TokenType.Event, GlobalContainer.GetFreeRID(type.Module))
            };

            //Creates the field
            FieldReference backingField = null;

            if (!type.IsInterface)
            {
                backingField = new FieldDefinition(
                    name,
                    FieldAttributes.Private,
                    eventType
                    )
                {
                    MetadataToken = new MetadataToken(TokenType.Field, GlobalContainer.GetFreeRID(type.Module))
                };
                type.Fields.Add((FieldDefinition)backingField);
            }

            //Checks if the type is generic
            if (type.HasGenericParameters)
            {
                var giType = new GenericInstanceType(type);
                foreach (var x in type.GenericParameters)
                {
                    giType.GenericArguments.Add(x);
                }
                backingField = new FieldReference(backingField.Name, eventType, giType);
            }

            //Creates the addon method
            evt.AddMethod = new MethodDefinition(
                "add_" + name,
                MethodAttributes.Public | MethodAttributes.SpecialName,
                type.Module.TypeSystem.Void
                )
            {
                IsSynchronized = !type.IsInterface,
                IsAddOn        = true,
                MetadataToken  = new MetadataToken(TokenType.Method, GlobalContainer.GetFreeRID(type.Module)),
                Parameters     =
                {
                    new ParameterDefinition("value", ParameterAttributes.None, eventType)
                }
            };

            //Checks if the destination type is an interface
            if (type.IsInterface)
            {
                evt.AddMethod.Attributes |= MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride | MethodAttributes.Abstract | MethodAttributes.Virtual;
            }
            else
            {
                //Writes the instruction of the addon method
                var addBody = evt.AddMethod.Body;
                addBody.MaxStackSize = 8;
                addBody.GetType().GetField("code_size", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(addBody, 1);
                var addIL = addBody.GetILProcessor();
                addIL.Emit(OpCodes.Ldarg_0);
                addIL.Emit(OpCodes.Ldarg_0);
                addIL.Emit(OpCodes.Ldfld, backingField);
                addIL.Emit(OpCodes.Ldarg_1);
                //Delegate.Combine(Delegate, Delegate)
                addIL.Emit(OpCodes.Call, type.Module.Import(new TypeReference("System", "Delegate", type.Module, type.Module.TypeSystem.Corlib).Resolve().Methods.First(x => x.Name == "Combine" && x.IsStatic && x.Parameters.Count == 2 && x.Parameters.All(p => p.ParameterType.FullName == "System.Delegate"))));
                addIL.Emit(OpCodes.Castclass, eventType);
                addIL.Emit(OpCodes.Stfld, backingField);
                addIL.Emit(OpCodes.Ret);
            }
            //Creates the removeon method
            evt.RemoveMethod = new MethodDefinition(
                "remove_" + name,
                MethodAttributes.Public | MethodAttributes.SpecialName,
                type.Module.TypeSystem.Void
                )
            {
                IsSynchronized = !type.IsInterface,
                IsRemoveOn     = true,
                MetadataToken  = new MetadataToken(TokenType.Method, GlobalContainer.GetFreeRID(type.Module)),
                Parameters     =
                {
                    new ParameterDefinition("value", ParameterAttributes.None, eventType)
                }
            };

            //Checks if the destination type is an interface
            if (type.IsInterface)
            {
                evt.RemoveMethod.Attributes |= MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride | MethodAttributes.Abstract | MethodAttributes.Virtual;
            }
            else
            {
                //Writes the instruction of the removeon method
                var removeBody = evt.RemoveMethod.Body;
                removeBody.MaxStackSize = 8;
                removeBody.GetType().GetField("code_size", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).SetValue(removeBody, 1);
                var removeIL = removeBody.GetILProcessor();
                removeIL.Emit(OpCodes.Ldarg_0);
                removeIL.Emit(OpCodes.Ldarg_0);
                removeIL.Emit(OpCodes.Ldfld, backingField);
                removeIL.Emit(OpCodes.Ldarg_1);
                //Delegate.Remove(Delegate, Delegate)
                removeIL.Emit(OpCodes.Call, type.Module.Import(new TypeReference("System", "Delegate", type.Module, type.Module.TypeSystem.Corlib).Resolve().Methods.First(x => x.Name == "Remove" && x.IsStatic && x.Parameters.Count == 2 && x.Parameters.All(p => p.ParameterType.FullName == "System.Delegate"))));
                removeIL.Emit(OpCodes.Castclass, eventType);
                removeIL.Emit(OpCodes.Stfld, backingField);
                removeIL.Emit(OpCodes.Ret);
            }

            //Adds the members to the type
            type.Methods.Add(evt.AddMethod);
            type.Methods.Add(evt.RemoveMethod);
            type.Events.Add(evt);
            evt.AddMethod.Overrides.Clear();
            evt.RemoveMethod.Overrides.Clear();

            //Creates the nodes
            if (node is TypeTreeNode)
            {
                if (!type.IsInterface)
                {
                    node.Children.Add(new ILEditTreeNode(backingField, true));
                }
                node.Children.Add(new ILEditTreeNode(evt, false));
                Helpers.Tree.SortChildren((TypeTreeNode)node);
            }
            else if (node is ILEditTreeNode)
            {
                ((ILEditTreeNode)node).RefreshChildren();
            }
        }
Esempio n. 3
0
        protected override void ScanCore(MemberImportingOptions options, List <MemberImporter> importList)
        {
            //Method
            var originalMethod = (MethodDefinition)Member;

            methodClone = originalMethod.Clone(Session);

            //Imports the generic parameters
            if (methodClone.HasGenericParameters)
            {
                importList.Add(new GenericParametersImporter(methodClone, methodClone, Session).Scan(options));
                methodClone.GenericParameters.Clear();
            }

            //Imports the attributes
            if (methodClone.HasCustomAttributes)
            {
                importList.Add(new CustomAttributesImporter(methodClone, methodClone, Session).Scan(options));
                methodClone.CustomAttributes.Clear();
            }

            //Imports the return type
            var retImporter = Helpers.CreateTypeImporter(originalMethod.ReturnType, Session, importList, options);

            retImporter.ImportFinished += t => methodClone.ReturnType = (TypeReference)t;

            //Imports the attributes of the return type
            if (methodClone.MethodReturnType.HasCustomAttributes)
            {
                importList.Add(new CustomAttributesImporter(methodClone.MethodReturnType, methodClone.MethodReturnType, Session).Scan(options));
                methodClone.MethodReturnType.CustomAttributes.Clear();
            }

            //Imports the parameters
            foreach (var p in originalMethod.Parameters)
            {
                //Creates a new parameter
                var param = new ParameterDefinition(p.Name, p.Attributes, p.ParameterType)
                {
                    Constant      = p.Constant,
                    MarshalInfo   = p.MarshalInfo,
                    MetadataToken = new MetadataToken(p.MetadataToken.TokenType, GlobalContainer.GetFreeRID(Session.DestinationModule))
                };
                methodClone.Parameters.Add(param);

                //Queues importing of custom attributes
                if (p.HasCustomAttributes)
                {
                    importList.Add(new CustomAttributesImporter(p, param, Session).Scan(options));
                    param.CustomAttributes.Clear();
                }

                //Queues importing of type
                var typeImporter = Helpers.CreateTypeImporter(p.ParameterType, Session, importList, options);
                typeImporter.ImportFinished += t => param.ParameterType = (TypeReference)t;
            }

            //Clones the body
            var originalBody = originalMethod.Body;
            var body         = methodClone.Body;

            body.InitLocals   = originalBody.InitLocals;
            body.MaxStackSize = originalBody.MaxStackSize;

            //Clones the variables
            foreach (var v in originalBody.Variables)
            {
                var var          = new VariableDefinition(v.Name, v.VariableType);
                var typeImporter = Helpers.CreateTypeImporter(var.VariableType, Session, importList, options);
                typeImporter.ImportFinished += t => var.VariableType = (TypeReference)t;
                body.Variables.Add(var);
            }

            //Clones the instructions
            foreach (var x in originalBody.Instructions)
            {
                //Creates a new instruction with the same opcode
                var i           = x;
                var instruction = Instruction.Create(OpCodes.Nop);
                instruction.OpCode = i.OpCode;
                body.Instructions.Add(instruction);
                instruction.Offset = i.Offset;

                //Switches on the type of the opcode to
                switch (i.OpCode.OperandType)
                {
                //Delays the importing of the operand
                case OperandType.ShortInlineBrTarget:
                case OperandType.InlineBrTarget:
                    var index = originalBody.Instructions.IndexOf((Instruction)i.Operand);
                    importList.Add(MemberImporter.Create((_, __) => {
                        instruction.Operand = body.Instructions[index];
                        return(null);
                    }));
                    break;

                case OperandType.InlineSwitch:
                    var indexes = ((Instruction[])i.Operand).Select(a => originalBody.Instructions.IndexOf(a)).ToArray();
                    importList.Add(MemberImporter.Create((_, __) => {
                        instruction.Operand = indexes.Select(a => body.Instructions[a]).ToArray();
                        return(null);
                    }));
                    break;

                //Registers importing of the type
                case OperandType.InlineType:
                    var importer = Helpers.CreateTypeImporter((TypeReference)i.Operand, Session, importList, options);
                    importer.ImportFinished += t => instruction.Operand = t;
                    break;

                //Registers importing of the declaring type
                //along with the field type
                case OperandType.InlineField:
                    var field = (FieldReference)i.Operand;
                    field = new FieldReference(field.Name, field.FieldType, field.DeclaringType);
                    Helpers.CreateTypeImporter(field.DeclaringType, Session, importList, options)
                    .ImportFinished += t => field.DeclaringType = (TypeReference)t;
                    Helpers.CreateTypeImporter(field.FieldType, Session, importList, options)
                    .ImportFinished    += t => field.FieldType = (TypeReference)t;
                    instruction.Operand = field;
                    break;

                //Registers importing of the method
                case OperandType.InlineMethod:
                    var m = (MethodReference)i.Operand;
                    var methodImporter = MemberImporter.Create((_, __) => {
                        instruction.Operand = Session.DestinationModule.Import(m);
                        return(null);
                    });
                    importList.Add(methodImporter);
                    break;

                //Keeps the same operand
                default:
                    instruction.Operand = i.Operand;
                    break;
                }
            }

            //Imports the overrides
            if (methodClone.HasOverrides)
            {
                foreach (var x in methodClone.Overrides)
                {
                    var o = x;
                    importList.Add(MemberImporter.Create((_, __) => {
                        methodClone.Overrides.Add(Session.DestinationModule.Import(o));
                        return(null);
                    }));
                }
                methodClone.Overrides.Clear();
            }
        }