コード例 #1
0
        public void OnType(TypeDefinition type)
        {
            if (type.IsInterface)
            {
                return;
            }
            foreach (var method in type.Methods)
            {
                try
                {
                    string          fieldName;
                    MethodReference methodR;

                    #region Get required info or continue

                    if (method.Name.StartsWith("add_"))
                    {
                        fieldName = method.Name.Substring("add_".Length);
                        methodR   = combineR;
                    }
                    else if (method.Name.StartsWith("remove_"))
                    {
                        fieldName = method.Name.Substring("remove_".Length);
                        methodR   = removeR;
                    }
                    else
                    {
                        continue;
                    }

                    #endregion

                    var newI = new List <Instruction>();

                    var processor = method.Body.GetILProcessor();

                    bool foundCompExch = false;
                    foreach (var existingInstruction in processor.Body.Instructions)
                    {
                        if (existingInstruction.OpCode == OpCodes.Call)
                        {
                            var meth = existingInstruction.Operand as MethodReference;
                            if (meth != null)
                            {
                                if (meth.Name == "CompareExchange")
                                {
                                    if (Verbosity > 7)
                                    {
                                        Console.WriteLine("   Found CompareExchange");
                                    }
                                    foundCompExch = true;
                                    break;
                                }
                            }
                        }
                    }

                    if (!foundCompExch)
                    {
                        if (Verbosity >= Verbosities.SkippingVerbose)
                        {
                            Console.WriteLine(" . ignoring body with no CompareExchange: " + type.Name + "." + method.Name);
                        }
                        skipped++;
                        continue;
                    }


                    FieldReference field;


                    if (type.HasGenericParameters)
                    {
                        var giType = new GenericInstanceType(type);
//						var
//						string x = type.FullName;
                        //giType.
                        field = type.Fields.Where(f => f.Name == fieldName).FirstOrDefault();


                        Console.WriteLine("==== GENERICTYPE: " + type + " (" + type.GenericParameters.Count + ") " + giType.ToString() + ", Field: " + field.FullName);
                        foreach (var genPar in type.GenericParameters)
                        {
                            Console.WriteLine(" ==> " + genPar.FullName);
                        }
                    }
                    else
                    {
                        field = type.Fields.Where(f => f.Name == fieldName).FirstOrDefault();
                    }

                    if (field == null)
                    {
                        throw new Exception("Could not find field: " + fieldName + " in type " + type.FullName);
                    }

                    if (method.IsStatic)
                    {
                        //	IL_0000:  ldfld class MyNamespace.ActionBool MyNamespace.EnableableBase::myHandler
                        newI.Add(processor.Create(OpCodes.Ldsfld, field));

                        //	IL_0005:  ldarg.0
                        newI.Add(processor.Create(OpCodes.Ldarg_0));

                        //	IL_0006:  call class [mscorlib]System.Delegate class [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
                        newI.Add(processor.Create(OpCodes.Call, methodR));

                        //	IL_000b:  castclass MyNamespace.ActionBool
                        newI.Add(processor.Create(OpCodes.Castclass, field.FieldType));

                        //	IL_0010:  stfld class MyNamespace.ActionBool MyNamespace.EnableableBase::myHandler
                        newI.Add(processor.Create(OpCodes.Stsfld, field));

                        //	IL_0015:  ret
                        newI.Add(processor.Create(OpCodes.Ret));
                    }
                    else
                    {
                        //	IL_0000:  ldarg.0
                        newI.Add(processor.Create(OpCodes.Ldarg_0));
                        //	IL_0001:  ldarg.0
                        newI.Add(processor.Create(OpCodes.Ldarg_0));

                        //	IL_0002:  ldfld class MyNamespace.ActionBool MyNamespace.EnableableBase::myHandler
                        newI.Add(processor.Create(OpCodes.Ldfld, field));

                        //	IL_0007:  ldarg.1
                        newI.Add(processor.Create(OpCodes.Ldarg_1));

                        //	IL_0008:  call class [mscorlib]System.Delegate class [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
                        newI.Add(processor.Create(OpCodes.Call, methodR));

                        //	IL_000d:  castclass MyNamespace.ActionBool
                        newI.Add(processor.Create(OpCodes.Castclass, field.FieldType));

                        //	IL_0012:  stfld class MyNamespace.ActionBool MyNamespace.EnableableBase::myHandler
                        newI.Add(processor.Create(OpCodes.Stfld, field));

                        //	IL_0017:  ret
                        newI.Add(processor.Create(OpCodes.Ret));
                    }
                    #region Replace the instructions

                    replaced++;
                    processor.Body.Instructions.Clear();
                    foreach (var i in newI)
                    {
                        processor.Body.Instructions.Add(i);
                    }

                    if (Verbosity >= Verbosities.Success)
                    {
                        Console.WriteLine(" - replaced method: " + type.Name + "." + method.Name);
                    }

                    #endregion
                } catch (Exception ex) {
                    Console.WriteLine("Exception for method: " + type.FullName + "." + method.Name + ": " + ex);
                }
            }
        }