AotCompatlyzer.ReplaceCE.OnType C# (CSharp) Method

OnType() public method

public OnType ( Mono.Cecil.TypeDefinition type ) : void
type Mono.Cecil.TypeDefinition
return void
        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);

                    //	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);
                }
            }
        }