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

📄 convert.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 5 页
字号:
					break;				}			}			EmptyExpression.Release (expr);			return best;		}			/// <summary>		///  Finds "most encompassing type" according to the spec (13.4.2)		///  amongst the types in the given set		/// </summary>		static Type FindMostEncompassingType (EmitContext ec, ArrayList types)		{			Type best = null;			if (types.Count == 0)				return null;			if (types.Count == 1)				return (Type) types [0];			EmptyExpression expr = EmptyExpression.Grab ();			foreach (Type t in types) {				if (best == null) {					best = t;					continue;				}				expr.SetType (best);				if (ImplicitStandardConversionExists (ec, expr, t))					best = t;			}			foreach (Type t in types) {				if (best == t)					continue;				expr.SetType (t);				if (!ImplicitStandardConversionExists (ec, expr, best)) {					best = null;					break;				}			}			EmptyExpression.Release (expr);			return best;		}		/// <summary>		///   Finds the most specific source Sx according to the rules of the spec (13.4.4)		///   by making use of FindMostEncomp* methods. Applies the correct rules separately		///   for explicit and implicit conversion operators.		/// </summary>		static public Type FindMostSpecificSource (EmitContext ec, IList list,							   Expression source, bool apply_explicit_conv_rules)		{			ArrayList src_types_set = new ArrayList ();						//			// If any operator converts from S then Sx = S			//			Type source_type = source.Type;			foreach (MethodBase mb in list){				ParameterData pd = TypeManager.GetParameterData (mb);				Type param_type = pd.ParameterType (0);				if (param_type == source_type)					return param_type;				src_types_set.Add (param_type);			}						//			// Explicit Conv rules			//			if (apply_explicit_conv_rules) {				ArrayList candidate_set = new ArrayList ();				foreach (Type param_type in src_types_set){					if (ImplicitStandardConversionExists (ec, source, param_type))						candidate_set.Add (param_type);				}				if (candidate_set.Count != 0)					return FindMostEncompassedType (ec, candidate_set);			}			//			// Final case			//			if (apply_explicit_conv_rules)				return FindMostEncompassingType (ec, src_types_set);			else				return FindMostEncompassedType (ec, src_types_set);		}				/// <summary>		///  Finds the most specific target Tx according to section 13.4.4		/// </summary>		static public Type FindMostSpecificTarget (EmitContext ec, IList list,							   Type target, bool apply_explicit_conv_rules)		{			ArrayList tgt_types_set = new ArrayList ();						//			// If any operator converts to T then Tx = T			//			foreach (MethodInfo mi in list){				Type ret_type = mi.ReturnType;				if (ret_type == target)					return ret_type;				tgt_types_set.Add (ret_type);			}			//			// Explicit conv rules			//			if (apply_explicit_conv_rules) {				ArrayList candidate_set = new ArrayList ();				EmptyExpression expr = EmptyExpression.Grab ();				foreach (Type ret_type in tgt_types_set){					expr.SetType (ret_type);										if (ImplicitStandardConversionExists (ec, expr, target))						candidate_set.Add (ret_type);				}				EmptyExpression.Release (expr);				if (candidate_set.Count != 0)					return FindMostEncompassingType (ec, candidate_set);			}						//			// Okay, final case !			//			if (apply_explicit_conv_rules)				return FindMostEncompassedType (ec, tgt_types_set);			else 				return FindMostEncompassingType (ec, tgt_types_set);		}				/// <summary>		///  User-defined Implicit conversions		/// </summary>		static public Expression ImplicitUserConversion (EmitContext ec, Expression source,								 Type target, Location loc)		{			return UserDefinedConversion (ec, source, target, loc, false);		}		/// <summary>		///  User-defined Explicit conversions		/// </summary>		static public Expression ExplicitUserConversion (EmitContext ec, Expression source,								 Type target, Location loc)		{			return UserDefinedConversion (ec, source, target, loc, true);		}		static void AddConversionOperators (EmitContext ec, ArrayList list, 						    Expression source, Type target_type, 						    bool look_for_explicit,						    MethodGroupExpr mg)		{			if (mg == null)				return;			Type source_type = source.Type;			EmptyExpression expr = EmptyExpression.Grab ();			foreach (MethodInfo m in mg.Methods) {				ParameterData pd = TypeManager.GetParameterData (m);				Type return_type = m.ReturnType;				Type arg_type = pd.ParameterType (0);				if (source_type != arg_type) {					if (!ImplicitStandardConversionExists (ec, source, arg_type)) {						if (!look_for_explicit)							continue;						expr.SetType (arg_type);						if (!ImplicitStandardConversionExists (ec, expr, source_type))							continue;					}				}				if (target_type != return_type) {					expr.SetType (return_type);					if (!ImplicitStandardConversionExists (ec, expr, target_type)) {						if (!look_for_explicit)							continue;						expr.SetType (target_type);						if (!ImplicitStandardConversionExists (ec, expr, return_type))							continue;					}				}				list.Add (m);			}			EmptyExpression.Release (expr);		}		/// <summary>		///   Compute the user-defined conversion operator from source_type to target_type. 		///   `look_for_explicit' controls whether we should also include the list of explicit operators		/// </summary>		static MethodInfo GetConversionOperator (EmitContext ec, Expression source, Type target_type, bool look_for_explicit)		{			ArrayList ops = new ArrayList (4);			Type source_type = source.Type;			if (source_type != TypeManager.decimal_type) {				AddConversionOperators (ec, ops, source, target_type, look_for_explicit,					Expression.MethodLookup (ec, source_type, "op_Implicit", Location.Null) as MethodGroupExpr);				if (look_for_explicit) {					AddConversionOperators (ec, ops, source, target_type, look_for_explicit,						Expression.MethodLookup (							ec, source_type, "op_Explicit", Location.Null) as MethodGroupExpr);				}			}			if (target_type != TypeManager.decimal_type) {				AddConversionOperators (ec, ops, source, target_type, look_for_explicit,					Expression.MethodLookup (ec, target_type, "op_Implicit", Location.Null) as MethodGroupExpr);				if (look_for_explicit) {					AddConversionOperators (ec, ops, source, target_type, look_for_explicit,						Expression.MethodLookup (							ec, target_type, "op_Explicit", Location.Null) as MethodGroupExpr);				}			}			if (ops.Count == 0)				return null;			Type most_specific_source = FindMostSpecificSource (ec, ops, source, look_for_explicit);			if (most_specific_source == null)				return null;			Type most_specific_target = FindMostSpecificTarget (ec, ops, target_type, look_for_explicit);			if (most_specific_target == null)				return null;			MethodInfo method = null;			foreach (MethodInfo m in ops) {				if (m.ReturnType != most_specific_target)					continue;				if (TypeManager.GetParameterData (m).ParameterType (0) != most_specific_source)					continue;				// Ambiguous: more than one conversion operator satisfies the signature.				if (method != null)					return null;				method = m;			}			return method;		}		static DoubleHash explicit_conv = new DoubleHash (100);		static DoubleHash implicit_conv = new DoubleHash (100);		/// <summary>		///   User-defined conversions		/// </summary>		static public Expression UserDefinedConversion (EmitContext ec, Expression source,								Type target, Location loc,								bool look_for_explicit)		{			Type source_type = source.Type;			MethodInfo method = null;			object o;			DoubleHash hash = look_for_explicit ? explicit_conv : implicit_conv;			if (!(source is Constant) && hash.Lookup (source_type, target, out o)) {				method = (MethodInfo) o;			} else {				method = GetConversionOperator (ec, source, target, look_for_explicit);				if (!(source is Constant))					hash.Insert (source_type, target, method);			}			if (method == null)				return null;						Type most_specific_source = TypeManager.GetParameterData (method).ParameterType (0);			//			// This will do the conversion to the best match that we			// found.  Now we need to perform an implict standard conversion			// if the best match was not the type that we were requested			// by target.			//			if (look_for_explicit)				source = ExplicitConversionStandard (ec, source, most_specific_source, loc);			else				source = ImplicitConversionStandard (ec, source, most_specific_source, loc);			if (source == null)				return null;			Expression e;			e =  new UserCast (method, source, loc);			if (e.Type != target){				if (!look_for_explicit)					e = ImplicitConversionStandard (ec, e, target, loc);				else					e = ExplicitConversionStandard (ec, e, target, loc);			}			return e;		}				/// <summary>		///   Converts implicitly the resolved expression `expr' into the		///   `target_type'.  It returns a new expression that can be used		///   in a context that expects a `target_type'. 		/// </summary>		static public Expression ImplicitConversion (EmitContext ec, Expression expr,							     Type target_type, Location loc)		{			Expression e;			if (target_type == null)				throw new Exception ("Target type is null");			e = ImplicitConversionStandard (ec, expr, target_type, loc);			if (e != null)				return e;			e = ImplicitUserConversion (ec, expr, target_type, loc);			if (e != null)				return e;			return null;		}				/// <summary>		///   Attempts to apply the `Standard Implicit		///   Conversion' rules to the expression `expr' into		///   the `target_type'.  It returns a new expression		///   that can be used in a context that expects a		///   `target_type'.		///		///   This is different from `ImplicitConversion' in that the		///   user defined implicit conversions are excluded. 		/// </summary>		static public Expression ImplicitConversionStandard (EmitContext ec, Expression expr,								     Type target_type, Location loc)		{			Type expr_type = expr.Type;			Expression e;			if (expr.eclass == ExprClass.MethodGroup){				if (!TypeManager.IsDelegateType (target_type)){					return null;				}

⌨️ 快捷键说明

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