mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
8.3 KiB
277 lines
8.3 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.IO; |
|
using System.Linq; |
|
|
|
using Mono.Cecil; |
|
using Mono.Cecil.Cil; |
|
|
|
using NUnit.Framework; |
|
|
|
namespace Mono.Cecil.Tests { |
|
|
|
[TestFixture] |
|
public class ResolveTests : BaseTestFixture { |
|
|
|
[Test] |
|
public void StringEmpty () |
|
{ |
|
var string_empty = GetReference<Func<string>, FieldReference> ( |
|
() => string.Empty); |
|
|
|
Assert.AreEqual ("System.String System.String::Empty", string_empty.FullName); |
|
|
|
var definition = string_empty.Resolve (); |
|
|
|
Assert.IsNotNull (definition); |
|
|
|
Assert.AreEqual ("System.String System.String::Empty", definition.FullName); |
|
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); |
|
} |
|
|
|
delegate string GetSubstring (string str, int start, int length); |
|
|
|
[Test] |
|
public void StringSubstring () |
|
{ |
|
var string_substring = GetReference<GetSubstring, MethodReference> ( |
|
(s, start, length) => s.Substring (start, length)); |
|
|
|
var definition = string_substring.Resolve (); |
|
|
|
Assert.IsNotNull (definition); |
|
|
|
Assert.AreEqual ("System.String System.String::Substring(System.Int32,System.Int32)", definition.FullName); |
|
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); |
|
} |
|
|
|
[Test] |
|
public void StringLength () |
|
{ |
|
var string_length = GetReference<Func<string, int>, MethodReference> (s => s.Length); |
|
|
|
var definition = string_length.Resolve (); |
|
|
|
Assert.IsNotNull (definition); |
|
|
|
Assert.AreEqual ("get_Length", definition.Name); |
|
Assert.AreEqual ("System.String", definition.DeclaringType.FullName); |
|
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); |
|
} |
|
|
|
[Test] |
|
public void ListOfStringAdd () |
|
{ |
|
var list_add = GetReference<Action<List<string>>, MethodReference> ( |
|
list => list.Add ("coucou")); |
|
|
|
Assert.AreEqual ("System.Void System.Collections.Generic.List`1<System.String>::Add(!0)", list_add.FullName); |
|
|
|
var definition = list_add.Resolve (); |
|
|
|
Assert.IsNotNull (definition); |
|
|
|
Assert.AreEqual ("System.Void System.Collections.Generic.List`1::Add(T)", definition.FullName); |
|
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); |
|
} |
|
|
|
[Test] |
|
public void DictionaryOfStringTypeDefinitionTryGetValue () |
|
{ |
|
var try_get_value = GetReference<Func<Dictionary<string, TypeDefinition>, string, bool>, MethodReference> ( |
|
(d, s) => { |
|
TypeDefinition type; |
|
return d.TryGetValue (s, out type); |
|
}); |
|
|
|
Assert.AreEqual ("System.Boolean System.Collections.Generic.Dictionary`2<System.String,Mono.Cecil.TypeDefinition>::TryGetValue(!0,!1&)", |
|
try_get_value.FullName); |
|
|
|
var definition = try_get_value.Resolve (); |
|
|
|
Assert.IsNotNull (definition); |
|
|
|
Assert.AreEqual ("System.Boolean System.Collections.Generic.Dictionary`2::TryGetValue(TKey,TValue&)", definition.FullName); |
|
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); |
|
} |
|
|
|
class CustomResolver : DefaultAssemblyResolver { |
|
|
|
public void Register (AssemblyDefinition assembly) |
|
{ |
|
this.RegisterAssembly (assembly); |
|
this.AddSearchDirectory (Path.GetDirectoryName (assembly.MainModule.FullyQualifiedName)); |
|
} |
|
} |
|
|
|
[Test] |
|
public void ExportedTypeFromModule () |
|
{ |
|
var resolver = new CustomResolver (); |
|
var parameters = new ReaderParameters { AssemblyResolver = resolver }; |
|
var mma = GetResourceModule ("mma.exe", parameters); |
|
|
|
resolver.Register (mma.Assembly); |
|
|
|
var current_module = GetCurrentModule (parameters); |
|
var reference = new TypeReference ("Module.A", "Foo", current_module, AssemblyNameReference.Parse (mma.Assembly.FullName), false); |
|
|
|
var definition = reference.Resolve (); |
|
Assert.IsNotNull (definition); |
|
Assert.AreEqual ("Module.A.Foo", definition.FullName); |
|
} |
|
|
|
[Test] |
|
public void TypeForwarder () |
|
{ |
|
var resolver = new CustomResolver (); |
|
var parameters = new ReaderParameters { AssemblyResolver = resolver }; |
|
|
|
var types = ModuleDefinition.ReadModule ( |
|
CompilationService.CompileResource (GetCSharpResourcePath ("CustomAttributes.cs", typeof (ResolveTests).Assembly)), |
|
parameters); |
|
|
|
resolver.Register (types.Assembly); |
|
|
|
var current_module = GetCurrentModule (parameters); |
|
var reference = new TypeReference ("System.Diagnostics", "DebuggableAttribute", current_module, AssemblyNameReference.Parse (types.Assembly.FullName), false); |
|
|
|
var definition = reference.Resolve (); |
|
Assert.IsNotNull (definition); |
|
Assert.AreEqual ("System.Diagnostics.DebuggableAttribute", definition.FullName); |
|
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); |
|
} |
|
|
|
[Test] |
|
public void NestedTypeForwarder () |
|
{ |
|
var resolver = new CustomResolver (); |
|
var parameters = new ReaderParameters { AssemblyResolver = resolver }; |
|
|
|
var types = ModuleDefinition.ReadModule ( |
|
CompilationService.CompileResource (GetCSharpResourcePath ("CustomAttributes.cs", typeof (ResolveTests).Assembly)), |
|
parameters); |
|
|
|
resolver.Register (types.Assembly); |
|
|
|
var current_module = GetCurrentModule (parameters); |
|
var reference = new TypeReference ("", "DebuggingModes", current_module, null, true); |
|
reference.DeclaringType = new TypeReference ("System.Diagnostics", "DebuggableAttribute", current_module, AssemblyNameReference.Parse (types.Assembly.FullName), false); |
|
|
|
var definition = reference.Resolve (); |
|
Assert.IsNotNull (definition); |
|
Assert.AreEqual ("System.Diagnostics.DebuggableAttribute/DebuggingModes", definition.FullName); |
|
Assert.AreEqual ("mscorlib", definition.Module.Assembly.Name.Name); |
|
} |
|
|
|
[Test] |
|
public void RectangularArrayResolveGetMethod () |
|
{ |
|
var get_a_b = GetReference<Func<int[,], int>, MethodReference> (matrix => matrix [2, 2]); |
|
|
|
Assert.AreEqual ("Get", get_a_b.Name); |
|
Assert.IsNotNull (get_a_b.Module); |
|
Assert.IsNull (get_a_b.Resolve ()); |
|
} |
|
|
|
[Test] |
|
public void ResolveFunctionPointer () |
|
{ |
|
var module = GetResourceModule ("cppcli.dll"); |
|
var global = module.GetType ("<Module>"); |
|
var field = global.GetField ("__onexitbegin_app_domain"); |
|
|
|
var type = field.FieldType as PointerType; |
|
Assert.IsNotNull(type); |
|
|
|
var fnptr = type.ElementType as FunctionPointerType; |
|
Assert.IsNotNull (fnptr); |
|
|
|
Assert.IsNull (fnptr.Resolve ()); |
|
} |
|
|
|
[Test] |
|
public void ResolveGenericParameter () |
|
{ |
|
var collection = typeof (Mono.Collections.Generic.Collection<>).ToDefinition (); |
|
var parameter = collection.GenericParameters [0]; |
|
|
|
Assert.IsNotNull (parameter); |
|
|
|
Assert.IsNull (parameter.Resolve ()); |
|
} |
|
|
|
[Test] |
|
public void ResolveNullVersionAssembly () |
|
{ |
|
var reference = AssemblyNameReference.Parse ("System.Core"); |
|
reference.Version = null; |
|
|
|
var resolver = new DefaultAssemblyResolver (); |
|
Assert.IsNotNull (resolver.Resolve (reference)); |
|
} |
|
|
|
[Test] |
|
public void ResolvePortableClassLibraryReference () |
|
{ |
|
var resolver = new DefaultAssemblyResolver (); |
|
var parameters = new ReaderParameters { AssemblyResolver = resolver }; |
|
var pcl = GetResourceModule ("PortableClassLibrary.dll", parameters); |
|
|
|
foreach (var reference in pcl.AssemblyReferences) { |
|
Assert.IsTrue (reference.IsRetargetable); |
|
var assembly = resolver.Resolve (reference); |
|
Assert.IsNotNull (assembly); |
|
Assert.AreEqual (typeof (object).Assembly.GetName ().Version, assembly.Name.Version); |
|
} |
|
} |
|
|
|
static TRet GetReference<TDel, TRet> (TDel code) |
|
{ |
|
var @delegate = code as Delegate; |
|
if (@delegate == null) |
|
throw new InvalidOperationException (); |
|
|
|
var reference = (TRet) GetReturnee (GetMethodFromDelegate (@delegate)); |
|
|
|
Assert.IsNotNull (reference); |
|
|
|
return reference; |
|
} |
|
|
|
static object GetReturnee (MethodDefinition method) |
|
{ |
|
Assert.IsTrue (method.HasBody); |
|
|
|
var instruction = method.Body.Instructions [method.Body.Instructions.Count - 1]; |
|
|
|
Assert.IsNotNull (instruction); |
|
|
|
while (instruction != null) { |
|
var opcode = instruction.OpCode; |
|
switch (opcode.OperandType) { |
|
case OperandType.InlineField: |
|
case OperandType.InlineTok: |
|
case OperandType.InlineType: |
|
case OperandType.InlineMethod: |
|
return instruction.Operand; |
|
default: |
|
instruction = instruction.Previous; |
|
break; |
|
} |
|
} |
|
|
|
throw new InvalidOperationException (); |
|
} |
|
|
|
static MethodDefinition GetMethodFromDelegate (Delegate @delegate) |
|
{ |
|
var method = @delegate.Method; |
|
var type = (TypeDefinition) TypeParser.ParseType (GetCurrentModule (), method.DeclaringType.FullName); |
|
|
|
Assert.IsNotNull (type); |
|
|
|
return type.Methods.Where (m => m.Name == method.Name).First (); |
|
} |
|
} |
|
}
|
|
|