PageRenderTime 48ms CodeModel.GetById 40ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/src/LinFu.IoC/Configuration/MethodBuilder.cs

http://github.com/philiplaureano/LinFu
C# | 83 lines | 42 code | 10 blank | 31 comment | 3 complexity | 21966a1347bccc1b2246724df339e35d MD5 | raw file
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Reflection;
 5using System.Reflection.Emit;
 6
 7namespace LinFu.IoC.Configuration
 8{
 9    /// <summary>
10    ///     A class that dynamically generates calls to a <see cref="MethodInfo" /> instance.
11    /// </summary>
12    public class MethodBuilder : BaseMethodBuilder<MethodInfo>
13    {
14        /// <summary>
15        ///     Pushes the method target onto the evaluation stack.
16        /// </summary>
17        /// <param name="IL">The <see cref="ILGenerator" /> of the method body.</param>
18        /// <param name="method">The target method.</param>
19        protected override void PushInstance(ILGenerator IL, MethodInfo method)
20        {
21            if (method.IsStatic)
22                return;
23
24            IL.Emit(OpCodes.Ldarg_0);
25        }
26
27        /// <summary>
28        ///     Pushes the method arguments onto the stack.
29        /// </summary>
30        /// <param name="IL">The <see cref="ILGenerator" /> of the target method body.</param>
31        /// <param name="targetMethod">The target method that will be invoked.</param>
32        protected override void PushMethodArguments(ILGenerator IL, MethodBase targetMethod)
33        {
34            var parameterTypes = (from p in targetMethod.GetParameters()
35                select p.ParameterType).ToArray();
36
37            var offset = targetMethod.IsStatic ? 0 : 1;
38            // Push the method arguments onto the stack
39            var parameterCount = parameterTypes.Length;
40            for (var index = 0; index < parameterCount; index++) IL.Emit(OpCodes.Ldarg, index + offset);
41        }
42
43        /// <summary>
44        ///     Determines the return type from the target <paramref name="method" />.
45        /// </summary>
46        /// <param name="method">The target method itself.</param>
47        /// <returns>The method return type.</returns>
48        protected override Type GetReturnType(MethodInfo method)
49        {
50            return method.ReturnType;
51        }
52
53        /// <summary>
54        ///     Determines the parameter types of the dynamically generated method.
55        /// </summary>
56        /// <param name="existingMethod">The target method.</param>
57        /// <param name="parameterTypes">The target method argument types.</param>
58        /// <returns>The list of <see cref="System.Type" /> objects that describe the signature of the method to generate.</returns>
59        /// <remarks>This override will add an additional parameter type to accomodate the method target.</remarks>
60        protected override IList<Type> GetParameterList(MethodInfo existingMethod, Type[] parameterTypes)
61        {
62            var parameterList = new List<Type>();
63
64            if (!existingMethod.IsStatic)
65                parameterList.Add(existingMethod.DeclaringType);
66
67            parameterList.AddRange(parameterTypes);
68
69            return parameterList;
70        }
71
72        /// <summary>
73        ///     Emits the instruction to call the target <paramref name="method" />
74        /// </summary>
75        /// <param name="IL">The <see cref="ILGenerator" /> of the target method body.</param>
76        /// <param name="method">The method that will be invoked.</param>
77        protected override void EmitCall(ILGenerator IL, MethodInfo method)
78        {
79            var callInstruction = method.IsVirtual ? OpCodes.Callvirt : OpCodes.Call;
80            IL.Emit(callInstruction, method);
81        }
82    }
83}