InvokeBuilder.PrepareEmit ();
if (BeginInvokeBuilder != null) {
+ BeginInvokeBuilder.TypeExpression = null;
+ EndInvokeBuilder.TypeExpression = null;
BeginInvokeBuilder.PrepareEmit ();
EndInvokeBuilder.PrepareEmit ();
}
//
public abstract class DelegateCreation : Expression, OverloadResolver.IErrorHandler
{
- bool conditional_access_receiver;
protected MethodSpec constructor_method;
protected MethodGroupExpr method_group;
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)
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;
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;
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 {
}
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)