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

📄 convert.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 5 页
字号:
//// conversion.cs: various routines for implementing conversions.//// Authors://   Miguel de Icaza (miguel@ximian.com)//   Ravi Pratap (ravi@ximian.com)//// (C) 2001, 2002, 2003 Ximian, Inc.//namespace Mono.CSharp {	using System;	using System.Collections;	using System.Diagnostics;	using System.Reflection;	using System.Reflection.Emit;	//	// A container class for all the conversion operations	//	public class Convert {		//		// This is used to prettify the code: a null argument is allowed		// for ImplicitStandardConversion as long as it is known that		// no anonymous method will play a role.		//		// FIXME: renamed from `const' to `static' to allow bootstraping from older		// versions of the compiler that could not cope with this construct.		//		public static EmitContext ConstantEC = null;				static EmptyExpression MyEmptyExpr;		static public Expression ImplicitReferenceConversion (Expression expr, Type target_type)		{			Type expr_type = expr.Type;			if (expr_type == null && expr.eclass == ExprClass.MethodGroup){				// if we are a method group, emit a warning				expr.Emit (null);			}			if (expr_type == TypeManager.void_type)				return null;						//			// notice that it is possible to write "ValueType v = 1", the ValueType here			// is an abstract class, and not really a value type, so we apply the same rules.			//			if (target_type == TypeManager.object_type) {				//				// A pointer type cannot be converted to object				// 				if (expr_type.IsPointer)					return null;				if (expr_type.IsValueType)					return new BoxedCast (expr, target_type);				if (expr_type.IsClass || expr_type.IsInterface || expr_type == TypeManager.enum_type){					if (expr_type == TypeManager.anonymous_method_type)						return null;					return new EmptyCast (expr, target_type);				}				return null;			} else if (target_type == TypeManager.value_type) {				if (expr_type.IsValueType)					return new BoxedCast (expr, target_type);				if (expr_type == TypeManager.null_type)					return new NullCast ((Constant)expr, target_type);				return null;			} else if (expr_type.IsSubclassOf (target_type)) {				//				// Special case: enumeration to System.Enum.				// System.Enum is not a value type, it is a class, so we need				// a boxing conversion				//				if (expr_type.IsEnum)					return new BoxedCast (expr, target_type);				return new EmptyCast (expr, target_type);			}			// This code is kind of mirrored inside ImplicitStandardConversionExists			// with the small distinction that we only probe there			//			// Always ensure that the code here and there is in sync			// from the null type to any reference-type.			if (expr_type == TypeManager.null_type){				if (target_type.IsPointer)					return new EmptyCast (NullPointer.Null, target_type);									if (!target_type.IsValueType) {					if (expr is Constant)						return new NullCast ((Constant)expr, target_type);					// I found only one case when it happens -- Foo () ? null : null;					Report.Warning (-100, 1, expr.Location, "The result of the expression is always `null'");					return new NullCast (new NullLiteral (expr.Location), target_type);				}			}			// from any class-type S to any interface-type T.			if (target_type.IsInterface) {				if (target_type != TypeManager.iconvertible_type &&				    expr_type.IsValueType && (expr is Constant) &&				    !(expr is IntLiteral || expr is BoolLiteral ||				      expr is FloatLiteral || expr is DoubleLiteral ||				      expr is LongLiteral || expr is CharLiteral ||				      expr is StringLiteral || expr is DecimalLiteral ||				      expr is UIntLiteral || expr is ULongLiteral)) {					return null;				}				if (TypeManager.ImplementsInterface (expr_type, target_type)){					if (expr_type.IsClass)						return new EmptyCast (expr, target_type);					else if (expr_type.IsValueType)						return new BoxedCast (expr, target_type);					else						return new EmptyCast (expr, target_type);				}			}			// from any interface type S to interface-type T.			if (expr_type.IsInterface && target_type.IsInterface) {				if (TypeManager.ImplementsInterface (expr_type, target_type))					return new EmptyCast (expr, target_type);				else					return null;			}							// from an array-type S to an array-type of type T			if (expr_type.IsArray && target_type.IsArray) {				if (expr_type.GetArrayRank () == target_type.GetArrayRank ()) {					Type expr_element_type = TypeManager.GetElementType (expr_type);					if (MyEmptyExpr == null)						MyEmptyExpr = new EmptyExpression ();											MyEmptyExpr.SetType (expr_element_type);					Type target_element_type = TypeManager.GetElementType (target_type);					if (!expr_element_type.IsValueType && !target_element_type.IsValueType)						if (ImplicitStandardConversionExists (ConstantEC, MyEmptyExpr,										      target_element_type))							return new EmptyCast (expr, target_type);				}			}							// from an array-type to System.Array			if (expr_type.IsArray && target_type == TypeManager.array_type)				return new EmptyCast (expr, target_type);							// from any delegate type to System.Delegate			if ((expr_type == TypeManager.delegate_type ||			     expr_type.IsSubclassOf (TypeManager.delegate_type)) &&			    target_type == TypeManager.delegate_type)				return new EmptyCast (expr, target_type);								// from any array-type or delegate type into System.ICloneable.			if (expr_type.IsArray ||			    expr_type == TypeManager.delegate_type ||			    expr_type.IsSubclassOf (TypeManager.delegate_type))				if (target_type == TypeManager.icloneable_type)					return new EmptyCast (expr, target_type);							return null;		}		//		// Tests whether an implicit reference conversion exists between expr_type		// and target_type		//		static bool ImplicitReferenceConversionExists (Expression expr, Type target_type)		{			if (target_type.IsValueType)				return false;			Type expr_type = expr.Type;			//			// This is the boxed case.			//			if (target_type == TypeManager.object_type) {				if (expr_type.IsClass || expr_type.IsValueType ||				    expr_type.IsInterface || expr_type == TypeManager.enum_type)					if (target_type != TypeManager.anonymous_method_type)						return true;				return false;			} else if (expr_type.IsSubclassOf (target_type)) 				return true;			// Please remember that all code below actually comes			// from ImplicitReferenceConversion so make sure code remains in sync							// from any class-type S to any interface-type T.			if (target_type.IsInterface) {				if (target_type != TypeManager.iconvertible_type &&				    expr_type.IsValueType && (expr is Constant) &&				    !(expr is IntLiteral || expr is BoolLiteral ||				      expr is FloatLiteral || expr is DoubleLiteral ||				      expr is LongLiteral || expr is CharLiteral ||				      expr is StringLiteral || expr is DecimalLiteral ||				      expr is UIntLiteral || expr is ULongLiteral)) {					return false;				}								if (TypeManager.ImplementsInterface (expr_type, target_type))					return true;			}							// from any interface type S to interface-type T.			if (expr_type.IsInterface && target_type.IsInterface)				if (TypeManager.ImplementsInterface (expr_type, target_type))					return true;							// from an array-type S to an array-type of type T			if (expr_type.IsArray && target_type.IsArray) {				if (expr_type.GetArrayRank () == target_type.GetArrayRank ()) {											Type expr_element_type = expr_type.GetElementType ();					if (MyEmptyExpr == null)						MyEmptyExpr = new EmptyExpression ();											MyEmptyExpr.SetType (expr_element_type);					Type target_element_type = TypeManager.GetElementType (target_type);											if (!expr_element_type.IsValueType && !target_element_type.IsValueType)						if (ImplicitStandardConversionExists (ConstantEC, MyEmptyExpr,										      target_element_type))							return true;				}			}							// from an array-type to System.Array			if (expr_type.IsArray && (target_type == TypeManager.array_type))				return true;							// from any delegate type to System.Delegate			if ((expr_type == TypeManager.delegate_type ||			     expr_type.IsSubclassOf (TypeManager.delegate_type)) &&			    target_type == TypeManager.delegate_type)				if (target_type.IsAssignableFrom (expr_type))					return true;								// from any array-type or delegate type into System.ICloneable.			if (expr_type.IsArray ||			    expr_type == TypeManager.delegate_type ||			    expr_type.IsSubclassOf (TypeManager.delegate_type))				if (target_type == TypeManager.icloneable_type)					return true;							// from the null type to any reference-type.			if (expr_type == TypeManager.null_type){				if (target_type.IsPointer)					return true;							if (!target_type.IsValueType)					return true;			}			return false;		}		/// <summary>		///   Implicit Numeric Conversions.		///		///   expr is the expression to convert, returns a new expression of type		///   target_type or null if an implicit conversion is not possible.		/// </summary>		static public Expression ImplicitNumericConversion (EmitContext ec, Expression expr,								    Type target_type)		{			Type expr_type = expr.Type;			//			// Attempt to do the implicit constant expression conversions			if (expr is Constant){				if (expr is IntConstant){					Expression e;										e = TryImplicitIntConversion (target_type, (IntConstant) expr);										if (e != null)						return e;				} else if (expr is LongConstant && target_type == TypeManager.uint64_type){					//					// Try the implicit constant expression conversion					// from long to ulong, instead of a nice routine,					// we just inline it					//					long v = ((LongConstant) expr).Value;					if (v >= 0)						return new ULongConstant ((ulong) v, expr.Location);				} 			}			 			Type real_target_type = target_type;			if (expr_type == TypeManager.sbyte_type){				//				// From sbyte to short, int, long, float, double, decimal				//				if (real_target_type == TypeManager.int32_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_I4);				if (real_target_type == TypeManager.int64_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_I8);				if (real_target_type == TypeManager.double_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);				if (real_target_type == TypeManager.float_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_R4);				if (real_target_type == TypeManager.short_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_I2);				if (real_target_type == TypeManager.decimal_type)					return new CastToDecimal (expr);			} else if (expr_type == TypeManager.byte_type){				//				// From byte to short, ushort, int, uint, long, ulong, float, double, decimal				// 				if ((real_target_type == TypeManager.short_type) ||				    (real_target_type == TypeManager.ushort_type) ||				    (real_target_type == TypeManager.int32_type) ||				    (real_target_type == TypeManager.uint32_type))					return new EmptyCast (expr, target_type);				if (real_target_type == TypeManager.uint64_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_U8);				if (real_target_type == TypeManager.int64_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_I8);				if (real_target_type == TypeManager.float_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_R4);				if (real_target_type == TypeManager.double_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);				if (real_target_type == TypeManager.decimal_type)					return new CastToDecimal (expr);							} else if (expr_type == TypeManager.short_type){				//				// From short to int, long, float, double, decimal				// 				if (real_target_type == TypeManager.int32_type)					return new EmptyCast (expr, target_type);				if (real_target_type == TypeManager.int64_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_I8);				if (real_target_type == TypeManager.double_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);				if (real_target_type == TypeManager.float_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_R4);				if (real_target_type == TypeManager.decimal_type)					return new CastToDecimal (expr);							} else if (expr_type == TypeManager.ushort_type){				//				// From ushort to int, uint, long, ulong, float, double, decimal				//				if (real_target_type == TypeManager.uint32_type)					return new EmptyCast (expr, target_type);				if (real_target_type == TypeManager.uint64_type)

⌨️ 快捷键说明

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