📄 typemanager.cs
字号:
return t.IsEnum; } public static bool IsBuiltinOrEnum (Type t) { if (IsBuiltinType (t)) return true; if (IsEnumType (t)) return true; return false; } static Stack unmanaged_enclosing_types = new Stack (4); // // Whether a type is unmanaged. This is used by the unsafe code (25.2) // public static bool IsUnmanagedType (Type t) { // Avoid infloops in the case of: unsafe struct Foo { Foo *x; } if (unmanaged_enclosing_types.Contains (t)) return true; // builtins that are not unmanaged types if (t == TypeManager.object_type || t == TypeManager.string_type) 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 true; // Arrays are disallowed, even if we mark them with [MarshalAs(UnmanagedType.ByValArray, ...)] if (t.IsArray) return false; if (!IsValueType (t)) return false; unmanaged_enclosing_types.Push (t); bool retval = true; if (t is TypeBuilder){ TypeContainer tc = LookupTypeContainer (t); if (tc.Fields != null){ foreach (FieldMember f in tc.Fields){ // Avoid using f.FieldBuilder: f.Define () may not yet have been invoked. if ((f.ModFlags & Modifiers.STATIC) != 0) continue; if (f.MemberType == null) continue; if (!IsUnmanagedType (f.MemberType)){ Report.SymbolRelatedToPreviousError (f.Location, CSharpName (t) + "." + f.Name); retval = false; } } } } else { FieldInfo [] fields = t.GetFields (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (FieldInfo f in fields){ if (!IsUnmanagedType (f.FieldType)){ Report.SymbolRelatedToPreviousError (f); retval = false; } } } unmanaged_enclosing_types.Pop (); return retval; } public static bool IsValueType (Type t) { if (t.IsSubclassOf (TypeManager.value_type) && (t != TypeManager.enum_type)) return true; else return false; } 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) { do { if (type.Equals (base_type)) return true; type = type.BaseType; } while (type != null); return false; } public static bool IsFamilyAccessible (Type type, Type base_type) { return IsSubclassOf (type, base_type); } // // Checks whether `type' is a subclass or nested child of `base_type'. // public static bool IsNestedFamilyAccessible (Type type, Type base_type) { do { if ((type == base_type) || type.IsSubclassOf (base_type)) return true; // Handle nested types. type = type.DeclaringType; } while (type != null); return false; } // // Checks whether `type' is a nested child of `parent'. // public static bool IsNestedChildOf (Type type, Type parent) { if (type == parent) return false; type = type.DeclaringType; while (type != null) { if (type == parent) return true; type = type.DeclaringType; } return false; } // // Do the right thing when returning the element type of an // array type based on whether we are compiling corlib or not // public static Type GetElementType (Type t) { if (RootContext.StdLib) return t.GetElementType (); else return TypeToCoreType (t.GetElementType ()); } /// <summary> /// This method is not implemented by MS runtime for dynamic types /// </summary> public static bool HasElementType (Type t) { return t.IsArray || t.IsPointer || t.IsByRef; } /// <summary> /// Gigantic work around for missing features in System.Reflection.Emit follows. /// </summary> /// /// <remarks> /// Since System.Reflection.Emit can not return MethodBase.GetParameters /// for anything which is dynamic, and we need this in a number of places, /// we register this information here, and use it afterwards. /// </remarks> static public void RegisterMethod (MethodBase mb, InternalParameters ip, Type [] args) { if (args == null) args = NoTypes; method_arguments.Add (mb, args); method_params.Add (mb, ip); } static public ParameterData GetParameterData (MethodBase mb) { object pd = method_params [mb]; if (pd == null) { if (mb is MethodBuilder || mb is ConstructorBuilder) throw new InternalErrorException ("Argument for Method not registered" + mb); method_params [mb] = pd = new ReflectionParameters (mb); } return (ParameterData) pd; } static public void RegisterOverride (MethodBase override_method, MethodBase base_method) { if (method_overrides.Contains (override_method)) { if (method_overrides [override_method] != base_method) throw new InternalErrorException ("Override mismatch: " + override_method); return; } method_overrides [override_method] = base_method; } static public bool IsOverride (MethodBase m) { return m.IsVirtual && (m.Attributes & MethodAttributes.NewSlot) == 0 && (m is MethodBuilder || method_overrides.Contains (m)); } /// <summary> /// Returns the argument types for a method based on its methodbase /// /// For dynamic methods, we use the compiler provided types, for /// methods from existing assemblies we load them from GetParameters, /// and insert them into the cache /// </summary> static public Type [] GetArgumentTypes (MethodBase mb) { object t = method_arguments [mb]; if (t != null) return (Type []) t; ParameterInfo [] pi = mb.GetParameters (); int c = pi.Length; Type [] types; if (c == 0) { types = NoTypes; } else { types = new Type [c]; for (int i = 0; i < c; i++) types [i] = pi [i].ParameterType; } method_arguments.Add (mb, types); return types; } /// <summary> /// Returns the argument types for an indexer based on its PropertyInfo /// /// For dynamic indexers, we use the compiler provided types, for /// indexers from existing assemblies we load them from GetParameters, /// and insert them into the cache /// </summary> static public Type [] GetArgumentTypes (PropertyInfo indexer) { if (indexer_arguments.Contains (indexer)) return (Type []) indexer_arguments [indexer]; else if (indexer is PropertyBuilder) // If we're a PropertyBuilder and not in the // `indexer_arguments' hash, then we're a property and // not an indexer. return NoTypes; else { ParameterInfo [] pi = indexer.GetIndexParameters (); // Property, not an indexer. if (pi == null) return NoTypes; int c = pi.Length; Type [] types = new Type [c]; for (int i = 0; i < c; i++) types [i] = pi [i].ParameterType; indexer_arguments.Add (indexer, types); return types; } } public static void RegisterConstant (FieldInfo fb, IConstant ic) { fields.Add (fb, ic); } public static IConstant GetConstant (FieldInfo fb) { if (fb == null) return null; return (IConstant)fields [fb]; } static public bool RegisterFieldBase (FieldBuilder fb, FieldBase f) { if (fieldbuilders_to_fields.Contains (fb)) return false; fieldbuilders_to_fields.Add (fb, f); return true; } // // The return value can be null; This will be the case for // auxiliary FieldBuilders created by the compiler that have no // real field being declared on the source code // static public FieldBase GetField (FieldInfo fb) { return (FieldBase) fieldbuilders_to_fields [fb]; } static Hashtable events; static public void RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove) { if (events == null) events = new Hashtable (); if (!events.Contains (eb)) { events.Add (eb, new Pair (add, remove)); } } static public MethodInfo GetAddMethod (EventInfo ei) { if (ei is MyEventBuilder) { Pair pair = (Pair) events [ei]; return (MethodInfo) pair.First; } return ei.GetAddMethod (true); } static public MethodInfo GetRemoveMethod (EventInfo ei) { if (ei is MyEventBuilder) { Pair pair = (Pair) events [ei]; return (MethodInfo) pair.Second; } return ei.GetRemoveMethod (true); } static Hashtable priv_fields_events; static public bool RegisterPrivateFieldOfEvent (EventInfo einfo, FieldBuilder builder) { if (priv_fields_events == null) priv_fields_events = new Hashtable (); if (priv_fields_events.Contains (einfo)) return false; priv_fields_events.Add (einfo, builder); return true; } static public MemberInfo GetPrivateFieldOfEvent (EventInfo ei) { if (priv_fields_events == null) return null; else return (MemberInfo) priv_fields_events [ei]; } static public bool RegisterIndexer (PropertyBuilder pb, MethodBase get, MethodBase set, Type[] args) { indexer_arguments.Add (pb, args); return true; } public static bool CheckStructCycles (TypeContainer tc, Hashtable seen) { Hashtable hash = new Hashtable (); return CheckStructCycles (tc, seen, hash); } public static bool CheckStructCycles (TypeContainer tc, Hashtable seen, Hashtable hash) { if ((tc.Kind != Kind.Struct) || IsBuiltinType (tc)) return true; // // `seen' contains all types we've already visited. // if (seen.Contains (tc)) return true; seen.Add (tc, null); if (tc.Fields == null) return true; foreach (FieldMember field in tc.Fields) { if (field.FieldBuilder == null || field.FieldBuilder.IsStatic) continue; Type ftype = field.FieldBuilder.FieldType; TypeContainer ftc = LookupTypeContainer (ftype); if (ftc == null) continue; if (hash.Contains (ftc)) { Report.Error (523, tc.Location, "Struct member `{0}.{1}' of type `{2}' " + "causes a cycle in the struct layout", tc.Name, field.Name, ftc.Name); return false; } // // `hash' contains all types in the current path. // hash.Add (tc, null); bool ok = CheckStructCycles (ftc, seen, hash); hash.Remove (tc); if (!ok) return false; if (!seen.Contains (ftc)) seen.Add (ftc, null); } return true; } /// <summary> /// Given an array of interface types, expand and eliminate repeated ocurrences
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -