PageRenderTime 233ms CodeModel.GetById 100ms app.highlight 4ms RepoModel.GetById 127ms app.codeStats 0ms

/src/LinFu.AOP/NewOperatorInterception/InterceptNewCalls.cs

http://github.com/philiplaureano/LinFu
C# | 72 lines | 59 code | 12 blank | 1 comment | 3 complexity | 9adad6433b1669ea06694c9416607f66 MD5 | raw file
 1using System.Reflection;
 2using LinFu.AOP.Cecil.Interfaces;
 3using LinFu.Reflection.Emit;
 4using Mono.Cecil;
 5using Mono.Cecil.Cil;
 6
 7namespace LinFu.AOP.Cecil
 8{
 9    internal class InterceptNewCalls : InstructionSwapper, IMethodWeaver
10    {
11        private readonly INewObjectWeaver _emitter;
12        private MethodReference _getCurrentMethod;
13
14        public InterceptNewCalls(INewObjectWeaver emitter)
15        {
16            _emitter = emitter;
17        }
18
19        public override void AddAdditionalMembers(TypeDefinition host)
20        {
21            _emitter.AddAdditionalMembers(host);
22        }
23
24        public override void ImportReferences(ModuleDefinition module)
25        {
26            _getCurrentMethod = module.ImportMethod<MethodBase>("GetCurrentMethod",
27                BindingFlags.Public | BindingFlags.Static);
28            _emitter.ImportReferences(module);
29        }
30
31        protected override void Replace(Instruction currentInstruction, MethodDefinition method, ILProcessor IL)
32        {
33            var constructor = (MethodReference) currentInstruction.Operand;
34            var concreteType = constructor.DeclaringType;
35            var parameters = constructor.Parameters;
36
37            if (!_emitter.ShouldIntercept(constructor, concreteType, method))
38            {
39                // Reuse the old instruction instead of emitting a new one
40                IL.Append(currentInstruction);
41                return;
42            }
43
44            _emitter.EmitNewObject(method, IL, constructor, concreteType);
45        }
46
47        public override void AddLocals(MethodDefinition hostMethod)
48        {
49            _emitter.AddLocals(hostMethod);
50        }
51
52        protected override bool ShouldReplace(Instruction oldInstruction, MethodDefinition hostMethod)
53        {
54            if (oldInstruction.OpCode != OpCodes.Newobj)
55                return false;
56
57            var constructor = (MethodReference) oldInstruction.Operand;
58            var declaringType = constructor.GetDeclaringType();
59            return _emitter.ShouldIntercept(constructor, declaringType, hostMethod);
60        }
61
62        public bool ShouldWeave(MethodDefinition item)
63        {
64            return item.HasBody;
65        }
66
67        public void Weave(MethodDefinition item)
68        {
69            Rewrite(item, item.GetILGenerator(), item.Body.Instructions.ToArray());
70        }
71    }
72}