Merge pull request #4540 from kumpera/android-changes-part1
[mono.git] / mcs / class / corlib / Test / System.Reflection / MethodInfoTest.cs
index b8a9de2b3c59a7908974d880877fdf8d4bcd2fb3..6a22ea1c638288ad05e8789c0d273423091ec327 100644 (file)
@@ -3,9 +3,11 @@
 //
 // Authors:
 //  Zoltan Varga (vargaz@gmail.com)
+//  Aleksey Kliger (aleksey@xamarin.com)
 //
 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2015 Xamarin, Inc. (http://www.xamarin.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -31,7 +33,7 @@ using NUnit.Framework;
 using System;
 using System.Threading;
 using System.Reflection;
-#if !MONOTOUCH
+#if !MONOTOUCH && !FULL_AOT_RUNTIME
 using System.Reflection.Emit;
 #endif
 using System.Runtime.InteropServices;
@@ -52,7 +54,12 @@ namespace MonoTests.System.Reflection
        [TestFixture]
        public class MethodInfoTest
        {
+#if MONOTOUCH || FULL_AOT_RUNTIME
+               // use an existing symbol - so we can build without dlsym. It does not matter that the signature does not match for the test
+               [DllImport ("libc", EntryPoint="readlink", CharSet=CharSet.Unicode, ExactSpelling=false, PreserveSig=true, SetLastError=true, BestFitMapping=true, ThrowOnUnmappableChar=true)]
+#else
                [DllImport ("libfoo", EntryPoint="foo", CharSet=CharSet.Unicode, ExactSpelling=false, PreserveSig=true, SetLastError=true, BestFitMapping=true, ThrowOnUnmappableChar=true)]
+#endif
                public static extern void dllImportMethod ();
                [MethodImplAttribute(MethodImplOptions.PreserveSig)]
                public void preserveSigMethod ()
@@ -108,8 +115,13 @@ namespace MonoTests.System.Reflection
                        DllImportAttribute attr = (DllImportAttribute)((t.GetMethod ("dllImportMethod").GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
 
                        Assert.AreEqual (CallingConvention.Winapi, attr.CallingConvention, "#1");
+#if MONOTOUCH || FULL_AOT_RUNTIME
+                       Assert.AreEqual ("readlink", attr.EntryPoint, "#2");
+                       Assert.AreEqual ("libc", attr.Value, "#3");
+#else
                        Assert.AreEqual ("foo", attr.EntryPoint, "#2");
                        Assert.AreEqual ("libfoo", attr.Value, "#3");
+#endif
                        Assert.AreEqual (CharSet.Unicode, attr.CharSet, "#4");
                        Assert.AreEqual (false, attr.ExactSpelling, "#5");
                        Assert.AreEqual (true, attr.PreserveSig, "#6");
@@ -275,12 +287,60 @@ namespace MonoTests.System.Reflection
                class GBD_D : GBD_C { public new virtual void f () {} }
                class GBD_E : GBD_D { public override    void f () {} }
 
+               class GBD_E2 : GBD_D { }
+               class GBD_F : GBD_E { }
+
+
                [Test]
                public void GetBaseDefinition ()
                {
                        Assert.AreEqual (typeof (GBD_A), typeof (GBD_C).GetMethod ("f").GetBaseDefinition ().DeclaringType);
+                       Assert.AreEqual (typeof (GBD_A), typeof (GBD_C).GetMethod ("f").GetBaseDefinition ().ReflectedType, "#1r");
+
                        Assert.AreEqual (typeof (GBD_D), typeof (GBD_D).GetMethod ("f").GetBaseDefinition ().DeclaringType);
+                       Assert.AreEqual (typeof (GBD_D), typeof (GBD_D).GetMethod ("f").GetBaseDefinition ().ReflectedType, "#2r");
+
                        Assert.AreEqual (typeof (GBD_D), typeof (GBD_E).GetMethod ("f").GetBaseDefinition ().DeclaringType);
+                       Assert.AreEqual (typeof (GBD_D), typeof (GBD_E).GetMethod ("f").GetBaseDefinition ().ReflectedType, "#3r");
+
+                       Assert.AreEqual (typeof (GBD_D), typeof (GBD_E2).GetMethod ("f").GetBaseDefinition ().DeclaringType, "#4");
+                       Assert.AreEqual (typeof (GBD_D), typeof (GBD_E2).GetMethod ("f").GetBaseDefinition ().ReflectedType, "#4r");
+
+                       Assert.AreEqual (typeof (GBD_D), typeof (GBD_F).GetMethod ("f").GetBaseDefinition ().DeclaringType, "#5");
+                       Assert.AreEqual (typeof (GBD_D), typeof (GBD_F).GetMethod ("f").GetBaseDefinition ().ReflectedType, "#5r");
+
+               }
+
+               class GenericBase<T,H> {
+                       public virtual void f2 () { }
+               }
+
+               class GenericMid<T, U> : GenericBase<T, Action<U>> {
+                       public virtual T f1 () { return default (T); }
+               }
+
+               class GenericChild<T> : GenericMid<T, int> {
+                       public override T f1 () { return default (T); }
+                       public override void f2 () { }
+               }
+
+               class DerivedFromGenericBase : GenericBase<int, int> {
+               }
+
+               [Test]
+               public void GetBaseDefinition_OpenConstructedBaseType () // 36305
+               {
+                       var t = typeof (GenericChild<string>);
+
+                       var mi1 = t.GetMethod ("f1");
+                       var mi1_base = mi1.GetBaseDefinition ();
+
+                       Assert.AreEqual (typeof (GenericMid<string, int>), mi1_base.DeclaringType, "#1");
+
+                       var mi2 = t.GetMethod ("f2");
+                       var mi2_base = mi2.GetBaseDefinition ();
+
+                       Assert.AreEqual (typeof (GenericBase<string, Action<int>>), mi2_base.DeclaringType, "#2");
                }
 
                class TestInheritedMethodA {
@@ -353,7 +413,7 @@ namespace MonoTests.System.Reflection
                [Test]
                public void GetMethodBody ()
                {
-#if MONOTOUCH && !DEBUG
+#if (MONOTOUCH || FULL_AOT_RUNTIME) && !DEBUG
                        Assert.Ignore ("Release app (on devices) are stripped of (managed) IL so this test would fail");
 #endif
                        MethodBody mb = typeof (MethodInfoTest).GetMethod ("locals_method").GetMethodBody ();
@@ -556,7 +616,7 @@ namespace MonoTests.System.Reflection
                        } catch (InvalidOperationException ex) {
                        }
                }
-#if !MONOTOUCH
+#if !MONOTOUCH && !FULL_AOT_RUNTIME
                public TFoo SimpleGenericMethod2<TFoo, TBar> () { return default (TFoo); }
                /*Test for the uggly broken behavior of SRE.*/
                [Test]
@@ -783,7 +843,34 @@ namespace MonoTests.System.Reflection
                        Assert.AreEqual ("System.Nullable`1[System.Int32] Bug12856()", m.ToString (), "#1");
                }
 
-#if !MONOTOUCH
+               [Test]
+               public void GetReflectedType () // #12205
+               {
+                       // public method declared in base type, queried from a derived type
+                       MethodInfo mi = typeof (TestInheritedMethodB).GetMethod ("TestMethod2");
+                       Assert.AreEqual (mi.ReflectedType, typeof (TestInheritedMethodB), "#1");
+
+                       // public method declared in a generic class,
+                       // queried from a non-generic class derived
+                       // from an instantiation of the generic class.
+                       mi = typeof (DerivedFromGenericBase).GetMethod ("f2");
+                       Assert.AreEqual (mi.ReflectedType, typeof (DerivedFromGenericBase), "#2");
+
+                       // public method declared in a generic class,
+                       // queried from the generic type defintion of
+                       // a generic derived class.
+                       mi = typeof (GenericMid<,>).GetMethod ("f2");
+                       Assert.AreEqual (mi.ReflectedType, typeof (GenericMid<,>), "#3");
+
+                       // public method declared in a generic class,
+                       // queried from an instantiation of a generic
+                       // derived class.
+                       mi = typeof (GenericMid<int,int>).GetMethod ("f2");
+                       Assert.AreEqual (mi.ReflectedType, typeof (GenericMid<int,int>), "#4");
+
+               }
+
+#if !MONOTOUCH && !FULL_AOT_RUNTIME
                class GenericClass<T>
                {
                        public void Method ()