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

📄 delegate.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 2 页
字号:
			int arg_count;			if (args == null)				arg_count = 0;			else				arg_count = args.Count;			Expression ml = Expression.MemberLookup (				ec, delegate_type, "Invoke", loc);			MethodGroupExpr me = ml as MethodGroupExpr;			if (me == null) {				Report.Error (-100, loc, "Internal error: could not find Invoke method!" + delegate_type);				return false;			}						MethodBase mb = me.Methods [0];			ParameterData pd = TypeManager.GetParameterData (mb);			int pd_count = pd.Count;			bool params_method = (pd_count != 0) &&				(pd.ParameterModifier (pd_count - 1) == Parameter.Modifier.PARAMS);			bool is_params_applicable = false;			bool is_applicable = Invocation.IsApplicable (ec, me, args, arg_count, ref mb);			if (!is_applicable && params_method &&			    Invocation.IsParamsMethodApplicable (ec, me, args, arg_count, ref mb))				is_applicable = is_params_applicable = true;			if (!is_applicable && !params_method && arg_count != pd_count) {				Report.Error (1593, loc, "Delegate `{0}' does not take `{1}' arguments",					TypeManager.CSharpName (delegate_type), arg_count);				return false;			}			return Invocation.VerifyArgumentsCompat (					ec, args, arg_count, mb, 					is_params_applicable || (!is_applicable && params_method),					delegate_type, false, loc);		}				/// <summary>		///  Verifies whether the delegate in question is compatible with this one in		///  order to determine if instantiation from the same is possible.		/// </summary>		public static bool VerifyDelegate (EmitContext ec, Type delegate_type, Type probe_type, Location loc)		{			Expression ml = Expression.MemberLookup (				ec, delegate_type, "Invoke", loc);						if (!(ml is MethodGroupExpr)) {				Report.Error (-100, loc, "Internal error: could not find Invoke method!");				return false;			}						MethodBase mb = ((MethodGroupExpr) ml).Methods [0];			ParameterData pd = TypeManager.GetParameterData (mb);			Expression probe_ml = Expression.MemberLookup (				ec, delegate_type, "Invoke", loc);						if (!(probe_ml is MethodGroupExpr)) {				Report.Error (-100, loc, "Internal error: could not find Invoke method!");				return false;			}						MethodBase probe_mb = ((MethodGroupExpr) probe_ml).Methods [0];			ParameterData probe_pd = TypeManager.GetParameterData (probe_mb);						if (((MethodInfo) mb).ReturnType != ((MethodInfo) probe_mb).ReturnType)				return false;			if (pd.Count != probe_pd.Count)				return false;			for (int i = pd.Count; i > 0; ) {				i--;				if (pd.ParameterType (i) != probe_pd.ParameterType (i) ||				    pd.ParameterModifier (i) != probe_pd.ParameterModifier (i))					return false;			}						return true;		}				public static string FullDelegateDesc (Type del_type, MethodBase mb, ParameterData pd)		{			StringBuilder sb = new StringBuilder ();			sb.Append (TypeManager.CSharpName (((MethodInfo) mb).ReturnType));			sb.Append (" ");			sb.Append (TypeManager.CSharpName (del_type));			sb.Append (pd.GetSignatureForError ());			return sb.ToString ();					}				// Hack around System.Reflection as found everywhere else		public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,							MemberFilter filter, object criteria)		{			ArrayList members = new ArrayList ();			if ((mt & MemberTypes.Method) != 0) {				if (ConstructorBuilder != null)				if (filter (ConstructorBuilder, criteria))					members.Add (ConstructorBuilder);				if (InvokeBuilder != null)				if (filter (InvokeBuilder, criteria))					members.Add (InvokeBuilder);				if (BeginInvokeBuilder != null)				if (filter (BeginInvokeBuilder, criteria))					members.Add (BeginInvokeBuilder);				if (EndInvokeBuilder != null)				if (filter (EndInvokeBuilder, criteria))					members.Add (EndInvokeBuilder);			}			return new MemberList (members);		}		public override MemberCache MemberCache {			get {				return null;			}		}		public Expression InstanceExpression {			get {				return instance_expr;			}			set {				instance_expr = value;			}		}		public MethodBase TargetMethod {			get {				return delegate_method;			}			set {				delegate_method = value;			}		}		public Type TargetReturnType {			get {				return ret_type;			}		}		public Type [] ParameterTypes {			get {				return param_types;			}		}		public override AttributeTargets AttributeTargets {			get {				return AttributeTargets.Delegate;			}		}		//		//   Represents header string for documentation comment.		//		public override string DocCommentHeader {			get { return "T:"; }		}	}	//	// Base class for `NewDelegate' and `ImplicitDelegateCreation'	//	public abstract class DelegateCreation : Expression {		protected MethodBase constructor_method;		protected MethodBase delegate_method;		protected MethodGroupExpr method_group;		protected Expression delegate_instance_expression;		public DelegateCreation () {}		public static void Error_NoMatchingMethodForDelegate (EmitContext ec, MethodGroupExpr mg, Type type, Location loc)		{			string method_desc;			MethodInfo found_method = (MethodInfo)mg.Methods [0];						if (mg.Methods.Length > 1)				method_desc = found_method.Name;			else				method_desc = Invocation.FullMethodDesc (found_method);			Expression invoke_method = Expression.MemberLookup (				ec, type, "Invoke", MemberTypes.Method,				Expression.AllBindingFlags, loc);			MethodInfo method = ((MethodGroupExpr) invoke_method).Methods [0] as MethodInfo;			ParameterData param = TypeManager.GetParameterData (method);			string delegate_desc = Delegate.FullDelegateDesc (type, method, param);			if (method.ReturnType != found_method.ReturnType) {				Report.Error (407, loc, "`{0}' has the wrong return type to match the delegate `{1}'", method_desc, delegate_desc);			} else {				Report.Error (123, loc, "Method `{0}' does not match delegate `{1}'", method_desc, delegate_desc);			}		}				public override void Emit (EmitContext ec)		{			if (delegate_instance_expression == null || delegate_method.IsStatic)				ec.ig.Emit (OpCodes.Ldnull);			else				delegate_instance_expression.Emit (ec);						if (delegate_method.IsVirtual && !method_group.IsBase) {				ec.ig.Emit (OpCodes.Dup);				ec.ig.Emit (OpCodes.Ldvirtftn, (MethodInfo) delegate_method);			} else				ec.ig.Emit (OpCodes.Ldftn, (MethodInfo) delegate_method);			ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) constructor_method);		}		protected bool ResolveConstructorMethod (EmitContext ec)		{			Expression ml = Expression.MemberLookup (				ec, type, ".ctor", loc);			if (!(ml is MethodGroupExpr)) {				Report.Error (-100, loc, "Internal error: Could not find delegate constructor!");				return false;			}			constructor_method = ((MethodGroupExpr) ml).Methods [0];			return true;		}		protected Expression ResolveMethodGroupExpr (EmitContext ec, MethodGroupExpr mg,							     bool check_only)		{			foreach (MethodInfo mi in mg.Methods){				delegate_method  = Delegate.VerifyMethod (ec, type, mi, loc);								if (delegate_method != null)					break;			}						if (delegate_method == null) {				if (!check_only)					Error_NoMatchingMethodForDelegate (ec, mg, type, loc);				return null;			}						//			// Check safe/unsafe of the delegate			//			if (!ec.InUnsafe){				ParameterData param = TypeManager.GetParameterData (delegate_method);				int count = param.Count;								for (int i = 0; i < count; i++){					if (param.ParameterType (i).IsPointer){						Expression.UnsafeError (loc);						return null;					}				}			}						//TODO: implement caching when performance will be low			IMethodData md = TypeManager.GetMethod (delegate_method);			if (md == null) {				if (System.Attribute.GetCustomAttribute (delegate_method, TypeManager.conditional_attribute_type) != null) {					Report.Error (1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute", TypeManager.CSharpSignature (delegate_method));				}			} else {				md.SetMemberIsUsed ();				if (md.OptAttributes != null && md.OptAttributes.Search (TypeManager.conditional_attribute_type, ec) != null) {					Report.Error (1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute", TypeManager.CSharpSignature (delegate_method));				}			}						if (mg.InstanceExpression != null)				delegate_instance_expression = mg.InstanceExpression.Resolve (ec);			else if (ec.IsStatic) {				if (!delegate_method.IsStatic) {					Report.Error (120, loc, "`{0}': An object reference is required for the nonstatic field, method or property",						      TypeManager.CSharpSignature (delegate_method));					return null;				}				delegate_instance_expression = null;			} else				delegate_instance_expression = ec.GetThis (loc);						if (delegate_instance_expression != null && delegate_instance_expression.Type.IsValueType)				delegate_instance_expression = new BoxedCast (					delegate_instance_expression, TypeManager.object_type);						method_group = mg;			eclass = ExprClass.Value;			return this;		}	}	//	// Created from the conversion code	//	public class ImplicitDelegateCreation : DelegateCreation {		ImplicitDelegateCreation (Type t, Location l)		{			type = t;			loc = l;		}		public override Expression DoResolve (EmitContext ec)		{			return this;		}		static public Expression Create (EmitContext ec, MethodGroupExpr mge,						 Type target_type, bool check_only, Location loc)		{			ImplicitDelegateCreation d = new ImplicitDelegateCreation (target_type, loc);			if (d.ResolveConstructorMethod (ec))				return d.ResolveMethodGroupExpr (ec, mge, check_only);			else				return null;		}	}	//	// A delegate-creation-expression, invoked from the `New' class 	//	public class NewDelegate : DelegateCreation {		public ArrayList Arguments;		//		// This constructor is invoked from the `New' expression		//		public NewDelegate (Type type, ArrayList Arguments, Location loc)		{			this.type = type;			this.Arguments = Arguments;			this.loc  = loc; 		}		public override Expression DoResolve (EmitContext ec)		{			if (Arguments == null || Arguments.Count != 1) {				Report.Error (149, loc,					      "Method name expected");				return null;			}			if (!ResolveConstructorMethod (ec))				return null;			Argument a = (Argument) Arguments [0];			if (!a.ResolveMethodGroup (ec, loc))				return null;						Expression e = a.Expr;			if (e is AnonymousMethod && RootContext.Version != LanguageVersion.ISO_1)				return ((AnonymousMethod) e).Compatible (ec, type, false);			MethodGroupExpr mg = e as MethodGroupExpr;			if (mg != null)				return ResolveMethodGroupExpr (ec, mg, false);			Type e_type = e.Type;			if (!TypeManager.IsDelegateType (e_type)) {				Report.Error (149, loc, "Method name expected");				return null;			}			method_group = Expression.MemberLookup (				ec, type, "Invoke", MemberTypes.Method,				Expression.AllBindingFlags, loc) as MethodGroupExpr;			if (method_group == null) {				Report.Error (-200, loc, "Internal error ! Could not find Invoke method!");				return null;			}			// This is what MS' compiler reports. We could always choose			// to be more verbose and actually give delegate-level specifics						if (!Delegate.VerifyDelegate (ec, type, e_type, loc)) {				Report.Error (29, loc, "Cannot implicitly convert type '" + e_type + "' " +					      "to type '" + type + "'");				return null;			}							delegate_instance_expression = e;			delegate_method = method_group.Methods [0];						eclass = ExprClass.Value;			return this;		}	}	public class DelegateInvocation : ExpressionStatement {		public Expression InstanceExpr;		public ArrayList  Arguments;		MethodBase method;				public DelegateInvocation (Expression instance_expr, ArrayList args, Location loc)		{			this.InstanceExpr = instance_expr;			this.Arguments = args;			this.loc = loc;		}		public override Expression DoResolve (EmitContext ec)		{			if (InstanceExpr is EventExpr) {								EventInfo ei = ((EventExpr) InstanceExpr).EventInfo;								Expression ml = MemberLookup (					ec, ec.ContainerType, ei.Name,					MemberTypes.Event, AllBindingFlags | BindingFlags.DeclaredOnly, loc);				if (ml == null) {				        //					// If this is the case, then the Event does not belong 					// to this Type and so, according to the spec					// cannot be accessed directly					//					// Note that target will not appear as an EventExpr					// in the case it is being referenced within the same type container;					// it will appear as a FieldExpr in that case.					//										Assign.error70 (ei, loc);					return null;				}			}									Type del_type = InstanceExpr.Type;			if (del_type == null)				return null;						if (Arguments != null){				foreach (Argument a in Arguments){					if (!a.Resolve (ec, loc))						return null;				}			}						if (!Delegate.VerifyApplicability (ec, del_type, Arguments, loc))				return null;			Expression lookup = Expression.MemberLookup (ec, del_type, "Invoke", loc);			if (!(lookup is MethodGroupExpr)) {				Report.Error (-100, loc, "Internal error: could not find Invoke method!");				return null;			}						method = ((MethodGroupExpr) lookup).Methods [0];			type = ((MethodInfo) method).ReturnType;			eclass = ExprClass.Value;						return this;		}		public override void Emit (EmitContext ec)		{			//			// Invocation on delegates call the virtual Invoke member			// so we are always `instance' calls			//			Invocation.EmitCall (ec, false, false, InstanceExpr, method, Arguments, loc);		}		public override void EmitStatement (EmitContext ec)		{			Emit (ec);			// 			// Pop the return value if there is one			//			if (method is MethodInfo){				if (((MethodInfo) method).ReturnType != TypeManager.void_type)					ec.ig.Emit (OpCodes.Pop);			}		}	}}

⌨️ 快捷键说明

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