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;
}
}
}
+ ReturnParameter CreateReturnBuilder ()
+ {
+ return return_attributes ?? (return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location));
+ }
+
protected override bool DoDefineMembers ()
{
var builtin_types = Compiler.BuiltinTypes;
}
}
- 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);
//
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;
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) {
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)
{
- 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 ?
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));