2008-11-14 11:42:07 +03:00
|
|
|
|
/*
|
2011-07-26 03:11:09 +04:00
|
|
|
|
Copyright (C) 2008-2011 Jeroen Frijters
|
2008-11-14 11:42:07 +03:00
|
|
|
|
|
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
|
|
|
warranty. In no event will the authors be held liable for any damages
|
|
|
|
|
arising from the use of this software.
|
|
|
|
|
|
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
|
|
|
including commercial applications, and to alter it and redistribute it
|
|
|
|
|
freely, subject to the following restrictions:
|
|
|
|
|
|
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
|
|
|
claim that you wrote the original software. If you use this software
|
|
|
|
|
in a product, an acknowledgment in the product documentation would be
|
|
|
|
|
appreciated but is not required.
|
|
|
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
|
|
|
misrepresented as being the original software.
|
|
|
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
|
|
|
|
|
|
|
|
Jeroen Frijters
|
|
|
|
|
jeroen@frijters.net
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
using System;
|
2010-01-28 12:18:33 +03:00
|
|
|
|
#if STATIC_COMPILER || STUB_GENERATOR
|
2010-01-25 10:52:27 +03:00
|
|
|
|
using IKVM.Reflection;
|
2008-11-14 11:42:07 +03:00
|
|
|
|
using IKVM.Reflection.Emit;
|
2010-01-25 10:52:27 +03:00
|
|
|
|
using Type = IKVM.Reflection.Type;
|
2008-11-14 11:42:07 +03:00
|
|
|
|
#else
|
2010-01-25 10:52:27 +03:00
|
|
|
|
using System.Reflection;
|
2008-11-14 11:42:07 +03:00
|
|
|
|
using System.Reflection.Emit;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
namespace IKVM.Internal
|
|
|
|
|
{
|
|
|
|
|
static class ReflectUtil
|
|
|
|
|
{
|
2010-01-29 09:58:10 +03:00
|
|
|
|
#if !NET_4_0 && !STATIC_COMPILER && !STUB_GENERATOR
|
2009-07-20 10:51:28 +04:00
|
|
|
|
private static readonly bool clr_v4 = Environment.Version.Major >= 4;
|
2010-01-29 09:58:10 +03:00
|
|
|
|
private static Predicate<Assembly> get_IsDynamic;
|
|
|
|
|
#endif
|
2009-07-20 10:51:28 +04:00
|
|
|
|
|
2008-11-14 11:42:07 +03:00
|
|
|
|
internal static bool IsSameAssembly(Type type1, Type type2)
|
|
|
|
|
{
|
|
|
|
|
return type1.Assembly.Equals(type2.Assembly);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static bool IsFromAssembly(Type type, Assembly assembly)
|
|
|
|
|
{
|
|
|
|
|
return type.Assembly.Equals(assembly);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static Assembly GetAssembly(Type type)
|
|
|
|
|
{
|
|
|
|
|
return type.Assembly;
|
|
|
|
|
}
|
2009-05-28 09:58:35 +04:00
|
|
|
|
|
|
|
|
|
internal static bool IsDynamicAssembly(Assembly asm)
|
|
|
|
|
{
|
2010-03-18 16:43:54 +03:00
|
|
|
|
#if STATIC_COMPILER || STUB_GENERATOR
|
2009-07-28 17:02:30 +04:00
|
|
|
|
return false;
|
2010-03-18 16:43:54 +03:00
|
|
|
|
#elif NET_4_0
|
|
|
|
|
return asm.IsDynamic;
|
2009-05-28 09:58:35 +04:00
|
|
|
|
#else
|
2009-07-20 10:51:28 +04:00
|
|
|
|
if (clr_v4)
|
|
|
|
|
{
|
|
|
|
|
// on .NET 4.0 dynamic assemblies have a non-AssemblyBuilder derived peer, so we have to call IsDynamic
|
2010-01-29 09:58:10 +03:00
|
|
|
|
if (get_IsDynamic == null)
|
|
|
|
|
{
|
|
|
|
|
get_IsDynamic = (Predicate<Assembly>)Delegate.CreateDelegate(typeof(Predicate<Assembly>), typeof(Assembly).GetMethod("get_IsDynamic"));
|
|
|
|
|
}
|
|
|
|
|
return get_IsDynamic(asm);
|
2009-07-20 10:51:28 +04:00
|
|
|
|
}
|
|
|
|
|
return asm is AssemblyBuilder;
|
2010-01-29 09:58:10 +03:00
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static bool IsReflectionOnly(Type type)
|
|
|
|
|
{
|
|
|
|
|
while (type.HasElementType)
|
|
|
|
|
{
|
|
|
|
|
type = type.GetElementType();
|
|
|
|
|
}
|
|
|
|
|
Assembly asm = type.Assembly;
|
|
|
|
|
if (asm != null && asm.ReflectionOnly)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (!type.IsGenericType || type.IsGenericTypeDefinition)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// we have a generic type instantiation, it might have ReflectionOnly type arguments
|
|
|
|
|
foreach (Type arg in type.GetGenericArguments())
|
|
|
|
|
{
|
|
|
|
|
if (IsReflectionOnly(arg))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-26 03:11:09 +04:00
|
|
|
|
internal static bool ContainsTypeBuilder(Type type)
|
|
|
|
|
{
|
|
|
|
|
while (type.HasElementType)
|
|
|
|
|
{
|
|
|
|
|
type = type.GetElementType();
|
|
|
|
|
}
|
|
|
|
|
if (!type.IsGenericType || type.IsGenericTypeDefinition)
|
|
|
|
|
{
|
|
|
|
|
return type is TypeBuilder;
|
|
|
|
|
}
|
|
|
|
|
foreach (Type arg in type.GetGenericArguments())
|
|
|
|
|
{
|
|
|
|
|
if (ContainsTypeBuilder(arg))
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return type.GetGenericTypeDefinition() is TypeBuilder;
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-29 09:58:10 +03:00
|
|
|
|
internal static bool IsVector(Type type)
|
|
|
|
|
{
|
|
|
|
|
#if STATIC_COMPILER || STUB_GENERATOR
|
|
|
|
|
return type.__IsVector;
|
|
|
|
|
#else
|
|
|
|
|
// there's no API to distinguish an array of rank 1 from a vector,
|
|
|
|
|
// so we check if the type name ends in [], which indicates it's a vector
|
|
|
|
|
// (non-vectors will have [*] or [,]).
|
|
|
|
|
return type.IsArray && type.Name.EndsWith("[]");
|
2009-05-28 09:58:35 +04:00
|
|
|
|
#endif
|
|
|
|
|
}
|
2011-08-06 15:00:10 +04:00
|
|
|
|
|
|
|
|
|
internal static bool IsDynamicMethod(MethodInfo method)
|
|
|
|
|
{
|
|
|
|
|
// there's no way to distinguish a baked DynamicMethod from a RuntimeMethodInfo and
|
|
|
|
|
// on top of that Mono behaves completely different from .NET
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// on Mono 2.10 the MetadataToken property returns zero instead of throwing InvalidOperationException
|
|
|
|
|
return method.MetadataToken == 0;
|
|
|
|
|
}
|
|
|
|
|
catch (InvalidOperationException)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-11-14 11:42:07 +03:00
|
|
|
|
}
|
|
|
|
|
}
|