7d7f676260
Former-commit-id: 38faa55fb9669e35e7d8448b15c25dc447f25767
1175 lines
37 KiB
C#
1175 lines
37 KiB
C#
//
|
|
// MethodBuilderTest.cs - NUnit Test Cases for the MethodBuilder class
|
|
//
|
|
// Zoltan Varga (vargaz@freemail.hu)
|
|
//
|
|
// (C) Ximian, Inc. http://www.ximian.com
|
|
|
|
// TODO:
|
|
// - implement 'Signature' (what the hell it does???) and test it
|
|
// - implement Equals and test it
|
|
|
|
using System;
|
|
using System.Threading;
|
|
using System.Reflection;
|
|
using System.Reflection.Emit;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Security;
|
|
using System.Security.Permissions;
|
|
using System.Runtime.InteropServices;
|
|
|
|
using NUnit.Framework;
|
|
|
|
namespace MonoTests.System.Reflection.Emit
|
|
{
|
|
[TestFixture]
|
|
public class MethodBuilderTest
|
|
{
|
|
private TypeBuilder genClass;
|
|
private ModuleBuilder module;
|
|
|
|
[SetUp]
|
|
protected void SetUp ()
|
|
{
|
|
AssemblyName assemblyName = new AssemblyName ();
|
|
assemblyName.Name = "MonoTests.System.Reflection.Emit.MethodBuilderTest";
|
|
|
|
AssemblyBuilder assembly = Thread.GetDomain ().DefineDynamicAssembly (
|
|
assemblyName, AssemblyBuilderAccess.Run);
|
|
module = assembly.DefineDynamicModule ("module1");
|
|
genClass = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
}
|
|
|
|
static int methodIndexer = 0;
|
|
static int typeIndexer = 0;
|
|
|
|
// Return a unique method name
|
|
private string genMethodName ()
|
|
{
|
|
return "m" + (methodIndexer++);
|
|
}
|
|
|
|
// Return a unique type name
|
|
private string genTypeName ()
|
|
{
|
|
return "class" + (typeIndexer++);
|
|
}
|
|
|
|
[Test]
|
|
public void TestAttributes ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), MethodAttributes.Public, typeof (void), new Type [0]);
|
|
Assert.AreEqual (MethodAttributes.Public, mb.Attributes);
|
|
}
|
|
|
|
[Test]
|
|
public void TestCallingConvention ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
Assert.AreEqual (CallingConventions.Standard | CallingConventions.HasThis,
|
|
mb.CallingConvention, "CallingConvetion defaults to Standard+HasThis");
|
|
|
|
MethodBuilder mb3 = genClass.DefineMethod (
|
|
genMethodName (), 0, CallingConventions.VarArgs, typeof (void), new Type [0]);
|
|
Assert.AreEqual (CallingConventions.VarArgs | CallingConventions.HasThis,
|
|
mb3.CallingConvention, "CallingConvetion works");
|
|
|
|
MethodBuilder mb4 = genClass.DefineMethod (
|
|
genMethodName (), MethodAttributes.Static, CallingConventions.Standard,
|
|
typeof (void), new Type [0]);
|
|
Assert.AreEqual (CallingConventions.Standard, mb4.CallingConvention,
|
|
"Static implies !HasThis");
|
|
}
|
|
|
|
[Test]
|
|
public void TestDeclaringType ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
|
|
Assert.AreEqual (genClass, mb.DeclaringType, "DeclaringType works");
|
|
}
|
|
|
|
[Test]
|
|
public void TestInitLocals ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
|
|
Assert.IsTrue (mb.InitLocals, "#1");
|
|
mb.InitLocals = false;
|
|
Assert.IsFalse (mb.InitLocals, "#2");
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException (typeof (NotSupportedException))]
|
|
public void TestMethodHandleIncomplete ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
|
|
RuntimeMethodHandle handle = mb.MethodHandle;
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException (typeof (NotSupportedException))]
|
|
public void TestMethodHandleComplete ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
mb.CreateMethodBody (new byte [2], 1);
|
|
genClass.CreateType ();
|
|
|
|
RuntimeMethodHandle handle = mb.MethodHandle;
|
|
}
|
|
|
|
[Test]
|
|
public void TestName ()
|
|
{
|
|
string name = genMethodName ();
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
name, 0, typeof (void), new Type [0]);
|
|
|
|
Assert.AreEqual (name, mb.Name);
|
|
}
|
|
|
|
[Test]
|
|
public void TestReflectedType ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
|
|
Assert.AreEqual (genClass, mb.ReflectedType);
|
|
}
|
|
|
|
[Test]
|
|
public void TestReturnType ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (Console), new Type [0]);
|
|
Assert.AreEqual (typeof (Console), mb.ReturnType, "#1");
|
|
|
|
MethodBuilder mb2 = genClass.DefineMethod (
|
|
genMethodName (), 0, null, new Type [0]);
|
|
Assert.IsTrue (mb2.ReturnType == null || mb2.ReturnType == typeof (void), "#2");
|
|
}
|
|
|
|
[Test]
|
|
public void TestReturnTypeCustomAttributes ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (Console), new Type [0]);
|
|
Assert.IsNull (mb.ReturnTypeCustomAttributes);
|
|
}
|
|
|
|
/*
|
|
public void TestSignature () {
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
"m91", 0, typeof (Console), new Type [1] { typeof (Console) });
|
|
|
|
Console.WriteLine (mb.Signature);
|
|
}
|
|
*/
|
|
|
|
[Test]
|
|
public void TestCreateMethodBody ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
|
|
// Clear body
|
|
mb.CreateMethodBody (null, 999);
|
|
|
|
// Check arguments 1.
|
|
try {
|
|
mb.CreateMethodBody (new byte [1], -1);
|
|
Assert.Fail ("#1");
|
|
} catch (ArgumentOutOfRangeException) {
|
|
}
|
|
|
|
// Check arguments 2.
|
|
try {
|
|
mb.CreateMethodBody (new byte [1], 2);
|
|
Assert.Fail ("#2");
|
|
} catch (ArgumentOutOfRangeException) {
|
|
}
|
|
|
|
mb.CreateMethodBody (new byte [2], 1);
|
|
|
|
// Could only be called once
|
|
try {
|
|
mb.CreateMethodBody (new byte [2], 1);
|
|
Assert.Fail ("#3");
|
|
} catch (InvalidOperationException) {
|
|
}
|
|
|
|
// Can not be called on a created type
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb2 = tb.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
ILGenerator ilgen = mb2.GetILGenerator ();
|
|
ilgen.Emit (OpCodes.Ret);
|
|
tb.CreateType ();
|
|
|
|
try {
|
|
mb2.CreateMethodBody (new byte [2], 1);
|
|
Assert.Fail ("#4");
|
|
} catch (InvalidOperationException) {
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException (typeof (InvalidOperationException))]
|
|
public void TestDefineParameterInvalidIndexComplete ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (genMethodName (), 0, typeof (void),
|
|
new Type [2] { typeof(int), typeof(int) });
|
|
mb.CreateMethodBody (new byte [2], 1);
|
|
tb.CreateType ();
|
|
mb.DefineParameter (-5, ParameterAttributes.None, "param1");
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException (typeof (InvalidOperationException))]
|
|
public void TestDefineParameterValidIndexComplete ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (genMethodName (), 0, typeof (void),
|
|
new Type [2] { typeof(int), typeof(int) });
|
|
mb.CreateMethodBody (new byte [2], 1);
|
|
tb.CreateType ();
|
|
mb.DefineParameter (1, ParameterAttributes.None, "param1");
|
|
}
|
|
|
|
[Test]
|
|
public void TestDefineParameter ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (
|
|
genMethodName (), 0, typeof (void),
|
|
new Type [2] { typeof (int), typeof (int) });
|
|
|
|
// index out of range
|
|
|
|
// This fails on mono because the mono version accepts a 0 index
|
|
/*
|
|
try {
|
|
mb.DefineParameter (0, 0, "param1");
|
|
Fail ();
|
|
} catch (ArgumentOutOfRangeException) {
|
|
}
|
|
*/
|
|
|
|
try {
|
|
mb.DefineParameter (3, 0, "param1");
|
|
Assert.Fail ("#1");
|
|
} catch (ArgumentOutOfRangeException) {
|
|
}
|
|
|
|
// Normal usage
|
|
mb.DefineParameter (1, 0, "param1");
|
|
mb.DefineParameter (1, 0, "param1");
|
|
mb.DefineParameter (2, 0, null);
|
|
|
|
mb.CreateMethodBody (new byte [2], 1);
|
|
tb.CreateType ();
|
|
try {
|
|
mb.DefineParameter (1, 0, "param1");
|
|
Assert.Fail ("#2");
|
|
} catch (InvalidOperationException) {
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
// MS.NET 2.x no longer allows a zero length method body
|
|
// to be emitted
|
|
[ExpectedException (typeof (InvalidOperationException))]
|
|
public void ZeroLengthBodyTest1 ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void),
|
|
new Type [2] { typeof (int), typeof (int) });
|
|
mb.CreateMethodBody (new byte [2], 0);
|
|
genClass.CreateType ();
|
|
}
|
|
|
|
// A zero length method body can be created
|
|
[Test]
|
|
public void ZeroLengthBodyTest2 ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void),
|
|
new Type [2] { typeof (int), typeof (int) });
|
|
mb.CreateMethodBody (new byte [2], 0);
|
|
}
|
|
|
|
[Test]
|
|
public void TestHashCode ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
string methodName = genMethodName ();
|
|
MethodBuilder mb = tb.DefineMethod (methodName, 0, typeof (void),
|
|
new Type [2] { typeof(int), typeof(int) });
|
|
Assert.AreEqual (methodName.GetHashCode (), mb.GetHashCode ());
|
|
}
|
|
|
|
[Test]
|
|
public void TestGetBaseDefinition ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
Assert.AreEqual (mb.GetBaseDefinition (), mb);
|
|
}
|
|
|
|
[Test]
|
|
public void TestGetILGenerator ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
|
|
// The same instance is returned on the second call
|
|
ILGenerator ilgen1 = mb.GetILGenerator ();
|
|
ILGenerator ilgen2 = mb.GetILGenerator ();
|
|
|
|
Assert.AreEqual (ilgen1, ilgen2, "#1");
|
|
|
|
// Does not work on unmanaged code
|
|
MethodBuilder mb2 = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
try {
|
|
mb2.SetImplementationFlags (MethodImplAttributes.Unmanaged);
|
|
mb2.GetILGenerator ();
|
|
Assert.Fail ("#2");
|
|
} catch (InvalidOperationException) {
|
|
}
|
|
try {
|
|
mb2.SetImplementationFlags (MethodImplAttributes.Native);
|
|
mb2.GetILGenerator ();
|
|
Assert.Fail ("#3");
|
|
} catch (InvalidOperationException) {
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestMethodImplementationFlags ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
|
|
Assert.AreEqual (MethodImplAttributes.Managed | MethodImplAttributes.IL,
|
|
mb.GetMethodImplementationFlags (), "#1");
|
|
|
|
mb.SetImplementationFlags (MethodImplAttributes.OPTIL);
|
|
|
|
Assert.AreEqual (MethodImplAttributes.OPTIL, mb.GetMethodImplementationFlags (), "#2");
|
|
|
|
mb.CreateMethodBody (new byte [2], 1);
|
|
mb.SetImplementationFlags (MethodImplAttributes.Managed);
|
|
tb.CreateType ();
|
|
try {
|
|
mb.SetImplementationFlags (MethodImplAttributes.OPTIL);
|
|
Assert.Fail ("#3");
|
|
} catch (InvalidOperationException) {
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestGetModule ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [0]);
|
|
Assert.AreEqual (module, mb.GetModule ());
|
|
}
|
|
|
|
[Test]
|
|
public void TestGetParameters ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (genMethodName (), 0, typeof (void),
|
|
new Type [1] { typeof (void) });
|
|
|
|
/*
|
|
* According to the MSDN docs, this method should fail with a
|
|
* NotSupportedException. In reality, it throws an
|
|
* InvalidOperationException under MS .NET, and returns the
|
|
* requested data under mono.
|
|
*/
|
|
/*
|
|
try {
|
|
mb.GetParameters ();
|
|
Fail ("#161");
|
|
} catch (InvalidOperationException ex) {
|
|
Console.WriteLine (ex);
|
|
}
|
|
*/
|
|
}
|
|
|
|
[Test]
|
|
public void TestGetToken ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (
|
|
genMethodName (), 0, typeof (void), new Type [1] { typeof (void) });
|
|
mb.GetToken ();
|
|
}
|
|
|
|
[Test]
|
|
public void TestInvoke ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void),
|
|
new Type [1] { typeof (int) });
|
|
|
|
try {
|
|
mb.Invoke (null, new object [1] { 42 });
|
|
Assert.Fail ("#1");
|
|
} catch (NotSupportedException) {
|
|
}
|
|
|
|
try {
|
|
mb.Invoke (null, 0, null, new object [1] { 42 }, null);
|
|
Assert.Fail ("#2");
|
|
} catch (NotSupportedException) {
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException (typeof (NotSupportedException))]
|
|
public void TestIsDefined ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void),
|
|
new Type [1] { typeof (int) });
|
|
mb.IsDefined (null, true);
|
|
}
|
|
|
|
[Test]
|
|
public void TestGetCustomAttributes_Incomplete ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void),
|
|
new Type [1] { typeof (int) });
|
|
|
|
try {
|
|
mb.GetCustomAttributes (true);
|
|
Assert.Fail ("#1");
|
|
} catch (NotSupportedException) {
|
|
}
|
|
|
|
try {
|
|
mb.GetCustomAttributes (null, true);
|
|
Assert.Fail ("#2");
|
|
} catch (NotSupportedException) {
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[Category ("NotWorking")]
|
|
public void TestGetCustomAttributes_Complete ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), 0, typeof (void),
|
|
new Type [1] { typeof (int) });
|
|
mb.GetILGenerator ().Emit (OpCodes.Ret);
|
|
genClass.CreateType ();
|
|
|
|
try {
|
|
mb.GetCustomAttributes (true);
|
|
Assert.Fail ("#1");
|
|
} catch (NotSupportedException) {
|
|
}
|
|
|
|
try {
|
|
mb.GetCustomAttributes (null, true);
|
|
Assert.Fail ("#2");
|
|
} catch (NotSupportedException) {
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestSetCustomAttribute ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
string name = genMethodName ();
|
|
MethodBuilder mb = tb.DefineMethod (
|
|
name, MethodAttributes.Public, typeof (void),
|
|
new Type [1] { typeof (int) });
|
|
|
|
// Null argument
|
|
try {
|
|
mb.SetCustomAttribute (null);
|
|
Assert.Fail ("#1");
|
|
} catch (ArgumentNullException) {
|
|
}
|
|
|
|
byte [] custAttrData = { 1, 0, 0, 0, 0 };
|
|
Type attrType = Type.GetType
|
|
("System.Reflection.AssemblyKeyNameAttribute");
|
|
Type [] paramTypes = new Type [1];
|
|
paramTypes [0] = typeof (String);
|
|
ConstructorInfo ctorInfo =
|
|
attrType.GetConstructor (paramTypes);
|
|
|
|
mb.SetCustomAttribute (ctorInfo, custAttrData);
|
|
|
|
// Test MethodImplAttribute
|
|
mb.SetCustomAttribute (new CustomAttributeBuilder (typeof (MethodImplAttribute).GetConstructor (new Type [1] { typeof (short) }), new object [1] { (short) MethodImplAttributes.Synchronized }));
|
|
mb.GetILGenerator ().Emit (OpCodes.Ret);
|
|
|
|
Type t = tb.CreateType ();
|
|
|
|
Assert.AreEqual (t.GetMethod (name).GetMethodImplementationFlags (),
|
|
MethodImplAttributes.Synchronized, "#2");
|
|
|
|
// Null arguments again
|
|
try {
|
|
mb.SetCustomAttribute (null, new byte [2]);
|
|
Assert.Fail ("#3");
|
|
} catch (ArgumentNullException) {
|
|
}
|
|
|
|
try {
|
|
mb.SetCustomAttribute (ctorInfo, null);
|
|
Assert.Fail ("#4");
|
|
} catch (ArgumentNullException) {
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SetCustomAttribute_DllImport_DllName_Empty ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (genMethodName (),
|
|
MethodAttributes.Public, typeof (void),
|
|
new Type [1] { typeof (int) });
|
|
|
|
ConstructorInfo ctorInfo = typeof (DllImportAttribute).GetConstructor (
|
|
new Type [] { typeof (string) });
|
|
try {
|
|
mb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo,
|
|
new object [] { string.Empty }));
|
|
Assert.Fail ("#1");
|
|
} catch (ArgumentException ex) {
|
|
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
|
|
Assert.IsNull (ex.InnerException, "#3");
|
|
Assert.IsNotNull (ex.Message, "#4");
|
|
Assert.IsNull (ex.ParamName, "#5");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SetCustomAttribute_DllImport_DllName_Null ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (genMethodName (),
|
|
MethodAttributes.Public, typeof (void),
|
|
new Type [1] { typeof (int) });
|
|
|
|
ConstructorInfo ctorInfo = typeof (DllImportAttribute).GetConstructor (
|
|
new Type [] { typeof (string) });
|
|
try {
|
|
mb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo,
|
|
new object [] { null }));
|
|
Assert.Fail ("#1");
|
|
} catch (ArgumentException ex) {
|
|
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
|
|
Assert.IsNull (ex.InnerException, "#3");
|
|
Assert.IsNotNull (ex.Message, "#4");
|
|
Assert.IsNull (ex.ParamName, "#5");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SetCustomAttribute_SuppressUnmanagedCodeSecurity ()
|
|
{
|
|
string mname = genMethodName ();
|
|
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (mname, MethodAttributes.Public,
|
|
typeof (void), new Type [] { typeof (int), typeof (string) });
|
|
ConstructorInfo attrCtor = typeof (SuppressUnmanagedCodeSecurityAttribute).
|
|
GetConstructor (new Type [0]);
|
|
CustomAttributeBuilder caBuilder = new CustomAttributeBuilder (
|
|
attrCtor, new object [0]);
|
|
Assert.IsTrue ((mb.Attributes & MethodAttributes.HasSecurity) == 0, "#1");
|
|
mb.SetCustomAttribute (caBuilder);
|
|
//Assert.IsTrue ((mb.Attributes & MethodAttributes.HasSecurity) == 0, "#2");
|
|
mb.GetILGenerator ().Emit (OpCodes.Ret);
|
|
Type emittedType = tb.CreateType ();
|
|
MethodInfo emittedMethod = emittedType.GetMethod (mname);
|
|
Assert.AreEqual (MethodAttributes.HasSecurity, emittedMethod.Attributes & MethodAttributes.HasSecurity, "#3");
|
|
//Assert.IsTrue ((mb.Attributes & MethodAttributes.HasSecurity) == 0, "#4");
|
|
object [] emittedAttrs = emittedMethod.GetCustomAttributes (typeof (SuppressUnmanagedCodeSecurityAttribute), true);
|
|
Assert.AreEqual (1, emittedAttrs.Length, "#5");
|
|
}
|
|
|
|
[AttributeUsage (AttributeTargets.Parameter)]
|
|
class PrivateAttribute : Attribute
|
|
{
|
|
|
|
public PrivateAttribute ()
|
|
{
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void GetCustomAttributes ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod ("foo", MethodAttributes.Public,
|
|
typeof (void),
|
|
new Type [1] { typeof (int) });
|
|
mb.GetILGenerator ().Emit (OpCodes.Ret);
|
|
|
|
Type attrType = typeof (ObsoleteAttribute);
|
|
ConstructorInfo ctorInfo =
|
|
attrType.GetConstructor (new Type [] { typeof (String) });
|
|
|
|
mb.SetCustomAttribute (new CustomAttributeBuilder (ctorInfo, new object [] { "FOO" }));
|
|
|
|
// Check that attributes not accessible are not returned
|
|
mb.SetCustomAttribute (new CustomAttributeBuilder (typeof (PrivateAttribute).GetConstructor (new Type [0]), new object [] { }));
|
|
|
|
Type t = tb.CreateType ();
|
|
|
|
// Try the created type
|
|
{
|
|
MethodInfo mi = t.GetMethod ("foo");
|
|
object [] attrs = mi.GetCustomAttributes (true);
|
|
|
|
Assert.AreEqual (1, attrs.Length, "#A1");
|
|
Assert.IsTrue (attrs [0] is ObsoleteAttribute, "#A2");
|
|
Assert.AreEqual ("FOO", ((ObsoleteAttribute) attrs [0]).Message, "#A3");
|
|
}
|
|
|
|
// Try the type builder
|
|
{
|
|
MethodInfo mi = tb.GetMethod ("foo");
|
|
object [] attrs = mi.GetCustomAttributes (true);
|
|
|
|
Assert.AreEqual (1, attrs.Length, "#B1");
|
|
Assert.IsTrue (attrs [0] is ObsoleteAttribute, "#B2");
|
|
Assert.AreEqual ("FOO", ((ObsoleteAttribute) attrs [0]).Message, "#B3");
|
|
}
|
|
}
|
|
#if !MOBILE
|
|
[Test]
|
|
[ExpectedException (typeof (InvalidOperationException))]
|
|
public void TestAddDeclarativeSecurityAlreadyCreated ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), MethodAttributes.Public, typeof (void),
|
|
new Type [0]);
|
|
ILGenerator ilgen = mb.GetILGenerator ();
|
|
ilgen.Emit (OpCodes.Ret);
|
|
genClass.CreateType ();
|
|
|
|
PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
|
|
mb.AddDeclarativeSecurity (SecurityAction.Demand, set);
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException (typeof (ArgumentNullException))]
|
|
public void TestAddDeclarativeSecurityNullPermissionSet ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), MethodAttributes.Public, typeof (void),
|
|
new Type [0]);
|
|
mb.AddDeclarativeSecurity (SecurityAction.Demand, null);
|
|
}
|
|
|
|
[Test]
|
|
public void TestAddDeclarativeSecurityInvalidAction ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), MethodAttributes.Public, typeof (void),
|
|
new Type [0]);
|
|
|
|
SecurityAction [] actions = new SecurityAction [] {
|
|
SecurityAction.RequestMinimum,
|
|
SecurityAction.RequestOptional,
|
|
SecurityAction.RequestRefuse };
|
|
PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
|
|
|
|
foreach (SecurityAction action in actions) {
|
|
try {
|
|
mb.AddDeclarativeSecurity (action, set);
|
|
Assert.Fail ();
|
|
} catch (ArgumentOutOfRangeException) {
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException (typeof (InvalidOperationException))]
|
|
public void TestAddDeclarativeSecurityDuplicateAction ()
|
|
{
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
genMethodName (), MethodAttributes.Public, typeof (void),
|
|
new Type [0]);
|
|
PermissionSet set = new PermissionSet (PermissionState.Unrestricted);
|
|
mb.AddDeclarativeSecurity (SecurityAction.Demand, set);
|
|
mb.AddDeclarativeSecurity (SecurityAction.Demand, set);
|
|
}
|
|
#endif
|
|
[AttributeUsage (AttributeTargets.Parameter)]
|
|
class ParamAttribute : Attribute
|
|
{
|
|
|
|
public ParamAttribute ()
|
|
{
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TestDynamicParams ()
|
|
{
|
|
string mname = genMethodName ();
|
|
|
|
MethodBuilder mb = genClass.DefineMethod (
|
|
mname, MethodAttributes.Public, typeof (void),
|
|
new Type [] { typeof (int), typeof (string) });
|
|
ParameterBuilder pb = mb.DefineParameter (1, ParameterAttributes.In, "foo");
|
|
pb.SetConstant (52);
|
|
pb.SetCustomAttribute (new CustomAttributeBuilder (typeof (ParamAttribute).GetConstructors () [0], new object [] { }));
|
|
ParameterBuilder pb2 = mb.DefineParameter (2, 0, "bar");
|
|
pb2.SetConstant ("foo");
|
|
mb.GetILGenerator ().Emit (OpCodes.Ret);
|
|
|
|
Type t = genClass.CreateType ();
|
|
MethodInfo m = t.GetMethod (mname);
|
|
ParameterInfo [] pi = m.GetParameters ();
|
|
|
|
Assert.AreEqual ("foo", pi [0].Name, "#A1");
|
|
Assert.IsTrue (pi [0].IsIn, "#A2");
|
|
Assert.AreEqual (52, pi [0].DefaultValue, "#A3");
|
|
object [] cattrs = pi [0].GetCustomAttributes (true);
|
|
Assert.AreEqual (1, cattrs.Length, "#A4");
|
|
Assert.AreEqual (typeof (InAttribute), cattrs [0].GetType (), "#A5");
|
|
|
|
cattrs = pi [1].GetCustomAttributes (true);
|
|
Assert.AreEqual ("foo", pi [1].DefaultValue, "#B1");
|
|
}
|
|
|
|
[Test]
|
|
public void SetCustomAttribute_DllImport1 ()
|
|
{
|
|
string mname = genMethodName ();
|
|
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (
|
|
mname, MethodAttributes.Public, typeof (void),
|
|
new Type [] { typeof (int), typeof (string) });
|
|
|
|
// Create an attribute with default values
|
|
mb.SetCustomAttribute (new CustomAttributeBuilder(typeof(DllImportAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { "kernel32" }));
|
|
|
|
Type t = tb.CreateType ();
|
|
|
|
DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
|
|
|
|
Assert.AreEqual (CallingConvention.Winapi, attr.CallingConvention, "#1");
|
|
Assert.AreEqual (mname, attr.EntryPoint, "#2");
|
|
Assert.AreEqual ("kernel32", attr.Value, "#3");
|
|
Assert.IsFalse (attr.ExactSpelling, "#4");
|
|
Assert.IsTrue (attr.PreserveSig, "#5");
|
|
Assert.IsFalse (attr.SetLastError, "#6");
|
|
Assert.IsFalse (attr.BestFitMapping, "#7");
|
|
Assert.IsFalse (attr.ThrowOnUnmappableChar, "#8");
|
|
}
|
|
|
|
[Test]
|
|
public void SetCustomAttribute_DllImport2 () {
|
|
string mname = genMethodName ();
|
|
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (
|
|
mname, MethodAttributes.Public, typeof (void),
|
|
new Type [] { typeof (int), typeof (string) });
|
|
|
|
CustomAttributeBuilder cb = new CustomAttributeBuilder (typeof (DllImportAttribute).GetConstructor (new Type [] {typeof (String)}), new object [] { "foo" }, new FieldInfo [] {typeof (DllImportAttribute).GetField ("EntryPoint"), typeof (DllImportAttribute).GetField ("CallingConvention"), typeof (DllImportAttribute).GetField ("CharSet"), typeof (DllImportAttribute).GetField ("ExactSpelling"), typeof (DllImportAttribute).GetField ("PreserveSig")}, new object [] { "bar", CallingConvention.StdCall, CharSet.Unicode, true, false });
|
|
mb.SetCustomAttribute (cb);
|
|
|
|
Type t = tb.CreateType ();
|
|
|
|
DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
|
|
|
|
Assert.AreEqual (CallingConvention.StdCall, attr.CallingConvention, "#1");
|
|
Assert.AreEqual (CharSet.Unicode, attr.CharSet, "#2");
|
|
Assert.AreEqual ("bar", attr.EntryPoint, "#3");
|
|
Assert.AreEqual ("foo", attr.Value, "#4");
|
|
Assert.IsTrue (attr.ExactSpelling, "#5");
|
|
Assert.IsFalse (attr.PreserveSig, "#6");
|
|
Assert.IsFalse (attr.SetLastError, "#7");
|
|
Assert.IsFalse (attr.BestFitMapping, "#8");
|
|
Assert.IsFalse (attr.ThrowOnUnmappableChar, "#9");
|
|
}
|
|
|
|
[Test]
|
|
public void SetCustomAttribute_DllImport3 () {
|
|
string mname = genMethodName ();
|
|
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (
|
|
mname, MethodAttributes.Public, typeof (void),
|
|
new Type [] { typeof (int), typeof (string) });
|
|
|
|
// Test attributes with three values (on/off/missing)
|
|
CustomAttributeBuilder cb = new CustomAttributeBuilder (typeof (DllImportAttribute).GetConstructor (new Type [] {typeof (String)}), new object [] { "foo" }, new FieldInfo [] { typeof (DllImportAttribute).GetField ("BestFitMapping"), typeof (DllImportAttribute).GetField ("ThrowOnUnmappableChar")}, new object [] { false, false });
|
|
mb.SetCustomAttribute (cb);
|
|
|
|
Type t = tb.CreateType ();
|
|
|
|
DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
|
|
|
|
Assert.IsFalse (attr.BestFitMapping, "#1");
|
|
Assert.IsFalse (attr.ThrowOnUnmappableChar, "#2");
|
|
}
|
|
|
|
[Test]
|
|
public void SetCustomAttribute_DllImport4 ()
|
|
{
|
|
string mname = genMethodName ();
|
|
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod (
|
|
mname, MethodAttributes.Public, typeof (void),
|
|
new Type [] { typeof (int), typeof (string) });
|
|
|
|
CustomAttributeBuilder cb = new CustomAttributeBuilder (typeof (DllImportAttribute).GetConstructor (new Type [] {typeof (String)}), new object [] { "foo" }, new FieldInfo [] { typeof (DllImportAttribute).GetField ("SetLastError"), typeof (DllImportAttribute).GetField ("BestFitMapping"), typeof (DllImportAttribute).GetField ("ThrowOnUnmappableChar")}, new object [] { true, true, true });
|
|
mb.SetCustomAttribute (cb);
|
|
|
|
Type t = tb.CreateType ();
|
|
|
|
DllImportAttribute attr = (DllImportAttribute)((t.GetMethod (mname).GetCustomAttributes (typeof (DllImportAttribute), true)) [0]);
|
|
|
|
Assert.IsTrue (attr.SetLastError, "#1");
|
|
Assert.IsTrue (attr.BestFitMapping, "#2");
|
|
Assert.IsTrue (attr.ThrowOnUnmappableChar, "#3");
|
|
}
|
|
|
|
public class GenericFoo <T> {
|
|
public static T field;
|
|
}
|
|
|
|
[Test]
|
|
public void ILGen_GenericTypeParameterBuilder ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod ("box_int",
|
|
MethodAttributes.Public|MethodAttributes.Static, typeof (object), new Type [] { typeof (int) });
|
|
|
|
GenericTypeParameterBuilder[] pars = mb.DefineGenericParameters (new string [] { "foo" });
|
|
|
|
ILGenerator ilgen = mb.GetILGenerator ();
|
|
ilgen.Emit (OpCodes.Ldarg_0);
|
|
ilgen.Emit (OpCodes.Box, pars [0]);
|
|
ilgen.Emit (OpCodes.Ret);
|
|
|
|
Type t = tb.CreateType ();
|
|
MethodInfo mi = t.GetMethod ("box_int");
|
|
MethodInfo mi2 = mi.MakeGenericMethod (new Type [] { typeof (int) });
|
|
Assert.AreEqual (1, mi2.Invoke (null, new object [] { 1 }));
|
|
}
|
|
|
|
public void ILGen_InstantiatedGenericType ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod ("return_type",
|
|
MethodAttributes.Public|MethodAttributes.Static, typeof (object), new Type [] { });
|
|
|
|
GenericTypeParameterBuilder[] pars = mb.DefineGenericParameters (new string [] { "foo" });
|
|
|
|
ILGenerator ilgen = mb.GetILGenerator ();
|
|
|
|
Type genericFoo = typeof (GenericFoo<int>).GetGenericTypeDefinition ().MakeGenericType (new Type [] { pars [0] });
|
|
|
|
ilgen.Emit (OpCodes.Ldtoken, genericFoo);
|
|
ilgen.Emit (OpCodes.Call, typeof (Type).GetMethod ("GetTypeFromHandle"));
|
|
ilgen.Emit (OpCodes.Ret);
|
|
|
|
Type t = tb.CreateType ();
|
|
MethodInfo mi = t.GetMethod ("box_int");
|
|
MethodInfo mi2 = mi.MakeGenericMethod (new Type [] { typeof (int) });
|
|
Assert.AreEqual (typeof (GenericFoo<int>), mi2.Invoke (null, new object [] { 1 }));
|
|
}
|
|
|
|
public void ILGen_InstantiatedTypeBuilder ()
|
|
{
|
|
TypeBuilder genericTb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
genericTb.DefineGenericParameters (new string [] { "foo" });
|
|
Type generatedGenericType = genericTb.CreateType ();
|
|
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod ("return_type",
|
|
MethodAttributes.Public|MethodAttributes.Static, typeof (object), new Type [] { });
|
|
|
|
GenericTypeParameterBuilder[] pars = mb.DefineGenericParameters (new string [] { "foo" });
|
|
|
|
ILGenerator ilgen = mb.GetILGenerator ();
|
|
|
|
ilgen.Emit (OpCodes.Ldtoken, genericTb.MakeGenericType (new Type [] { pars [0] }));
|
|
ilgen.Emit (OpCodes.Call, typeof (Type).GetMethod ("GetTypeFromHandle"));
|
|
ilgen.Emit (OpCodes.Ret);
|
|
|
|
Type t = tb.CreateType ();
|
|
MethodInfo mi = t.GetMethod ("return_type");
|
|
MethodInfo mi2 = mi.MakeGenericMethod (new Type [] { typeof (int) });
|
|
Assert.AreEqual (generatedGenericType.MakeGenericType (new Type [] { typeof (int) }), mi2.Invoke (null, new object [] { 1 }));
|
|
}
|
|
|
|
[Test]
|
|
public void Bug354757 ()
|
|
{
|
|
TypeBuilder gtb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
gtb.DefineGenericParameters ("T");
|
|
MethodBuilder mb = gtb.DefineMethod ("foo", MethodAttributes.Public);
|
|
mb.DefineGenericParameters ("S");
|
|
Assert.IsTrue (mb.IsGenericMethodDefinition);
|
|
|
|
Type gt = gtb.MakeGenericType (typeof (object));
|
|
MethodInfo m = TypeBuilder.GetMethod (gt, mb);
|
|
Assert.IsTrue (m.IsGenericMethodDefinition);
|
|
|
|
MethodInfo mopen = m.MakeGenericMethod (m.GetGenericArguments ());
|
|
Assert.IsFalse (mopen.IsGenericMethodDefinition);
|
|
}
|
|
|
|
[Test]
|
|
public void DefineGenericParameters_Names_Empty ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod ("foo", MethodAttributes.Public);
|
|
|
|
try {
|
|
mb.DefineGenericParameters (new string [0]);
|
|
Assert.Fail ("#1");
|
|
} catch (ArgumentException ex) {
|
|
// Value does not fall within the expected range
|
|
Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
|
|
Assert.IsNull (ex.InnerException, "#3");
|
|
Assert.IsNotNull (ex.Message, "#4");
|
|
Assert.IsNull (ex.ParamName, "#5");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
public void DefineGenericParameters_Names_Null ()
|
|
{
|
|
TypeBuilder tb = module.DefineType (genTypeName (), TypeAttributes.Public);
|
|
MethodBuilder mb = tb.DefineMethod ("foo", MethodAttributes.Public);
|
|
|
|
try {
|
|
mb.DefineGenericParameters ((string []) null);
|
|
Assert.Fail ("#A1");
|
|
} catch (ArgumentNullException ex) {
|
|
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
|
|
Assert.IsNull (ex.InnerException, "#A3");
|
|
Assert.IsNotNull (ex.Message, "#A4");
|
|
Assert.AreEqual ("names", ex.ParamName, "#A5");
|
|
}
|
|
|
|
try {
|
|
mb.DefineGenericParameters ("K", null, "V");
|
|
Assert.Fail ("#B1");
|
|
} catch (ArgumentNullException ex) {
|
|
Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
|
|
Assert.IsNull (ex.InnerException, "#B3");
|
|
Assert.IsNotNull (ex.Message, "#B4");
|
|
Assert.AreEqual ("names", ex.ParamName, "#B5");
|
|
}
|
|
}
|
|
|
|
|
|
public static int Foo<T> (T a, T b) {
|
|
return 99;
|
|
}
|
|
|
|
[Test]//bug #591226
|
|
public void GenericMethodIsProperlyInflated ()
|
|
{
|
|
var tb = module.DefineType ("foo");
|
|
var met = typeof (MethodBuilderTest).GetMethod ("Foo");
|
|
|
|
var mb = tb.DefineMethod ("myFunc", MethodAttributes.Public | MethodAttributes.Static, typeof (int), Type.EmptyTypes);
|
|
var garg = mb.DefineGenericParameters ("a") [0];
|
|
mb.SetParameters (garg, garg);
|
|
|
|
var ilgen = mb.GetILGenerator ();
|
|
ilgen.Emit (OpCodes.Ldarg_0);
|
|
ilgen.Emit (OpCodes.Ldarg_1);
|
|
ilgen.Emit (OpCodes.Call, met.MakeGenericMethod (garg));
|
|
ilgen.Emit (OpCodes.Ret);
|
|
|
|
var res = tb.CreateType ();
|
|
var mm = res.GetMethod ("myFunc").MakeGenericMethod (typeof (int));
|
|
|
|
var rt = mm.Invoke (null, new object[] { 10, 20 });
|
|
Assert.AreEqual (99, rt, "#1");
|
|
}
|
|
|
|
public static void VarargMethod (string headline, __arglist) {
|
|
ArgIterator ai = new ArgIterator (__arglist);
|
|
|
|
Console.Write (headline);
|
|
while (ai.GetRemainingCount () > 0)
|
|
Console.Write (TypedReference.ToObject (ai.GetNextArg ()));
|
|
Console.WriteLine ();
|
|
}
|
|
|
|
[Test]//bug #626441
|
|
public void CanCallVarargMethods ()
|
|
{
|
|
var tb = module.DefineType ("foo");
|
|
MethodBuilder mb = tb.DefineMethod ("CallVarargMethod",
|
|
MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard,
|
|
typeof (void), Type.EmptyTypes);
|
|
|
|
ILGenerator il = mb.GetILGenerator ();
|
|
MethodInfo miVarargMethod = typeof (MethodBuilderTest).GetMethod ("VarargMethod");
|
|
|
|
il.Emit (OpCodes.Ldstr, "Hello world from ");
|
|
il.Emit (OpCodes.Call, typeof(Assembly).GetMethod ("GetExecutingAssembly"));
|
|
il.EmitCall (OpCodes.Call, miVarargMethod, new Type[] { typeof(Assembly) });
|
|
|
|
il.Emit (OpCodes.Ldstr, "Current time: ");
|
|
il.Emit (OpCodes.Call, typeof(DateTime).GetMethod("get_Now"));
|
|
il.Emit (OpCodes.Ldstr, " (UTC ");
|
|
il.Emit (OpCodes.Call, typeof(DateTime).GetMethod("get_UtcNow"));
|
|
il.Emit (OpCodes.Ldstr, ")");
|
|
il.EmitCall (OpCodes.Call, miVarargMethod, new Type[] { typeof (DateTime), typeof (string), typeof (DateTime), typeof (string) });
|
|
il.Emit (OpCodes.Ret);
|
|
|
|
Type type = tb.CreateType ();
|
|
type.GetMethod ("CallVarargMethod").Invoke (null, null);
|
|
}
|
|
|
|
public static string GenericMethodWithOneArg<T> (T t)
|
|
{
|
|
return t.ToString ();
|
|
}
|
|
|
|
[Test]
|
|
public void ParamerersOfGenericArgumentsAreProperlyEncoded ()
|
|
{
|
|
var type = module.DefineType (
|
|
"Bar",
|
|
TypeAttributes.Public
|
|
| TypeAttributes.Abstract
|
|
| TypeAttributes.Sealed,
|
|
typeof (object));
|
|
|
|
var foo_method = typeof (MethodBuilderTest).GetMethod ("GenericMethodWithOneArg");
|
|
|
|
var method = type.DefineMethod (
|
|
"ReFoo",
|
|
MethodAttributes.Static | MethodAttributes.Public,
|
|
typeof (string),
|
|
new [] { foo_method.GetGenericArguments () [0] });
|
|
method.DefineGenericParameters ("K");
|
|
|
|
var il = method.GetILGenerator ();
|
|
il.Emit (OpCodes.Ldarga, 0);
|
|
il.Emit (OpCodes.Constrained, method.GetGenericArguments () [0]);
|
|
il.Emit (OpCodes.Callvirt, typeof (object).GetMethod ("ToString"));
|
|
il.Emit (OpCodes.Ret);
|
|
|
|
type.CreateType ();
|
|
|
|
var re_foo_open = module.GetType ("Bar").GetMethod ("ReFoo");
|
|
|
|
Assert.AreEqual (re_foo_open.GetGenericArguments ()[0], re_foo_open.GetParameters () [0].ParameterType, "#1");
|
|
}
|
|
|
|
[Test] // #628660
|
|
public void CanCallGetMethodBodyOnDynamicImageMethod ()
|
|
{
|
|
var type = module.DefineType (
|
|
"CanCallGetMethodBodyOnDynamicImageMethod",
|
|
TypeAttributes.Public,
|
|
typeof (object));
|
|
|
|
var baz = type.DefineMethod ("Foo", MethodAttributes.Public | MethodAttributes.Static, typeof (object), Type.EmptyTypes);
|
|
|
|
var il = baz.GetILGenerator ();
|
|
var temp = il.DeclareLocal (typeof (object));
|
|
il.Emit (OpCodes.Ldnull);
|
|
il.Emit (OpCodes.Stloc, temp);
|
|
il.Emit (OpCodes.Ldloc, temp);
|
|
il.Emit (OpCodes.Ret);
|
|
|
|
var body = type.CreateType ().GetMethod ("Foo").GetMethodBody ();
|
|
|
|
Assert.IsNotNull (body);
|
|
Assert.AreEqual (1, body.LocalVariables.Count);
|
|
Assert.AreEqual (typeof (object), body.LocalVariables [0].LocalType);
|
|
}
|
|
|
|
|
|
[Test] //#384127
|
|
public void GetGenericArgumentsReturnsNullForNonGenericMethod ()
|
|
{
|
|
var tb = module.DefineType ("Base");
|
|
|
|
var mb = tb.DefineMethod ("foo", MethodAttributes.Public, typeof (void), Type.EmptyTypes);
|
|
|
|
Assert.IsNull (mb.GetGenericArguments ());
|
|
|
|
}
|
|
|
|
[Test]
|
|
[ExpectedException (typeof (ArgumentException))]
|
|
public void SetConstantIllegalType ()
|
|
{
|
|
var tb = module.DefineType ("Base");
|
|
|
|
var mb = tb.DefineMethod ("foo", MethodAttributes.Public, typeof (void), new Type [] { typeof (decimal) });
|
|
ParameterBuilder pb = mb.DefineParameter (1, ParameterAttributes.In, "foo");
|
|
pb.SetConstant (5m);
|
|
}
|
|
|
|
public interface ITest
|
|
{
|
|
T[] Method<T>(T[] value);
|
|
}
|
|
|
|
[Test]
|
|
// #7964
|
|
public void ArrayOfGenericParam ()
|
|
{
|
|
var tb = module.DefineType ("Base");
|
|
|
|
tb.AddInterfaceImplementation (typeof (ITest));
|
|
|
|
var testMethod = tb.DefineMethod ("Method", MethodAttributes.Public | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis);
|
|
|
|
var testParameters = Array.ConvertAll (testMethod.DefineGenericParameters("T"), b => (Type)b);
|
|
|
|
var returnType = testParameters[0].MakeArrayType();
|
|
|
|
testMethod.SetParameters (testParameters[0].MakeArrayType());
|
|
testMethod.SetReturnType (returnType);
|
|
|
|
var testIl = testMethod.GetILGenerator ();
|
|
testIl.Emit (OpCodes.Ldarg_1);
|
|
testIl.Emit (OpCodes.Castclass, returnType);
|
|
testIl.Emit (OpCodes.Ret);
|
|
|
|
var t = tb.CreateType ();
|
|
|
|
var test = (ITest) Activator.CreateInstance (t);
|
|
|
|
var o = new int[0];
|
|
var returnValue = test.Method (o);
|
|
|
|
Assert.AreEqual (o, returnValue);
|
|
}
|
|
}
|
|
}
|