[runtime] Prioritize loading a profiler library from the installation dir over standa...
[mono.git] / mcs / mcs / delegate.cs
index b083cfd46d23d36cc51f84433941f566fe6ac941..2073041afa252248e1f856efef43e9b91afaa1d4 100644 (file)
@@ -294,9 +294,8 @@ namespace Mono.CSharp {
 
                public override void PrepareEmit ()
                {
-                       if (!Parameters.IsEmpty) {
-                               parameters.ResolveDefaultValues (this);
-                       }
+                       if ((caching_flags & Flags.CloseTypeCreated) != 0)
+                               return;
 
                        InvokeBuilder.PrepareEmit ();
                        if (BeginInvokeBuilder != null) {
@@ -439,6 +438,7 @@ namespace Mono.CSharp {
        //
        public abstract class DelegateCreation : Expression, OverloadResolver.IErrorHandler
        {
+               bool conditional_access_receiver;
                protected MethodSpec constructor_method;
                protected MethodGroupExpr method_group;
 
@@ -507,8 +507,19 @@ namespace Mono.CSharp {
 
                        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);
+                               }
+                       }
+
                        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;
 
@@ -564,14 +575,14 @@ namespace Mono.CSharp {
                
                public override void Emit (EmitContext ec)
                {
-                       InstanceEmitter ie;
+                       if (conditional_access_receiver)
+                               ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ());
+
                        if (method_group.InstanceExpression == null) {
-                               ie = new InstanceEmitter ();
                                ec.EmitNull ();
                        } else {
-                               ie = new InstanceEmitter (method_group.InstanceExpression, false);
-                               ie.NullShortCircuit = method_group.NullShortCircuit;
-                               ie.Emit (ec);
+                               var ie = new InstanceEmitter (method_group.InstanceExpression, false);
+                               ie.Emit (ec, method_group.ConditionalAccess);
                        }
 
                        var delegate_method = method_group.BestCandidate;
@@ -586,14 +597,17 @@ namespace Mono.CSharp {
 
                        ec.Emit (OpCodes.Newobj, constructor_method);
 
-                       if (method_group.NullShortCircuit) {
-                               ie.EmitResultLift (ec, type, false);
-                       }
+                       if (conditional_access_receiver)
+                               ec.CloseConditionalAccess (null);
                }
 
-               public override void FlowAnalysis (FlowAnalysisContext fc) {
+               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)
@@ -631,7 +645,8 @@ namespace Mono.CSharp {
                        var invoke = Delegate.GetInvokeMethod (target_type);
 
                        Arguments arguments = CreateDelegateMethodArguments (ec, invoke.Parameters, invoke.Parameters.Types, mg.Location);
-                       return mg.OverloadResolve (ec, ref arguments, null, OverloadResolver.Restrictions.CovariantDelegate | OverloadResolver.Restrictions.ProbingOnly) != null;
+                       mg = mg.OverloadResolve (ec, ref arguments, null, OverloadResolver.Restrictions.CovariantDelegate | OverloadResolver.Restrictions.ProbingOnly);
+                       return mg != null && Delegate.IsTypeCovariant (ec, mg.BestCandidateReturnType, invoke.ReturnType);
                }
 
                #region IErrorHandler Members
@@ -839,13 +854,15 @@ namespace Mono.CSharp {
        class DelegateInvocation : ExpressionStatement
        {
                readonly Expression InstanceExpr;
+               readonly bool conditionalAccessReceiver;
                Arguments arguments;
                MethodSpec method;
                
-               public DelegateInvocation (Expression instance_expr, Arguments args, Location loc)
+               public DelegateInvocation (Expression instance_expr, Arguments args, bool conditionalAccessReceiver, Location loc)
                {
                        this.InstanceExpr = instance_expr;
                        this.arguments = args;
+                       this.conditionalAccessReceiver = conditionalAccessReceiver;
                        this.loc = loc;
                }
 
@@ -886,12 +903,19 @@ namespace Mono.CSharp {
                                return null;
 
                        type = method.ReturnType;
+                       if (conditionalAccessReceiver)
+                               type = LiftMemberType (ec, type);
+
                        eclass = ExprClass.Value;
                        return this;
                }
 
                public override void Emit (EmitContext ec)
                {
+                       if (conditionalAccessReceiver) {
+                               ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ());
+                       }
+
                        //
                        // Invocation on delegates call the virtual Invoke member
                        // so we are always `instance' calls
@@ -899,13 +923,25 @@ namespace Mono.CSharp {
                        var call = new CallEmitter ();
                        call.InstanceExpression = InstanceExpr;
                        call.Emit (ec, method, arguments, loc);
+
+                       if (conditionalAccessReceiver)
+                               ec.CloseConditionalAccess (type.IsNullableType && type !=  method.ReturnType ? type : null);
                }
 
                public override void EmitStatement (EmitContext ec)
                {
+                       if (conditionalAccessReceiver) {
+                               ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ()) {
+                                       Statement = true
+                               };
+                       }
+
                        var call = new CallEmitter ();
                        call.InstanceExpression = InstanceExpr;
                        call.EmitStatement (ec, method, arguments, loc);
+
+                       if (conditionalAccessReceiver)
+                               ec.CloseConditionalAccess (null);
                }
 
                public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)