X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fdelegate.cs;h=80eb7e265f1395bec67ce6ba117212b0474a80b5;hb=34866ac4c20c781f10c40fe6f6fe0c39733fd946;hp=4ccd836a4764354366f99fabcaa4e3c103276251;hpb=4d5ffcb9adab30ecb5a95acc83d66f4eebb23e35;p=mono.git diff --git a/mcs/mcs/delegate.cs b/mcs/mcs/delegate.cs index 4ccd836a476..80eb7e265f1 100644 --- a/mcs/mcs/delegate.cs +++ b/mcs/mcs/delegate.cs @@ -101,9 +101,7 @@ 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; } @@ -122,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; @@ -329,13 +332,16 @@ namespace Mono.CSharp { } } - 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); + 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); @@ -459,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; @@ -500,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) @@ -510,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; @@ -522,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; @@ -570,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) { @@ -596,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 { @@ -617,23 +630,15 @@ namespace Mono.CSharp { } ec.Emit (OpCodes.Newobj, constructor_method); - - if (conditional_access_receiver) - ec.CloseConditionalAccess (null); } public override void FlowAnalysis (FlowAnalysisContext fc) { - var da = conditional_access_receiver ? fc.BranchDefiniteAssignment () : null; - base.FlowAnalysis (fc); method_group.FlowAnalysis (fc); - - if (conditional_access_receiver) - fc.DefiniteAssignment = da; } - 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 ? @@ -655,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));