static TypeBuilder DefineDelegate () { TypeBuilder typeBuilder = module.DefineType( "MyDelegate", TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed, typeof (object) ); args = typeBuilder.DefineGenericParameters ("TIn", "TOut"); delegate_ctor = typeBuilder.DefineConstructor( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName, CallingConventions.Standard, new Type[] { typeof(Object), typeof (IntPtr) } ); delegate_ctor.SetImplementationFlags( MethodImplAttributes.Runtime | MethodImplAttributes.Managed ); invoke_mb = typeBuilder.DefineMethod( "Invoke", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, args [1], new Type[] { args [0] } ); invoke_mb.SetImplementationFlags( MethodImplAttributes.Runtime | MethodImplAttributes.Managed ); MethodBuilder mb = typeBuilder.DefineMethod( "BeginInvoke", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, typeof (IAsyncResult), new Type[] { args [0], typeof (AsyncCallback), typeof (object) } ); mb.SetImplementationFlags( MethodImplAttributes.Runtime | MethodImplAttributes.Managed ); mb = typeBuilder.DefineMethod( "EndInvoke", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, args [1], new Type[] { typeof (IAsyncResult) } ); mb.SetImplementationFlags( MethodImplAttributes.Runtime | MethodImplAttributes.Managed ); return typeBuilder; }
public override bool Define () { if (IsGeneric) { foreach (TypeParameter type_param in TypeParameters) { if (!type_param.Resolve (this)) return false; } foreach (TypeParameter type_param in TypeParameters) { if (!type_param.DefineType (this)) return false; } } member_cache = new MemberCache (TypeManager.multicast_delegate_type, this); // FIXME: POSSIBLY make this static, as it is always constant // Type [] const_arg_types = new Type [2]; const_arg_types [0] = TypeManager.object_type; const_arg_types [1] = TypeManager.intptr_type; const MethodAttributes ctor_mattr = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Public; ConstructorBuilder = TypeBuilder.DefineConstructor (ctor_mattr, CallingConventions.Standard, const_arg_types); ConstructorBuilder.DefineParameter (1, ParameterAttributes.None, "object"); ConstructorBuilder.DefineParameter (2, ParameterAttributes.None, "method"); // // HACK because System.Reflection.Emit is lame // IParameterData [] fixed_pars = new IParameterData [] { new ParameterData ("object", Parameter.Modifier.NONE), new ParameterData ("method", Parameter.Modifier.NONE) }; AParametersCollection const_parameters = new ParametersImported ( fixed_pars, new Type[] { TypeManager.object_type, TypeManager.intptr_type }); TypeManager.RegisterMethod (ConstructorBuilder, const_parameters); member_cache.AddMember (ConstructorBuilder, this); ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); // // Here the various methods like Invoke, BeginInvoke etc are defined // // First, call the `out of band' special method for // defining recursively any types we need: if (!Parameters.Resolve (this)) return false; // // Invoke method // // Check accessibility foreach (Type partype in Parameters.Types){ if (!IsAccessibleAs (partype)) { Report.SymbolRelatedToPreviousError (partype); Report.Error (59, Location, "Inconsistent accessibility: parameter type `{0}' is less accessible than delegate `{1}'", TypeManager.CSharpName (partype), GetSignatureForError ()); return false; } } ReturnType = ReturnType.ResolveAsTypeTerminal (this, false); if (ReturnType == null) return false; ret_type = ReturnType.Type; if (!IsAccessibleAs (ret_type)) { Report.SymbolRelatedToPreviousError (ret_type); Report.Error (58, Location, "Inconsistent accessibility: return type `" + TypeManager.CSharpName (ret_type) + "' is less " + "accessible than delegate `" + GetSignatureForError () + "'"); return false; } CheckProtectedModifier (); if (RootContext.StdLib && TypeManager.IsSpecialType (ret_type)) { Method.Error1599 (Location, ret_type, Report); return false; } TypeManager.CheckTypeVariance (ret_type, Variance.Covariant, this); // // We don't have to check any others because they are all // guaranteed to be accessible - they are standard types. // CallingConventions cc = Parameters.CallingConvention; InvokeBuilder = TypeBuilder.DefineMethod ("Invoke", mattr, cc, ret_type, Parameters.GetEmitTypes ()); InvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); TypeManager.RegisterMethod (InvokeBuilder, Parameters); member_cache.AddMember (InvokeBuilder, this); // // Don't emit async method for compiler generated delegates (e.g. dynamic site containers) // if (TypeManager.iasyncresult_type != null && TypeManager.asynccallback_type != null && !IsCompilerGenerated) { DefineAsyncMethods (cc); } return true; }
// // Creates the ConstructorBuilder // public override bool Define () { if (ConstructorBuilder != null) return true; MethodAttributes ca = (MethodAttributes.RTSpecialName | MethodAttributes.SpecialName); if ((ModFlags & Modifiers.STATIC) != 0) { ca |= MethodAttributes.Static | MethodAttributes.Private; } else { ca |= MethodAttributes.HideBySig; if ((ModFlags & Modifiers.PUBLIC) != 0) ca |= MethodAttributes.Public; else if ((ModFlags & Modifiers.PROTECTED) != 0){ if ((ModFlags & Modifiers.INTERNAL) != 0) ca |= MethodAttributes.FamORAssem; else ca |= MethodAttributes.Family; } else if ((ModFlags & Modifiers.INTERNAL) != 0) ca |= MethodAttributes.Assembly; else ca |= MethodAttributes.Private; } if (!CheckAbstractAndExtern (block != null)) return false; // Check if arguments were correct. if (!CheckBase ()) return false; ConstructorBuilder = Parent.TypeBuilder.DefineConstructor ( ca, CallingConventions, Parameters.GetEmitTypes ()); if (Parent.PartialContainer.IsComImport) { if (!IsDefault ()) { Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor", Parent.GetSignatureForError ()); } ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall); } Parent.MemberCache.AddMember (ConstructorBuilder, this); TypeManager.AddMethod (ConstructorBuilder, this); // It's here only to report an error if (block != null && block.IsIterator) { member_type = TypeManager.void_type; Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler); } return true; }