コード例 #1
0
ファイル: AutoLogProcessor.cs プロジェクト: mniak/AutoLog
        private static void ProcessModule(ModuleDefinition module, Func <TypeDefinition, bool> typeFilter = null, Func <MethodDefinition, bool> methodFilter = null)
        {
            logger.Info($"Processing Module '{module.Name}'");

            var refs = new ModuleReferences(module);

            // ------------------------------------------------------
            logger.Info($"Processing Module '{module.Name}'");

            var types = module.Types.Where(x => !x.IsEnum);

            if (typeFilter != null)
            {
                types = types.Where(typeFilter);
            }

            foreach (var type in types)
            {
                logger.Info($"Processing Type '{type.Name}'");

                var loggerField = AddStaticLoggerField(type, refs);
                IEnumerable <MethodDefinition> methods = type.Methods;
                if (methodFilter != null)
                {
                    methods = methods.Where(methodFilter);
                }
                foreach (var method in methods)
                {
                    ProcessMethod(refs, method, loggerField);
                }
            }
        }
コード例 #2
0
ファイル: AutoLogProcessor.cs プロジェクト: mniak/AutoLog
        private static void ProcessMethod(ModuleReferences refs, MethodDefinition method, FieldDefinition loggerField)
        {
            logger.Info($"Processing Method '{method.Name}'");
            if (method.Body == null)
            {
                return;
            }
            int shift = AddCatchLogger(refs, method, loggerField);

            ReplaceShortInstructions(method);
        }
コード例 #3
0
ファイル: AutoLogProcessor.cs プロジェクト: mniak/AutoLog
        private static FieldDefinition AddStaticLoggerField(TypeDefinition type, ModuleReferences refs)
        {
            var loggerField = new FieldDefinition(DetermineLoggerFieldName(type), FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly, refs.Ilogger);

            type.Fields.Add(loggerField);

            FieldReference refLoggerField = loggerField;

            if (type.HasGenericParameters)
            {
                var declaringType = new GenericInstanceType(loggerField.DeclaringType);
                foreach (var parameter in loggerField.DeclaringType.GenericParameters)
                {
                    declaringType.GenericArguments.Add(parameter);
                }
                refLoggerField = new FieldReference(loggerField.Name, loggerField.FieldType, declaringType);
            }

            var initr = new[] {
                Instruction.Create(OpCodes.Call, refs.GetCurrentClassLogger),
                Instruction.Create(OpCodes.Stsfld, refLoggerField),
            };

            var cctor = type.Methods.SingleOrDefault(x => x.Name == ".cctor");

            if (cctor != null)
            { // If there is already a private constructor
                var first = cctor.Body.Instructions.FirstOrDefault();
                var il    = cctor.Body.GetILProcessor();
                if (first != null)
                {
                    il.InjectBefore(first, initr);
                }
                else
                {
                    cctor.Body.Instructions.AddMany(initr);
                }
            }
            else
            { // If there is NO private constructor
                var methodAttributes = MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Static;
                cctor = new MethodDefinition(".cctor", methodAttributes, type.Module.TypeSystem.Void);
                type.Methods.Add(cctor);
                cctor.Body.Instructions.AddMany(initr);
                cctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
            }
            return(loggerField);
        }
コード例 #4
0
ファイル: AutoLogProcessor.cs プロジェクト: mniak/AutoLog
        private static int AddCatchLogger(ModuleReferences refs, MethodDefinition method, FieldDefinition loggerField)
        {
            var body    = method.Body;
            var catches = body.ExceptionHandlers.Where(x => x.HandlerType == ExceptionHandlerType.Catch);
            int result  = 0;

            foreach (var exh in catches)
            {
                var hstart = exh.HandlerStart;
                if (exh.CatchType.FullName == typeof(object).FullName)
                {
                    exh.CatchType = refs.Exception;
                }

                var il   = body.GetILProcessor();
                int slot = 0;
                if (hstart.OpCode == OpCodes.Pop)
                {
                    slot = method.Body.Variables.Count();
                    method.Body.Variables.Add(new VariableDefinition(refs.Exception));
                    var newhstart = InstructionHelper.CreateStloc(method, slot);
                    il.Replace(hstart, newhstart);
                    hstart           = newhstart;
                    exh.TryEnd       = newhstart;
                    exh.HandlerStart = newhstart;
                }
                else
                {
                    slot = InstructionHelper.GetSlot(hstart);
                }
                var instructions = new[] {
                    Instruction.Create(OpCodes.Ldsfld, loggerField),
                    InstructionHelper.CreateLdloc(method, slot),
                    Instruction.Create(OpCodes.Ldstr, "AUTOLOG EXCEPTION"),
                    #if NLOG_LT_4311
                    Instruction.Create(OpCodes.Ldc_I4_0),
                    Instruction.Create(OpCodes.Newarr, refs.Object),
                    #endif
                    Instruction.Create(OpCodes.Callvirt, refs.LogError),
                };
                il.Body.MaxStackSize += 10;
                il.InjectAfter(hstart, instructions);

                result += instructions.Sum(x => x.GetSize());
            }
            return(result);
        }