/// <summary> /// C# allows this kind of scenarios: /// interface I { void M (); } /// class X { public void M (); } /// class Y : X, I { } /// /// For that case, we create an explicit implementation function /// I.M in Y. /// </summary> void DefineProxy(Type iface, MethodInfo base_method, MethodInfo iface_method, AParametersCollection param) { // TODO: Handle nested iface names string proxy_name = SimpleName.RemoveGenericArity(iface.FullName) + "." + iface_method.Name; MethodBuilder proxy = container.TypeBuilder.DefineMethod( proxy_name, MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis, base_method.ReturnType, param.GetEmitTypes()); Type[] gargs = TypeManager.GetGenericArguments(iface_method); if (gargs.Length > 0) { string[] gnames = new string[gargs.Length]; for (int i = 0; i < gargs.Length; ++i) { gnames[i] = gargs[i].Name; } #if GMCS_SOURCE proxy.DefineGenericParameters(gnames); #else throw new NotSupportedException(); #endif } for (int i = 0; i < param.Count; i++) { string name = param.FixedParameters [i].Name; ParameterAttributes attr = ParametersCompiled.GetParameterAttribute(param.FixedParameters [i].ModFlags); proxy.DefineParameter(i + 1, attr, name); } int top = param.Count; ILGenerator ig = proxy.GetILGenerator(); for (int i = 0; i <= top; i++) { ParameterReference.EmitLdArg(ig, i); } ig.Emit(OpCodes.Call, base_method); ig.Emit(OpCodes.Ret); container.TypeBuilder.DefineMethodOverride(proxy, iface_method); }
/// <summary> /// C# allows this kind of scenarios: /// interface I { void M (); } /// class X { public void M (); } /// class Y : X, I { } /// /// For that case, we create an explicit implementation function /// I.M in Y. /// </summary> void DefineProxy (Type iface, MethodInfo base_method, MethodInfo iface_method, AParametersCollection param) { // TODO: Handle nested iface names string proxy_name = SimpleName.RemoveGenericArity (iface.FullName) + "." + iface_method.Name; MethodBuilder proxy = container.TypeBuilder.DefineMethod ( proxy_name, MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.CheckAccessOnOverride | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis, base_method.ReturnType, param.GetEmitTypes ()); Type[] gargs = TypeManager.GetGenericArguments (iface_method); if (gargs.Length > 0) { string[] gnames = new string[gargs.Length]; for (int i = 0; i < gargs.Length; ++i) gnames[i] = gargs[i].Name; #if GMCS_SOURCE proxy.DefineGenericParameters (gnames); #else throw new NotSupportedException (); #endif } for (int i = 0; i < param.Count; i++) { string name = param.FixedParameters [i].Name; ParameterAttributes attr = ParametersCompiled.GetParameterAttribute (param.FixedParameters [i].ModFlags); proxy.DefineParameter (i + 1, attr, name); } int top = param.Count; ILGenerator ig = proxy.GetILGenerator (); for (int i = 0; i <= top; i++) ParameterReference.EmitLdArg (ig, i); ig.Emit (OpCodes.Call, base_method); ig.Emit (OpCodes.Ret); container.TypeBuilder.DefineMethodOverride (proxy, iface_method); }