Пример #1
0
        /// <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);
        }
Пример #2
0
		/// <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);
		}