PageRenderTime 35ms CodeModel.GetById 28ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/src/LinFu.AOP/BaseMethodRewriter.cs

http://github.com/philiplaureano/LinFu
C# | 96 lines | 45 code | 18 blank | 33 comment | 4 complexity | 452f1c1f4e871addc6466fbad13317b4 MD5 | raw file
 1using System.Collections.Generic;
 2using LinFu.AOP.Cecil.Interfaces;
 3using Mono.Cecil;
 4using Mono.Cecil.Cil;
 5
 6namespace LinFu.AOP.Cecil
 7{
 8    /// <summary>
 9    ///     Represents the basic implementation of a method rewriter class.
10    /// </summary>
11    public abstract class BaseMethodRewriter : IMethodRewriter
12    {
13        private readonly HashSet<TypeDefinition> _modifiedTypes = new HashSet<TypeDefinition>();
14
15
16        /// <summary>
17        ///     Rewrites a target method using the given ILProcessor.
18        /// </summary>
19        /// <param name="method">The target method.</param>
20        /// <param name="IL">The ILProcessor that will be used to rewrite the target method.</param>
21        /// <param name="oldInstructions">The original instructions from the target method body.</param>
22        public void Rewrite(MethodDefinition method, ILProcessor IL, IEnumerable<Instruction> oldInstructions)
23        {
24            if (!ShouldRewrite(method))
25                return;
26
27            var declaringType = method.DeclaringType;
28
29            var body = IL.Body;
30            body.InitLocals = true;
31
32            var module = declaringType.Module;
33
34            // Interfaces and Enums cannot be modified
35            if (declaringType.IsInterface || declaringType.IsEnum)
36                return;
37
38            ImportReferences(module);
39
40            AddLocals(method);
41
42            if (!_modifiedTypes.Contains(declaringType))
43            {
44                AddAdditionalMembers(declaringType);
45                _modifiedTypes.Add(declaringType);
46            }
47
48            RewriteMethodBody(method, IL, oldInstructions);
49        }
50
51
52        /// <summary>
53        ///     Adds additional members to the host type.
54        /// </summary>
55        /// <param name="host">The host type.</param>
56        public virtual void AddAdditionalMembers(TypeDefinition host)
57        {
58        }
59
60        /// <summary>
61        ///     Adds additional references to the target module.
62        /// </summary>
63        /// <param name="module">The host module.</param>
64        public virtual void ImportReferences(ModuleDefinition module)
65        {
66        }
67
68        /// <summary>
69        ///     Adds local variables to the <paramref name="hostMethod" />.
70        /// </summary>
71        /// <param name="hostMethod">The target method.</param>
72        public virtual void AddLocals(MethodDefinition hostMethod)
73        {
74        }
75
76
77        /// <summary>
78        ///     Determines whether or not the given method should be modified.
79        /// </summary>
80        /// <param name="targetMethod">The target method.</param>
81        /// <returns>A <see cref="bool" /> indicating whether or not a method should be rewritten.</returns>
82        protected virtual bool ShouldRewrite(MethodDefinition targetMethod)
83        {
84            return true;
85        }
86
87        /// <summary>
88        ///     Rewrites the instructions in the target method body.
89        /// </summary>
90        /// <param name="method">The target method.</param>
91        /// <param name="IL">The <see cref="ILProcessor" /> instance that represents the method body.</param>
92        /// <param name="oldInstructions">The IL instructions of the original method body.</param>
93        protected abstract void RewriteMethodBody(MethodDefinition method, ILProcessor IL,
94            IEnumerable<Instruction> oldInstructions);
95    }
96}