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

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.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
// method.cs: Method based declarations
 
3
//
 
4
// Authors: Miguel de Icaza (miguel@gnu.org)
 
5
//          Martin Baulig (martin@ximian.com)
 
6
//          Marek Safar (marek.safar@gmail.com)
 
7
//
 
8
// Dual licensed under the terms of the MIT X11 or GNU GPL
 
9
//
 
10
// Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
 
11
// Copyright 2004-2008 Novell, Inc
 
12
// Copyright 2011 Xamarin Inc.
 
13
//
 
14
 
 
15
using System;
 
16
using System.Collections.Generic;
 
17
using System.Security;
 
18
using System.Security.Permissions;
 
19
using System.Text;
 
20
using System.Linq;
 
21
using Mono.CompilerServices.SymbolWriter;
 
22
using System.Runtime.CompilerServices;
 
23
 
 
24
#if NET_2_1
 
25
using XmlElement = System.Object;
 
26
#else
 
27
using System.Xml;
 
28
#endif
 
29
 
 
30
#if STATIC
 
31
using MetaType = IKVM.Reflection.Type;
 
32
using SecurityType = System.Collections.Generic.List<IKVM.Reflection.Emit.CustomAttributeBuilder>;
 
33
using IKVM.Reflection;
 
34
using IKVM.Reflection.Emit;
 
35
#else
 
36
using MetaType = System.Type;
 
37
using SecurityType = System.Collections.Generic.Dictionary<System.Security.Permissions.SecurityAction, System.Security.PermissionSet>;
 
38
using System.Reflection;
 
39
using System.Reflection.Emit;
 
40
#endif
 
41
 
 
42
namespace Mono.CSharp {
 
43
 
 
44
        public abstract class MethodCore : InterfaceMemberBase, IParametersMember
 
45
        {
 
46
                protected ParametersCompiled parameters;
 
47
                protected ToplevelBlock block;
 
48
                protected MethodSpec spec;
 
49
 
 
50
                public MethodCore (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod,
 
51
                        MemberName name, Attributes attrs, ParametersCompiled parameters)
 
52
                        : base (parent, type, mod, allowed_mod, name, attrs)
 
53
                {
 
54
                        this.parameters = parameters;
 
55
                }
 
56
 
 
57
                public override Variance ExpectedMemberTypeVariance {
 
58
                        get {
 
59
                                return Variance.Covariant;
 
60
                        }
 
61
                }
 
62
 
 
63
                //
 
64
                //  Returns the System.Type array for the parameters of this method
 
65
                //
 
66
                public TypeSpec [] ParameterTypes {
 
67
                        get {
 
68
                                return parameters.Types;
 
69
                        }
 
70
                }
 
71
 
 
72
                public ParametersCompiled ParameterInfo {
 
73
                        get {
 
74
                                return parameters;
 
75
                        }
 
76
                }
 
77
 
 
78
                AParametersCollection IParametersMember.Parameters {
 
79
                        get { return parameters; }
 
80
                }
 
81
                
 
82
                public ToplevelBlock Block {
 
83
                        get {
 
84
                                return block;
 
85
                        }
 
86
 
 
87
                        set {
 
88
                                block = value;
 
89
                        }
 
90
                }
 
91
 
 
92
                public CallingConventions CallingConventions {
 
93
                        get {
 
94
                                CallingConventions cc = parameters.CallingConvention;
 
95
                                if (!IsInterface)
 
96
                                        if ((ModFlags & Modifiers.STATIC) == 0)
 
97
                                                cc |= CallingConventions.HasThis;
 
98
 
 
99
                                // FIXME: How is `ExplicitThis' used in C#?
 
100
                        
 
101
                                return cc;
 
102
                        }
 
103
                }
 
104
 
 
105
                protected override bool CheckOverrideAgainstBase (MemberSpec base_member)
 
106
                {
 
107
                        bool res = base.CheckOverrideAgainstBase (base_member);
 
108
 
 
109
                        //
 
110
                        // Check that the permissions are not being changed
 
111
                        //
 
112
                        if (!CheckAccessModifiers (this, base_member)) {
 
113
                                Error_CannotChangeAccessModifiers (this, base_member);
 
114
                                res = false;
 
115
                        }
 
116
 
 
117
                        return res;
 
118
                }
 
119
 
 
120
                protected override bool CheckBase ()
 
121
                {
 
122
                        // Check whether arguments were correct.
 
123
                        if (!DefineParameters (parameters))
 
124
                                return false;
 
125
 
 
126
                        return base.CheckBase ();
 
127
                }
 
128
 
 
129
                //
 
130
                //   Represents header string for documentation comment.
 
131
                //
 
132
                public override string DocCommentHeader 
 
133
                {
 
134
                        get { return "M:"; }
 
135
                }
 
136
 
 
137
                public override void Emit ()
 
138
                {
 
139
                        if ((ModFlags & Modifiers.COMPILER_GENERATED) == 0) {
 
140
                                parameters.CheckConstraints (this);
 
141
                        }
 
142
 
 
143
                        base.Emit ();
 
144
                }
 
145
 
 
146
                public override bool EnableOverloadChecks (MemberCore overload)
 
147
                {
 
148
                        if (overload is MethodCore) {
 
149
                                caching_flags |= Flags.MethodOverloadsExist;
 
150
                                return true;
 
151
                        }
 
152
 
 
153
                        if (overload is AbstractPropertyEventMethod)
 
154
                                return true;
 
155
 
 
156
                        return base.EnableOverloadChecks (overload);
 
157
                }
 
158
 
 
159
                public override string GetSignatureForDocumentation ()
 
160
                {
 
161
                        string s = base.GetSignatureForDocumentation ();
 
162
                        if (MemberName.Arity > 0)
 
163
                                s += "``" + MemberName.Arity.ToString ();
 
164
 
 
165
                        return s + parameters.GetSignatureForDocumentation ();
 
166
                }
 
167
 
 
168
                public MethodSpec Spec {
 
169
                        get { return spec; }
 
170
                }
 
171
 
 
172
                protected override bool VerifyClsCompliance ()
 
173
                {
 
174
                        if (!base.VerifyClsCompliance ())
 
175
                                return false;
 
176
 
 
177
                        if (parameters.HasArglist) {
 
178
                                Report.Warning (3000, 1, Location, "Methods with variable arguments are not CLS-compliant");
 
179
                        }
 
180
 
 
181
                        if (member_type != null && !member_type.IsCLSCompliant ()) {
 
182
                                Report.Warning (3002, 1, Location, "Return type of `{0}' is not CLS-compliant",
 
183
                                        GetSignatureForError ());
 
184
                        }
 
185
 
 
186
                        parameters.VerifyClsCompliance (this);
 
187
                        return true;
 
188
                }
 
189
        }
 
190
 
 
191
        public interface IGenericMethodDefinition : IMemberDefinition
 
192
        {
 
193
                TypeParameterSpec[] TypeParameters { get; }
 
194
                int TypeParametersCount { get; }
 
195
 
 
196
//              MethodInfo MakeGenericMethod (TypeSpec[] targs);
 
197
        }
 
198
 
 
199
        public sealed class MethodSpec : MemberSpec, IParametersMember
 
200
        {
 
201
                MethodBase metaInfo, inflatedMetaInfo;
 
202
                AParametersCollection parameters;
 
203
                TypeSpec returnType;
 
204
 
 
205
                TypeSpec[] targs;
 
206
                TypeParameterSpec[] constraints;
 
207
 
 
208
                public MethodSpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition details, TypeSpec returnType,
 
209
                        MethodBase info, AParametersCollection parameters, Modifiers modifiers)
 
210
                        : base (kind, declaringType, details, modifiers)
 
211
                {
 
212
                        this.metaInfo = info;
 
213
                        this.parameters = parameters;
 
214
                        this.returnType = returnType;
 
215
                }
 
216
 
 
217
                #region Properties
 
218
 
 
219
                public override int Arity {
 
220
                        get {
 
221
                                return IsGeneric ? GenericDefinition.TypeParametersCount : 0;
 
222
                        }
 
223
                }
 
224
 
 
225
                public TypeParameterSpec[] Constraints {
 
226
                        get {
 
227
                                if (constraints == null && IsGeneric)
 
228
                                        constraints = GenericDefinition.TypeParameters;
 
229
 
 
230
                                return constraints;
 
231
                        }
 
232
                }
 
233
 
 
234
                public bool IsConstructor {
 
235
                        get {
 
236
                                return Kind == MemberKind.Constructor;
 
237
                        }
 
238
                }
 
239
 
 
240
                public IGenericMethodDefinition GenericDefinition {
 
241
                        get {
 
242
                                return (IGenericMethodDefinition) definition;
 
243
                        }
 
244
                }
 
245
 
 
246
                public bool IsAsync {
 
247
                        get {
 
248
                                return (Modifiers & Modifiers.ASYNC) != 0;
 
249
                        }
 
250
                }
 
251
 
 
252
                public bool IsExtensionMethod {
 
253
                        get {
 
254
                                return IsStatic && parameters.HasExtensionMethodType;
 
255
                        }
 
256
                }
 
257
 
 
258
                public bool IsSealed {
 
259
                        get {
 
260
                                return (Modifiers & Modifiers.SEALED) != 0;
 
261
                        }
 
262
                }
 
263
 
 
264
                // When is virtual or abstract
 
265
                public bool IsVirtual {
 
266
                        get {
 
267
                                return (Modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) != 0;
 
268
                        }
 
269
                }
 
270
 
 
271
                public bool IsReservedMethod {
 
272
                        get {
 
273
                                return Kind == MemberKind.Operator || IsAccessor;
 
274
                        }
 
275
                }
 
276
 
 
277
                TypeSpec IInterfaceMemberSpec.MemberType {
 
278
                        get {
 
279
                                return returnType;
 
280
                        }
 
281
                }
 
282
 
 
283
                public AParametersCollection Parameters {
 
284
                        get { 
 
285
                                return parameters;
 
286
                        }
 
287
                }
 
288
 
 
289
                public TypeSpec ReturnType {
 
290
                        get {
 
291
                                return returnType;
 
292
                        }
 
293
                }
 
294
 
 
295
                public TypeSpec[] TypeArguments {
 
296
                        get {
 
297
                                return targs;
 
298
                        }
 
299
                }
 
300
 
 
301
                #endregion
 
302
 
 
303
                public MethodSpec GetGenericMethodDefinition ()
 
304
                {
 
305
                        if (!IsGeneric && !DeclaringType.IsGeneric)
 
306
                                return this;
 
307
 
 
308
                        return MemberCache.GetMember (declaringType, this);
 
309
                }
 
310
 
 
311
                public MethodBase GetMetaInfo ()
 
312
                {
 
313
                        //
 
314
                        // inflatedMetaInfo is extra field needed for cases where we
 
315
                        // inflate method but another nested type can later inflate
 
316
                        // again (the cache would be build with inflated metaInfo) and
 
317
                        // TypeBuilder can work with method definitions only
 
318
                        //
 
319
                        if (inflatedMetaInfo == null) {
 
320
                                if ((state & StateFlags.PendingMetaInflate) != 0) {
 
321
                                        var dt_meta = DeclaringType.GetMetaInfo ();
 
322
 
 
323
                                        if (DeclaringType.IsTypeBuilder) {
 
324
                                                if (IsConstructor)
 
325
                                                        inflatedMetaInfo = TypeBuilder.GetConstructor (dt_meta, (ConstructorInfo) metaInfo);
 
326
                                                else
 
327
                                                        inflatedMetaInfo = TypeBuilder.GetMethod (dt_meta, (MethodInfo) metaInfo);
 
328
                                        } else {
 
329
#if STATIC
 
330
                                                // it should not be reached
 
331
                                                throw new NotImplementedException ();
 
332
#else
 
333
                                                inflatedMetaInfo = MethodInfo.GetMethodFromHandle (metaInfo.MethodHandle, dt_meta.TypeHandle);
 
334
#endif
 
335
                                        }
 
336
 
 
337
                                        state &= ~StateFlags.PendingMetaInflate;
 
338
                                } else {
 
339
                                        inflatedMetaInfo = metaInfo;
 
340
                                }
 
341
                        }
 
342
 
 
343
                        if ((state & StateFlags.PendingMakeMethod) != 0) {
 
344
                                var sre_targs = new MetaType[targs.Length];
 
345
                                for (int i = 0; i < sre_targs.Length; ++i)
 
346
                                        sre_targs[i] = targs[i].GetMetaInfo ();
 
347
 
 
348
                                inflatedMetaInfo = ((MethodInfo) inflatedMetaInfo).MakeGenericMethod (sre_targs);
 
349
                                state &= ~StateFlags.PendingMakeMethod;
 
350
                        }
 
351
 
 
352
                        return inflatedMetaInfo;
 
353
                }
 
354
 
 
355
                public override string GetSignatureForDocumentation ()
 
356
                {
 
357
                        string name;
 
358
                        switch (Kind) {
 
359
                        case MemberKind.Constructor:
 
360
                                name = "#ctor";
 
361
                                break;
 
362
                        case MemberKind.Method:
 
363
                                if (Arity > 0)
 
364
                                        name = Name + "``" + Arity.ToString ();
 
365
                                else
 
366
                                        name = Name;
 
367
 
 
368
                                break;
 
369
                        default:
 
370
                                name = Name;
 
371
                                break;
 
372
                        }
 
373
 
 
374
                        name = DeclaringType.GetSignatureForDocumentation () + "." + name + parameters.GetSignatureForDocumentation ();
 
375
                        if (Kind == MemberKind.Operator) {
 
376
                                var op = Operator.GetType (Name).Value;
 
377
                                if (op == Operator.OpType.Explicit || op == Operator.OpType.Implicit) {
 
378
                                        name += "~" + ReturnType.GetSignatureForDocumentation ();
 
379
                                }
 
380
                        }
 
381
 
 
382
                        return name;
 
383
                }
 
384
 
 
385
                public override string GetSignatureForError ()
 
386
                {
 
387
                        string name;
 
388
                        if (IsConstructor) {
 
389
                                name = DeclaringType.GetSignatureForError () + "." + DeclaringType.Name;
 
390
                        } else if (Kind == MemberKind.Operator) {
 
391
                                var op = Operator.GetType (Name).Value;
 
392
                                if (op == Operator.OpType.Implicit || op == Operator.OpType.Explicit) {
 
393
                                        name = DeclaringType.GetSignatureForError () + "." + Operator.GetName (op) + " operator " + returnType.GetSignatureForError ();
 
394
                                } else {
 
395
                                        name = DeclaringType.GetSignatureForError () + ".operator " + Operator.GetName (op);
 
396
                                }
 
397
                        } else if (IsAccessor) {
 
398
                                int split = Name.IndexOf ('_');
 
399
                                name = Name.Substring (split + 1);
 
400
                                var postfix = Name.Substring (0, split);
 
401
                                if (split == 3) {
 
402
                                        var pc = parameters.Count;
 
403
                                        if (pc > 0 && postfix == "get") {
 
404
                                                name = "this" + parameters.GetSignatureForError ("[", "]", pc);
 
405
                                        } else if (pc > 1 && postfix == "set") {
 
406
                                                name = "this" + parameters.GetSignatureForError ("[", "]", pc - 1);
 
407
                                        }
 
408
                                }
 
409
 
 
410
                                return DeclaringType.GetSignatureForError () + "." + name + "." + postfix;
 
411
                        } else {
 
412
                                name = base.GetSignatureForError ();
 
413
                                if (targs != null)
 
414
                                        name += "<" + TypeManager.CSharpName (targs) + ">";
 
415
                                else if (IsGeneric)
 
416
                                        name += "<" + TypeManager.CSharpName (GenericDefinition.TypeParameters) + ">";
 
417
                        }
 
418
 
 
419
                        return name + parameters.GetSignatureForError ();
 
420
                }
 
421
 
 
422
                public override MemberSpec InflateMember (TypeParameterInflator inflator)
 
423
                {
 
424
                        var ms = (MethodSpec) base.InflateMember (inflator);
 
425
                        ms.inflatedMetaInfo = null;
 
426
                        ms.returnType = inflator.Inflate (returnType);
 
427
                        ms.parameters = parameters.Inflate (inflator);
 
428
                        if (IsGeneric)
 
429
                                ms.constraints = TypeParameterSpec.InflateConstraints (inflator, Constraints);
 
430
 
 
431
                        return ms;
 
432
                }
 
433
 
 
434
                public MethodSpec MakeGenericMethod (IMemberContext context, params TypeSpec[] targs)
 
435
                {
 
436
                        if (targs == null)
 
437
                                throw new ArgumentNullException ();
 
438
// TODO MemberCache
 
439
//                      if (generic_intances != null && generic_intances.TryGetValue (targs, out ginstance))
 
440
//                              return ginstance;
 
441
 
 
442
                        //if (generic_intances == null)
 
443
                        //    generic_intances = new Dictionary<TypeSpec[], Method> (TypeSpecArrayComparer.Default);
 
444
 
 
445
                        var inflator = new TypeParameterInflator (context, DeclaringType, GenericDefinition.TypeParameters, targs);
 
446
 
 
447
                        var inflated = (MethodSpec) MemberwiseClone ();
 
448
                        inflated.declaringType = inflator.TypeInstance;
 
449
                        inflated.returnType = inflator.Inflate (returnType);
 
450
                        inflated.parameters = parameters.Inflate (inflator);
 
451
                        inflated.targs = targs;
 
452
                        inflated.constraints = TypeParameterSpec.InflateConstraints (inflator, constraints ?? GenericDefinition.TypeParameters);
 
453
                        inflated.state |= StateFlags.PendingMakeMethod;
 
454
 
 
455
                        //                      if (inflated.parent == null)
 
456
                        //                              inflated.parent = parent;
 
457
 
 
458
                        //generic_intances.Add (targs, inflated);
 
459
                        return inflated;
 
460
                }
 
461
 
 
462
                public MethodSpec Mutate (TypeParameterMutator mutator)
 
463
                {
 
464
                        var targs = TypeArguments;
 
465
                        if (targs != null)
 
466
                                targs = mutator.Mutate (targs);
 
467
 
 
468
                        var decl = DeclaringType;
 
469
                        if (DeclaringType.IsGenericOrParentIsGeneric) {
 
470
                                decl = mutator.Mutate (decl);
 
471
                        }
 
472
 
 
473
                        if (targs == TypeArguments && decl == DeclaringType)
 
474
                                return this;
 
475
 
 
476
                        var ms = (MethodSpec) MemberwiseClone ();
 
477
                        if (decl != DeclaringType) {
 
478
                                ms.inflatedMetaInfo = null;
 
479
                                ms.declaringType = decl;
 
480
                                ms.state |= StateFlags.PendingMetaInflate;
 
481
                        }
 
482
 
 
483
                        if (targs != null) {
 
484
                                ms.targs = targs;
 
485
                                ms.state |= StateFlags.PendingMakeMethod;
 
486
                        }
 
487
 
 
488
                        return ms;
 
489
                }
 
490
 
 
491
                public override List<TypeSpec> ResolveMissingDependencies ()
 
492
                {
 
493
                        var missing = returnType.ResolveMissingDependencies ();
 
494
                        foreach (var pt in parameters.Types) {
 
495
                                var m = pt.GetMissingDependencies ();
 
496
                                if (m == null)
 
497
                                        continue;
 
498
 
 
499
                                if (missing == null)
 
500
                                        missing = new List<TypeSpec> ();
 
501
 
 
502
                                missing.AddRange (m);
 
503
                        }
 
504
 
 
505
                        if (Arity > 0) {
 
506
                                foreach (var tp in GenericDefinition.TypeParameters) {
 
507
                                        var m = tp.GetMissingDependencies ();
 
508
 
 
509
                                        if (m == null)
 
510
                                                continue;
 
511
 
 
512
                                        if (missing == null)
 
513
                                                missing = new List<TypeSpec> ();
 
514
 
 
515
                                        missing.AddRange (m);
 
516
                                }
 
517
                        }
 
518
 
 
519
                        return missing;                 
 
520
                }
 
521
 
 
522
                public void SetMetaInfo (MethodInfo info)
 
523
                {
 
524
                        if (this.metaInfo != null)
 
525
                                throw new InternalErrorException ("MetaInfo reset");
 
526
 
 
527
                        this.metaInfo = info;
 
528
                }
 
529
        }
 
530
 
 
531
        public abstract class MethodOrOperator : MethodCore, IMethodData
 
532
        {
 
533
                public MethodBuilder MethodBuilder;
 
534
                ReturnParameter return_attributes;
 
535
                SecurityType declarative_security;
 
536
                protected MethodData MethodData;
 
537
 
 
538
                static readonly string[] attribute_targets = new string [] { "method", "return" };
 
539
 
 
540
                protected MethodOrOperator (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name,
 
541
                                Attributes attrs, ParametersCompiled parameters)
 
542
                        : base (parent, type, mod, allowed_mod, name, attrs, parameters)
 
543
                {
 
544
                }
 
545
 
 
546
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
547
                {
 
548
                        if (a.Target == AttributeTargets.ReturnValue) {
 
549
                                if (return_attributes == null)
 
550
                                        return_attributes = new ReturnParameter (this, MethodBuilder, Location);
 
551
 
 
552
                                return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
553
                                return;
 
554
                        }
 
555
 
 
556
                        if (a.Type == pa.MethodImpl) {
 
557
                                if ((ModFlags & Modifiers.ASYNC) != 0 && (a.GetMethodImplOptions () & MethodImplOptions.Synchronized) != 0) {
 
558
                                        Report.Error (4015, a.Location, "`{0}': Async methods cannot use `MethodImplOptions.Synchronized'",
 
559
                                                GetSignatureForError ());
 
560
                                }
 
561
 
 
562
                                is_external_implementation = a.IsInternalCall ();
 
563
                        } else if (a.Type == pa.DllImport) {
 
564
                                const Modifiers extern_static = Modifiers.EXTERN | Modifiers.STATIC;
 
565
                                if ((ModFlags & extern_static) != extern_static) {
 
566
                                        Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
 
567
                                }
 
568
                                is_external_implementation = true;
 
569
                        }
 
570
 
 
571
                        if (a.IsValidSecurityAttribute ()) {
 
572
                                a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
 
573
                                return;
 
574
                        }
 
575
 
 
576
                        if (MethodBuilder != null)
 
577
                                MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
 
578
                }
 
579
 
 
580
                public override AttributeTargets AttributeTargets {
 
581
                        get {
 
582
                                return AttributeTargets.Method; 
 
583
                        }
 
584
                }
 
585
 
 
586
                protected override bool CheckForDuplications ()
 
587
                {
 
588
                        return Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
 
589
                }
 
590
 
 
591
                public virtual EmitContext CreateEmitContext (ILGenerator ig, SourceMethodBuilder sourceMethod)
 
592
                {
 
593
                        return new EmitContext (this, ig, MemberType, sourceMethod);
 
594
                }
 
595
 
 
596
                public override bool Define ()
 
597
                {
 
598
                        if (!base.Define ())
 
599
                                return false;
 
600
 
 
601
                        if (!CheckBase ())
 
602
                                return false;
 
603
 
 
604
                        MemberKind kind;
 
605
                        if (this is Operator)
 
606
                                kind = MemberKind.Operator;
 
607
                        else if (this is Destructor)
 
608
                                kind = MemberKind.Destructor;
 
609
                        else
 
610
                                kind = MemberKind.Method;
 
611
 
 
612
                        if (IsPartialDefinition) {
 
613
                                caching_flags &= ~Flags.Excluded_Undetected;
 
614
                                caching_flags |= Flags.Excluded;
 
615
 
 
616
                                // Add to member cache only when a partial method implementation has not been found yet
 
617
                                if ((caching_flags & Flags.PartialDefinitionExists) == 0) {
 
618
//                                      MethodBase mb = new PartialMethodDefinitionInfo (this);
 
619
 
 
620
                                        spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, null, parameters, ModFlags);
 
621
                                        if (MemberName.Arity > 0) {
 
622
                                                spec.IsGeneric = true;
 
623
 
 
624
                                                // TODO: Have to move DefineMethod after Define (ideally to Emit)
 
625
                                                throw new NotImplementedException ("Generic partial methods");
 
626
                                        }
 
627
 
 
628
                                        Parent.MemberCache.AddMember (spec);
 
629
                                }
 
630
 
 
631
                                return true;
 
632
                        }
 
633
 
 
634
                        MethodData = new MethodData (
 
635
                                this, ModFlags, flags, this, MethodBuilder, base_method);
 
636
 
 
637
                        if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName)))
 
638
                                return false;
 
639
                                        
 
640
                        MethodBuilder = MethodData.MethodBuilder;
 
641
 
 
642
                        spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, MethodBuilder, parameters, ModFlags);
 
643
                        if (MemberName.Arity > 0)
 
644
                                spec.IsGeneric = true;
 
645
                        
 
646
                        Parent.MemberCache.AddMember (this, MethodBuilder.Name, spec);
 
647
 
 
648
                        return true;
 
649
                }
 
650
 
 
651
                protected override void DoMemberTypeIndependentChecks ()
 
652
                {
 
653
                        base.DoMemberTypeIndependentChecks ();
 
654
 
 
655
                        CheckAbstractAndExtern (block != null);
 
656
 
 
657
                        if ((ModFlags & Modifiers.PARTIAL) != 0) {
 
658
                                for (int i = 0; i < parameters.Count; ++i) {
 
659
                                        IParameterData p = parameters.FixedParameters [i];
 
660
                                        if ((p.ModFlags & Parameter.Modifier.OUT) != 0) {
 
661
                                                Report.Error (752, Location, "`{0}': A partial method parameters cannot use `out' modifier",
 
662
                                                        GetSignatureForError ());
 
663
                                        }
 
664
 
 
665
                                        if (p.HasDefaultValue && IsPartialImplementation)
 
666
                                                ((Parameter) p).Warning_UselessOptionalParameter (Report);
 
667
                                }
 
668
                        }
 
669
                }
 
670
 
 
671
                protected override void DoMemberTypeDependentChecks ()
 
672
                {
 
673
                        base.DoMemberTypeDependentChecks ();
 
674
 
 
675
                        if (MemberType.IsStatic) {
 
676
                                Error_StaticReturnType ();
 
677
                        }
 
678
                }
 
679
 
 
680
                public override void Emit ()
 
681
                {
 
682
                        if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
 
683
                                Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (MethodBuilder);
 
684
                        if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
 
685
                                Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (MethodBuilder);
 
686
 
 
687
                        if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
 
688
                                return_attributes = new ReturnParameter (this, MethodBuilder, Location);
 
689
                                Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
 
690
                        } else if (ReturnType.HasDynamicElement) {
 
691
                                return_attributes = new ReturnParameter (this, MethodBuilder, Location);
 
692
                                Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
 
693
                        }
 
694
 
 
695
                        if (OptAttributes != null)
 
696
                                OptAttributes.Emit ();
 
697
 
 
698
                        if (declarative_security != null) {
 
699
                                foreach (var de in declarative_security) {
 
700
#if STATIC
 
701
                                        MethodBuilder.__AddDeclarativeSecurity (de);
 
702
#else
 
703
                                        MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
 
704
#endif
 
705
                                }
 
706
                        }
 
707
 
 
708
                        if (type_expr != null)
 
709
                                ConstraintChecker.Check (this, member_type, type_expr.Location);
 
710
 
 
711
                        base.Emit ();
 
712
 
 
713
                        if (MethodData != null)
 
714
                                MethodData.Emit (Parent);
 
715
 
 
716
                        Block = null;
 
717
                }
 
718
 
 
719
                protected void Error_ConditionalAttributeIsNotValid ()
 
720
                {
 
721
                        Report.Error (577, Location,
 
722
                                "Conditional not valid on `{0}' because it is a constructor, destructor, operator or explicit interface implementation",
 
723
                                GetSignatureForError ());
 
724
                }
 
725
 
 
726
                public bool IsPartialDefinition {
 
727
                        get {
 
728
                                return (ModFlags & Modifiers.PARTIAL) != 0 && Block == null;
 
729
                        }
 
730
                }
 
731
 
 
732
                public bool IsPartialImplementation {
 
733
                        get {
 
734
                                return (ModFlags & Modifiers.PARTIAL) != 0 && Block != null;
 
735
                        }
 
736
                }
 
737
 
 
738
                public override string[] ValidAttributeTargets {
 
739
                        get {
 
740
                                return attribute_targets;
 
741
                        }
 
742
                }
 
743
 
 
744
                #region IMethodData Members
 
745
 
 
746
                bool IMethodData.IsAccessor {
 
747
                        get {
 
748
                                return false;
 
749
                        }
 
750
                }
 
751
 
 
752
                public TypeSpec ReturnType {
 
753
                        get {
 
754
                                return MemberType;
 
755
                        }
 
756
                }
 
757
 
 
758
                public MemberName MethodName {
 
759
                        get {
 
760
                                return MemberName;
 
761
                        }
 
762
                }
 
763
 
 
764
                /// <summary>
 
765
                /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
 
766
                /// </summary>
 
767
                public override string[] ConditionalConditions ()
 
768
                {
 
769
                        if ((caching_flags & (Flags.Excluded_Undetected | Flags.Excluded)) == 0)
 
770
                                return null;
 
771
 
 
772
                        if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.Excluded) != 0)
 
773
                                return new string [0];
 
774
 
 
775
                        caching_flags &= ~Flags.Excluded_Undetected;
 
776
                        string[] conditions;
 
777
 
 
778
                        if (base_method == null) {
 
779
                                if (OptAttributes == null)
 
780
                                        return null;
 
781
 
 
782
                                Attribute[] attrs = OptAttributes.SearchMulti (Module.PredefinedAttributes.Conditional);
 
783
                                if (attrs == null)
 
784
                                        return null;
 
785
 
 
786
                                conditions = new string[attrs.Length];
 
787
                                for (int i = 0; i < conditions.Length; ++i)
 
788
                                        conditions[i] = attrs[i].GetConditionalAttributeValue ();
 
789
                        } else {
 
790
                                conditions = base_method.MemberDefinition.ConditionalConditions();
 
791
                        }
 
792
 
 
793
                        if (conditions != null)
 
794
                                caching_flags |= Flags.Excluded;
 
795
 
 
796
                        return conditions;
 
797
                }
 
798
 
 
799
                #endregion
 
800
 
 
801
                public override void WriteDebugSymbol (MonoSymbolFile file)
 
802
                {
 
803
                        if (MethodData != null)
 
804
                                MethodData.WriteDebugSymbol (file);
 
805
                }
 
806
        }
 
807
 
 
808
        public class Method : MethodOrOperator, IGenericMethodDefinition
 
809
        {
 
810
                Method partialMethodImplementation;
 
811
 
 
812
                public Method (TypeDefinition parent, FullNamedExpression return_type, Modifiers mod, MemberName name, ParametersCompiled parameters, Attributes attrs)
 
813
                        : base (parent, return_type, mod,
 
814
                                parent.PartialContainer.Kind == MemberKind.Interface ? AllowedModifiersInterface :
 
815
                                parent.PartialContainer.Kind == MemberKind.Struct ? AllowedModifiersStruct | Modifiers.ASYNC :
 
816
                                AllowedModifiersClass | Modifiers.ASYNC,
 
817
                                name, attrs, parameters)
 
818
                {
 
819
                }
 
820
 
 
821
                protected Method (TypeDefinition parent, FullNamedExpression return_type, Modifiers mod, Modifiers amod,
 
822
                                        MemberName name, ParametersCompiled parameters, Attributes attrs)
 
823
                        : base (parent, return_type, mod, amod, name, attrs, parameters)
 
824
                {
 
825
                }
 
826
 
 
827
                #region Properties
 
828
 
 
829
                public override TypeParameters CurrentTypeParameters {
 
830
                        get {
 
831
                                return MemberName.TypeParameters;
 
832
                        }
 
833
                }
 
834
 
 
835
                public TypeParameterSpec[] TypeParameters {
 
836
                        get {
 
837
                                return CurrentTypeParameters.Types;
 
838
                        }
 
839
                }
 
840
 
 
841
                public int TypeParametersCount {
 
842
                        get {
 
843
                                return CurrentTypeParameters == null ? 0 : CurrentTypeParameters.Count;
 
844
                        }
 
845
                }
 
846
 
 
847
#endregion
 
848
 
 
849
                public override void Accept (StructuralVisitor visitor)
 
850
                {
 
851
                        visitor.Visit (this);
 
852
                }
 
853
 
 
854
                public static Method Create (TypeDefinition parent, FullNamedExpression returnType, Modifiers mod,
 
855
                                   MemberName name, ParametersCompiled parameters, Attributes attrs)
 
856
                {
 
857
                        var m = new Method (parent, returnType, mod, name, parameters, attrs);
 
858
 
 
859
                        if ((mod & Modifiers.PARTIAL) != 0) {
 
860
                                const Modifiers invalid_partial_mod = Modifiers.AccessibilityMask | Modifiers.ABSTRACT | Modifiers.EXTERN |
 
861
                                        Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.SEALED | Modifiers.VIRTUAL;
 
862
 
 
863
                                if ((mod & invalid_partial_mod) != 0) {
 
864
                                        m.Report.Error (750, m.Location,
 
865
                                                "A partial method cannot define access modifier or any of abstract, extern, new, override, sealed, or virtual modifiers");
 
866
                                        mod &= ~invalid_partial_mod;
 
867
                                }
 
868
 
 
869
                                if ((parent.ModFlags & Modifiers.PARTIAL) == 0) {
 
870
                                        m.Report.Error (751, m.Location, 
 
871
                                                "A partial method must be declared within a partial class or partial struct");
 
872
                                }
 
873
                        }
 
874
 
 
875
                        if ((mod & Modifiers.STATIC) == 0 && parameters.HasExtensionMethodType) {
 
876
                                m.Report.Error (1105, m.Location, "`{0}': Extension methods must be declared static",
 
877
                                        m.GetSignatureForError ());
 
878
                        }
 
879
 
 
880
 
 
881
                        return m;
 
882
                }
 
883
 
 
884
                public override string GetSignatureForError()
 
885
                {
 
886
                        return base.GetSignatureForError () + parameters.GetSignatureForError ();
 
887
                }
 
888
 
 
889
                void Error_DuplicateEntryPoint (Method b)
 
890
                {
 
891
                        Report.Error (17, b.Location,
 
892
                                "Program `{0}' has more than one entry point defined: `{1}'",
 
893
                                b.Module.Builder.ScopeName, b.GetSignatureForError ());
 
894
                }
 
895
 
 
896
                bool IsEntryPoint ()
 
897
                {
 
898
                        if (ReturnType.Kind != MemberKind.Void && ReturnType.BuiltinType != BuiltinTypeSpec.Type.Int)
 
899
                                return false;
 
900
 
 
901
                        if (parameters.IsEmpty)
 
902
                                return true;
 
903
 
 
904
                        if (parameters.Count > 1)
 
905
                                return false;
 
906
 
 
907
                        var ac = parameters.Types [0] as ArrayContainer;
 
908
                        return ac != null && ac.Rank == 1 && ac.Element.BuiltinType == BuiltinTypeSpec.Type.String &&
 
909
                                        (parameters[0].ModFlags & Parameter.Modifier.RefOutMask) == 0;
 
910
                }
 
911
 
 
912
                public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
 
913
                {
 
914
                        if (arity == 0) {
 
915
                                var tp = CurrentTypeParameters;
 
916
                                if (tp != null) {
 
917
                                        TypeParameter t = tp.Find (name);
 
918
                                        if (t != null)
 
919
                                                return new TypeParameterExpr (t, loc);
 
920
                                }
 
921
                        }
 
922
 
 
923
                        return base.LookupNamespaceOrType (name, arity, mode, loc);
 
924
                }
 
925
 
 
926
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
927
                {
 
928
                        if (a.Type == pa.Conditional) {
 
929
                                if (IsExplicitImpl) {
 
930
                                        Error_ConditionalAttributeIsNotValid ();
 
931
                                        return;
 
932
                                }
 
933
 
 
934
                                if ((ModFlags & Modifiers.OVERRIDE) != 0) {
 
935
                                        Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
 
936
                                        return;
 
937
                                }
 
938
 
 
939
                                if (ReturnType.Kind != MemberKind.Void) {
 
940
                                        Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
 
941
                                        return;
 
942
                                }
 
943
 
 
944
                                if (IsInterface) {
 
945
                                        Report.Error (582, Location, "Conditional not valid on interface members");
 
946
                                        return;
 
947
                                }
 
948
 
 
949
                                if (MethodData.implementing != null) {
 
950
                                        Report.SymbolRelatedToPreviousError (MethodData.implementing.DeclaringType);
 
951
                                        Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
 
952
                                                GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
 
953
                                        return;
 
954
                                }
 
955
 
 
956
                                for (int i = 0; i < parameters.Count; ++i) {
 
957
                                        if ((parameters.FixedParameters [i].ModFlags & Parameter.Modifier.OUT) != 0) {
 
958
                                                Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
 
959
                                                return;
 
960
                                        }
 
961
                                }
 
962
                        }
 
963
 
 
964
                        if (a.Type == pa.Extension) {
 
965
                                a.Error_MisusedExtensionAttribute ();
 
966
                                return;
 
967
                        }
 
968
 
 
969
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
970
                }
 
971
 
 
972
                void CreateTypeParameters ()
 
973
                {
 
974
                        var tparams = MemberName.TypeParameters;
 
975
                        string[] snames = new string[MemberName.Arity];
 
976
                        var parent_tparams = Parent.TypeParametersAll;
 
977
 
 
978
                        for (int i = 0; i < snames.Length; i++) {
 
979
                                string type_argument_name = tparams[i].MemberName.Name;
 
980
 
 
981
                                if (block == null) {
 
982
                                        int idx = parameters.GetParameterIndexByName (type_argument_name);
 
983
                                        if (idx >= 0) {
 
984
                                                var b = block;
 
985
                                                if (b == null)
 
986
                                                        b = new ToplevelBlock (Compiler, Location);
 
987
 
 
988
                                                b.Error_AlreadyDeclaredTypeParameter (type_argument_name, parameters[i].Location);
 
989
                                        }
 
990
                                } else {
 
991
                                        INamedBlockVariable variable = null;
 
992
                                        block.GetLocalName (type_argument_name, block, ref variable);
 
993
                                        if (variable != null)
 
994
                                                variable.Block.Error_AlreadyDeclaredTypeParameter (type_argument_name, variable.Location);
 
995
                                }
 
996
 
 
997
                                if (parent_tparams != null) {
 
998
                                        var tp = parent_tparams.Find (type_argument_name);
 
999
                                        if (tp != null) {
 
1000
                                                tparams[i].WarningParentNameConflict (tp);
 
1001
                                        }
 
1002
                                }
 
1003
 
 
1004
                                snames[i] = type_argument_name;
 
1005
                        }
 
1006
 
 
1007
                        GenericTypeParameterBuilder[] gen_params = MethodBuilder.DefineGenericParameters (snames);
 
1008
                        tparams.Define (gen_params, null, 0, Parent);
 
1009
                }
 
1010
 
 
1011
                protected virtual void DefineTypeParameters ()
 
1012
                {
 
1013
                        var tparams = CurrentTypeParameters;
 
1014
 
 
1015
                        TypeParameterSpec[] base_tparams = null;
 
1016
                        TypeParameterSpec[] base_decl_tparams = TypeParameterSpec.EmptyTypes;
 
1017
                        TypeSpec[] base_targs = TypeSpec.EmptyTypes;
 
1018
                        if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
 
1019
                                MethodSpec base_override = base_method ?? MethodData.implementing;
 
1020
 
 
1021
                                if (base_override != null) {
 
1022
                                        base_tparams = base_override.GenericDefinition.TypeParameters;
 
1023
 
 
1024
                                        if (base_override.DeclaringType.IsGeneric) {
 
1025
                                                base_decl_tparams = base_override.DeclaringType.MemberDefinition.TypeParameters;
 
1026
 
 
1027
                                                if (base_method != null) {
 
1028
                                                        var base_type_parent = CurrentType;
 
1029
                                                        while (base_type_parent.BaseType != base_override.DeclaringType) {
 
1030
                                                                base_type_parent = base_type_parent.BaseType;
 
1031
                                                        }
 
1032
 
 
1033
                                                        base_targs = base_type_parent.BaseType.TypeArguments;
 
1034
                                                } else {
 
1035
                                                        foreach (var iface in Parent.CurrentType.Interfaces) {
 
1036
                                                                if (iface == base_override.DeclaringType) {
 
1037
                                                                        base_targs = iface.TypeArguments;
 
1038
                                                                        break;
 
1039
                                                                }
 
1040
                                                        }
 
1041
                                                }
 
1042
                                        }
 
1043
 
 
1044
                                        if (base_override.IsGeneric) {
 
1045
                                                ObsoleteAttribute oa;
 
1046
                                                foreach (var base_tp in base_tparams) {
 
1047
                                                        oa = base_tp.BaseType.GetAttributeObsolete ();
 
1048
                                                        if (oa != null) {
 
1049
                                                                AttributeTester.Report_ObsoleteMessage (oa, base_tp.BaseType.GetSignatureForError (), Location, Report);
 
1050
                                                        }
 
1051
 
 
1052
                                                        if (base_tp.InterfacesDefined != null) {
 
1053
                                                                foreach (var iface in base_tp.InterfacesDefined) {
 
1054
                                                                        oa = iface.GetAttributeObsolete ();
 
1055
                                                                        if (oa != null) {
 
1056
                                                                                AttributeTester.Report_ObsoleteMessage (oa, iface.GetSignatureForError (), Location, Report);
 
1057
                                                                        }
 
1058
                                                                }
 
1059
                                                        }
 
1060
                                                }
 
1061
 
 
1062
                                                if (base_decl_tparams.Length != 0) {
 
1063
                                                        base_decl_tparams = base_decl_tparams.Concat (base_tparams).ToArray ();
 
1064
                                                        base_targs = base_targs.Concat (tparams.Types).ToArray ();
 
1065
                                                } else {
 
1066
                                                        base_decl_tparams = base_tparams;
 
1067
                                                        base_targs = tparams.Types;
 
1068
                                                }
 
1069
                                        }
 
1070
                                }
 
1071
                        }
 
1072
 
 
1073
                        for (int i = 0; i < tparams.Count; ++i) {
 
1074
                                var tp = tparams[i];
 
1075
 
 
1076
                                if (!tp.ResolveConstraints (this))
 
1077
                                        continue;
 
1078
 
 
1079
                                //
 
1080
                                // Copy base constraints for override/explicit methods
 
1081
                                //
 
1082
                                if (base_tparams != null) {
 
1083
                                        var base_tparam = base_tparams[i];
 
1084
                                        var local_tparam = tp.Type;
 
1085
                                        local_tparam.SpecialConstraint = base_tparam.SpecialConstraint;
 
1086
 
 
1087
                                        var inflator = new TypeParameterInflator (this, CurrentType, base_decl_tparams, base_targs);
 
1088
                                        base_tparam.InflateConstraints (inflator, local_tparam);
 
1089
 
 
1090
                                        //
 
1091
                                        // Check all type argument constraints for possible collision or unification
 
1092
                                        // introduced by inflating inherited constraints in this context
 
1093
                                        //
 
1094
                                        // Conflict example:
 
1095
                                        //
 
1096
                                        // class A<T> { virtual void Foo<U> () where U : class, T {} }
 
1097
                                        // class B : A<int> { override void Foo<U> {} }
 
1098
                                        //
 
1099
                                        var local_tparam_targs = local_tparam.TypeArguments;
 
1100
                                        if (local_tparam_targs != null) {
 
1101
                                                for (int ii = 0; ii < local_tparam_targs.Length; ++ii) {
 
1102
                                                        var ta = local_tparam_targs [ii];
 
1103
                                                        if (!ta.IsClass && !ta.IsStruct)
 
1104
                                                                continue;
 
1105
 
 
1106
                                                        TypeSpec[] unique_tparams = null;
 
1107
                                                        for (int iii = ii + 1; iii < local_tparam_targs.Length; ++iii) {
 
1108
                                                                //
 
1109
                                                                // Remove any identical or unified constraint types
 
1110
                                                                //
 
1111
                                                                var tparam_checked = local_tparam_targs[iii];
 
1112
                                                                if (TypeSpecComparer.IsEqual (ta, tparam_checked) || TypeSpec.IsBaseClass (ta, tparam_checked, false)) {
 
1113
                                                                        unique_tparams = new TypeSpec[local_tparam_targs.Length - 1];
 
1114
                                                                        Array.Copy (local_tparam_targs, 0, unique_tparams, 0, iii);
 
1115
                                                                        Array.Copy (local_tparam_targs, iii + 1, unique_tparams, iii, local_tparam_targs.Length - iii - 1);
 
1116
                                                                } else if (!TypeSpec.IsBaseClass (tparam_checked, ta, false)) {
 
1117
                                                                        Constraints.Error_ConflictingConstraints (this, local_tparam, ta, tparam_checked, Location);
 
1118
                                                                }
 
1119
                                                        }
 
1120
 
 
1121
                                                        if (unique_tparams != null) {
 
1122
                                                                local_tparam_targs = unique_tparams;
 
1123
                                                                local_tparam.TypeArguments = local_tparam_targs;
 
1124
                                                                continue;
 
1125
                                                        }
 
1126
 
 
1127
                                                        Constraints.CheckConflictingInheritedConstraint (local_tparam, ta, this, Location);
 
1128
                                                }
 
1129
                                        }
 
1130
                                }
 
1131
                        }
 
1132
 
 
1133
                        if (base_tparams == null && MethodData != null && MethodData.implementing != null) {
 
1134
                                CheckImplementingMethodConstraints (Parent, spec, MethodData.implementing);
 
1135
                        }
 
1136
                }
 
1137
 
 
1138
                public static bool CheckImplementingMethodConstraints (TypeContainer container, MethodSpec method, MethodSpec baseMethod)
 
1139
                {
 
1140
                        var tparams = method.Constraints;
 
1141
                        var base_tparams = baseMethod.Constraints;
 
1142
                        for (int i = 0; i < tparams.Length; ++i) {
 
1143
                                if (!tparams[i].HasSameConstraintsImplementation (base_tparams[i])) {
 
1144
                                        container.Compiler.Report.SymbolRelatedToPreviousError (method);
 
1145
                                        container.Compiler.Report.SymbolRelatedToPreviousError (baseMethod);
 
1146
 
 
1147
                                        // Using container location because the interface can be implemented
 
1148
                                        // by base class
 
1149
                                        container.Compiler.Report.Error (425, container.Location,
 
1150
                                                "The constraints for type parameter `{0}' of method `{1}' must match the constraints for type parameter `{2}' of interface method `{3}'. Consider using an explicit interface implementation instead",
 
1151
                                                tparams[i].GetSignatureForError (), method.GetSignatureForError (),
 
1152
                                                base_tparams[i].GetSignatureForError (), baseMethod.GetSignatureForError ());
 
1153
 
 
1154
                                        return false;
 
1155
                                }
 
1156
                        }
 
1157
 
 
1158
                        return true;
 
1159
                }
 
1160
 
 
1161
                //
 
1162
                // Creates the type
 
1163
                //
 
1164
                public override bool Define ()
 
1165
                {
 
1166
                        if (!base.Define ())
 
1167
                                return false;
 
1168
 
 
1169
                        if (member_type.Kind == MemberKind.Void && parameters.IsEmpty && MemberName.Arity == 0 && MemberName.Name == Destructor.MetadataName) {
 
1170
                                Report.Warning (465, 1, Location,
 
1171
                                        "Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
 
1172
                        }
 
1173
 
 
1174
                        if (partialMethodImplementation != null && IsPartialDefinition)
 
1175
                                MethodBuilder = partialMethodImplementation.MethodBuilder;
 
1176
 
 
1177
                        if (Compiler.Settings.StdLib && ReturnType.IsSpecialRuntimeType) {
 
1178
                                Error1599 (Location, ReturnType, Report);
 
1179
                                return false;
 
1180
                        }
 
1181
 
 
1182
                        if (CurrentTypeParameters == null) {
 
1183
                                if (base_method != null && !IsExplicitImpl) {
 
1184
                                        if (parameters.Count == 1 && ParameterTypes[0].BuiltinType == BuiltinTypeSpec.Type.Object && MemberName.Name == "Equals")
 
1185
                                                Parent.PartialContainer.Mark_HasEquals ();
 
1186
                                        else if (parameters.IsEmpty && MemberName.Name == "GetHashCode")
 
1187
                                                Parent.PartialContainer.Mark_HasGetHashCode ();
 
1188
                                }
 
1189
                                        
 
1190
                        } else {
 
1191
                                DefineTypeParameters ();
 
1192
                        }
 
1193
 
 
1194
                        if (block != null) {
 
1195
                                if (block.IsIterator) {
 
1196
                                        //
 
1197
                                        // Current method is turned into automatically generated
 
1198
                                        // wrapper which creates an instance of iterator
 
1199
                                        //
 
1200
                                        Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
 
1201
                                        ModFlags |= Modifiers.DEBUGGER_HIDDEN;
 
1202
                                }
 
1203
 
 
1204
                                if ((ModFlags & Modifiers.ASYNC) != 0) {
 
1205
                                        if (ReturnType.Kind != MemberKind.Void &&
 
1206
                                                ReturnType != Module.PredefinedTypes.Task.TypeSpec &&
 
1207
                                                !ReturnType.IsGenericTask) {
 
1208
                                                Report.Error (1983, Location, "The return type of an async method must be void, Task, or Task<T>");
 
1209
                                        }
 
1210
 
 
1211
                                        block = (ToplevelBlock) block.ConvertToAsyncTask (this, Parent.PartialContainer, parameters, ReturnType, Location);
 
1212
                                        ModFlags |= Modifiers.DEBUGGER_HIDDEN;
 
1213
                                }
 
1214
 
 
1215
                                if (Compiler.Settings.WriteMetadataOnly)
 
1216
                                        block = null;
 
1217
                        }
 
1218
 
 
1219
                        if ((ModFlags & Modifiers.STATIC) == 0)
 
1220
                                return true;
 
1221
 
 
1222
                        if (parameters.HasExtensionMethodType) {
 
1223
                                if (Parent.PartialContainer.IsStatic && !Parent.IsGenericOrParentIsGeneric) {
 
1224
                                        if (!Parent.IsTopLevel)
 
1225
                                                Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class",
 
1226
                                                        GetSignatureForError ());
 
1227
 
 
1228
                                        PredefinedAttribute pa = Module.PredefinedAttributes.Extension;
 
1229
                                        if (!pa.IsDefined) {
 
1230
                                                Report.Error (1110, Location,
 
1231
                                                        "`{0}': Extension methods require `System.Runtime.CompilerServices.ExtensionAttribute' type to be available. Are you missing an assembly reference?",
 
1232
                                                        GetSignatureForError ());
 
1233
                                        }
 
1234
 
 
1235
                                        ModFlags |= Modifiers.METHOD_EXTENSION;
 
1236
                                        Parent.PartialContainer.ModFlags |= Modifiers.METHOD_EXTENSION;
 
1237
                                        Spec.DeclaringType.SetExtensionMethodContainer ();
 
1238
                                        Parent.Module.HasExtensionMethod = true;
 
1239
                                } else {
 
1240
                                        Report.Error (1106, Location, "`{0}': Extension methods must be defined in a non-generic static class",
 
1241
                                                GetSignatureForError ());
 
1242
                                }
 
1243
                        }
 
1244
 
 
1245
                        //
 
1246
                        // This is used to track the Entry Point,
 
1247
                        //
 
1248
                        var settings = Compiler.Settings;
 
1249
                        if (settings.NeedsEntryPoint && MemberName.Name == "Main" && (settings.MainClass == null || settings.MainClass == Parent.TypeBuilder.FullName)) {
 
1250
                                if (IsEntryPoint ()) {
 
1251
                                        if (Parent.DeclaringAssembly.EntryPoint == null) {
 
1252
                                                if (Parent.IsGenericOrParentIsGeneric || MemberName.IsGeneric) {
 
1253
                                                        Report.Warning (402, 4, Location, "`{0}': an entry point cannot be generic or in a generic type",
 
1254
                                                                GetSignatureForError ());
 
1255
                                                } else if ((ModFlags & Modifiers.ASYNC) != 0) {
 
1256
                                                        Report.Error (4009, Location, "`{0}': an entry point cannot be async method",
 
1257
                                                                GetSignatureForError ());
 
1258
                                                } else {
 
1259
                                                        SetIsUsed ();
 
1260
                                                        Parent.DeclaringAssembly.EntryPoint = this;
 
1261
                                                }
 
1262
                                        } else {
 
1263
                                                Error_DuplicateEntryPoint (Parent.DeclaringAssembly.EntryPoint);
 
1264
                                                Error_DuplicateEntryPoint (this);
 
1265
                                        }
 
1266
                                } else {
 
1267
                                        Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point",
 
1268
                                                GetSignatureForError ());
 
1269
                                }
 
1270
                        }
 
1271
 
 
1272
                        return true;
 
1273
                }
 
1274
 
 
1275
                //
 
1276
                // Emits the code
 
1277
                // 
 
1278
                public override void Emit ()
 
1279
                {
 
1280
                        try {
 
1281
                                if (IsPartialDefinition) {
 
1282
                                        //
 
1283
                                        // Use partial method implementation builder for partial method declaration attributes
 
1284
                                        //
 
1285
                                        if (partialMethodImplementation != null) {
 
1286
                                                MethodBuilder = partialMethodImplementation.MethodBuilder;
 
1287
                                        }
 
1288
 
 
1289
                                        return;
 
1290
                                }
 
1291
                                
 
1292
                                if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.PartialDefinitionExists) == 0) {
 
1293
                                        Report.Error (759, Location, "A partial method `{0}' implementation is missing a partial method declaration",
 
1294
                                                GetSignatureForError ());
 
1295
                                }
 
1296
 
 
1297
                                if (CurrentTypeParameters != null) {
 
1298
                                        for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
 
1299
                                                var tp = CurrentTypeParameters [i];
 
1300
                                                tp.CheckGenericConstraints (false);
 
1301
                                                tp.Emit ();
 
1302
                                        }
 
1303
                                }
 
1304
 
 
1305
                                if (block != null && block.StateMachine is AsyncTaskStorey) {
 
1306
                                        var psm = Module.PredefinedAttributes.AsyncStateMachine;
 
1307
                                        
 
1308
                                        psm.EmitAttribute (MethodBuilder, block.StateMachine);
 
1309
                                }
 
1310
 
 
1311
                                if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
 
1312
                                        Module.PredefinedAttributes.Extension.EmitAttribute (MethodBuilder);
 
1313
 
 
1314
                                base.Emit ();
 
1315
                        } catch {
 
1316
                                Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
 
1317
                                                   Location, MethodBuilder);
 
1318
                                throw;
 
1319
                        }
 
1320
                }
 
1321
 
 
1322
                public override bool EnableOverloadChecks (MemberCore overload)
 
1323
                {
 
1324
                        if (overload is Indexer)
 
1325
                                return false;
 
1326
 
 
1327
                        return base.EnableOverloadChecks (overload);
 
1328
                }
 
1329
 
 
1330
                public static void Error1599 (Location loc, TypeSpec t, Report Report)
 
1331
                {
 
1332
                        Report.Error (1599, loc, "Method or delegate cannot return type `{0}'", TypeManager.CSharpName (t));
 
1333
                }
 
1334
 
 
1335
                protected override bool ResolveMemberType ()
 
1336
                {
 
1337
                        if (CurrentTypeParameters != null) {
 
1338
                                MethodBuilder = Parent.TypeBuilder.DefineMethod (GetFullName (MemberName), flags);
 
1339
                                CreateTypeParameters ();
 
1340
                        }
 
1341
 
 
1342
                        return base.ResolveMemberType ();
 
1343
                }
 
1344
 
 
1345
                public void SetPartialDefinition (Method methodDefinition)
 
1346
                {
 
1347
                        caching_flags |= Flags.PartialDefinitionExists;
 
1348
                        methodDefinition.partialMethodImplementation = this;
 
1349
 
 
1350
                        // Ensure we are always using method declaration parameters
 
1351
                        for (int i = 0; i < methodDefinition.parameters.Count; ++i ) {
 
1352
                                parameters [i].Name = methodDefinition.parameters [i].Name;
 
1353
                                parameters [i].DefaultValue = methodDefinition.parameters [i].DefaultValue;
 
1354
                        }
 
1355
 
 
1356
                        if (methodDefinition.attributes == null)
 
1357
                                return;
 
1358
 
 
1359
                        if (attributes == null) {
 
1360
                                attributes = methodDefinition.attributes;
 
1361
                        } else {
 
1362
                                attributes.Attrs.AddRange (methodDefinition.attributes.Attrs);
 
1363
                        }
 
1364
                }
 
1365
        }
 
1366
 
 
1367
        public abstract class ConstructorInitializer : ExpressionStatement
 
1368
        {
 
1369
                Arguments argument_list;
 
1370
                MethodSpec base_ctor;
 
1371
 
 
1372
                public ConstructorInitializer (Arguments argument_list, Location loc)
 
1373
                {
 
1374
                        this.argument_list = argument_list;
 
1375
                        this.loc = loc;
 
1376
                }
 
1377
 
 
1378
                public Arguments Arguments {
 
1379
                        get {
 
1380
                                return argument_list;
 
1381
                        }
 
1382
                }
 
1383
 
 
1384
                public override bool ContainsEmitWithAwait ()
 
1385
                {
 
1386
                        throw new NotSupportedException ();
 
1387
                }
 
1388
 
 
1389
                public override Expression CreateExpressionTree (ResolveContext ec)
 
1390
                {
 
1391
                        throw new NotSupportedException ("ET");
 
1392
                }
 
1393
 
 
1394
                protected override Expression DoResolve (ResolveContext ec)
 
1395
                {
 
1396
                        eclass = ExprClass.Value;
 
1397
 
 
1398
                        // FIXME: Hack
 
1399
                        var caller_builder = (Constructor) ec.MemberContext;
 
1400
 
 
1401
                        //
 
1402
                        // Spec mandates that constructor initializer will not have `this' access
 
1403
                        //
 
1404
                        using (ec.Set (ResolveContext.Options.BaseInitializer)) {
 
1405
                                if (argument_list != null) {
 
1406
                                        bool dynamic;
 
1407
                                        argument_list.Resolve (ec, out dynamic);
 
1408
 
 
1409
                                        if (dynamic) {
 
1410
                                                ec.Report.Error (1975, loc,
 
1411
                                                        "The constructor call cannot be dynamically dispatched within constructor initializer");
 
1412
 
 
1413
                                                return null;
 
1414
                                        }
 
1415
                                }
 
1416
 
 
1417
                                type = ec.CurrentType;
 
1418
                                if (this is ConstructorBaseInitializer) {
 
1419
                                        if (ec.CurrentType.BaseType == null)
 
1420
                                                return this;
 
1421
 
 
1422
                                        type = ec.CurrentType.BaseType;
 
1423
                                        if (ec.CurrentType.IsStruct) {
 
1424
                                                ec.Report.Error (522, loc,
 
1425
                                                        "`{0}': Struct constructors cannot call base constructors", caller_builder.GetSignatureForError ());
 
1426
                                                return this;
 
1427
                                        }
 
1428
                                } else {
 
1429
                                        //
 
1430
                                        // It is legal to have "this" initializers that take no arguments
 
1431
                                        // in structs, they are just no-ops.
 
1432
                                        //
 
1433
                                        // struct D { public D (int a) : this () {}
 
1434
                                        //
 
1435
                                        if (ec.CurrentType.IsStruct && argument_list == null)
 
1436
                                                return this;
 
1437
                                }
 
1438
 
 
1439
                                base_ctor = ConstructorLookup (ec, type, ref argument_list, loc);
 
1440
                        }
 
1441
        
 
1442
                        if (base_ctor != null && base_ctor.MemberDefinition == caller_builder.Spec.MemberDefinition) {
 
1443
                                ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself",
 
1444
                                        caller_builder.GetSignatureForError ());
 
1445
                        }
 
1446
 
 
1447
                        return this;
 
1448
                }
 
1449
 
 
1450
                public override void Emit (EmitContext ec)
 
1451
                {
 
1452
                        // It can be null for static initializers
 
1453
                        if (base_ctor == null)
 
1454
                                return;
 
1455
                        
 
1456
                        var call = new CallEmitter ();
 
1457
                        call.InstanceExpression = new CompilerGeneratedThis (type, loc); 
 
1458
                        call.EmitPredefined (ec, base_ctor, argument_list);
 
1459
                }
 
1460
 
 
1461
                public override void EmitStatement (EmitContext ec)
 
1462
                {
 
1463
                        Emit (ec);
 
1464
                }
 
1465
        }
 
1466
 
 
1467
        public class ConstructorBaseInitializer : ConstructorInitializer {
 
1468
                public ConstructorBaseInitializer (Arguments argument_list, Location l) :
 
1469
                        base (argument_list, l)
 
1470
                {
 
1471
                }
 
1472
        }
 
1473
 
 
1474
        class GeneratedBaseInitializer: ConstructorBaseInitializer {
 
1475
                public GeneratedBaseInitializer (Location loc):
 
1476
                        base (null, loc)
 
1477
                {
 
1478
                }
 
1479
        }
 
1480
 
 
1481
        public class ConstructorThisInitializer : ConstructorInitializer {
 
1482
                public ConstructorThisInitializer (Arguments argument_list, Location l) :
 
1483
                        base (argument_list, l)
 
1484
                {
 
1485
                }
 
1486
        }
 
1487
        
 
1488
        public class Constructor : MethodCore, IMethodData
 
1489
        {
 
1490
                public ConstructorBuilder ConstructorBuilder;
 
1491
                public ConstructorInitializer Initializer;
 
1492
                SecurityType declarative_security;
 
1493
                bool has_compliant_args;
 
1494
                SourceMethodBuilder debug_builder;
 
1495
 
 
1496
                // <summary>
 
1497
                //   Modifiers allowed for a constructor.
 
1498
                // </summary>
 
1499
                public const Modifiers AllowedModifiers =
 
1500
                        Modifiers.PUBLIC |
 
1501
                        Modifiers.PROTECTED |
 
1502
                        Modifiers.INTERNAL |
 
1503
                        Modifiers.STATIC |
 
1504
                        Modifiers.UNSAFE |
 
1505
                        Modifiers.EXTERN |              
 
1506
                        Modifiers.PRIVATE;
 
1507
 
 
1508
                static readonly string[] attribute_targets = new string [] { "method" };
 
1509
 
 
1510
                public static readonly string ConstructorName = ".ctor";
 
1511
                public static readonly string TypeConstructorName = ".cctor";
 
1512
 
 
1513
                public Constructor (TypeDefinition parent, string name, Modifiers mod, Attributes attrs, ParametersCompiled args, Location loc)
 
1514
                        : base (parent, null, mod, AllowedModifiers, new MemberName (name, loc), attrs, args)
 
1515
                {
 
1516
                }
 
1517
 
 
1518
                public bool HasCompliantArgs {
 
1519
                        get {
 
1520
                                return has_compliant_args;
 
1521
                        }
 
1522
                }
 
1523
 
 
1524
                public override AttributeTargets AttributeTargets {
 
1525
                        get {
 
1526
                                return AttributeTargets.Constructor;
 
1527
                        }
 
1528
                }
 
1529
 
 
1530
                bool IMethodData.IsAccessor {
 
1531
                    get {
 
1532
                        return false;
 
1533
                    }
 
1534
                }
 
1535
 
 
1536
                //
 
1537
                // Returns true if this is a default constructor
 
1538
                //
 
1539
                public bool IsDefault ()
 
1540
                {
 
1541
                        if ((ModFlags & Modifiers.STATIC) != 0)
 
1542
                                return parameters.IsEmpty;
 
1543
 
 
1544
                        return parameters.IsEmpty &&
 
1545
                                        (Initializer is ConstructorBaseInitializer) &&
 
1546
                                        (Initializer.Arguments == null);
 
1547
                }
 
1548
 
 
1549
                public override void Accept (StructuralVisitor visitor)
 
1550
                {
 
1551
                        visitor.Visit (this);
 
1552
                }
 
1553
 
 
1554
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
1555
                {
 
1556
                        if (a.IsValidSecurityAttribute ()) {
 
1557
                                a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
 
1558
                                return;
 
1559
                        }
 
1560
 
 
1561
                        if (a.Type == pa.MethodImpl) {
 
1562
                                is_external_implementation = a.IsInternalCall ();
 
1563
                        }
 
1564
 
 
1565
                        ConstructorBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
 
1566
                }
 
1567
 
 
1568
                protected override bool CheckBase ()
 
1569
                {
 
1570
                        if ((ModFlags & Modifiers.STATIC) != 0) {
 
1571
                                if (!parameters.IsEmpty) {
 
1572
                                        Report.Error (132, Location, "`{0}': The static constructor must be parameterless",
 
1573
                                                GetSignatureForError ());
 
1574
                                        return false;
 
1575
                                }
 
1576
 
 
1577
                                if ((caching_flags & Flags.MethodOverloadsExist) != 0)
 
1578
                                        Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
 
1579
 
 
1580
                                // the rest can be ignored
 
1581
                                return true;
 
1582
                        }
 
1583
 
 
1584
                        // Check whether arguments were correct.
 
1585
                        if (!DefineParameters (parameters))
 
1586
                                return false;
 
1587
 
 
1588
                        if ((caching_flags & Flags.MethodOverloadsExist) != 0)
 
1589
                                Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
 
1590
 
 
1591
                        if (Parent.PartialContainer.Kind == MemberKind.Struct && parameters.IsEmpty) {
 
1592
                                Report.Error (568, Location, 
 
1593
                                        "Structs cannot contain explicit parameterless constructors");
 
1594
                                return false;
 
1595
                        }
 
1596
 
 
1597
                        CheckProtectedModifier ();
 
1598
                        
 
1599
                        return true;
 
1600
                }
 
1601
                
 
1602
                //
 
1603
                // Creates the ConstructorBuilder
 
1604
                //
 
1605
                public override bool Define ()
 
1606
                {
 
1607
                        if (ConstructorBuilder != null)
 
1608
                                return true;
 
1609
 
 
1610
                        if (!CheckAbstractAndExtern (block != null))
 
1611
                                return false;
 
1612
                        
 
1613
                        // Check if arguments were correct.
 
1614
                        if (!CheckBase ())
 
1615
                                return false;
 
1616
 
 
1617
                        var ca = ModifiersExtensions.MethodAttr (ModFlags) | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
 
1618
 
 
1619
                        ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
 
1620
                                ca, CallingConventions,
 
1621
                                parameters.GetMetaInfo ());
 
1622
 
 
1623
                        spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, Compiler.BuiltinTypes.Void, ConstructorBuilder, parameters, ModFlags);
 
1624
                        
 
1625
                        Parent.MemberCache.AddMember (spec);
 
1626
                        
 
1627
                        if (block != null) {
 
1628
                                // It's here only to report an error
 
1629
                                if (block.IsIterator) {
 
1630
                                        member_type = Compiler.BuiltinTypes.Void;
 
1631
                                        Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
 
1632
                                }
 
1633
 
 
1634
                                if (Compiler.Settings.WriteMetadataOnly)
 
1635
                                        block = null;
 
1636
                        }
 
1637
 
 
1638
                        return true;
 
1639
                }
 
1640
 
 
1641
                //
 
1642
                // Emits the code
 
1643
                //
 
1644
                public override void Emit ()
 
1645
                {
 
1646
                        if (Parent.PartialContainer.IsComImport) {
 
1647
                                if (!IsDefault ()) {
 
1648
                                        Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor",
 
1649
                                                Parent.GetSignatureForError ());
 
1650
                                }
 
1651
 
 
1652
                                // Set as internal implementation and reset block data
 
1653
                                // to ensure no IL is generated
 
1654
                                ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall);
 
1655
                                block = null;
 
1656
                        }
 
1657
 
 
1658
                        if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)
 
1659
                                Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (ConstructorBuilder);
 
1660
 
 
1661
                        if (OptAttributes != null)
 
1662
                                OptAttributes.Emit ();
 
1663
 
 
1664
                        base.Emit ();
 
1665
                        parameters.ApplyAttributes (this, ConstructorBuilder);
 
1666
 
 
1667
 
 
1668
                        BlockContext bc = new BlockContext (this, block, Compiler.BuiltinTypes.Void);
 
1669
                        bc.Set (ResolveContext.Options.ConstructorScope);
 
1670
 
 
1671
                        if (block != null) {
 
1672
                                //
 
1673
                                // If we use a "this (...)" constructor initializer, then
 
1674
                                // do not emit field initializers, they are initialized in the other constructor
 
1675
                                //
 
1676
                                if (!(Initializer is ConstructorThisInitializer))
 
1677
                                        Parent.PartialContainer.ResolveFieldInitializers (bc);
 
1678
 
 
1679
                                if (!IsStatic) {
 
1680
                                        if (Initializer == null) {
 
1681
                                                if (Parent.PartialContainer.Kind == MemberKind.Struct) {
 
1682
                                                        //
 
1683
                                                        // If this is a non-static `struct' constructor and doesn't have any
 
1684
                                                        // initializer, it must initialize all of the struct's fields.
 
1685
                                                        //
 
1686
                                                        block.AddThisVariable (bc);
 
1687
                                                } else if (Parent.PartialContainer.Kind == MemberKind.Class) {
 
1688
                                                        Initializer = new GeneratedBaseInitializer (Location);
 
1689
                                                }
 
1690
                                        }
 
1691
 
 
1692
                                        if (Initializer != null) {
 
1693
                                                //
 
1694
                                                // mdb format does not support reqions. Try to workaround this by emitting the
 
1695
                                                // sequence point at initializer. Any breakpoint at constructor header should
 
1696
                                                // be adjusted to this sequence point as it's the next one which follows.
 
1697
                                                //
 
1698
                                                block.AddScopeStatement (new StatementExpression (Initializer));
 
1699
                                        }
 
1700
                                }
 
1701
 
 
1702
                                if (block.Resolve (null, bc, this)) {
 
1703
                                        debug_builder = Parent.CreateMethodSymbolEntry ();
 
1704
                                        EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType, debug_builder);
 
1705
                                        ec.With (EmitContext.Options.ConstructorScope, true);
 
1706
 
 
1707
                                        block.Emit (ec);
 
1708
                                }
 
1709
                        }
 
1710
 
 
1711
                        if (declarative_security != null) {
 
1712
                                foreach (var de in declarative_security) {
 
1713
#if STATIC
 
1714
                                        ConstructorBuilder.__AddDeclarativeSecurity (de);
 
1715
#else
 
1716
                                        ConstructorBuilder.AddDeclarativeSecurity (de.Key, de.Value);
 
1717
#endif
 
1718
                                }
 
1719
                        }
 
1720
 
 
1721
                        block = null;
 
1722
                }
 
1723
 
 
1724
                protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
 
1725
                {
 
1726
                        // Is never override
 
1727
                        bestCandidate = null;
 
1728
                        return null;
 
1729
                }
 
1730
 
 
1731
                public override string GetCallerMemberName ()
 
1732
                {
 
1733
                        return IsStatic ? TypeConstructorName : ConstructorName;
 
1734
                }
 
1735
 
 
1736
                public override string GetSignatureForDocumentation ()
 
1737
                {
 
1738
                        return Parent.GetSignatureForDocumentation () + ".#ctor" + parameters.GetSignatureForDocumentation ();
 
1739
                }
 
1740
 
 
1741
                public override string GetSignatureForError()
 
1742
                {
 
1743
                        return base.GetSignatureForError () + parameters.GetSignatureForError ();
 
1744
                }
 
1745
 
 
1746
                public override string[] ValidAttributeTargets {
 
1747
                        get {
 
1748
                                return attribute_targets;
 
1749
                        }
 
1750
                }
 
1751
 
 
1752
                protected override bool VerifyClsCompliance ()
 
1753
                {
 
1754
                        if (!base.VerifyClsCompliance () || !IsExposedFromAssembly ()) {
 
1755
                                return false;
 
1756
                        }
 
1757
 
 
1758
                        if (!parameters.IsEmpty && Parent.Definition.IsAttribute) {
 
1759
                                foreach (TypeSpec param in parameters.Types) {
 
1760
                                        if (param.IsArray) {
 
1761
                                                return true;
 
1762
                                        }
 
1763
                                }
 
1764
                        }
 
1765
 
 
1766
                        has_compliant_args = true;
 
1767
                        return true;
 
1768
                }
 
1769
 
 
1770
                public override void WriteDebugSymbol (MonoSymbolFile file)
 
1771
                {
 
1772
                        if (debug_builder == null)
 
1773
                                return;
 
1774
 
 
1775
                        var token = ConstructorBuilder.GetToken ();
 
1776
                        int t = token.Token;
 
1777
#if STATIC
 
1778
                        if (ModuleBuilder.IsPseudoToken (t))
 
1779
                                t = Module.Builder.ResolvePseudoToken (t);
 
1780
#endif
 
1781
 
 
1782
                        debug_builder.DefineMethod (file, t);
 
1783
                }
 
1784
 
 
1785
                #region IMethodData Members
 
1786
 
 
1787
                public MemberName MethodName {
 
1788
                        get {
 
1789
                                return MemberName;
 
1790
                        }
 
1791
                }
 
1792
 
 
1793
                public TypeSpec ReturnType {
 
1794
                        get {
 
1795
                                return MemberType;
 
1796
                        }
 
1797
                }
 
1798
 
 
1799
                EmitContext IMethodData.CreateEmitContext (ILGenerator ig, SourceMethodBuilder sourceMethod)
 
1800
                {
 
1801
                        throw new NotImplementedException ();
 
1802
                }
 
1803
 
 
1804
                #endregion
 
1805
        }
 
1806
 
 
1807
        /// <summary>
 
1808
        /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
 
1809
        /// </summary>
 
1810
        public interface IMethodData : IMemberContext
 
1811
        {
 
1812
                CallingConventions CallingConventions { get; }
 
1813
                Location Location { get; }
 
1814
                MemberName MethodName { get; }
 
1815
                TypeSpec ReturnType { get; }
 
1816
                ParametersCompiled ParameterInfo { get; }
 
1817
                MethodSpec Spec { get; }
 
1818
                bool IsAccessor { get; }
 
1819
 
 
1820
                Attributes OptAttributes { get; }
 
1821
                ToplevelBlock Block { get; set; }
 
1822
 
 
1823
                EmitContext CreateEmitContext (ILGenerator ig, SourceMethodBuilder sourceMethod);
 
1824
        }
 
1825
 
 
1826
        //
 
1827
        // Encapsulates most of the Method's state
 
1828
        //
 
1829
        public class MethodData
 
1830
        {
 
1831
#if !STATIC
 
1832
                static FieldInfo methodbuilder_attrs_field;
 
1833
#endif
 
1834
 
 
1835
                public readonly IMethodData method;
 
1836
 
 
1837
                //
 
1838
                // Are we implementing an interface ?
 
1839
                //
 
1840
                public MethodSpec implementing;
 
1841
 
 
1842
                //
 
1843
                // Protected data.
 
1844
                //
 
1845
                protected InterfaceMemberBase member;
 
1846
                protected Modifiers modifiers;
 
1847
                protected MethodAttributes flags;
 
1848
                protected TypeSpec declaring_type;
 
1849
                protected MethodSpec parent_method;
 
1850
                SourceMethodBuilder debug_builder;
 
1851
 
 
1852
                MethodBuilder builder;
 
1853
                public MethodBuilder MethodBuilder {
 
1854
                        get {
 
1855
                                return builder;
 
1856
                        }
 
1857
                }
 
1858
 
 
1859
                public TypeSpec DeclaringType {
 
1860
                        get {
 
1861
                                return declaring_type;
 
1862
                        }
 
1863
                }
 
1864
 
 
1865
                public MethodData (InterfaceMemberBase member,
 
1866
                                   Modifiers modifiers, MethodAttributes flags, IMethodData method)
 
1867
                {
 
1868
                        this.member = member;
 
1869
                        this.modifiers = modifiers;
 
1870
                        this.flags = flags;
 
1871
 
 
1872
                        this.method = method;
 
1873
                }
 
1874
 
 
1875
                public MethodData (InterfaceMemberBase member,
 
1876
                                   Modifiers modifiers, MethodAttributes flags, 
 
1877
                                   IMethodData method, MethodBuilder builder,
 
1878
                                   MethodSpec parent_method)
 
1879
                        : this (member, modifiers, flags, method)
 
1880
                {
 
1881
                        this.builder = builder;
 
1882
                        this.parent_method = parent_method;
 
1883
                }
 
1884
 
 
1885
                public bool Define (TypeDefinition container, string method_full_name)
 
1886
                {
 
1887
                        PendingImplementation pending = container.PendingImplementations;
 
1888
                        MethodSpec ambig_iface_method;
 
1889
                        bool optional = false;
 
1890
 
 
1891
                        if (pending != null) {
 
1892
                                implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this, out ambig_iface_method, ref optional);
 
1893
 
 
1894
                                if (member.InterfaceType != null) {
 
1895
                                        if (implementing == null) {
 
1896
                                                if (member is PropertyBase) {
 
1897
                                                        container.Compiler.Report.Error (550, method.Location,
 
1898
                                                                "`{0}' is an accessor not found in interface member `{1}{2}'",
 
1899
                                                                          method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
 
1900
                                                                          member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));
 
1901
 
 
1902
                                                } else {
 
1903
                                                        container.Compiler.Report.Error (539, method.Location,
 
1904
                                                                          "`{0}.{1}' in explicit interface declaration is not a member of interface",
 
1905
                                                                          TypeManager.CSharpName (member.InterfaceType), member.ShortName);
 
1906
                                                }
 
1907
                                                return false;
 
1908
                                        }
 
1909
                                        if (implementing.IsAccessor && !method.IsAccessor) {
 
1910
                                                container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
 
1911
                                                container.Compiler.Report.Error (683, method.Location,
 
1912
                                                        "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
 
1913
                                                        member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
 
1914
                                                return false;
 
1915
                                        }
 
1916
                                } else {
 
1917
                                        if (implementing != null) {
 
1918
                                                if (!method.IsAccessor) {
 
1919
                                                        if (implementing.IsAccessor) {
 
1920
                                                                container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
 
1921
                                                                container.Compiler.Report.Error (470, method.Location,
 
1922
                                                                        "Method `{0}' cannot implement interface accessor `{1}'",
 
1923
                                                                        method.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
 
1924
                                                        }
 
1925
                                                } else if (implementing.DeclaringType.IsInterface) {
 
1926
                                                        if (!implementing.IsAccessor) {
 
1927
                                                                container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
 
1928
                                                                container.Compiler.Report.Error (686, method.Location,
 
1929
                                                                        "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
 
1930
                                                                        method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
 
1931
                                                        } else {
 
1932
                                                                PropertyBase.PropertyMethod pm = method as PropertyBase.PropertyMethod;
 
1933
                                                                if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
 
1934
                                                                        container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
 
1935
                                                                        container.Compiler.Report.Error (277, method.Location,
 
1936
                                                                                "Accessor `{0}' must be declared public to implement interface member `{1}'",
 
1937
                                                                                method.GetSignatureForError (), implementing.GetSignatureForError ());
 
1938
                                                                }
 
1939
                                                        }
 
1940
                                                }
 
1941
                                        }
 
1942
                                }
 
1943
                        } else {
 
1944
                                ambig_iface_method = null;
 
1945
                        }
 
1946
 
 
1947
                        //
 
1948
                        // For implicit implementations, make sure we are public, for
 
1949
                        // explicit implementations, make sure we are private.
 
1950
                        //
 
1951
                        if (implementing != null){
 
1952
                                if (member.IsExplicitImpl) {
 
1953
                                        if (method.ParameterInfo.HasParams && !implementing.Parameters.HasParams) {
 
1954
                                                container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
 
1955
                                                container.Compiler.Report.Error (466, method.Location,
 
1956
                                                        "`{0}': the explicit interface implementation cannot introduce the params modifier",
 
1957
                                                        method.GetSignatureForError ());
 
1958
                                        }
 
1959
 
 
1960
                                        if (ambig_iface_method != null) {
 
1961
                                                container.Compiler.Report.SymbolRelatedToPreviousError (ambig_iface_method);
 
1962
                                                container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
 
1963
                                                container.Compiler.Report.Warning (473, 2, method.Location,
 
1964
                                                        "Explicit interface implementation `{0}' matches more than one interface member. Consider using a non-explicit implementation instead",
 
1965
                                                        method.GetSignatureForError ());
 
1966
                                        }
 
1967
                                } else {
 
1968
                                        //
 
1969
                                        // Setting implementin to null inside this block will trigger a more
 
1970
                                        // verbose error reporting for missing interface implementations
 
1971
                                        //
 
1972
                                        if (implementing.DeclaringType.IsInterface) {
 
1973
                                                //
 
1974
                                                // If this is an interface method implementation,
 
1975
                                                // check for public accessibility
 
1976
                                                //
 
1977
                                                if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) {
 
1978
                                                        implementing = null;
 
1979
                                                } else if (optional && (container.Interfaces == null || !container.Definition.Interfaces.Contains (implementing.DeclaringType))) {
 
1980
                                                        //
 
1981
                                                        // We are not implementing interface when base class already implemented it
 
1982
                                                        //
 
1983
                                                        implementing = null;
 
1984
                                                }
 
1985
                                        } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private) {
 
1986
                                                // We may never be private.
 
1987
                                                implementing = null;
 
1988
 
 
1989
                                        } else if ((modifiers & Modifiers.OVERRIDE) == 0) {
 
1990
                                                //
 
1991
                                                // We may be protected if we're overriding something.
 
1992
                                                //
 
1993
                                                implementing = null;
 
1994
                                        }
 
1995
                                }
 
1996
                                        
 
1997
                                //
 
1998
                                // Static is not allowed
 
1999
                                //
 
2000
                                if ((modifiers & Modifiers.STATIC) != 0){
 
2001
                                        implementing = null;
 
2002
                                }
 
2003
                        }
 
2004
                        
 
2005
                        //
 
2006
                        // If implementing is still valid, set flags
 
2007
                        //
 
2008
                        if (implementing != null){
 
2009
                                //
 
2010
                                // When implementing interface methods, set NewSlot
 
2011
                                // unless, we are overwriting a method.
 
2012
                                //
 
2013
                                if ((modifiers & Modifiers.OVERRIDE) == 0 && implementing.DeclaringType.IsInterface) {
 
2014
                                        flags |= MethodAttributes.NewSlot;
 
2015
                                }
 
2016
 
 
2017
                                flags |= MethodAttributes.Virtual | MethodAttributes.HideBySig;
 
2018
 
 
2019
                                // Set Final unless we're virtual, abstract or already overriding a method.
 
2020
                                if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
 
2021
                                        flags |= MethodAttributes.Final;
 
2022
 
 
2023
                                //
 
2024
                                // clear the pending implementation flag (requires explicit methods to be defined first)
 
2025
                                //
 
2026
                                pending.ImplementMethod (method.MethodName,
 
2027
                                        member.InterfaceType, this, member.IsExplicitImpl, out ambig_iface_method, ref optional);
 
2028
 
 
2029
                                //
 
2030
                                // Update indexer accessor name to match implementing abstract accessor
 
2031
                                //
 
2032
                                if (!implementing.DeclaringType.IsInterface && !member.IsExplicitImpl && implementing.IsAccessor)
 
2033
                                        method_full_name = implementing.MemberDefinition.Name;
 
2034
                        }
 
2035
 
 
2036
                        DefineMethodBuilder (container, method_full_name, method.ParameterInfo);
 
2037
 
 
2038
                        if (builder == null)
 
2039
                                return false;
 
2040
 
 
2041
//                      if (container.CurrentType != null)
 
2042
//                              declaring_type = container.CurrentType;
 
2043
//                      else
 
2044
                                declaring_type = container.Definition;
 
2045
 
 
2046
                        if (implementing != null && member.IsExplicitImpl) {
 
2047
                                container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ());
 
2048
                        }
 
2049
 
 
2050
                        return true;
 
2051
                }
 
2052
 
 
2053
 
 
2054
                /// <summary>
 
2055
                /// Create the MethodBuilder for the method 
 
2056
                /// </summary>
 
2057
                void DefineMethodBuilder (TypeDefinition container, string method_name, ParametersCompiled param)
 
2058
                {
 
2059
                        var return_type = method.ReturnType.GetMetaInfo ();
 
2060
                        var p_types = param.GetMetaInfo ();
 
2061
 
 
2062
                        if (builder == null) {
 
2063
                                builder = container.TypeBuilder.DefineMethod (
 
2064
                                        method_name, flags, method.CallingConventions,
 
2065
                                        return_type, p_types);
 
2066
                                return;
 
2067
                        }
 
2068
 
 
2069
                        //
 
2070
                        // Generic method has been already defined to resolve method parameters
 
2071
                        // correctly when they use type parameters
 
2072
                        //
 
2073
                        builder.SetParameters (p_types);
 
2074
                        builder.SetReturnType (return_type);
 
2075
                        if (builder.Attributes != flags) {
 
2076
#if STATIC
 
2077
                                builder.__SetAttributes (flags);
 
2078
#else
 
2079
                                try {
 
2080
                                        if (methodbuilder_attrs_field == null)
 
2081
                                                methodbuilder_attrs_field = typeof (MethodBuilder).GetField ("attrs", BindingFlags.NonPublic | BindingFlags.Instance);
 
2082
                                        methodbuilder_attrs_field.SetValue (builder, flags);
 
2083
                                } catch {
 
2084
                                        container.Compiler.Report.RuntimeMissingSupport (method.Location, "Generic method MethodAttributes");
 
2085
                                }
 
2086
#endif
 
2087
                        }
 
2088
                }
 
2089
 
 
2090
                //
 
2091
                // Emits the code
 
2092
                // 
 
2093
                public void Emit (TypeDefinition parent)
 
2094
                {
 
2095
                        var mc = (IMemberContext) method;
 
2096
 
 
2097
                        method.ParameterInfo.ApplyAttributes (mc, MethodBuilder);
 
2098
 
 
2099
                        ToplevelBlock block = method.Block;
 
2100
                        if (block != null) {
 
2101
                                BlockContext bc = new BlockContext (mc, block, method.ReturnType);
 
2102
                                if (block.Resolve (null, bc, method)) {
 
2103
                                        debug_builder = member.Parent.CreateMethodSymbolEntry ();
 
2104
                                        EmitContext ec = method.CreateEmitContext (MethodBuilder.GetILGenerator (), debug_builder);
 
2105
 
 
2106
                                        block.Emit (ec);
 
2107
                                }
 
2108
                        }
 
2109
                }
 
2110
 
 
2111
                public void WriteDebugSymbol (MonoSymbolFile file)
 
2112
                {
 
2113
                        if (debug_builder == null)
 
2114
                                return;
 
2115
 
 
2116
                        var token = builder.GetToken ();
 
2117
                        int t = token.Token;
 
2118
#if STATIC
 
2119
                        if (ModuleBuilder.IsPseudoToken (t))
 
2120
                                t = member.Module.Builder.ResolvePseudoToken (t);
 
2121
#endif
 
2122
 
 
2123
                        debug_builder.DefineMethod (file, t);
 
2124
                }
 
2125
        }
 
2126
 
 
2127
        public class Destructor : MethodOrOperator
 
2128
        {
 
2129
                const Modifiers AllowedModifiers =
 
2130
                        Modifiers.UNSAFE |
 
2131
                        Modifiers.EXTERN;
 
2132
 
 
2133
                static readonly string[] attribute_targets = new string [] { "method" };
 
2134
 
 
2135
                public static readonly string MetadataName = "Finalize";
 
2136
 
 
2137
                public string Identifier {
 
2138
                        get;
 
2139
                        set;
 
2140
                }
 
2141
                
 
2142
                public Destructor (TypeDefinition parent, Modifiers mod, ParametersCompiled parameters, Attributes attrs, Location l)
 
2143
                        : base (parent, null, mod, AllowedModifiers, new MemberName (MetadataName, l), attrs, parameters)
 
2144
                {
 
2145
                        ModFlags &= ~Modifiers.PRIVATE;
 
2146
                        ModFlags |= Modifiers.PROTECTED | Modifiers.OVERRIDE;
 
2147
                }
 
2148
 
 
2149
                public override void Accept (StructuralVisitor visitor)
 
2150
                {
 
2151
                        visitor.Visit (this);
 
2152
                }
 
2153
 
 
2154
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
2155
                {
 
2156
                        if (a.Type == pa.Conditional) {
 
2157
                                Error_ConditionalAttributeIsNotValid ();
 
2158
                                return;
 
2159
                        }
 
2160
 
 
2161
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
2162
                }
 
2163
                
 
2164
                protected override bool CheckBase ()
 
2165
                {
 
2166
                        // Don't check base, destructors have special syntax
 
2167
                        return true;
 
2168
                }
 
2169
 
 
2170
                public override bool Define ()
 
2171
                {
 
2172
                        base.Define ();
 
2173
 
 
2174
                        if (Compiler.Settings.WriteMetadataOnly)
 
2175
                                block = null;
 
2176
 
 
2177
                        return true;
 
2178
                }
 
2179
 
 
2180
                public override void Emit()
 
2181
                {
 
2182
                        var base_type = Parent.PartialContainer.BaseType;
 
2183
                        if (base_type != null && Block != null) {
 
2184
                                var base_dtor = MemberCache.FindMember (base_type,
 
2185
                                        new MemberFilter (MetadataName, 0, MemberKind.Destructor, null, null), BindingRestriction.InstanceOnly) as MethodSpec;
 
2186
 
 
2187
                                if (base_dtor == null)
 
2188
                                        throw new NotImplementedException ();
 
2189
 
 
2190
                                MethodGroupExpr method_expr = MethodGroupExpr.CreatePredefined (base_dtor, base_type, Location);
 
2191
                                method_expr.InstanceExpression = new BaseThis (base_type, Location);
 
2192
 
 
2193
                                var try_block = new ExplicitBlock (block, block.StartLocation, block.EndLocation) {
 
2194
                                        IsCompilerGenerated = true
 
2195
                                };
 
2196
                                var finaly_block = new ExplicitBlock (block, Location, Location) {
 
2197
                                        IsCompilerGenerated = true
 
2198
                                };
 
2199
 
 
2200
                                //
 
2201
                                // 0-size arguments to avoid CS0250 error
 
2202
                                // TODO: Should use AddScopeStatement or something else which emits correct
 
2203
                                // debugger scope
 
2204
                                //
 
2205
                                finaly_block.AddStatement (new StatementExpression (new Invocation (method_expr, new Arguments (0)), Location.Null));
 
2206
 
 
2207
                                var tf = new TryFinally (try_block, finaly_block, Location);
 
2208
                                block.WrapIntoDestructor (tf, try_block);
 
2209
                        }
 
2210
 
 
2211
                        base.Emit ();
 
2212
                }
 
2213
 
 
2214
                public override string GetSignatureForError ()
 
2215
                {
 
2216
                        return Parent.GetSignatureForError () + ".~" + Parent.MemberName.Name + "()";
 
2217
                }
 
2218
 
 
2219
                protected override bool ResolveMemberType ()
 
2220
                {
 
2221
                        member_type = Compiler.BuiltinTypes.Void;
 
2222
                        return true;
 
2223
                }
 
2224
 
 
2225
                public override string[] ValidAttributeTargets {
 
2226
                        get {
 
2227
                                return attribute_targets;
 
2228
                        }
 
2229
                }
 
2230
        }
 
2231
 
 
2232
        // Ooouh Martin, templates are missing here.
 
2233
        // When it will be possible move here a lot of child code and template method type.
 
2234
        public abstract class AbstractPropertyEventMethod : MemberCore, IMethodData {
 
2235
                protected MethodData method_data;
 
2236
                protected ToplevelBlock block;
 
2237
                protected SecurityType declarative_security;
 
2238
 
 
2239
                protected readonly string prefix;
 
2240
 
 
2241
                ReturnParameter return_attributes;
 
2242
 
 
2243
                public AbstractPropertyEventMethod (InterfaceMemberBase member, string prefix, Attributes attrs, Location loc)
 
2244
                        : base (member.Parent, SetupName (prefix, member, loc), attrs)
 
2245
                {
 
2246
                        this.prefix = prefix;
 
2247
                }
 
2248
 
 
2249
                static MemberName SetupName (string prefix, InterfaceMemberBase member, Location loc)
 
2250
                {
 
2251
                        return new MemberName (member.MemberName.Left, prefix + member.ShortName, member.MemberName.ExplicitInterface, loc);
 
2252
                }
 
2253
 
 
2254
                public void UpdateName (InterfaceMemberBase member)
 
2255
                {
 
2256
                        SetMemberName (SetupName (prefix, member, Location));
 
2257
                }
 
2258
 
 
2259
                #region IMethodData Members
 
2260
 
 
2261
                public ToplevelBlock Block {
 
2262
                        get {
 
2263
                                return block;
 
2264
                        }
 
2265
 
 
2266
                        set {
 
2267
                                block = value;
 
2268
                        }
 
2269
                }
 
2270
 
 
2271
                public CallingConventions CallingConventions {
 
2272
                        get {
 
2273
                                return CallingConventions.Standard;
 
2274
                        }
 
2275
                }
 
2276
 
 
2277
                public EmitContext CreateEmitContext (ILGenerator ig, SourceMethodBuilder sourceMethod)
 
2278
                {
 
2279
                        return new EmitContext (this, ig, ReturnType, sourceMethod);
 
2280
                }
 
2281
 
 
2282
                public bool IsAccessor {
 
2283
                        get {
 
2284
                                return true;
 
2285
                        }
 
2286
                }
 
2287
 
 
2288
                public MemberName MethodName {
 
2289
                        get {
 
2290
                                return MemberName;
 
2291
                        }
 
2292
                }
 
2293
 
 
2294
                public TypeSpec[] ParameterTypes { 
 
2295
                        get {
 
2296
                                return ParameterInfo.Types;
 
2297
                        }
 
2298
                }
 
2299
 
 
2300
                public abstract ParametersCompiled ParameterInfo { get ; }
 
2301
                public abstract TypeSpec ReturnType { get; }
 
2302
 
 
2303
                #endregion
 
2304
 
 
2305
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
2306
                {
 
2307
                        if (a.Type == pa.CLSCompliant || a.Type == pa.Obsolete || a.Type == pa.Conditional) {
 
2308
                                Report.Error (1667, a.Location,
 
2309
                                        "Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
 
2310
                                        TypeManager.CSharpName (a.Type), a.GetValidTargets ());
 
2311
                                return;
 
2312
                        }
 
2313
 
 
2314
                        if (a.IsValidSecurityAttribute ()) {
 
2315
                                a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
 
2316
                                return;
 
2317
                        }
 
2318
 
 
2319
                        if (a.Target == AttributeTargets.Method) {
 
2320
                                method_data.MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
 
2321
                                return;
 
2322
                        }
 
2323
 
 
2324
                        if (a.Target == AttributeTargets.ReturnValue) {
 
2325
                                if (return_attributes == null)
 
2326
                                        return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
 
2327
 
 
2328
                                return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
2329
                                return;
 
2330
                        }
 
2331
 
 
2332
                        ApplyToExtraTarget (a, ctor, cdata, pa);
 
2333
                }
 
2334
 
 
2335
                protected virtual void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
2336
                {
 
2337
                        throw new NotSupportedException ("You forgot to define special attribute target handling");
 
2338
                }
 
2339
 
 
2340
                // It is not supported for the accessors
 
2341
                public sealed override bool Define()
 
2342
                {
 
2343
                        throw new NotSupportedException ();
 
2344
                }
 
2345
 
 
2346
                public virtual void Emit (TypeDefinition parent)
 
2347
                {
 
2348
                        method_data.Emit (parent);
 
2349
 
 
2350
                        if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated)
 
2351
                                Module.PredefinedAttributes.CompilerGenerated.EmitAttribute (method_data.MethodBuilder);
 
2352
                        if (((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0))
 
2353
                                Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (method_data.MethodBuilder);
 
2354
 
 
2355
                        if (ReturnType.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
 
2356
                                return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
 
2357
                                Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder);
 
2358
                        } else if (ReturnType.HasDynamicElement) {
 
2359
                                return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);
 
2360
                                Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType, Location);
 
2361
                        }
 
2362
 
 
2363
                        if (OptAttributes != null)
 
2364
                                OptAttributes.Emit ();
 
2365
 
 
2366
                        if (declarative_security != null) {
 
2367
                                foreach (var de in declarative_security) {
 
2368
#if STATIC
 
2369
                                        method_data.MethodBuilder.__AddDeclarativeSecurity (de);
 
2370
#else
 
2371
                                        method_data.MethodBuilder.AddDeclarativeSecurity (de.Key, de.Value);
 
2372
#endif
 
2373
                                }
 
2374
                        }
 
2375
 
 
2376
                        block = null;
 
2377
                }
 
2378
 
 
2379
                public override bool EnableOverloadChecks (MemberCore overload)
 
2380
                {
 
2381
                        if (overload is MethodCore) {
 
2382
                                caching_flags |= Flags.MethodOverloadsExist;
 
2383
                                return true;
 
2384
                        }
 
2385
 
 
2386
                        // This can only happen with indexers and it will
 
2387
                        // be catched as indexer difference
 
2388
                        if (overload is AbstractPropertyEventMethod)
 
2389
                                return true;
 
2390
 
 
2391
                        return false;
 
2392
                }
 
2393
 
 
2394
                public override string GetCallerMemberName ()
 
2395
                {
 
2396
                        return base.GetCallerMemberName ().Substring (prefix.Length);
 
2397
                }
 
2398
 
 
2399
                public override string GetSignatureForDocumentation ()
 
2400
                {
 
2401
                        // should not be called
 
2402
                        throw new NotSupportedException ();
 
2403
                }
 
2404
 
 
2405
                public override bool IsClsComplianceRequired()
 
2406
                {
 
2407
                        return false;
 
2408
                }
 
2409
 
 
2410
                public override void WriteDebugSymbol (MonoSymbolFile file)
 
2411
                {
 
2412
                        if (method_data != null)
 
2413
                                method_data.WriteDebugSymbol (file);
 
2414
                }
 
2415
 
 
2416
                public MethodSpec Spec { get; protected set; }
 
2417
 
 
2418
                //
 
2419
                //   Represents header string for documentation comment.
 
2420
                //
 
2421
                public override string DocCommentHeader {
 
2422
                        get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
 
2423
                }
 
2424
        }
 
2425
 
 
2426
        public class Operator : MethodOrOperator {
 
2427
 
 
2428
                const Modifiers AllowedModifiers =
 
2429
                        Modifiers.PUBLIC |
 
2430
                        Modifiers.UNSAFE |
 
2431
                        Modifiers.EXTERN |
 
2432
                        Modifiers.STATIC;
 
2433
 
 
2434
                public enum OpType : byte {
 
2435
 
 
2436
                        // Unary operators
 
2437
                        LogicalNot,
 
2438
                        OnesComplement,
 
2439
                        Increment,
 
2440
                        Decrement,
 
2441
                        True,
 
2442
                        False,
 
2443
 
 
2444
                        // Unary and Binary operators
 
2445
                        Addition,
 
2446
                        Subtraction,
 
2447
 
 
2448
                        UnaryPlus,
 
2449
                        UnaryNegation,
 
2450
                        
 
2451
                        // Binary operators
 
2452
                        Multiply,
 
2453
                        Division,
 
2454
                        Modulus,
 
2455
                        BitwiseAnd,
 
2456
                        BitwiseOr,
 
2457
                        ExclusiveOr,
 
2458
                        LeftShift,
 
2459
                        RightShift,
 
2460
                        Equality,
 
2461
                        Inequality,
 
2462
                        GreaterThan,
 
2463
                        LessThan,
 
2464
                        GreaterThanOrEqual,
 
2465
                        LessThanOrEqual,
 
2466
 
 
2467
                        // Implicit and Explicit
 
2468
                        Implicit,
 
2469
                        Explicit,
 
2470
 
 
2471
                        // Just because of enum
 
2472
                        TOP
 
2473
                };
 
2474
 
 
2475
                public readonly OpType OperatorType;
 
2476
 
 
2477
                static readonly string [] [] names;
 
2478
 
 
2479
                static Operator ()
 
2480
                {
 
2481
                        names = new string[(int)OpType.TOP][];
 
2482
                        names [(int) OpType.LogicalNot] = new string [] { "!", "op_LogicalNot" };
 
2483
                        names [(int) OpType.OnesComplement] = new string [] { "~", "op_OnesComplement" };
 
2484
                        names [(int) OpType.Increment] = new string [] { "++", "op_Increment" };
 
2485
                        names [(int) OpType.Decrement] = new string [] { "--", "op_Decrement" };
 
2486
                        names [(int) OpType.True] = new string [] { "true", "op_True" };
 
2487
                        names [(int) OpType.False] = new string [] { "false", "op_False" };
 
2488
                        names [(int) OpType.Addition] = new string [] { "+", "op_Addition" };
 
2489
                        names [(int) OpType.Subtraction] = new string [] { "-", "op_Subtraction" };
 
2490
                        names [(int) OpType.UnaryPlus] = new string [] { "+", "op_UnaryPlus" };
 
2491
                        names [(int) OpType.UnaryNegation] = new string [] { "-", "op_UnaryNegation" };
 
2492
                        names [(int) OpType.Multiply] = new string [] { "*", "op_Multiply" };
 
2493
                        names [(int) OpType.Division] = new string [] { "/", "op_Division" };
 
2494
                        names [(int) OpType.Modulus] = new string [] { "%", "op_Modulus" };
 
2495
                        names [(int) OpType.BitwiseAnd] = new string [] { "&", "op_BitwiseAnd" };
 
2496
                        names [(int) OpType.BitwiseOr] = new string [] { "|", "op_BitwiseOr" };
 
2497
                        names [(int) OpType.ExclusiveOr] = new string [] { "^", "op_ExclusiveOr" };
 
2498
                        names [(int) OpType.LeftShift] = new string [] { "<<", "op_LeftShift" };
 
2499
                        names [(int) OpType.RightShift] = new string [] { ">>", "op_RightShift" };
 
2500
                        names [(int) OpType.Equality] = new string [] { "==", "op_Equality" };
 
2501
                        names [(int) OpType.Inequality] = new string [] { "!=", "op_Inequality" };
 
2502
                        names [(int) OpType.GreaterThan] = new string [] { ">", "op_GreaterThan" };
 
2503
                        names [(int) OpType.LessThan] = new string [] { "<", "op_LessThan" };
 
2504
                        names [(int) OpType.GreaterThanOrEqual] = new string [] { ">=", "op_GreaterThanOrEqual" };
 
2505
                        names [(int) OpType.LessThanOrEqual] = new string [] { "<=", "op_LessThanOrEqual" };
 
2506
                        names [(int) OpType.Implicit] = new string [] { "implicit", "op_Implicit" };
 
2507
                        names [(int) OpType.Explicit] = new string [] { "explicit", "op_Explicit" };
 
2508
                }
 
2509
 
 
2510
                public Operator (TypeDefinition parent, OpType type, FullNamedExpression ret_type, Modifiers mod_flags, ParametersCompiled parameters,
 
2511
                                 ToplevelBlock block, Attributes attrs, Location loc)
 
2512
                        : base (parent, ret_type, mod_flags, AllowedModifiers, new MemberName (GetMetadataName (type), loc), attrs, parameters)
 
2513
                {
 
2514
                        OperatorType = type;
 
2515
                        Block = block;
 
2516
                }
 
2517
 
 
2518
                public override void Accept (StructuralVisitor visitor)
 
2519
                {
 
2520
                        visitor.Visit (this);
 
2521
                }
 
2522
 
 
2523
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
2524
                {
 
2525
                        if (a.Type == pa.Conditional) {
 
2526
                                Error_ConditionalAttributeIsNotValid ();
 
2527
                                return;
 
2528
                        }
 
2529
 
 
2530
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
2531
                }
 
2532
                
 
2533
                public override bool Define ()
 
2534
                {
 
2535
                        const Modifiers RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
 
2536
                        if ((ModFlags & RequiredModifiers) != RequiredModifiers){
 
2537
                                Report.Error (558, Location, "User-defined operator `{0}' must be declared static and public", GetSignatureForError ());
 
2538
                        }
 
2539
 
 
2540
                        if (!base.Define ())
 
2541
                                return false;
 
2542
 
 
2543
                        if (block != null) {
 
2544
                                if (block.IsIterator) {
 
2545
                                        //
 
2546
                                        // Current method is turned into automatically generated
 
2547
                                        // wrapper which creates an instance of iterator
 
2548
                                        //
 
2549
                                        Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
 
2550
                                        ModFlags |= Modifiers.DEBUGGER_HIDDEN;
 
2551
                                }
 
2552
 
 
2553
                                if (Compiler.Settings.WriteMetadataOnly)
 
2554
                                        block = null;
 
2555
                        }
 
2556
 
 
2557
                        // imlicit and explicit operator of same types are not allowed
 
2558
                        if (OperatorType == OpType.Explicit)
 
2559
                                Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), parameters);
 
2560
                        else if (OperatorType == OpType.Implicit)
 
2561
                                Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Explicit), parameters);
 
2562
 
 
2563
                        TypeSpec declaring_type = Parent.CurrentType;
 
2564
                        TypeSpec return_type = MemberType;
 
2565
                        TypeSpec first_arg_type = ParameterTypes [0];
 
2566
                        
 
2567
                        TypeSpec first_arg_type_unwrap = first_arg_type;
 
2568
                        if (first_arg_type.IsNullableType)
 
2569
                                first_arg_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (first_arg_type);
 
2570
                        
 
2571
                        TypeSpec return_type_unwrap = return_type;
 
2572
                        if (return_type.IsNullableType)
 
2573
                                return_type_unwrap = Nullable.NullableInfo.GetUnderlyingType (return_type);
 
2574
 
 
2575
                        //
 
2576
                        // Rules for conversion operators
 
2577
                        //
 
2578
                        if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
 
2579
                                if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type) {
 
2580
                                        Report.Error (555, Location,
 
2581
                                                "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
 
2582
                                        return false;
 
2583
                                }
 
2584
 
 
2585
                                TypeSpec conv_type;
 
2586
                                if (declaring_type == return_type || declaring_type == return_type_unwrap) {
 
2587
                                        conv_type = first_arg_type;
 
2588
                                } else if (declaring_type == first_arg_type || declaring_type == first_arg_type_unwrap) {
 
2589
                                        conv_type = return_type;
 
2590
                                } else {
 
2591
                                        Report.Error (556, Location,
 
2592
                                                "User-defined conversion must convert to or from the enclosing type");
 
2593
                                        return false;
 
2594
                                }
 
2595
 
 
2596
                                if (conv_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
 
2597
                                        Report.Error (1964, Location,
 
2598
                                                "User-defined conversion `{0}' cannot convert to or from the dynamic type",
 
2599
                                                GetSignatureForError ());
 
2600
 
 
2601
                                        return false;
 
2602
                                }
 
2603
 
 
2604
                                if (conv_type.IsInterface) {
 
2605
                                        Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
 
2606
                                                GetSignatureForError ());
 
2607
                                        return false;
 
2608
                                }
 
2609
 
 
2610
                                if (conv_type.IsClass) {
 
2611
                                        if (TypeSpec.IsBaseClass (declaring_type, conv_type, true)) {
 
2612
                                                Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
 
2613
                                                        GetSignatureForError ());
 
2614
                                                return false;
 
2615
                                        }
 
2616
 
 
2617
                                        if (TypeSpec.IsBaseClass (conv_type, declaring_type, false)) {
 
2618
                                                Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
 
2619
                                                        GetSignatureForError ());
 
2620
                                                return false;
 
2621
                                        }
 
2622
                                }
 
2623
                        } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
 
2624
                                if (first_arg_type != declaring_type || parameters.Types[1].BuiltinType != BuiltinTypeSpec.Type.Int) {
 
2625
                                        Report.Error (564, Location, "Overloaded shift operator must have the type of the first operand be the containing type, and the type of the second operand must be int");
 
2626
                                        return false;
 
2627
                                }
 
2628
                        } else if (parameters.Count == 1) {
 
2629
                                // Checks for Unary operators
 
2630
 
 
2631
                                if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
 
2632
                                        if (return_type != declaring_type && !TypeSpec.IsBaseClass (return_type, declaring_type, false)) {
 
2633
                                                Report.Error (448, Location,
 
2634
                                                        "The return type for ++ or -- operator must be the containing type or derived from the containing type");
 
2635
                                                return false;
 
2636
                                        }
 
2637
                                        if (first_arg_type != declaring_type) {
 
2638
                                                Report.Error (
 
2639
                                                        559, Location, "The parameter type for ++ or -- operator must be the containing type");
 
2640
                                                return false;
 
2641
                                        }
 
2642
                                }
 
2643
 
 
2644
                                if (first_arg_type_unwrap != declaring_type) {
 
2645
                                        Report.Error (562, Location,
 
2646
                                                "The parameter type of a unary operator must be the containing type");
 
2647
                                        return false;
 
2648
                                }
 
2649
 
 
2650
                                if (OperatorType == OpType.True || OperatorType == OpType.False) {
 
2651
                                        if (return_type.BuiltinType != BuiltinTypeSpec.Type.Bool) {
 
2652
                                                Report.Error (
 
2653
                                                        215, Location,
 
2654
                                                        "The return type of operator True or False " +
 
2655
                                                        "must be bool");
 
2656
                                                return false;
 
2657
                                        }
 
2658
                                }
 
2659
 
 
2660
                        } else if (first_arg_type_unwrap != declaring_type) {
 
2661
                                // Checks for Binary operators
 
2662
 
 
2663
                                var second_arg_type = ParameterTypes[1];
 
2664
                                if (second_arg_type.IsNullableType)
 
2665
                                        second_arg_type = Nullable.NullableInfo.GetUnderlyingType (second_arg_type);
 
2666
 
 
2667
                                if (second_arg_type != declaring_type) {
 
2668
                                        Report.Error (563, Location,
 
2669
                                                "One of the parameters of a binary operator must be the containing type");
 
2670
                                        return false;
 
2671
                                }
 
2672
                        }
 
2673
 
 
2674
                        return true;
 
2675
                }
 
2676
 
 
2677
                protected override bool ResolveMemberType ()
 
2678
                {
 
2679
                        if (!base.ResolveMemberType ())
 
2680
                                return false;
 
2681
 
 
2682
                        flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
 
2683
                        return true;
 
2684
                }
 
2685
 
 
2686
                protected override MemberSpec FindBaseMember (out MemberSpec bestCandidate, ref bool overrides)
 
2687
                {
 
2688
                        // Operator cannot be override
 
2689
                        bestCandidate = null;
 
2690
                        return null;
 
2691
                }
 
2692
 
 
2693
                public static string GetName (OpType ot)
 
2694
                {
 
2695
                        return names [(int) ot] [0];
 
2696
                }
 
2697
 
 
2698
                public static string GetName (string metadata_name)
 
2699
                {
 
2700
                        for (int i = 0; i < names.Length; ++i) {
 
2701
                                if (names [i] [1] == metadata_name)
 
2702
                                        return names [i] [0];
 
2703
                        }
 
2704
                        return null;
 
2705
                }
 
2706
 
 
2707
                public static string GetMetadataName (OpType ot)
 
2708
                {
 
2709
                        return names [(int) ot] [1];
 
2710
                }
 
2711
 
 
2712
                public static string GetMetadataName (string name)
 
2713
                {
 
2714
                        for (int i = 0; i < names.Length; ++i) {
 
2715
                                if (names [i] [0] == name)
 
2716
                                        return names [i] [1];
 
2717
                        }
 
2718
                        return null;
 
2719
                }
 
2720
 
 
2721
                public static OpType? GetType (string metadata_name)
 
2722
                {
 
2723
                        for (int i = 0; i < names.Length; ++i) {
 
2724
                                if (names[i][1] == metadata_name)
 
2725
                                        return (OpType) i;
 
2726
                        }
 
2727
 
 
2728
                        return null;
 
2729
                }
 
2730
 
 
2731
                public OpType GetMatchingOperator ()
 
2732
                {
 
2733
                        switch (OperatorType) {
 
2734
                        case OpType.Equality:
 
2735
                                return OpType.Inequality;
 
2736
                        case OpType.Inequality:
 
2737
                                return OpType.Equality;
 
2738
                        case OpType.True:
 
2739
                                return OpType.False;
 
2740
                        case OpType.False:
 
2741
                                return OpType.True;
 
2742
                        case OpType.GreaterThan:
 
2743
                                return OpType.LessThan;
 
2744
                        case OpType.LessThan:
 
2745
                                return OpType.GreaterThan;
 
2746
                        case OpType.GreaterThanOrEqual:
 
2747
                                return OpType.LessThanOrEqual;
 
2748
                        case OpType.LessThanOrEqual:
 
2749
                                return OpType.GreaterThanOrEqual;
 
2750
                        default:
 
2751
                                return OpType.TOP;
 
2752
                        }
 
2753
                }
 
2754
 
 
2755
                public override string GetSignatureForDocumentation ()
 
2756
                {
 
2757
                        string s = base.GetSignatureForDocumentation ();
 
2758
                        if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
 
2759
                                s = s + "~" + ReturnType.GetSignatureForDocumentation ();
 
2760
                        }
 
2761
 
 
2762
                        return s;
 
2763
                }
 
2764
 
 
2765
                public override string GetSignatureForError ()
 
2766
                {
 
2767
                        StringBuilder sb = new StringBuilder ();
 
2768
                        if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
 
2769
                                sb.AppendFormat ("{0}.{1} operator {2}",
 
2770
                                        Parent.GetSignatureForError (), GetName (OperatorType),
 
2771
                                        member_type == null ? type_expr.GetSignatureForError () : member_type.GetSignatureForError ());
 
2772
                        }
 
2773
                        else {
 
2774
                                sb.AppendFormat ("{0}.operator {1}", Parent.GetSignatureForError (), GetName (OperatorType));
 
2775
                        }
 
2776
 
 
2777
                        sb.Append (parameters.GetSignatureForError ());
 
2778
                        return sb.ToString ();
 
2779
                }
 
2780
        }
 
2781
}
 
2782