⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 typemanager.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 5 页
字号:
	///   of an interface.  	/// </summary>	///	/// <remarks>	///   This expands in context like: IA; IB : IA; IC : IA, IB; the interface "IC" to	///   be IA, IB, IC.	/// </remarks>	public static Type[] ExpandInterfaces (EmitContext ec, TypeExpr [] base_interfaces)	{		ArrayList new_ifaces = new ArrayList ();		foreach (TypeExpr iface in base_interfaces){			Type itype = iface.ResolveType (ec);			if (itype == null)				return null;			if (!new_ifaces.Contains (itype))				new_ifaces.Add (itype);						Type [] implementing = itype.GetInterfaces ();						foreach (Type imp in implementing){				if (!new_ifaces.Contains (imp))					new_ifaces.Add (imp);			}		}		Type [] ret = new Type [new_ifaces.Count];		new_ifaces.CopyTo (ret, 0);		return ret;	}		static PtrHashtable iface_cache = new PtrHashtable ();			/// <summary>	///   This function returns the interfaces in the type `t'.  Works with	///   both types and TypeBuilders.	/// </summary>	public static Type [] GetInterfaces (Type t)	{				Type [] cached = iface_cache [t] as Type [];		if (cached != null)			return cached;				//		// The reason for catching the Array case is that Reflection.Emit		// will not return a TypeBuilder for Array types of TypeBuilder types,		// but will still throw an exception if we try to call GetInterfaces		// on the type.		//		// Since the array interfaces are always constant, we return those for		// the System.Array		//				if (t.IsArray)			t = TypeManager.array_type;				if (t is TypeBuilder){			Type [] base_ifaces;						if (t.BaseType == null)				base_ifaces = NoTypes;			else				base_ifaces = GetInterfaces (t.BaseType);			Type [] type_ifaces = (Type []) builder_to_ifaces [t];			if (type_ifaces == null)				type_ifaces = NoTypes;			int base_count = base_ifaces.Length;			Type [] result = new Type [base_count + type_ifaces.Length];			base_ifaces.CopyTo (result, 0);			type_ifaces.CopyTo (result, base_count);			iface_cache [t] = result;			return result;		} else {			Type[] ifaces = t.GetInterfaces ();			iface_cache [t] = ifaces;			return ifaces;		}	}		//	// gets the interfaces that are declared explicitly on t	//	public static Type [] GetExplicitInterfaces (TypeBuilder t)	{		return (Type []) builder_to_ifaces [t];	}		/// <remarks>	///  The following is used to check if a given type implements an interface.	///  The cache helps us reduce the expense of hitting Type.GetInterfaces everytime.	/// </remarks>	public static bool ImplementsInterface (Type t, Type iface)	{		Type [] interfaces;		//		// FIXME OPTIMIZATION:		// as soon as we hit a non-TypeBuiler in the interface		// chain, we could return, as the `Type.GetInterfaces'		// will return all the interfaces implement by the type		// or its bases.		//		do {			interfaces = GetInterfaces (t);			if (interfaces != null){				foreach (Type i in interfaces){					if (i == iface)						return true;				}			}						t = t.BaseType;		} while (t != null);				return false;	}	static NumberFormatInfo nf_provider = CultureInfo.CurrentCulture.NumberFormat;	// This is a custom version of Convert.ChangeType() which works	// with the TypeBuilder defined types when compiling corlib.	public static object ChangeType (object value, Type conversionType, out bool error)	{		IConvertible convert_value = value as IConvertible;				if (convert_value == null){			error = true;			return null;		}				//		// We must use Type.Equals() here since `conversionType' is		// the TypeBuilder created version of a system type and not		// the system type itself.  You cannot use Type.GetTypeCode()		// on such a type - it'd always return TypeCode.Object.		//		error = false;		try {			if (conversionType.Equals (typeof (Boolean)))				return (object)(convert_value.ToBoolean (nf_provider));			else if (conversionType.Equals (typeof (Byte)))				return (object)(convert_value.ToByte (nf_provider));			else if (conversionType.Equals (typeof (Char)))				return (object)(convert_value.ToChar (nf_provider));			else if (conversionType.Equals (typeof (DateTime)))				return (object)(convert_value.ToDateTime (nf_provider));			else if (conversionType.Equals (TypeManager.decimal_type)) // typeof (Decimal)))				return (object)(convert_value.ToDecimal (nf_provider));			else if (conversionType.Equals (typeof (Double)))				return (object)(convert_value.ToDouble (nf_provider));			else if (conversionType.Equals (typeof (Int16)))				return (object)(convert_value.ToInt16 (nf_provider));			else if (conversionType.Equals (typeof (Int32)))				return (object)(convert_value.ToInt32 (nf_provider));			else if (conversionType.Equals (typeof (Int64)))				return (object)(convert_value.ToInt64 (nf_provider));			else if (conversionType.Equals (typeof (SByte)))				return (object)(convert_value.ToSByte (nf_provider));			else if (conversionType.Equals (typeof (Single)))				return (object)(convert_value.ToSingle (nf_provider));			else if (conversionType.Equals (typeof (String)))				return (object)(convert_value.ToString (nf_provider));			else if (conversionType.Equals (typeof (UInt16)))				return (object)(convert_value.ToUInt16 (nf_provider));			else if (conversionType.Equals (typeof (UInt32)))				return (object)(convert_value.ToUInt32 (nf_provider));			else if (conversionType.Equals (typeof (UInt64)))				return (object)(convert_value.ToUInt64 (nf_provider));			else if (conversionType.Equals (typeof (Object)))				return (object)(value);			else 				error = true;		} catch {			error = true;		}		return null;	}	//	// This is needed, because enumerations from assemblies	// do not report their underlyingtype, but they report	// themselves	//	public static Type EnumToUnderlying (Type t)	{		if (t == TypeManager.enum_type)			return t;		t = t.UnderlyingSystemType;		if (!TypeManager.IsEnumType (t))			return t;			if (t is TypeBuilder) {			// slow path needed to compile corlib			if (t == TypeManager.bool_type ||			    t == TypeManager.byte_type ||			    t == TypeManager.sbyte_type ||			    t == TypeManager.char_type ||			    t == TypeManager.short_type ||			    t == TypeManager.ushort_type ||			    t == TypeManager.int32_type ||			    t == TypeManager.uint32_type ||			    t == TypeManager.int64_type ||			    t == TypeManager.uint64_type)				return t;		}		TypeCode tc = Type.GetTypeCode (t);		switch (tc){		case TypeCode.Boolean:			return TypeManager.bool_type;		case TypeCode.Byte:			return TypeManager.byte_type;		case TypeCode.SByte:			return TypeManager.sbyte_type;		case TypeCode.Char:			return TypeManager.char_type;		case TypeCode.Int16:			return TypeManager.short_type;		case TypeCode.UInt16:			return TypeManager.ushort_type;		case TypeCode.Int32:			return TypeManager.int32_type;		case TypeCode.UInt32:			return TypeManager.uint32_type;		case TypeCode.Int64:			return TypeManager.int64_type;		case TypeCode.UInt64:			return TypeManager.uint64_type;		}		throw new Exception ("Unhandled typecode in enum " + tc + " from " + t.AssemblyQualifiedName);	}	//	// When compiling corlib and called with one of the core types, return	// the corresponding typebuilder for that type.	//	public static Type TypeToCoreType (Type t)	{		if (RootContext.StdLib || (t is TypeBuilder))			return t;		TypeCode tc = Type.GetTypeCode (t);		switch (tc){		case TypeCode.Boolean:			return TypeManager.bool_type;		case TypeCode.Byte:			return TypeManager.byte_type;		case TypeCode.SByte:			return TypeManager.sbyte_type;		case TypeCode.Char:			return TypeManager.char_type;		case TypeCode.Int16:			return TypeManager.short_type;		case TypeCode.UInt16:			return TypeManager.ushort_type;		case TypeCode.Int32:			return TypeManager.int32_type;		case TypeCode.UInt32:			return TypeManager.uint32_type;		case TypeCode.Int64:			return TypeManager.int64_type;		case TypeCode.UInt64:			return TypeManager.uint64_type;		case TypeCode.Single:			return TypeManager.float_type;		case TypeCode.Double:			return TypeManager.double_type;		case TypeCode.String:			return TypeManager.string_type;		case TypeCode.Decimal:			return TypeManager.decimal_type;		default:			if (t == typeof (void))				return TypeManager.void_type;			if (t == typeof (object))				return TypeManager.object_type;			if (t == typeof (System.Type))				return TypeManager.type_type;			if (t == typeof (System.IntPtr))				return TypeManager.intptr_type;			return t;		}	}	/// <summary>	///   Utility function that can be used to probe whether a type	///   is managed or not.  	/// </summary>	public static bool VerifyUnManaged (Type t, Location loc)	{		if (IsUnmanagedType (t))			return true;		Report.Error (208, loc, "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",			CSharpName (t));		return false;		}		/// <summary>	///   Returns the name of the indexer in a given type.	/// </summary>	/// <remarks>	///   The default is not always `Item'.  The user can change this behaviour by	///   using the IndexerNameAttribute in the container.	///   For example, the String class indexer is named `Chars' not `Item' 	/// </remarks>	public static string IndexerPropertyName (Type t)	{		if (t is TypeBuilder) {			TypeContainer tc = t.IsInterface ? LookupInterface (t) : LookupTypeContainer (t);			return tc == null ? TypeContainer.DefaultIndexerName : tc.IndexerName;		}				System.Attribute attr = System.Attribute.GetCustomAttribute (			t, TypeManager.default_member_type);		if (attr != null){			DefaultMemberAttribute dma = (DefaultMemberAttribute) attr;			return dma.MemberName;		}		return TypeContainer.DefaultIndexerName;	}	static MethodInfo declare_local_method = null;		public static LocalBuilder DeclareLocalPinned (ILGenerator ig, Type t)	{		if (declare_local_method == null){			declare_local_method = typeof (ILGenerator).GetMethod (				"DeclareLocal",				BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,				null, 				new Type [] { typeof (Type), typeof (bool)},				null);			if (declare_local_method == null){				Report.Warning (-30, new Location (-1),						"This version of the runtime does not support making pinned local variables.  " +						"This code may cause errors on a runtime with a moving GC");				return ig.DeclareLocal (t);			}		}		return (LocalBuilder) declare_local_method.Invoke (ig, new object [] { t, true });	}		//	// Returns whether the array of memberinfos contains the given method	//	public static bool ArrayContainsMethod (MemberInfo [] array, MethodBase new_method)	{		Type [] new_args = TypeManager.GetArgumentTypes (new_method);				foreach (MethodBase method in array) {			if (method.Name != new_method.Name)				continue;                        if (method is MethodInfo && new_method is MethodInfo)                                if (((MethodInfo) method).ReturnType != ((MethodInfo) new_method).ReturnType)                                        continue;                        			Type [] old_args = TypeManager.GetArgumentTypes (method);			int old_count = old_args.Length;			int i;						if (new_args.Length != old_count)				continue;						for (i = 0; i < old_count; i++){				if (old_args [i] != new_args [i])					break;			}			if (i != old_count)				continue;			return true;		}                		return false;	}		//	// We copy methods from `new_members' into `target_list' if the signature	// for the method from in the new list does not exist in the target_list	//	// The name is assumed to be the same.	//	public static ArrayList CopyNewMethods (ArrayList target_list, IList new_members)	{		if (target_list == null){			target_list = new ArrayList ();			foreach (MemberInfo mi in new_members){				if (mi is MethodBase)					target_list.Add (mi);			}			return target_list;		}				MemberInfo [] target_array = new MemberInfo [target_list.Count];		target_list.CopyTo (target_array, 0);				foreach (MemberInfo mi in new_members){			MethodBase new_method = (MethodBase) mi;						if (!ArrayContainsMethod (target_array, new_method))				target_list.Add (new_method);		}		return target_list;	}#region MemberLookup implementation		//	// Whether we allow private members in the result (since FindMembers	// uses NonPublic for both protected and private), we need to distinguish.	//	static internal bool FilterNone (MemberInfo

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -