/src/LinFu.Reflection.Emit/ModuleDefinitionExtensions.cs

http://github.com/philiplaureano/LinFu · C# · 169 lines · 63 code · 12 blank · 94 comment · 1 complexity · 996ef63b79a89763eb5279173d585abb MD5 · raw file

  1. using System;
  2. using System.Linq;
  3. using System.Reflection;
  4. using Mono.Cecil;
  5. using TypeAttributes = Mono.Cecil.TypeAttributes;
  6. namespace LinFu.Reflection.Emit
  7. {
  8. /// <summary>
  9. /// A class that provides helper extension methods
  10. /// for the <see cref="ModuleDefinition" /> class.
  11. /// </summary>
  12. public static class ModuleDefinitionExtensions
  13. {
  14. /// <summary>
  15. /// Defines a new class and adds it to the <paramref name="mainModule" /> module.
  16. /// </summary>
  17. /// <param name="mainModule">The module which will hold the new created type.</param>
  18. /// <param name="typeName">The name of the class to create.</param>
  19. /// <param name="namespaceName">The namespace that will contain the new class.</param>
  20. /// <param name="attributes">The <see cref="Mono.Cecil.TypeAttributes" /> for the given type.</param>
  21. /// <param name="baseType">The base class of the new type.</param>
  22. /// <returns>A <see cref="TypeDefinition" /> representing the new class being created.</returns>
  23. public static TypeDefinition DefineClass(this ModuleDefinition mainModule,
  24. string typeName, string namespaceName, TypeAttributes attributes,
  25. TypeReference baseType)
  26. {
  27. var resultType = new TypeDefinition(typeName, namespaceName,
  28. attributes, baseType);
  29. mainModule.Types.Add(resultType);
  30. return resultType;
  31. }
  32. /// <summary>
  33. /// Imports a constructor with the given <paramref name="constructorParameters" />
  34. /// into the target <paramref name="module" />.
  35. /// </summary>
  36. /// <typeparam name="T">The type that holds the target constructor</typeparam>
  37. /// <param name="module">The <see cref="ModuleDefinition" /> that will import the target constructor.</param>
  38. /// <param name="constructorParameters">
  39. /// The list of <see cref="System.Type" /> objects that describe the signature of the
  40. /// constructor.
  41. /// </param>
  42. /// <returns>A <see cref="MethodReference" /> that represents the constructor itself.</returns>
  43. public static MethodReference ImportConstructor<T>(this ModuleDefinition module,
  44. params Type[] constructorParameters)
  45. {
  46. return module.Import(typeof(T).GetConstructor(constructorParameters));
  47. }
  48. /// <summary>
  49. /// Imports a method with a particular <paramref name="methodName" /> from the <paramref name="declaringType" />
  50. /// into the <paramref name="module">target module</paramref>.
  51. /// </summary>
  52. /// <param name="module">The <see cref="ModuleDefinition" /> instance that will import the actual method.</param>
  53. /// <param name="methodName">The name of the method being imported.</param>
  54. /// <param name="declaringType">The <see cref="System.Type" /> instance that holds the target method.</param>
  55. /// <returns>A <see cref="MethodReference" /> that represents the method being imported.</returns>
  56. public static MethodReference ImportMethod(this ModuleDefinition module, string methodName, Type declaringType)
  57. {
  58. return module.Import(declaringType.GetMethod(methodName));
  59. }
  60. /// <summary>
  61. /// Imports a method with a particular <paramref name="methodName" /> and <see cref="BindingFlags" /> from the
  62. /// <paramref name="declaringType" />
  63. /// into the <paramref name="module">target module</paramref>.
  64. /// </summary>
  65. /// <param name="module">The <see cref="ModuleDefinition" /> instance that will import the actual method.</param>
  66. /// <param name="methodName">The name of the method being imported.</param>
  67. /// <param name="declaringType">The <see cref="System.Type" /> instance that holds the target method.</param>
  68. /// <param name="flags">The <see cref="BindingFlags" /> that describes the visibility and behavior of the target method.</param>
  69. /// <returns>A <see cref="MethodReference" /> that represents the method being imported.</returns>
  70. public static MethodReference ImportMethod(this ModuleDefinition module, string methodName, Type declaringType,
  71. BindingFlags flags)
  72. {
  73. return module.Import(declaringType.GetMethod(methodName, flags));
  74. }
  75. /// <summary>
  76. /// Imports a method with a particular <paramref name="methodName" /> and <see cref="BindingFlags" /> from the
  77. /// declaring type
  78. /// into the <paramref name="module">target module</paramref>.
  79. /// </summary>
  80. /// <typeparam name="T">The target type that holds the target method.</typeparam>
  81. /// <param name="module">The <see cref="ModuleDefinition" /> instance that will import the actual method.</param>
  82. /// <param name="methodName">The name of the method being imported.</param>
  83. /// <returns>A <see cref="MethodReference" /> that represents the method being imported.</returns>
  84. public static MethodReference ImportMethod<T>(this ModuleDefinition module, string methodName)
  85. {
  86. return module.Import(typeof(T).GetMethod(methodName));
  87. }
  88. /// <summary>
  89. /// Imports a method with a particular <paramref name="methodName" />, <paramref name="parameterTypes" />, and
  90. /// <see cref="BindingFlags" /> from the declaring type
  91. /// into the <paramref name="module">target module</paramref>.
  92. /// </summary>
  93. /// <typeparam name="T">The target type that holds the target method.</typeparam>
  94. /// <param name="parameterTypes">The list of <see cref="Type" /> objects that describe the method signature.</param>
  95. /// <param name="module">The <see cref="ModuleDefinition" /> instance that will import the actual method.</param>
  96. /// <param name="methodName">The name of the method being imported.</param>
  97. /// <returns>A <see cref="MethodReference" /> that represents the method being imported.</returns>
  98. public static MethodReference ImportMethod<T>(this ModuleDefinition module, string methodName,
  99. params Type[] parameterTypes)
  100. {
  101. return module.Import(typeof(T).GetMethod(methodName, parameterTypes));
  102. }
  103. /// <summary>
  104. /// Imports a method with a particular <paramref name="methodName" /> and <see cref="BindingFlags" /> from the
  105. /// declaring type.
  106. /// into the <paramref name="module">target module</paramref>.
  107. /// </summary>
  108. /// <typeparam name="T">The target type that holds the target method itself.</typeparam>
  109. /// <param name="module">The <see cref="ModuleDefinition" /> instance that will import the actual method.</param>
  110. /// <param name="methodName">The name of the method being imported.</param>
  111. /// <param name="flags">The <see cref="BindingFlags" /> that describes the visibility and behavior of the target method.</param>
  112. /// <returns>A <see cref="MethodReference" /> that represents the method being imported.</returns>
  113. public static MethodReference ImportMethod<T>(this ModuleDefinition module,
  114. string methodName, BindingFlags flags)
  115. {
  116. return module.Import(typeof(T).GetMethod(methodName, flags));
  117. }
  118. /// <summary>
  119. /// Imports a target of type <typeparamref name="T" /> into the
  120. /// <paramref name="module" /> instance.
  121. /// </summary>
  122. /// <typeparam name="T">The type that will be imported into the <see cref="ModuleDefinition" /> instance itself.</typeparam>
  123. /// <param name="module">The module that will store the imported type.</param>
  124. /// <returns>A <see cref="TypeReference" /> instance that represents the imported type.</returns>
  125. public static TypeReference ImportType<T>(this ModuleDefinition module)
  126. {
  127. return module.Import(typeof(T));
  128. }
  129. /// <summary>
  130. /// Imports a <paramref name="targetType">target type</paramref> into the
  131. /// <paramref name="module" /> instance.
  132. /// </summary>
  133. /// <param name="targetType">The type that will be imported into the <see cref="ModuleDefinition" /> instance itself.</param>
  134. /// <param name="module">The module that will store the imported type.</param>
  135. /// <returns>A <see cref="TypeDefinition" /> instance that represents the imported type.</returns>
  136. public static TypeReference ImportType(this ModuleDefinition module, Type targetType)
  137. {
  138. return module.Import(targetType);
  139. }
  140. /// <summary>
  141. /// Returns a <see cref="TypeDefinition" /> that matches the given <paramref name="typeName" />.
  142. /// </summary>
  143. /// <param name="module">The target module to search.</param>
  144. /// <param name="typeName">The name of the target type.</param>
  145. /// <returns>
  146. /// A type that matches the given type name. If the type cannot be found, then this method will return <c>null</c>
  147. /// .
  148. /// </returns>
  149. public static TypeDefinition GetType(this ModuleDefinition module, string typeName)
  150. {
  151. var result = (from TypeDefinition t in module.Types
  152. where t.Name == typeName
  153. select t).FirstOrDefault();
  154. return result;
  155. }
  156. }
  157. }