X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fdelegate.cs;h=80eb7e265f1395bec67ce6ba117212b0474a80b5;hb=34866ac4c20c781f10c40fe6f6fe0c39733fd946;hp=2073041afa252248e1f856efef43e9b91afaa1d4;hpb=c7a4778737bd531addc20cf694dd14972204c644;p=mono.git diff --git a/mcs/mcs/delegate.cs b/mcs/mcs/delegate.cs index 2073041afa2..80eb7e265f1 100644 --- a/mcs/mcs/delegate.cs +++ b/mcs/mcs/delegate.cs @@ -16,9 +16,11 @@ using System; #if STATIC +using SecurityType = System.Collections.Generic.List; using IKVM.Reflection; using IKVM.Reflection.Emit; #else +using SecurityType = System.Collections.Generic.Dictionary; using System.Reflection; using System.Reflection.Emit; #endif @@ -45,6 +47,8 @@ namespace Mono.CSharp { Expression instance_expr; ReturnParameter return_attributes; + SecurityType declarative_security; + const Modifiers MethodModifiers = Modifiers.PUBLIC | Modifiers.VIRTUAL; const Modifiers AllowedModifiers = @@ -97,13 +101,16 @@ namespace Mono.CSharp { public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (a.Target == AttributeTargets.ReturnValue) { - if (return_attributes == null) - return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location); - + CreateReturnBuilder (); return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa); return; } + if (a.IsValidSecurityAttribute ()) { + a.ExtractSecurityPermissionSet (ctor, ref declarative_security); + return; + } + base.ApplyAttributeBuilder (a, ctor, cdata, pa); } @@ -113,6 +120,11 @@ namespace Mono.CSharp { } } + ReturnParameter CreateReturnBuilder () + { + return return_attributes ?? (return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location)); + } + protected override bool DoDefineMembers () { var builtin_types = Compiler.BuiltinTypes; @@ -299,6 +311,8 @@ namespace Mono.CSharp { InvokeBuilder.PrepareEmit (); if (BeginInvokeBuilder != null) { + BeginInvokeBuilder.TypeExpression = null; + EndInvokeBuilder.TypeExpression = null; BeginInvokeBuilder.PrepareEmit (); EndInvokeBuilder.PrepareEmit (); } @@ -308,13 +322,26 @@ namespace Mono.CSharp { { base.Emit (); - if (ReturnType.Type != null) { - if (ReturnType.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { - return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location); - Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder); - } else if (ReturnType.Type.HasDynamicElement) { - return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location); - Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType.Type, Location); + if (declarative_security != null) { + foreach (var de in declarative_security) { +#if STATIC + TypeBuilder.__AddDeclarativeSecurity (de); +#else + TypeBuilder.AddDeclarativeSecurity (de.Key, de.Value); +#endif + } + } + + var rtype = ReturnType.Type; + if (rtype != null) { + if (rtype.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { + Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder); + } else if (rtype.HasDynamicElement) { + Module.PredefinedAttributes.Dynamic.EmitAttribute (CreateReturnBuilder ().Builder, rtype, Location); + } + + if (rtype.HasNamedTupleElement) { + Module.PredefinedAttributes.TupleElementNames.EmitAttribute (CreateReturnBuilder ().Builder, rtype, Location); } ConstraintChecker.Check (this, ReturnType.Type, ReturnType.Location); @@ -438,7 +465,6 @@ namespace Mono.CSharp { // public abstract class DelegateCreation : Expression, OverloadResolver.IErrorHandler { - bool conditional_access_receiver; protected MethodSpec constructor_method; protected MethodGroupExpr method_group; @@ -479,9 +505,7 @@ namespace Mono.CSharp { public override Expression CreateExpressionTree (ResolveContext ec) { - MemberAccess ma = new MemberAccess (new MemberAccess (new QualifiedAliasMember ("global", "System", loc), "Delegate", loc), "CreateDelegate", loc); - - Arguments args = new Arguments (3); + Arguments args = new Arguments (2); args.Add (new Argument (new TypeOf (type, loc))); if (method_group.InstanceExpression == null) @@ -489,7 +513,21 @@ namespace Mono.CSharp { else args.Add (new Argument (method_group.InstanceExpression)); - args.Add (new Argument (method_group.CreateExpressionTree (ec))); + Expression ma; + var create_v45 = ec.Module.PredefinedMembers.MethodInfoCreateDelegate.Get (); + if (create_v45 != null) { + // + // .NET 4.5 has better API but it produces different instance than Delegate::CreateDelegate + // and because csc uses this enhancement we have to as well to be fully compatible + // + var mg = MethodGroupExpr.CreatePredefined (create_v45, create_v45.DeclaringType, loc); + mg.InstanceExpression = method_group.CreateExpressionTree (ec); + ma = mg; + } else { + ma = new MemberAccess (new MemberAccess (new QualifiedAliasMember ("global", "System", loc), "Delegate", loc), "CreateDelegate", loc); + args.Add (new Argument (method_group.CreateExpressionTree (ec))); + } + Expression e = new Invocation (ma, args).Resolve (ec); if (e == null) return null; @@ -501,25 +539,25 @@ namespace Mono.CSharp { return e.CreateExpressionTree (ec); } + void ResolveConditionalAccessReceiver (ResolveContext rc) + { + // LAMESPEC: Not sure why this is explicitly disallowed with very odd error message + if (!rc.HasSet (ResolveContext.Options.DontSetConditionalAccessReceiver) && method_group.HasConditionalAccess ()) { + Error_OperatorCannotBeApplied (rc, loc, "?", method_group.Type); + } + } + protected override Expression DoResolve (ResolveContext ec) { constructor_method = Delegate.GetConstructor (type); var invoke_method = Delegate.GetInvokeMethod (type); - if (!ec.HasSet (ResolveContext.Options.ConditionalAccessReceiver)) { - if (method_group.HasConditionalAccess ()) { - conditional_access_receiver = true; - ec.Set (ResolveContext.Options.ConditionalAccessReceiver); - } - } + ResolveConditionalAccessReceiver (ec); Arguments arguments = CreateDelegateMethodArguments (ec, invoke_method.Parameters, invoke_method.Parameters.Types, loc); method_group = method_group.OverloadResolve (ec, ref arguments, this, OverloadResolver.Restrictions.CovariantDelegate); - if (conditional_access_receiver) - ec.With (ResolveContext.Options.ConditionalAccessReceiver, false); - if (method_group == null) return null; @@ -549,8 +587,7 @@ namespace Mono.CSharp { rt = ec.BuiltinTypes.Object; if (!Delegate.IsTypeCovariant (ec, rt, invoke_method.ReturnType)) { - Expression ret_expr = new TypeExpression (delegate_method.ReturnType, loc); - Error_ConversionFailed (ec, delegate_method, ret_expr); + Error_ConversionFailed (ec, delegate_method, delegate_method.ReturnType); } if (method_group.IsConditionallyExcluded) { @@ -575,9 +612,6 @@ namespace Mono.CSharp { public override void Emit (EmitContext ec) { - if (conditional_access_receiver) - ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ()); - if (method_group.InstanceExpression == null) { ec.EmitNull (); } else { @@ -596,21 +630,15 @@ namespace Mono.CSharp { } ec.Emit (OpCodes.Newobj, constructor_method); - - if (conditional_access_receiver) - ec.CloseConditionalAccess (null); } public override void FlowAnalysis (FlowAnalysisContext fc) { base.FlowAnalysis (fc); method_group.FlowAnalysis (fc); - - if (conditional_access_receiver) - fc.ConditionalAccessEnd (); } - void Error_ConversionFailed (ResolveContext ec, MethodSpec method, Expression return_type) + void Error_ConversionFailed (ResolveContext ec, MethodSpec method, TypeSpec return_type) { var invoke_method = Delegate.GetInvokeMethod (type); string member_name = method_group.InstanceExpression != null ? @@ -632,6 +660,12 @@ namespace Mono.CSharp { return; } + if (invoke_method.ReturnType.Kind == MemberKind.ByRef) { + ec.Report.Error (8189, loc, "By reference return delegate does not match `{0}' return type", + Delegate.FullDelegateDesc (invoke_method)); + return; + } + ec.Report.Error (407, loc, "A method or delegate `{0} {1}' return type does not match delegate `{2} {3}' return type", return_type.GetSignatureForError (), member_name, invoke_method.ReturnType.GetSignatureForError (), Delegate.FullDelegateDesc (invoke_method));