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