/// <summary> /// Create a <see cref="Call"/>. /// </summary> public Call(MethodDecl methodDecl, params Expression[] arguments) : this(methodDecl.CreateRef(), arguments) { }
/// <summary> /// Create (or re-create) the compiler-generated invoke methods and constructor. /// This method should be called whenever the parameters of the delegate are set or changed. /// </summary> public void GenerateMethods() { // Remove any existing methods before generating them - since the Body is compiler-generated just // to hold these methods, we can just re-create it. Body = new Block { IsGenerated = true }; // The Invoke method has the same parameters as the delegate, and the same return type MethodDecl invokeDecl = new MethodDecl("Invoke", (Expression)_returnType.Clone(), Modifiers.Public) { IsGenerated = true }; invokeDecl.Parameters = (_parameters != null ? ChildListHelpers.Clone(_parameters, invokeDecl) : null); Add(invokeDecl); // The BeginInvoke method has the same parameters as the delegate, plus 2 extra ones, and a return type of IAsyncResult MethodDecl beginInvokeDecl = new MethodDecl("BeginInvoke", (TypeRef)TypeRef.IAsyncResultRef.Clone(), Modifiers.Public) { IsGenerated = true }; ChildList <ParameterDecl> parameters = (_parameters != null ? ChildListHelpers.Clone(_parameters, beginInvokeDecl) : new ChildList <ParameterDecl>(beginInvokeDecl)); parameters.Add(new ParameterDecl("callback", (TypeRef)TypeRef.AsyncCallbackRef.Clone())); parameters.Add(new ParameterDecl("object", (TypeRef)TypeRef.ObjectRef.Clone())); beginInvokeDecl.Parameters = parameters; Add(beginInvokeDecl); // The EndInvoke method has any 'ref' or 'out' parameters of the delegate, plus 1 extra one, and the same return type MethodDecl endInvokeDecl = new MethodDecl("EndInvoke", (Expression)_returnType.Clone(), Modifiers.Public) { IsGenerated = true }; parameters = new ChildList <ParameterDecl>(endInvokeDecl); if (_parameters != null) { foreach (ParameterDecl parameterDecl in _parameters) { if (parameterDecl.IsRef || parameterDecl.IsOut) { parameters.Add((ParameterDecl)parameterDecl.Clone()); } } } parameters.Add(new ParameterDecl("result", (TypeRef)TypeRef.IAsyncResultRef.Clone())); endInvokeDecl.Parameters = parameters; Add(endInvokeDecl); // Delegates have a constructor that takes an object and an IntPtr that is used internally by the compiler during // code generation. We have to create a dummy constructor that will allow a MethodRef to be passed to it, in order // to make the C# syntax work when resolving. TypeRef delegateTypeRef = CreateRef(); ConstructorDecl constructor = new ConstructorDecl(new[] { new ParameterDecl(DelegateConstructorParameterName, delegateTypeRef) }) { IsGenerated = true }; Add(constructor); }