PageRenderTime 227ms CodeModel.GetById 106ms app.highlight 12ms RepoModel.GetById 104ms app.codeStats 0ms

/src/LinFu.AOP/Emitters/GetMethodReplacementProvider.cs

http://github.com/philiplaureano/LinFu
C# | 63 lines | 39 code | 7 blank | 17 comment | 3 complexity | e2abf9a61e1b32da5f4822621b2ab9d1 MD5 | raw file
 1using System;
 2using LinFu.AOP.Cecil.Interfaces;
 3using LinFu.AOP.Interfaces;
 4using Mono.Cecil;
 5using Mono.Cecil.Cil;
 6
 7namespace LinFu.AOP.Cecil
 8{
 9    /// <summary>
10    ///     Represents a class that emits the instructions that obtain an instance-level
11    ///     <see cref="IMethodReplacementProvider" /> instance.
12    /// </summary>
13    public class GetMethodReplacementProvider : IInstructionEmitter
14    {
15        private readonly MethodDefinition _hostMethod;
16        private readonly VariableDefinition _methodReplacementProvider;
17        private readonly Func<ModuleDefinition, MethodReference> _resolveGetProviderMethod;
18
19        /// <summary>
20        ///     Initializes a new instance of the <see cref="GetMethodReplacementProvider" /> class.
21        /// </summary>
22        /// <param name="methodReplacementProvider">
23        ///     The local variable that contains the <see cref="IMethodReplacementProvider" />
24        ///     instance.
25        /// </param>
26        /// <param name="hostMethod">The target method.</param>
27        /// <param name="resolveGetProviderMethod">The functor that will resolve the GetProvider method.</param>
28        public GetMethodReplacementProvider(VariableDefinition methodReplacementProvider, MethodDefinition hostMethod,
29            Func<ModuleDefinition, MethodReference> resolveGetProviderMethod)
30        {
31            if (methodReplacementProvider.VariableType.FullName != typeof(IMethodReplacementProvider).FullName)
32                throw new ArgumentException();
33
34            _methodReplacementProvider = methodReplacementProvider;
35            _hostMethod = hostMethod;
36            _resolveGetProviderMethod = resolveGetProviderMethod;
37        }
38
39
40        /// <summary>
41        ///     Emits the instructions that obtain the <see cref="IMethodReplacementProvider" /> instance.
42        /// </summary>
43        /// <param name="IL">The <see cref="ILProcessor" /> instance.</param>
44        public void Emit(ILProcessor IL)
45        {
46            var method = _hostMethod;
47            var declaringType = method.DeclaringType;
48            var module = declaringType.Module;
49
50            if (!method.HasThis)
51            {
52                IL.Emit(OpCodes.Ldnull);
53                IL.Emit(OpCodes.Stloc, _methodReplacementProvider);
54                return;
55            }
56
57            var getProvider = _resolveGetProviderMethod(module);
58            IL.Emit(OpCodes.Ldarg_0);
59            IL.Emit(OpCodes.Callvirt, getProvider);
60            IL.Emit(OpCodes.Stloc, _methodReplacementProvider);
61        }
62    }
63}