// // Returns the MethodBase for "Invoke" from a delegate type, this is used // to extract the signature of a delegate. // public static MethodInfo GetInvokeMethod(CompilerContext ctx, Type container_type, Type delegate_type) { Type dt = delegate_type; Type[] g_args = null; if (TypeManager.IsGenericType(delegate_type)) { g_args = TypeManager.GetTypeArguments(delegate_type); delegate_type = TypeManager.DropGenericTypeArguments(delegate_type); } Delegate d = TypeManager.LookupDelegate(delegate_type); MethodInfo invoke; if (d != null) { #if GMCS_SOURCE if (g_args != null) { invoke = TypeBuilder.GetMethod(dt, d.InvokeBuilder); #if MS_COMPATIBLE ParametersCompiled p = (ParametersCompiled)d.Parameters.InflateTypes(g_args, g_args); TypeManager.RegisterMethod(invoke, p); #endif return(invoke); } #endif return(d.InvokeBuilder); } Expression ml = Expression.MemberLookup(ctx, container_type, null, dt, "Invoke", Location.Null); MethodGroupExpr mg = ml as MethodGroupExpr; if (mg == null) { ctx.Report.Error(-100, Location.Null, "Internal error: could not find Invoke method!"); // FIXME: null will cause a crash later return(null); } invoke = (MethodInfo)mg.Methods[0]; #if MS_COMPATIBLE if (g_args != null) { AParametersCollection p = TypeManager.GetParameterData(invoke); p = p.InflateTypes(g_args, g_args); TypeManager.RegisterMethod(invoke, p); return(invoke); } #endif return(invoke); }
// <summary> // Verifies whether the invocation arguments are compatible with the // delegate's target method // </summary> public static bool VerifyApplicability(EmitContext ec, Type delegate_type, ArrayList args, Location loc) { int arg_count; if (args == null) { arg_count = 0; } else { arg_count = args.Count; } Expression ml = Expression.MemberLookup( ec.ContainerType, 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 = GetInvokeMethod(ec.ContainerType, delegate_type); AParametersCollection pd = TypeManager.GetParameterData(mb); int pd_count = pd.Count; bool params_method = pd.HasParams; bool is_params_applicable = false; bool is_applicable = me.IsApplicable(ec, args, arg_count, ref mb, ref is_params_applicable) == 0; 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.ToString()); return(false); } return(me.VerifyArgumentsCompat( ec, ref args, arg_count, mb, is_params_applicable || (!is_applicable && params_method), false, loc)); }
public static ConstructorInfo GetConstructor(Type container_type, Type delegate_type) { Type dt = delegate_type; #if GMCS_SOURCE Type[] g_args = null; if (delegate_type.IsGenericType) { g_args = delegate_type.GetGenericArguments(); delegate_type = delegate_type.GetGenericTypeDefinition(); } #endif Delegate d = TypeManager.LookupDelegate(delegate_type); if (d != null) { #if GMCS_SOURCE if (g_args != null) { return(TypeBuilder.GetConstructor(dt, d.ConstructorBuilder)); } #endif return(d.ConstructorBuilder); } Expression ml = Expression.MemberLookup(container_type, null, dt, ConstructorInfo.ConstructorName, MemberTypes.Constructor, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, Location.Null); MethodGroupExpr mg = ml as MethodGroupExpr; if (mg == null) { Report.Error(-100, Location.Null, "Internal error: could not find delegate constructor!"); // FIXME: null will cause a crash later return(null); } return((ConstructorInfo)mg.Methods[0]); }