Xamarin Public Jenkins (auto-signing) ef583813eb Imported Upstream version 6.4.0.137
Former-commit-id: 943baa9f16a098c33e129777827f3a9d20da00d6
2019-07-26 19:53:28 +00:00

299 lines
8.9 KiB
C#

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 (Platform.OnCoreClr ? "System.Private.CoreLib" : "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 (Platform.OnCoreClr ? "System.Private.CoreLib" : "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 (Platform.OnCoreClr ? "System.Private.CoreLib" : "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 (Platform.OnCoreClr ? "System.Private.CoreLib" : "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 (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
definition.Module.Assembly.Name.Name);
}
class CustomResolver : DefaultAssemblyResolver {
public void Register (AssemblyDefinition assembly)
{
this.RegisterAssembly (assembly);
this.AddSearchDirectory (Path.GetDirectoryName (assembly.MainModule.FileName));
}
}
[Test]
public void ExportedTypeFromModule ()
{
var resolver = new CustomResolver ();
var parameters = new ReaderParameters { AssemblyResolver = resolver };
var mma = GetResourceModule ("mma.exe", parameters);
resolver.Register (mma.Assembly);
using (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")),
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 (Platform.OnCoreClr ? "System.Private.CoreLib" : "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")),
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 (Platform.OnCoreClr ? "System.Private.CoreLib" : "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 GenericRectangularArrayGetMethodInMemberReferences ()
{
using (var module = GetResourceModule ("FSharp.Core.dll")) {
foreach (var member in module.GetMemberReferences ()) {
if (!member.DeclaringType.IsArray)
continue;
Assert.IsNull (member.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);
if (!Platform.OnCoreClr)
Assert.AreEqual (typeof (object).Assembly.GetName ().Version, assembly.Name.Version);
}
}
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 ();
}
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 ();
}
}
}