~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// delegate.cs: Delegate Handler
3
 
//
4
 
// Authors:
5
 
//     Ravi Pratap (ravi@ximian.com)
6
 
//     Miguel de Icaza (miguel@ximian.com)
7
 
//     Marek Safar (marek.safar@gmail.com)
8
 
//
9
 
// Dual licensed under the terms of the MIT X11 or GNU GPL
10
 
//
11
 
// Copyright 2001 Ximian, Inc (http://www.ximian.com)
12
 
// Copyright 2003-2009 Novell, Inc (http://www.novell.com)
13
 
// Copyright 2011 Xamarin Inc
14
 
//
15
 
 
16
 
using System;
17
 
 
18
 
#if STATIC
19
 
using IKVM.Reflection;
20
 
using IKVM.Reflection.Emit;
21
 
#else
22
 
using System.Reflection;
23
 
using System.Reflection.Emit;
24
 
#endif
25
 
 
26
 
namespace Mono.CSharp {
27
 
 
28
 
        //
29
 
        // Delegate container implementation
30
 
        //
31
 
        public class Delegate : TypeDefinition, IParametersMember
32
 
        {
33
 
                public FullNamedExpression ReturnType;
34
 
                readonly ParametersCompiled parameters;
35
 
 
36
 
                Constructor Constructor;
37
 
                Method InvokeBuilder;
38
 
                Method BeginInvokeBuilder;
39
 
                Method EndInvokeBuilder;
40
 
 
41
 
                static readonly string[] attribute_targets = new string [] { "type", "return" };
42
 
 
43
 
                public static readonly string InvokeMethodName = "Invoke";
44
 
                
45
 
                Expression instance_expr;
46
 
                ReturnParameter return_attributes;
47
 
 
48
 
                const Modifiers MethodModifiers = Modifiers.PUBLIC | Modifiers.VIRTUAL;
49
 
 
50
 
                const Modifiers AllowedModifiers =
51
 
                        Modifiers.NEW |
52
 
                        Modifiers.PUBLIC |
53
 
                        Modifiers.PROTECTED |
54
 
                        Modifiers.INTERNAL |
55
 
                        Modifiers.UNSAFE |
56
 
                        Modifiers.PRIVATE;
57
 
 
58
 
                public Delegate (TypeContainer parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, ParametersCompiled param_list,
59
 
                                 Attributes attrs)
60
 
                        : base (parent, name, attrs, MemberKind.Delegate)
61
 
 
62
 
                {
63
 
                        this.ReturnType = type;
64
 
                        ModFlags        = ModifiersExtensions.Check (AllowedModifiers, mod_flags,
65
 
                                                           IsTopLevel ? Modifiers.INTERNAL :
66
 
                                                           Modifiers.PRIVATE, name.Location, Report);
67
 
                        parameters      = param_list;
68
 
                        spec = new TypeSpec (Kind, null, this, null, ModFlags | Modifiers.SEALED);
69
 
                }
70
 
 
71
 
                #region Properties
72
 
                public TypeSpec MemberType {
73
 
                        get {
74
 
                                return ReturnType.Type;
75
 
                        }
76
 
                }
77
 
 
78
 
                public AParametersCollection Parameters {
79
 
                        get {
80
 
                                return parameters;
81
 
                        }
82
 
                }
83
 
 
84
 
                public FullNamedExpression TypExpression {
85
 
                        get {
86
 
                                return ReturnType;
87
 
                        }
88
 
                }
89
 
 
90
 
                #endregion
91
 
 
92
 
                public override void Accept (StructuralVisitor visitor)
93
 
                {
94
 
                        visitor.Visit (this);
95
 
                }
96
 
 
97
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
98
 
                {
99
 
                        if (a.Target == AttributeTargets.ReturnValue) {
100
 
                                if (return_attributes == null)
101
 
                                        return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location);
102
 
 
103
 
                                return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
104
 
                                return;
105
 
                        }
106
 
 
107
 
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
108
 
                }
109
 
 
110
 
                public override AttributeTargets AttributeTargets {
111
 
                        get {
112
 
                                return AttributeTargets.Delegate;
113
 
                        }
114
 
                }
115
 
 
116
 
                protected override bool DoDefineMembers ()
117
 
                {
118
 
                        var builtin_types = Compiler.BuiltinTypes;
119
 
 
120
 
                        var ctor_parameters = ParametersCompiled.CreateFullyResolved (
121
 
                                new [] {
122
 
                                        new Parameter (new TypeExpression (builtin_types.Object, Location), "object", Parameter.Modifier.NONE, null, Location),
123
 
                                        new Parameter (new TypeExpression (builtin_types.IntPtr, Location), "method", Parameter.Modifier.NONE, null, Location)
124
 
                                },
125
 
                                new [] {
126
 
                                        builtin_types.Object,
127
 
                                        builtin_types.IntPtr
128
 
                                }
129
 
                        );
130
 
 
131
 
                        Constructor = new Constructor (this, Constructor.ConstructorName,
132
 
                                Modifiers.PUBLIC, null, ctor_parameters, Location);
133
 
                        Constructor.Define ();
134
 
 
135
 
                        //
136
 
                        // Here the various methods like Invoke, BeginInvoke etc are defined
137
 
                        //
138
 
                        // First, call the `out of band' special method for
139
 
                        // defining recursively any types we need:
140
 
                        //
141
 
                        var p = parameters;
142
 
 
143
 
                        if (!p.Resolve (this))
144
 
                                return false;
145
 
 
146
 
                        //
147
 
                        // Invoke method
148
 
                        //
149
 
 
150
 
                        // Check accessibility
151
 
                        foreach (var partype in p.Types) {
152
 
                                if (!IsAccessibleAs (partype)) {
153
 
                                        Report.SymbolRelatedToPreviousError (partype);
154
 
                                        Report.Error (59, Location,
155
 
                                                "Inconsistent accessibility: parameter type `{0}' is less accessible than delegate `{1}'",
156
 
                                                TypeManager.CSharpName (partype), GetSignatureForError ());
157
 
                                }
158
 
                        }
159
 
 
160
 
                        var ret_type = ReturnType.ResolveAsType (this);
161
 
                        if (ret_type == null)
162
 
                                return false;
163
 
 
164
 
                        //
165
 
                        // We don't have to check any others because they are all
166
 
                        // guaranteed to be accessible - they are standard types.
167
 
                        //
168
 
                        if (!IsAccessibleAs (ret_type)) {
169
 
                                Report.SymbolRelatedToPreviousError (ret_type);
170
 
                                Report.Error (58, Location,
171
 
                                                  "Inconsistent accessibility: return type `" +
172
 
                                                  TypeManager.CSharpName (ret_type) + "' is less " +
173
 
                                                  "accessible than delegate `" + GetSignatureForError () + "'");
174
 
                                return false;
175
 
                        }
176
 
 
177
 
                        CheckProtectedModifier ();
178
 
 
179
 
                        if (Compiler.Settings.StdLib && ret_type.IsSpecialRuntimeType) {
180
 
                                Method.Error1599 (Location, ret_type, Report);
181
 
                                return false;
182
 
                        }
183
 
 
184
 
                        TypeManager.CheckTypeVariance (ret_type, Variance.Covariant, this);
185
 
 
186
 
                        var resolved_rt = new TypeExpression (ret_type, Location);
187
 
                        InvokeBuilder = new Method (this, resolved_rt, MethodModifiers, new MemberName (InvokeMethodName), p, null);
188
 
                        InvokeBuilder.Define ();
189
 
 
190
 
                        //
191
 
                        // Don't emit async method for compiler generated delegates (e.g. dynamic site containers)
192
 
                        //
193
 
                        if (!IsCompilerGenerated) {
194
 
                                DefineAsyncMethods (Parameters.CallingConvention, resolved_rt);
195
 
                        }
196
 
 
197
 
                        return true;
198
 
                }
199
 
 
200
 
                void DefineAsyncMethods (CallingConventions cc, TypeExpression returnType)
201
 
                {
202
 
                        var iasync_result = Module.PredefinedTypes.IAsyncResult;
203
 
                        var async_callback = Module.PredefinedTypes.AsyncCallback;
204
 
 
205
 
                        //
206
 
                        // It's ok when async types don't exist, the delegate will have Invoke method only
207
 
                        //
208
 
                        if (!iasync_result.Define () || !async_callback.Define ())
209
 
                                return;
210
 
 
211
 
                        //
212
 
                        // BeginInvoke
213
 
                        //
214
 
                        ParametersCompiled async_parameters;
215
 
                        if (Parameters.Count == 0) {
216
 
                                async_parameters = ParametersCompiled.EmptyReadOnlyParameters;
217
 
                        } else {
218
 
                                var compiled = new Parameter[Parameters.Count];
219
 
                                for (int i = 0; i < compiled.Length; ++i) {
220
 
                                        var p = parameters[i];
221
 
                                        compiled[i] = new Parameter (new TypeExpression (parameters.Types[i], Location),
222
 
                                                p.Name,
223
 
                                                p.ModFlags & Parameter.Modifier.RefOutMask,
224
 
                                                p.OptAttributes == null ? null : p.OptAttributes.Clone (), Location);
225
 
                                }
226
 
 
227
 
                                async_parameters = new ParametersCompiled (compiled);
228
 
                        }
229
 
 
230
 
                        async_parameters = ParametersCompiled.MergeGenerated (Compiler, async_parameters, false,
231
 
                                new Parameter[] {
232
 
                                        new Parameter (new TypeExpression (async_callback.TypeSpec, Location), "callback", Parameter.Modifier.NONE, null, Location),
233
 
                                        new Parameter (new TypeExpression (Compiler.BuiltinTypes.Object, Location), "object", Parameter.Modifier.NONE, null, Location)
234
 
                                },
235
 
                                new [] {
236
 
                                        async_callback.TypeSpec,
237
 
                                        Compiler.BuiltinTypes.Object
238
 
                                }
239
 
                        );
240
 
 
241
 
                        BeginInvokeBuilder = new Method (this,
242
 
                                new TypeExpression (iasync_result.TypeSpec, Location), MethodModifiers,
243
 
                                new MemberName ("BeginInvoke"), async_parameters, null);
244
 
                        BeginInvokeBuilder.Define ();
245
 
 
246
 
                        //
247
 
                        // EndInvoke is a bit more interesting, all the parameters labeled as
248
 
                        // out or ref have to be duplicated here.
249
 
                        //
250
 
 
251
 
                        //
252
 
                        // Define parameters, and count out/ref parameters
253
 
                        //
254
 
                        ParametersCompiled end_parameters;
255
 
                        int out_params = 0;
256
 
 
257
 
                        foreach (Parameter p in Parameters.FixedParameters) {
258
 
                                if ((p.ModFlags & Parameter.Modifier.RefOutMask) != 0)
259
 
                                        ++out_params;
260
 
                        }
261
 
 
262
 
                        if (out_params > 0) {
263
 
                                Parameter[] end_params = new Parameter[out_params];
264
 
 
265
 
                                int param = 0;
266
 
                                for (int i = 0; i < Parameters.FixedParameters.Length; ++i) {
267
 
                                        Parameter p = parameters [i];
268
 
                                        if ((p.ModFlags & Parameter.Modifier.RefOutMask) == 0)
269
 
                                                continue;
270
 
 
271
 
                                        end_params [param++] = new Parameter (new TypeExpression (p.Type, Location),
272
 
                                                p.Name,
273
 
                                                p.ModFlags & Parameter.Modifier.RefOutMask,
274
 
                                                p.OptAttributes == null ? null : p.OptAttributes.Clone (), Location);
275
 
                                }
276
 
 
277
 
                                end_parameters = new ParametersCompiled (end_params);
278
 
                        } else {
279
 
                                end_parameters = ParametersCompiled.EmptyReadOnlyParameters;
280
 
                        }
281
 
 
282
 
                        end_parameters = ParametersCompiled.MergeGenerated (Compiler, end_parameters, false,
283
 
                                new Parameter (
284
 
                                        new TypeExpression (iasync_result.TypeSpec, Location),
285
 
                                        "result", Parameter.Modifier.NONE, null, Location),
286
 
                                iasync_result.TypeSpec);
287
 
 
288
 
                        //
289
 
                        // Create method, define parameters, register parameters with type system
290
 
                        //
291
 
                        EndInvokeBuilder = new Method (this, returnType, MethodModifiers, new MemberName ("EndInvoke"), end_parameters, null);
292
 
                        EndInvokeBuilder.Define ();
293
 
                }
294
 
 
295
 
                public override void PrepareEmit ()
296
 
                {
297
 
                        if (!Parameters.IsEmpty) {
298
 
                                parameters.ResolveDefaultValues (this);
299
 
                        }
300
 
                }
301
 
 
302
 
                public override void Emit ()
303
 
                {
304
 
                        base.Emit ();
305
 
 
306
 
                        if (ReturnType.Type != null) {
307
 
                                if (ReturnType.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
308
 
                                        return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location);
309
 
                                        Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
310
 
                                } else if (ReturnType.Type.HasDynamicElement) {
311
 
                                        return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location);
312
 
                                        Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType.Type, Location);
313
 
                                }
314
 
 
315
 
                                ConstraintChecker.Check (this, ReturnType.Type, ReturnType.Location);
316
 
                        }
317
 
 
318
 
                        Constructor.ParameterInfo.ApplyAttributes (this, Constructor.ConstructorBuilder);
319
 
                        Constructor.ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
320
 
 
321
 
                        parameters.CheckConstraints (this);
322
 
                        parameters.ApplyAttributes (this, InvokeBuilder.MethodBuilder);
323
 
                        InvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
324
 
 
325
 
                        if (BeginInvokeBuilder != null) {
326
 
                                BeginInvokeBuilder.ParameterInfo.ApplyAttributes (this, BeginInvokeBuilder.MethodBuilder);
327
 
                                EndInvokeBuilder.ParameterInfo.ApplyAttributes (this, EndInvokeBuilder.MethodBuilder);
328
 
 
329
 
                                BeginInvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
330
 
                                EndInvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
331
 
                        }
332
 
                }
333
 
 
334
 
                protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
335
 
                {
336
 
                        base_type = Compiler.BuiltinTypes.MulticastDelegate;
337
 
                        base_class = null;
338
 
                        return null;
339
 
                }
340
 
 
341
 
                protected override TypeAttributes TypeAttr {
342
 
                        get {
343
 
                                return base.TypeAttr | TypeAttributes.Class | TypeAttributes.Sealed;
344
 
                        }
345
 
                }
346
 
 
347
 
                public override string[] ValidAttributeTargets {
348
 
                        get {
349
 
                                return attribute_targets;
350
 
                        }
351
 
                }
352
 
 
353
 
                //TODO: duplicate
354
 
                protected override bool VerifyClsCompliance ()
355
 
                {
356
 
                        if (!base.VerifyClsCompliance ()) {
357
 
                                return false;
358
 
                        }
359
 
 
360
 
                        parameters.VerifyClsCompliance (this);
361
 
 
362
 
                        if (!InvokeBuilder.MemberType.IsCLSCompliant ()) {
363
 
                                Report.Warning (3002, 1, Location, "Return type of `{0}' is not CLS-compliant",
364
 
                                        GetSignatureForError ());
365
 
                        }
366
 
                        return true;
367
 
                }
368
 
 
369
 
 
370
 
                public static MethodSpec GetConstructor (TypeSpec delType)
371
 
                {
372
 
                        var ctor = MemberCache.FindMember (delType, MemberFilter.Constructor (null), BindingRestriction.DeclaredOnly);
373
 
                        return (MethodSpec) ctor;
374
 
                }
375
 
 
376
 
                //
377
 
                // Returns the "Invoke" from a delegate type
378
 
                //
379
 
                public static MethodSpec GetInvokeMethod (TypeSpec delType)
380
 
                {
381
 
                        var invoke = MemberCache.FindMember (delType,
382
 
                                MemberFilter.Method (InvokeMethodName, 0, null, null),
383
 
                                BindingRestriction.DeclaredOnly);
384
 
 
385
 
                        return (MethodSpec) invoke;
386
 
                }
387
 
 
388
 
                public static AParametersCollection GetParameters (TypeSpec delType)
389
 
                {
390
 
                        var invoke_mb = GetInvokeMethod (delType);
391
 
                        return invoke_mb.Parameters;
392
 
                }
393
 
 
394
 
                //
395
 
                // 15.2 Delegate compatibility
396
 
                //
397
 
                public static bool IsTypeCovariant (ResolveContext rc, TypeSpec a, TypeSpec b)
398
 
                {
399
 
                        //
400
 
                        // For each value parameter (a parameter with no ref or out modifier), an 
401
 
                        // identity conversion or implicit reference conversion exists from the
402
 
                        // parameter type in D to the corresponding parameter type in M
403
 
                        //
404
 
                        if (a == b)
405
 
                                return true;
406
 
 
407
 
                        if (rc.Module.Compiler.Settings.Version == LanguageVersion.ISO_1)
408
 
                                return false;
409
 
 
410
 
                        if (a.IsGenericParameter && b.IsGenericParameter)
411
 
                                return a == b;
412
 
 
413
 
                        return Convert.ImplicitReferenceConversionExists (a, b);
414
 
                }
415
 
 
416
 
                public static string FullDelegateDesc (MethodSpec invoke_method)
417
 
                {
418
 
                        return TypeManager.GetFullNameSignature (invoke_method).Replace (".Invoke", "");
419
 
                }
420
 
                
421
 
                public Expression InstanceExpression {
422
 
                        get {
423
 
                                return instance_expr;
424
 
                        }
425
 
                        set {
426
 
                                instance_expr = value;
427
 
                        }
428
 
                }
429
 
        }
430
 
 
431
 
        //
432
 
        // Base class for `NewDelegate' and `ImplicitDelegateCreation'
433
 
        //
434
 
        public abstract class DelegateCreation : Expression, OverloadResolver.IErrorHandler
435
 
        {
436
 
                protected MethodSpec constructor_method;
437
 
                protected MethodGroupExpr method_group;
438
 
 
439
 
                public override bool ContainsEmitWithAwait ()
440
 
                {
441
 
                        return false;
442
 
                }
443
 
 
444
 
                public static Arguments CreateDelegateMethodArguments (AParametersCollection pd, TypeSpec[] types, Location loc)
445
 
                {
446
 
                        Arguments delegate_arguments = new Arguments (pd.Count);
447
 
                        for (int i = 0; i < pd.Count; ++i) {
448
 
                                Argument.AType atype_modifier;
449
 
                                switch (pd.FixedParameters [i].ModFlags) {
450
 
                                case Parameter.Modifier.REF:
451
 
                                        atype_modifier = Argument.AType.Ref;
452
 
                                        break;
453
 
                                case Parameter.Modifier.OUT:
454
 
                                        atype_modifier = Argument.AType.Out;
455
 
                                        break;
456
 
                                default:
457
 
                                        atype_modifier = 0;
458
 
                                        break;
459
 
                                }
460
 
 
461
 
                                delegate_arguments.Add (new Argument (new TypeExpression (types [i], loc), atype_modifier));
462
 
                        }
463
 
 
464
 
                        return delegate_arguments;
465
 
                }
466
 
 
467
 
                public override Expression CreateExpressionTree (ResolveContext ec)
468
 
                {
469
 
                        MemberAccess ma = new MemberAccess (new MemberAccess (new QualifiedAliasMember ("global", "System", loc), "Delegate", loc), "CreateDelegate", loc);
470
 
 
471
 
                        Arguments args = new Arguments (3);
472
 
                        args.Add (new Argument (new TypeOf (type, loc)));
473
 
 
474
 
                        if (method_group.InstanceExpression == null)
475
 
                                args.Add (new Argument (new NullLiteral (loc)));
476
 
                        else
477
 
                                args.Add (new Argument (method_group.InstanceExpression));
478
 
 
479
 
                        args.Add (new Argument (method_group.CreateExpressionTree (ec)));
480
 
                        Expression e = new Invocation (ma, args).Resolve (ec);
481
 
                        if (e == null)
482
 
                                return null;
483
 
 
484
 
                        e = Convert.ExplicitConversion (ec, e, type, loc);
485
 
                        if (e == null)
486
 
                                return null;
487
 
 
488
 
                        return e.CreateExpressionTree (ec);
489
 
                }
490
 
 
491
 
                protected override Expression DoResolve (ResolveContext ec)
492
 
                {
493
 
                        constructor_method = Delegate.GetConstructor (type);
494
 
 
495
 
                        var invoke_method = Delegate.GetInvokeMethod (type);
496
 
 
497
 
                        Arguments arguments = CreateDelegateMethodArguments (invoke_method.Parameters, invoke_method.Parameters.Types, loc);
498
 
                        method_group = method_group.OverloadResolve (ec, ref arguments, this, OverloadResolver.Restrictions.CovariantDelegate);
499
 
                        if (method_group == null)
500
 
                                return null;
501
 
 
502
 
                        var delegate_method = method_group.BestCandidate;
503
 
                        
504
 
                        if (delegate_method.DeclaringType.IsNullableType) {
505
 
                                ec.Report.Error (1728, loc, "Cannot create delegate from method `{0}' because it is a member of System.Nullable<T> type",
506
 
                                        delegate_method.GetSignatureForError ());
507
 
                                return null;
508
 
                        }               
509
 
                        
510
 
                        Invocation.IsSpecialMethodInvocation (ec, delegate_method, loc);
511
 
 
512
 
                        ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr;
513
 
                        if (emg != null) {
514
 
                                method_group.InstanceExpression = emg.ExtensionExpression;
515
 
                                TypeSpec e_type = emg.ExtensionExpression.Type;
516
 
                                if (TypeSpec.IsValueType (e_type)) {
517
 
                                        ec.Report.Error (1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates",
518
 
                                                delegate_method.GetSignatureForError (), TypeManager.CSharpName (e_type));
519
 
                                }
520
 
                        }
521
 
 
522
 
                        TypeSpec rt = delegate_method.ReturnType;
523
 
                        if (!Delegate.IsTypeCovariant (ec, rt, invoke_method.ReturnType)) {
524
 
                                Expression ret_expr = new TypeExpression (rt, loc);
525
 
                                Error_ConversionFailed (ec, delegate_method, ret_expr);
526
 
                        }
527
 
 
528
 
                        if (delegate_method.IsConditionallyExcluded (ec, loc)) {
529
 
                                ec.Report.SymbolRelatedToPreviousError (delegate_method);
530
 
                                MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator;
531
 
                                if (m != null && m.IsPartialDefinition) {
532
 
                                        ec.Report.Error (762, loc, "Cannot create delegate from partial method declaration `{0}'",
533
 
                                                delegate_method.GetSignatureForError ());
534
 
                                } else {
535
 
                                        ec.Report.Error (1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute",
536
 
                                                TypeManager.CSharpSignature (delegate_method));
537
 
                                }
538
 
                        }
539
 
 
540
 
                        var expr = method_group.InstanceExpression;
541
 
                        if (expr != null && (expr.Type.IsGenericParameter || !TypeSpec.IsReferenceType (expr.Type)))
542
 
                                method_group.InstanceExpression = new BoxedCast (expr, ec.BuiltinTypes.Object);
543
 
 
544
 
                        eclass = ExprClass.Value;
545
 
                        return this;
546
 
                }
547
 
                
548
 
                public override void Emit (EmitContext ec)
549
 
                {
550
 
                        if (method_group.InstanceExpression == null)
551
 
                                ec.EmitNull ();
552
 
                        else
553
 
                                method_group.InstanceExpression.Emit (ec);
554
 
 
555
 
                        var delegate_method = method_group.BestCandidate;
556
 
 
557
 
                        // Any delegate must be sealed
558
 
                        if (!delegate_method.DeclaringType.IsDelegate && delegate_method.IsVirtual && !method_group.IsBase) {
559
 
                                ec.Emit (OpCodes.Dup);
560
 
                                ec.Emit (OpCodes.Ldvirtftn, delegate_method);
561
 
                        } else {
562
 
                                ec.Emit (OpCodes.Ldftn, delegate_method);
563
 
                        }
564
 
 
565
 
                        ec.Emit (OpCodes.Newobj, constructor_method);
566
 
                }
567
 
 
568
 
                void Error_ConversionFailed (ResolveContext ec, MethodSpec method, Expression return_type)
569
 
                {
570
 
                        var invoke_method = Delegate.GetInvokeMethod (type);
571
 
                        string member_name = method_group.InstanceExpression != null ?
572
 
                                Delegate.FullDelegateDesc (method) :
573
 
                                TypeManager.GetFullNameSignature (method);
574
 
 
575
 
                        ec.Report.SymbolRelatedToPreviousError (type);
576
 
                        ec.Report.SymbolRelatedToPreviousError (method);
577
 
                        if (ec.Module.Compiler.Settings.Version == LanguageVersion.ISO_1) {
578
 
                                ec.Report.Error (410, loc, "A method or delegate `{0} {1}' parameters and return type must be same as delegate `{2} {3}' parameters and return type",
579
 
                                        TypeManager.CSharpName (method.ReturnType), member_name,
580
 
                                        TypeManager.CSharpName (invoke_method.ReturnType), Delegate.FullDelegateDesc (invoke_method));
581
 
                                return;
582
 
                        }
583
 
 
584
 
                        if (return_type == null) {
585
 
                                ec.Report.Error (123, loc, "A method or delegate `{0}' parameters do not match delegate `{1}' parameters",
586
 
                                        member_name, Delegate.FullDelegateDesc (invoke_method));
587
 
                                return;
588
 
                        }
589
 
 
590
 
                        ec.Report.Error (407, loc, "A method or delegate `{0} {1}' return type does not match delegate `{2} {3}' return type",
591
 
                                return_type.GetSignatureForError (), member_name,
592
 
                                TypeManager.CSharpName (invoke_method.ReturnType), Delegate.FullDelegateDesc (invoke_method));
593
 
                }
594
 
 
595
 
                public static bool ImplicitStandardConversionExists (ResolveContext ec, MethodGroupExpr mg, TypeSpec target_type)
596
 
                {
597
 
//                      if (target_type == TypeManager.delegate_type || target_type == TypeManager.multicast_delegate_type)
598
 
//                              return false;
599
 
 
600
 
                        var invoke = Delegate.GetInvokeMethod (target_type);
601
 
 
602
 
                        Arguments arguments = CreateDelegateMethodArguments (invoke.Parameters, invoke.Parameters.Types, mg.Location);
603
 
                        return mg.OverloadResolve (ec, ref arguments, null, OverloadResolver.Restrictions.CovariantDelegate | OverloadResolver.Restrictions.ProbingOnly) != null;
604
 
                }
605
 
 
606
 
                #region IErrorHandler Members
607
 
 
608
 
                bool OverloadResolver.IErrorHandler.AmbiguousCandidates (ResolveContext ec, MemberSpec best, MemberSpec ambiguous)
609
 
                {
610
 
                        return false;
611
 
                }
612
 
 
613
 
                bool OverloadResolver.IErrorHandler.ArgumentMismatch (ResolveContext rc, MemberSpec best, Argument arg, int index)
614
 
                {
615
 
                        Error_ConversionFailed (rc, best as MethodSpec, null);
616
 
                        return true;
617
 
                }
618
 
 
619
 
                bool OverloadResolver.IErrorHandler.NoArgumentMatch (ResolveContext rc, MemberSpec best)
620
 
                {
621
 
                        Error_ConversionFailed (rc, best as MethodSpec, null);
622
 
                        return true;
623
 
                }
624
 
 
625
 
                bool OverloadResolver.IErrorHandler.TypeInferenceFailed (ResolveContext rc, MemberSpec best)
626
 
                {
627
 
                        return false;
628
 
                }
629
 
 
630
 
                #endregion
631
 
        }
632
 
 
633
 
        //
634
 
        // Created from the conversion code
635
 
        //
636
 
        public class ImplicitDelegateCreation : DelegateCreation
637
 
        {
638
 
                ImplicitDelegateCreation (TypeSpec t, MethodGroupExpr mg, Location l)
639
 
                {
640
 
                        type = t;
641
 
                        this.method_group = mg;
642
 
                        loc = l;
643
 
                }
644
 
 
645
 
                static public Expression Create (ResolveContext ec, MethodGroupExpr mge,
646
 
                                                 TypeSpec target_type, Location loc)
647
 
                {
648
 
                        ImplicitDelegateCreation d = new ImplicitDelegateCreation (target_type, mge, loc);
649
 
                        return d.DoResolve (ec);
650
 
                }
651
 
        }
652
 
        
653
 
        //
654
 
        // A delegate-creation-expression, invoked from the `New' class 
655
 
        //
656
 
        public class NewDelegate : DelegateCreation
657
 
        {
658
 
                public Arguments Arguments;
659
 
 
660
 
                //
661
 
                // This constructor is invoked from the `New' expression
662
 
                //
663
 
                public NewDelegate (TypeSpec type, Arguments Arguments, Location loc)
664
 
                {
665
 
                        this.type = type;
666
 
                        this.Arguments = Arguments;
667
 
                        this.loc  = loc; 
668
 
                }
669
 
 
670
 
                protected override Expression DoResolve (ResolveContext ec)
671
 
                {
672
 
                        if (Arguments == null || Arguments.Count != 1) {
673
 
                                ec.Report.Error (149, loc, "Method name expected");
674
 
                                return null;
675
 
                        }
676
 
 
677
 
                        Argument a = Arguments [0];
678
 
                        if (!a.ResolveMethodGroup (ec))
679
 
                                return null;
680
 
 
681
 
                        Expression e = a.Expr;
682
 
 
683
 
                        AnonymousMethodExpression ame = e as AnonymousMethodExpression;
684
 
                        if (ame != null && ec.Module.Compiler.Settings.Version != LanguageVersion.ISO_1) {
685
 
                                e = ame.Compatible (ec, type);
686
 
                                if (e == null)
687
 
                                        return null;
688
 
 
689
 
                                return e.Resolve (ec);
690
 
                        }
691
 
 
692
 
                        method_group = e as MethodGroupExpr;
693
 
                        if (method_group == null) {
694
 
                                if (e.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
695
 
                                        e = Convert.ImplicitConversionRequired (ec, e, type, loc);
696
 
                                } else if (!e.Type.IsDelegate) {
697
 
                                        e.Error_UnexpectedKind (ec, ResolveFlags.MethodGroup | ResolveFlags.Type, loc);
698
 
                                        return null;
699
 
                                }
700
 
 
701
 
                                //
702
 
                                // An argument is not a method but another delegate
703
 
                                //
704
 
                                method_group = new MethodGroupExpr (Delegate.GetInvokeMethod (e.Type), e.Type, loc);
705
 
                                method_group.InstanceExpression = e;
706
 
                        }
707
 
 
708
 
                        return base.DoResolve (ec);
709
 
                }
710
 
        }
711
 
 
712
 
        //
713
 
        // Invocation converted to delegate Invoke call
714
 
        //
715
 
        class DelegateInvocation : ExpressionStatement
716
 
        {
717
 
                readonly Expression InstanceExpr;
718
 
                Arguments arguments;
719
 
                MethodSpec method;
720
 
                
721
 
                public DelegateInvocation (Expression instance_expr, Arguments args, Location loc)
722
 
                {
723
 
                        this.InstanceExpr = instance_expr;
724
 
                        this.arguments = args;
725
 
                        this.loc = loc;
726
 
                }
727
 
 
728
 
                public override bool ContainsEmitWithAwait ()
729
 
                {
730
 
                        return InstanceExpr.ContainsEmitWithAwait () || (arguments != null && arguments.ContainsEmitWithAwait ());
731
 
                }
732
 
                
733
 
                public override Expression CreateExpressionTree (ResolveContext ec)
734
 
                {
735
 
                        Arguments args = Arguments.CreateForExpressionTree (ec, this.arguments,
736
 
                                InstanceExpr.CreateExpressionTree (ec));
737
 
 
738
 
                        return CreateExpressionFactoryCall (ec, "Invoke", args);
739
 
                }
740
 
 
741
 
                protected override Expression DoResolve (ResolveContext ec)
742
 
                {               
743
 
                        TypeSpec del_type = InstanceExpr.Type;
744
 
                        if (del_type == null)
745
 
                                return null;
746
 
 
747
 
                        //
748
 
                        // Do only core overload resolution the rest of the checks has been
749
 
                        // done on primary expression
750
 
                        //
751
 
                        method = Delegate.GetInvokeMethod (del_type);
752
 
                        var res = new OverloadResolver (new MemberSpec[] { method }, OverloadResolver.Restrictions.DelegateInvoke, loc);
753
 
                        var valid = res.ResolveMember<MethodSpec> (ec, ref arguments);
754
 
                        if (valid == null && !res.BestCandidateIsDynamic)
755
 
                                return null;
756
 
 
757
 
                        type = method.ReturnType;
758
 
                        eclass = ExprClass.Value;
759
 
                        return this;
760
 
                }
761
 
 
762
 
                public override void Emit (EmitContext ec)
763
 
                {
764
 
                        //
765
 
                        // Invocation on delegates call the virtual Invoke member
766
 
                        // so we are always `instance' calls
767
 
                        //
768
 
                        var call = new CallEmitter ();
769
 
                        call.InstanceExpression = InstanceExpr;
770
 
                        call.EmitPredefined (ec, method, arguments);
771
 
                }
772
 
 
773
 
                public override void EmitStatement (EmitContext ec)
774
 
                {
775
 
                        Emit (ec);
776
 
                        // 
777
 
                        // Pop the return value if there is one
778
 
                        //
779
 
                        if (type.Kind != MemberKind.Void)
780
 
                                ec.Emit (OpCodes.Pop);
781
 
                }
782
 
 
783
 
                public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
784
 
                {
785
 
                        return Invocation.MakeExpression (ctx, InstanceExpr, method, arguments);
786
 
                }
787
 
        }
788
 
}