- //
- // Returns the MethodInfo for a method named `name' defined
- // in type `t' which takes arguments of types `args'
- //
- public static MethodInfo GetPredefinedMethod (Type t, string name, Location loc, params Type [] args)
- {
- return (MethodInfo)GetPredefinedMember (t, name, MemberTypes.Method, loc, args);
- }
-
- public static FieldInfo GetPredefinedField (Type t, string name, Location loc, params Type [] args)
- {
- return (FieldInfo) GetPredefinedMember (t, name, MemberTypes.Field, loc, args);
- }
-
- public static PropertyInfo GetPredefinedProperty (Type t, string name, Location loc, params Type [] args)
- {
- return (PropertyInfo) GetPredefinedMember (t, name, MemberTypes.Property, loc, args);
- }
-
- /// <remarks>
- /// The types have to be initialized after the initial
- /// population of the type has happened (for example, to
- /// bootstrap the corlib.dll
- /// </remarks>
- public static bool InitCoreTypes ()
- {
- object_type = CoreLookupType ("System", "Object", Kind.Class, true);
- system_object_expr.Type = object_type;
- value_type = CoreLookupType ("System", "ValueType", Kind.Class, true);
- system_valuetype_expr.Type = value_type;
- attribute_type = CoreLookupType ("System", "Attribute", Kind.Class, true);
-
- int32_type = CoreLookupType ("System", "Int32", Kind.Struct, true);
- system_int32_expr.Type = int32_type;
- int64_type = CoreLookupType ("System", "Int64", Kind.Struct, true);
- system_int64_expr.Type = int64_type;
- uint32_type = CoreLookupType ("System", "UInt32", Kind.Struct, true);
- system_uint32_expr.Type = uint32_type;
- uint64_type = CoreLookupType ("System", "UInt64", Kind.Struct, true);
- system_uint64_expr.Type = uint64_type;
- byte_type = CoreLookupType ("System", "Byte", Kind.Struct, true);
- system_byte_expr.Type = byte_type;
- sbyte_type = CoreLookupType ("System", "SByte", Kind.Struct, true);
- system_sbyte_expr.Type = sbyte_type;
- short_type = CoreLookupType ("System", "Int16", Kind.Struct, true);
- system_int16_expr.Type = short_type;
- ushort_type = CoreLookupType ("System", "UInt16", Kind.Struct, true);
- system_uint16_expr.Type = ushort_type;
-
- ienumerator_type = CoreLookupType ("System.Collections", "IEnumerator", Kind.Interface, true);
- ienumerable_type = CoreLookupType ("System.Collections", "IEnumerable", Kind.Interface, true);
- idisposable_type = CoreLookupType ("System", "IDisposable", Kind.Interface, true);
-
- // HACK: DefineType immediately resolves iterators (very wrong)
- generic_ienumerator_type = CoreLookupType ("System.Collections.Generic", "IEnumerator`1", Kind.Interface, false);
-
- char_type = CoreLookupType ("System", "Char", Kind.Struct, true);
- system_char_expr.Type = char_type;
- string_type = CoreLookupType ("System", "String", Kind.Class, true);
- system_string_expr.Type = string_type;
- float_type = CoreLookupType ("System", "Single", Kind.Struct, true);
- system_single_expr.Type = float_type;
- double_type = CoreLookupType ("System", "Double", Kind.Struct, true);
- system_double_expr.Type = double_type;
- decimal_type = CoreLookupType ("System", "Decimal", Kind.Struct, true);
- system_decimal_expr.Type = decimal_type;
- bool_type = CoreLookupType ("System", "Boolean", Kind.Struct, true);
- system_boolean_expr.Type = bool_type;
- intptr_type = CoreLookupType ("System", "IntPtr", Kind.Struct, true);
- system_intptr_expr.Type = intptr_type;
- uintptr_type = CoreLookupType ("System", "UIntPtr", Kind.Struct, true);
-
- multicast_delegate_type = CoreLookupType ("System", "MulticastDelegate", Kind.Class, true);
- delegate_type = CoreLookupType ("System", "Delegate", Kind.Class, true);
-
- enum_type = CoreLookupType ("System", "Enum", Kind.Class, true);
- array_type = CoreLookupType ("System", "Array", Kind.Class, true);
- void_type = CoreLookupType ("System", "Void", Kind.Struct, true);
- system_void_expr.Type = void_type;
- type_type = CoreLookupType ("System", "Type", Kind.Class, true);
- exception_type = CoreLookupType ("System", "Exception", Kind.Class, true);
-
- runtime_field_handle_type = CoreLookupType ("System", "RuntimeFieldHandle", Kind.Struct, true);
- runtime_handle_type = CoreLookupType ("System", "RuntimeTypeHandle", Kind.Struct, true);
-
- PredefinedAttributes.Get.ParamArray.Resolve (false);
- PredefinedAttributes.Get.Out.Resolve (false);
-
- return Report.Errors == 0;
- }
-
- //
- // Initializes optional core types
- //
- public static void InitOptionalCoreTypes ()
- {
- //
- // These are only used for compare purposes
- //
- anonymous_method_type = typeof (AnonymousMethodBody);
- null_type = typeof (NullLiteral);
-
- void_ptr_type = GetPointerType (void_type);
-
- //
- // Initialize InternalsVisibleTo as the very first optional type. Otherwise we would populate
- // types cache with incorrect accessiblity when any of optional types is internal.
- //
- PredefinedAttributes.Get.Initialize ();
-
- runtime_argument_handle_type = CoreLookupType ("System", "RuntimeArgumentHandle", Kind.Struct, false);
- asynccallback_type = CoreLookupType ("System", "AsyncCallback", Kind.Delegate, false);
- iasyncresult_type = CoreLookupType ("System", "IAsyncResult", Kind.Interface, false);
- typed_reference_type = CoreLookupType ("System", "TypedReference", Kind.Struct, false);
- arg_iterator_type = CoreLookupType ("System", "ArgIterator", Kind.Struct, false);
- mbr_type = CoreLookupType ("System", "MarshalByRefObject", Kind.Class, false);
-
- //
- // Optional attributes, used for error reporting only
- //
- //if (PredefinedAttributes.Get.Obsolete.IsDefined) {
- // Class c = TypeManager.LookupClass (PredefinedAttributes.Get.Obsolete.Type);
- // if (c != null)
- // c.Define ();
- //}
-
- generic_ilist_type = CoreLookupType ("System.Collections.Generic", "IList`1", Kind.Interface, false);
- generic_icollection_type = CoreLookupType ("System.Collections.Generic", "ICollection`1", Kind.Interface, false);
- generic_ienumerable_type = CoreLookupType ("System.Collections.Generic", "IEnumerable`1", Kind.Interface, false);
- generic_nullable_type = CoreLookupType ("System", "Nullable`1", Kind.Struct, false);
-
- //
- // Optional types which are used as types and for member lookup
- //
- runtime_helpers_type = CoreLookupType ("System.Runtime.CompilerServices", "RuntimeHelpers", Kind.Class, false);
-
- // New in .NET 3.5
- // Note: extension_attribute_type is already loaded
- expression_type = CoreLookupType ("System.Linq.Expressions", "Expression`1", Kind.Class, false);
-
- if (!RootContext.StdLib) {
- //
- // HACK: When building Mono corlib mcs uses loaded mscorlib which
- // has different predefined types and this method sets mscorlib types
- // to be same to avoid any type check errors.
- //
-
- Type type = typeof (Type);
- Type [] system_4_type_arg = { type, type, type, type };
-
- MethodInfo set_corlib_type_builders =
- typeof (System.Reflection.Emit.AssemblyBuilder).GetMethod (
- "SetCorlibTypeBuilders", BindingFlags.NonPublic | BindingFlags.Instance, null,
- system_4_type_arg, null);
-
- if (set_corlib_type_builders != null) {
- object[] args = new object [4];
- args [0] = object_type;
- args [1] = value_type;
- args [2] = enum_type;
- args [3] = void_type;
-
- set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
- } else {
- Report.Warning (-26, 3, "The compilation may fail due to missing `{0}.SetCorlibTypeBuilders({1})' method",
- TypeManager.CSharpName (typeof (System.Reflection.Emit.AssemblyBuilder)),
- TypeManager.CSharpName (system_4_type_arg));
- }
- }
- }
-
- const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
-
- /// <remarks>
- /// This is the "old", non-cache based FindMembers() function. We cannot use
- /// the cache here because there is no member name argument.
- /// </remarks>
- public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
- MemberFilter filter, object criteria)
- {
-#if MS_COMPATIBLE && GMCS_SOURCE
- if (t.IsGenericType)
- t = t.GetGenericTypeDefinition ();
-#endif
-
- DeclSpace decl = (DeclSpace) builder_to_declspace [t];
-
- //
- // `builder_to_declspace' contains all dynamic types.
- //
- if (decl != null) {
- MemberList list;
- Timer.StartTimer (TimerType.FindMembers);
- list = decl.FindMembers (mt, bf, filter, criteria);
- Timer.StopTimer (TimerType.FindMembers);
- return list;
- }
-
- //
- // We have to take care of arrays specially, because GetType on
- // a TypeBuilder array will return a Type, not a TypeBuilder,
- // and we can not call FindMembers on this type.
- //
- if (
-#if MS_COMPATIBLE && GMCS_SOURCE
- !t.IsGenericType &&
-#endif
- t.IsSubclassOf (TypeManager.array_type))
- return new MemberList (TypeManager.array_type.FindMembers (mt, bf, filter, criteria));
-
-#if GMCS_SOURCE
- if (t is GenericTypeParameterBuilder) {
- TypeParameter tparam = (TypeParameter) builder_to_type_param [t];
-
- Timer.StartTimer (TimerType.FindMembers);
- MemberList list = tparam.FindMembers (
- mt, bf | BindingFlags.DeclaredOnly, filter, criteria);
- Timer.StopTimer (TimerType.FindMembers);
- return list;
- }
-#endif
-
- //
- // Since FindMembers will not lookup both static and instance
- // members, we emulate this behaviour here.
- //
- if ((bf & instance_and_static) == instance_and_static){
- MemberInfo [] i_members = t.FindMembers (
- mt, bf & ~BindingFlags.Static, filter, criteria);
-
- int i_len = i_members.Length;
- if (i_len == 1){
- MemberInfo one = i_members [0];
-
- //
- // If any of these are present, we are done!
- //
- if ((one is Type) || (one is EventInfo) || (one is FieldInfo))
- return new MemberList (i_members);
- }
-
- MemberInfo [] s_members = t.FindMembers (
- mt, bf & ~BindingFlags.Instance, filter, criteria);
-
- int s_len = s_members.Length;
- if (i_len > 0 || s_len > 0)
- return new MemberList (i_members, s_members);
- else {
- if (i_len > 0)
- return new MemberList (i_members);
- else
- return new MemberList (s_members);
- }
- }
-
- return new MemberList (t.FindMembers (mt, bf, filter, criteria));
- }
-
-
- /// <summary>
- /// This method is only called from within MemberLookup. It tries to use the member
- /// cache if possible and falls back to the normal FindMembers if not. The `used_cache'
- /// flag tells the caller whether we used the cache or not. If we used the cache, then
- /// our return value will already contain all inherited members and the caller don't need
- /// to check base classes and interfaces anymore.
- /// </summary>
- private static MemberInfo [] MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
- string name, out bool used_cache)
- {
- MemberCache cache;
-
- //
- // If this is a dynamic type, it's always in the `builder_to_declspace' hash table
- // and we can ask the DeclSpace for the MemberCache.
- //
-#if MS_COMPATIBLE
- if (t.Assembly == CodeGen.Assembly.Builder) {
- if (t.IsGenericParameter) {
- TypeParameter tparam = (TypeParameter) builder_to_type_param[t];
-
- used_cache = true;
- if (tparam.MemberCache == null)
- return new MemberInfo[0];
-
- return tparam.MemberCache.FindMembers (
- mt, bf, name, FilterWithClosure_delegate, null);
- }
-
- //
- // We have to take care of arrays specially, because GetType on
- // a TypeBuilder array will return a Type, not a TypeBuilder,
- // and we can not call FindMembers on this type.
- //
- if (t.IsArray) {
- used_cache = true;
- return TypeHandle.ArrayType.MemberCache.FindMembers (
- mt, bf, name, FilterWithClosure_delegate, null);
- }
-
- if (t.IsGenericType && !t.IsGenericTypeDefinition)
- t = t.GetGenericTypeDefinition ();
-#else
- if (t is TypeBuilder) {
-#endif
- DeclSpace decl = (DeclSpace) builder_to_declspace [t];
- cache = decl.MemberCache;
-
- //
- // If this DeclSpace has a MemberCache, use it.
- //
-
- if (cache != null) {
- used_cache = true;
- return cache.FindMembers (
- mt, bf, name, FilterWithClosure_delegate, null);
- }
-
- // If there is no MemberCache, we need to use the "normal" FindMembers.
- // Note, this is a VERY uncommon route!
-
- MemberList list;
- Timer.StartTimer (TimerType.FindMembers);
- list = decl.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
- FilterWithClosure_delegate, name);
- Timer.StopTimer (TimerType.FindMembers);
- used_cache = false;
- return (MemberInfo []) list;
- }
-
- //
- // We have to take care of arrays specially, because GetType on
- // a TypeBuilder array will return a Type, not a TypeBuilder,
- // and we can not call FindMembers on this type.
- //
- if (t.IsArray) {
- used_cache = true;
- return TypeHandle.ArrayType.MemberCache.FindMembers (
- mt, bf, name, FilterWithClosure_delegate, null);
- }
-
-#if GMCS_SOURCE
- if (t is GenericTypeParameterBuilder) {
- TypeParameter tparam = (TypeParameter) builder_to_type_param [t];
-
- used_cache = true;
- if (tparam.MemberCache == null)
- return new MemberInfo [0];
-
- return tparam.MemberCache.FindMembers (
- mt, bf, name, FilterWithClosure_delegate, null);
- }
-#endif
-
- if (IsGenericType (t) && (mt == MemberTypes.NestedType)) {
- //
- // This happens if we're resolving a class'es base class and interfaces
- // in TypeContainer.DefineType(). At this time, the types aren't
- // populated yet, so we can't use the cache.
- //
- MemberInfo[] info = t.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
- FilterWithClosure_delegate, name);
- used_cache = false;
- return info;
- }
-
- //
- // This call will always succeed. There is exactly one TypeHandle instance per
- // type, TypeHandle.GetMemberCache() will, if necessary, create a new one, and return
- // the corresponding MemberCache.
- //
- cache = TypeHandle.GetMemberCache (t);
-
- used_cache = true;
- return cache.FindMembers (mt, bf, name, FilterWithClosure_delegate, null);
- }
-
- public static bool IsBuiltinType (Type t)
- {
- t = TypeToCoreType (t);
- if (t == object_type || t == string_type || t == int32_type || t == uint32_type ||
- t == int64_type || t == uint64_type || t == float_type || t == double_type ||
- t == char_type || t == short_type || t == decimal_type || t == bool_type ||
- t == sbyte_type || t == byte_type || t == ushort_type || t == void_type)
- return true;
- else
- return false;
- }
-
- //
- // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
- // the pieces in the code where we use IsBuiltinType and special case decimal_type.
- //
- public static bool IsPrimitiveType (Type t)
- {
- return (t == int32_type || t == uint32_type ||
- t == int64_type || t == uint64_type || t == float_type || t == double_type ||
- t == char_type || t == short_type || t == bool_type ||
- t == sbyte_type || t == byte_type || t == ushort_type);
- }
-
- public static bool IsDelegateType (Type t)
- {
- if (TypeManager.IsGenericParameter (t))
- return false;
-
- if (t == TypeManager.delegate_type || t == TypeManager.multicast_delegate_type)
- return false;
-
- t = DropGenericTypeArguments (t);
- return IsSubclassOf (t, TypeManager.delegate_type);
- }
-
- public static bool IsEnumType (Type t)
- {
- t = DropGenericTypeArguments (t);
- return t.BaseType == TypeManager.enum_type;
- }
-
- public static bool IsBuiltinOrEnum (Type t)
- {
- if (IsBuiltinType (t))
- return true;
-
- if (IsEnumType (t))
- return true;
-
- return false;
- }
-
- public static bool IsAttributeType (Type t)
- {
- return t == attribute_type && t.BaseType != null || IsSubclassOf (t, attribute_type);
- }
-
- //
- // Whether a type is unmanaged. This is used by the unsafe code (25.2)
- //
- // mcs4: delete, DeclSpace.IsUnmanagedType is replacement
- public static bool IsUnmanagedType (Type t)
- {
- DeclSpace ds = TypeManager.LookupDeclSpace (t);
- if (ds != null)
- return ds.IsUnmanagedType ();
-
- // builtins that are not unmanaged types
- if (t == TypeManager.object_type || t == TypeManager.string_type)
- return false;
-
- if (IsGenericType (t) || IsGenericParameter (t))
- return false;
-
- if (IsBuiltinOrEnum (t))
- return true;
-
- // Someone did the work of checking if the ElementType of t is unmanaged. Let's not repeat it.
- if (t.IsPointer)
- return IsUnmanagedType (GetElementType (t));
-
- // Arrays are disallowed, even if we mark them with [MarshalAs(UnmanagedType.ByValArray, ...)]
- if (t.IsArray)
- return false;
-
- if (!IsValueType (t))
- return false;
-
- for (Type p = t.DeclaringType; p != null; p = p.DeclaringType) {
- if (IsGenericTypeDefinition (p))
- return false;
- }
-
- bool retval = true;
- {
- FieldInfo [] fields = t.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
-
- foreach (FieldInfo f in fields){
- if (!IsUnmanagedType (f.FieldType)){
- retval = false;
- }
- }
- }
-
- return retval;
- }
-
- //
- // Null is considered to be a reference type
- //
- public static bool IsReferenceType (Type t)
- {
- if (TypeManager.IsGenericParameter (t)) {
- GenericConstraints constraints = TypeManager.GetTypeParameterConstraints (t);
- if (constraints == null)
- return false;
-
- return constraints.IsReferenceType;
- }
-
- return !IsStruct (t) && !IsEnumType (t);
- }
-
- public static bool IsValueType (Type t)
- {
- if (TypeManager.IsGenericParameter (t)) {
- GenericConstraints constraints = TypeManager.GetTypeParameterConstraints (t);
- if (constraints == null)
- return false;
-
- return constraints.IsValueType;
- }
-
- return IsStruct (t) || IsEnumType (t);
- }
-
- public static bool IsStruct (Type t)
- {
- return t.BaseType == value_type && t != enum_type && t.IsSealed;
- }
-
- public static bool IsInterfaceType (Type t)
- {
- TypeContainer tc = (TypeContainer) builder_to_declspace [t];
- if (tc == null)
- return false;
-
- return tc.Kind == Kind.Interface;
- }
-
- public static bool IsSubclassOf (Type type, Type base_type)