/* * Copyright (c) 2003-2008 The University of Wroclaw. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the University may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE UNIVERSITY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using Nemerle.Collections; using Nemerle.Compiler.Parsetree; using Nemerle.Compiler; using Nemerle.Assertions; namespace Nemerle.Compiler { // stateless utility module internal module Delegates { /** * Generates a delegate class */ internal GenerateDelegateClass ([NotNull] globenv : GlobalEnv, parent_type : TypeBuilder, attrs : Modifiers, header : Fun_header) : TypeBuilder { Util.locate (header.Location, { when ((attrs.mods %& ~NemerleAttributes.AccessModifiers) != NemerleAttributes.None) Message.Error (header.Location, "delegates are only allowed to have access specifiers as attributes"); attrs.mods |= NemerleAttributes.Sealed; // create the BeginInvoke parameters def begin_invoke_parms = create_begin_invoke_parms (header.parms); // build the delegate's return type and method body for the type inference engine def ret_type = header.ret_type; def invoke_body = <[ Nemerle.Extensions.DefaultValue ($ret_type) ]>; def delegate_name = header.name.GetName (); def tparms = header.typarms; // add the delegate class as a nested type in the delegate's parent type or in global env def pt_decl = <[ decl: ..$attrs class $(delegate_name : name) [..$(tparms.tyvars)] : System.MulticastDelegate where ..$(tparms.constraints) { public virtual BeginInvoke (..$begin_invoke_parms) : System.IAsyncResult { null } public virtual EndInvoke (_ : System.IAsyncResult) : $ret_type $invoke_body public virtual Invoke (..$(header.parms)) : $ret_type $invoke_body public this (_ : object, _ : System.IntPtr) { base (typeof (System.Object), "") } } ]>; def td = match (parent_type) { | null => globenv.Define (pt_decl) | parent => parent.DefineNestedType (pt_decl); }; td.MarkAsDelegate (); td.Compile (); td }) } create_begin_invoke_parms (existing : list [Fun_parm]) : list [Fun_parm] { | [] => [<[ parameter: _ : System.AsyncCallback ]>, <[ parameter: _ : object ]>] | x :: xs => def hasnt_params (x) { !(x is <[ System.ParamArrayAttribute ]>) } if (!List.ForAll (x.modifiers.custom_attrs, hasnt_params)) Fun_parm (x.Location, x.name, x.ty, Modifiers (x.modifiers.mods, x.modifiers.custom_attrs.Filter (hasnt_params))) :: create_begin_invoke_parms(xs); else x :: create_begin_invoke_parms(xs); } } }