/Test/Mono.Cecil.Tests/ResolveTests.cs

http://github.com/jbevain/cecil · C# · 298 lines · 226 code · 72 blank · 0 comment · 8 complexity · 21a7a44138172548fd6572d40168cc50 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using Mono.Cecil;
  6. using Mono.Cecil.Cil;
  7. using NUnit.Framework;
  8. namespace Mono.Cecil.Tests {
  9. [TestFixture]
  10. public class ResolveTests : BaseTestFixture {
  11. [Test]
  12. public void StringEmpty ()
  13. {
  14. var string_empty = GetReference<Func<string>, FieldReference> (
  15. () => string.Empty);
  16. Assert.AreEqual ("System.String System.String::Empty", string_empty.FullName);
  17. var definition = string_empty.Resolve ();
  18. Assert.IsNotNull (definition);
  19. Assert.AreEqual ("System.String System.String::Empty", definition.FullName);
  20. Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
  21. definition.Module.Assembly.Name.Name);
  22. }
  23. delegate string GetSubstring (string str, int start, int length);
  24. [Test]
  25. public void StringSubstring ()
  26. {
  27. var string_substring = GetReference<GetSubstring, MethodReference> (
  28. (s, start, length) => s.Substring (start, length));
  29. var definition = string_substring.Resolve ();
  30. Assert.IsNotNull (definition);
  31. Assert.AreEqual ("System.String System.String::Substring(System.Int32,System.Int32)", definition.FullName);
  32. Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
  33. definition.Module.Assembly.Name.Name);
  34. }
  35. [Test]
  36. public void StringLength ()
  37. {
  38. var string_length = GetReference<Func<string, int>, MethodReference> (s => s.Length);
  39. var definition = string_length.Resolve ();
  40. Assert.IsNotNull (definition);
  41. Assert.AreEqual ("get_Length", definition.Name);
  42. Assert.AreEqual ("System.String", definition.DeclaringType.FullName);
  43. Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
  44. definition.Module.Assembly.Name.Name);
  45. }
  46. [Test]
  47. public void ListOfStringAdd ()
  48. {
  49. var list_add = GetReference<Action<List<string>>, MethodReference> (
  50. list => list.Add ("coucou"));
  51. Assert.AreEqual ("System.Void System.Collections.Generic.List`1<System.String>::Add(!0)", list_add.FullName);
  52. var definition = list_add.Resolve ();
  53. Assert.IsNotNull (definition);
  54. Assert.AreEqual ("System.Void System.Collections.Generic.List`1::Add(T)", definition.FullName);
  55. Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
  56. definition.Module.Assembly.Name.Name);
  57. }
  58. [Test]
  59. public void DictionaryOfStringTypeDefinitionTryGetValue ()
  60. {
  61. var try_get_value = GetReference<Func<Dictionary<string, TypeDefinition>, string, bool>, MethodReference> (
  62. (d, s) => {
  63. TypeDefinition type;
  64. return d.TryGetValue (s, out type);
  65. });
  66. Assert.AreEqual ("System.Boolean System.Collections.Generic.Dictionary`2<System.String,Mono.Cecil.TypeDefinition>::TryGetValue(!0,!1&)",
  67. try_get_value.FullName);
  68. var definition = try_get_value.Resolve ();
  69. Assert.IsNotNull (definition);
  70. Assert.AreEqual ("System.Boolean System.Collections.Generic.Dictionary`2::TryGetValue(TKey,TValue&)", definition.FullName);
  71. Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
  72. definition.Module.Assembly.Name.Name);
  73. }
  74. class CustomResolver : DefaultAssemblyResolver {
  75. public void Register (AssemblyDefinition assembly)
  76. {
  77. this.RegisterAssembly (assembly);
  78. this.AddSearchDirectory (Path.GetDirectoryName (assembly.MainModule.FileName));
  79. }
  80. }
  81. [Test]
  82. public void ExportedTypeFromModule ()
  83. {
  84. var resolver = new CustomResolver ();
  85. var parameters = new ReaderParameters { AssemblyResolver = resolver };
  86. var mma = GetResourceModule ("mma.exe", parameters);
  87. resolver.Register (mma.Assembly);
  88. using (var current_module = GetCurrentModule (parameters)) {
  89. var reference = new TypeReference ("Module.A", "Foo", current_module, AssemblyNameReference.Parse (mma.Assembly.FullName), false);
  90. var definition = reference.Resolve ();
  91. Assert.IsNotNull (definition);
  92. Assert.AreEqual ("Module.A.Foo", definition.FullName);
  93. }
  94. }
  95. [Test]
  96. public void TypeForwarder ()
  97. {
  98. var resolver = new CustomResolver ();
  99. var parameters = new ReaderParameters { AssemblyResolver = resolver };
  100. var types = ModuleDefinition.ReadModule (
  101. CompilationService.CompileResource (GetCSharpResourcePath ("CustomAttributes.cs")),
  102. parameters);
  103. resolver.Register (types.Assembly);
  104. var current_module = GetCurrentModule (parameters);
  105. var reference = new TypeReference ("System.Diagnostics", "DebuggableAttribute", current_module, AssemblyNameReference.Parse (types.Assembly.FullName), false);
  106. var definition = reference.Resolve ();
  107. Assert.IsNotNull (definition);
  108. Assert.AreEqual ("System.Diagnostics.DebuggableAttribute", definition.FullName);
  109. Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", definition.Module.Assembly.Name.Name);
  110. }
  111. [Test]
  112. public void NestedTypeForwarder ()
  113. {
  114. var resolver = new CustomResolver ();
  115. var parameters = new ReaderParameters { AssemblyResolver = resolver };
  116. var types = ModuleDefinition.ReadModule (
  117. CompilationService.CompileResource (GetCSharpResourcePath ("CustomAttributes.cs")),
  118. parameters);
  119. resolver.Register (types.Assembly);
  120. var current_module = GetCurrentModule (parameters);
  121. var reference = new TypeReference ("", "DebuggingModes", current_module, null, true);
  122. reference.DeclaringType = new TypeReference ("System.Diagnostics", "DebuggableAttribute", current_module, AssemblyNameReference.Parse (types.Assembly.FullName), false);
  123. var definition = reference.Resolve ();
  124. Assert.IsNotNull (definition);
  125. Assert.AreEqual ("System.Diagnostics.DebuggableAttribute/DebuggingModes", definition.FullName);
  126. Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", definition.Module.Assembly.Name.Name);
  127. }
  128. [Test]
  129. public void RectangularArrayResolveGetMethod ()
  130. {
  131. var get_a_b = GetReference<Func<int[,], int>, MethodReference> (matrix => matrix [2, 2]);
  132. Assert.AreEqual ("Get", get_a_b.Name);
  133. Assert.IsNotNull (get_a_b.Module);
  134. Assert.IsNull (get_a_b.Resolve ());
  135. }
  136. [Test]
  137. public void GenericRectangularArrayGetMethodInMemberReferences ()
  138. {
  139. using (var module = GetResourceModule ("FSharp.Core.dll")) {
  140. foreach (var member in module.GetMemberReferences ()) {
  141. if (!member.DeclaringType.IsArray)
  142. continue;
  143. Assert.IsNull (member.Resolve ());
  144. }
  145. }
  146. }
  147. [Test]
  148. public void ResolveFunctionPointer ()
  149. {
  150. var module = GetResourceModule ("cppcli.dll");
  151. var global = module.GetType ("<Module>");
  152. var field = global.GetField ("__onexitbegin_app_domain");
  153. var type = field.FieldType as PointerType;
  154. Assert.IsNotNull(type);
  155. var fnptr = type.ElementType as FunctionPointerType;
  156. Assert.IsNotNull (fnptr);
  157. Assert.IsNull (fnptr.Resolve ());
  158. }
  159. [Test]
  160. public void ResolveGenericParameter ()
  161. {
  162. var collection = typeof (Mono.Collections.Generic.Collection<>).ToDefinition ();
  163. var parameter = collection.GenericParameters [0];
  164. Assert.IsNotNull (parameter);
  165. Assert.IsNull (parameter.Resolve ());
  166. }
  167. [Test]
  168. public void ResolveNullVersionAssembly ()
  169. {
  170. var reference = AssemblyNameReference.Parse ("System.Core");
  171. reference.Version = null;
  172. var resolver = new DefaultAssemblyResolver ();
  173. Assert.IsNotNull (resolver.Resolve (reference));
  174. }
  175. [Test]
  176. public void ResolvePortableClassLibraryReference ()
  177. {
  178. var resolver = new DefaultAssemblyResolver ();
  179. var parameters = new ReaderParameters { AssemblyResolver = resolver };
  180. var pcl = GetResourceModule ("PortableClassLibrary.dll", parameters);
  181. foreach (var reference in pcl.AssemblyReferences) {
  182. Assert.IsTrue (reference.IsRetargetable);
  183. var assembly = resolver.Resolve (reference);
  184. Assert.IsNotNull (assembly);
  185. if (!Platform.OnCoreClr)
  186. Assert.AreEqual (typeof (object).Assembly.GetName ().Version, assembly.Name.Version);
  187. }
  188. }
  189. TRet GetReference<TDel, TRet> (TDel code)
  190. {
  191. var @delegate = code as Delegate;
  192. if (@delegate == null)
  193. throw new InvalidOperationException ();
  194. var reference = (TRet) GetReturnee (GetMethodFromDelegate (@delegate));
  195. Assert.IsNotNull (reference);
  196. return reference;
  197. }
  198. static object GetReturnee (MethodDefinition method)
  199. {
  200. Assert.IsTrue (method.HasBody);
  201. var instruction = method.Body.Instructions [method.Body.Instructions.Count - 1];
  202. Assert.IsNotNull (instruction);
  203. while (instruction != null) {
  204. var opcode = instruction.OpCode;
  205. switch (opcode.OperandType) {
  206. case OperandType.InlineField:
  207. case OperandType.InlineTok:
  208. case OperandType.InlineType:
  209. case OperandType.InlineMethod:
  210. return instruction.Operand;
  211. default:
  212. instruction = instruction.Previous;
  213. break;
  214. }
  215. }
  216. throw new InvalidOperationException ();
  217. }
  218. MethodDefinition GetMethodFromDelegate (Delegate @delegate)
  219. {
  220. var method = @delegate.Method;
  221. var type = (TypeDefinition) TypeParser.ParseType (GetCurrentModule (), method.DeclaringType.FullName);
  222. Assert.IsNotNull (type);
  223. return type.Methods.Where (m => m.Name == method.Name).First ();
  224. }
  225. }
  226. }