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

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/property.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
// property.cs: Property based handlers
 
3
//
 
4
// Authors: Miguel de Icaza (miguel@gnu.org)
 
5
//          Martin Baulig (martin@ximian.com)
 
6
//          Marek Safar (marek.safar@seznam.cz)
 
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.Text;
 
18
using Mono.CompilerServices.SymbolWriter;
 
19
 
 
20
#if NET_2_1
 
21
using XmlElement = System.Object;
 
22
#endif
 
23
 
 
24
#if STATIC
 
25
using IKVM.Reflection;
 
26
using IKVM.Reflection.Emit;
 
27
#else
 
28
using System.Reflection;
 
29
using System.Reflection.Emit;
 
30
#endif
 
31
 
 
32
namespace Mono.CSharp
 
33
{
 
34
        // It is used as a base class for all property based members
 
35
        // This includes properties, indexers, and events
 
36
        public abstract class PropertyBasedMember : InterfaceMemberBase
 
37
        {
 
38
                public PropertyBasedMember (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs)
 
39
                        : base (parent, type, mod, allowed_mod, name, attrs)
 
40
                {
 
41
                }
 
42
 
 
43
                protected void CheckReservedNameConflict (string prefix, MethodSpec accessor)
 
44
                {
 
45
                        string name;
 
46
                        AParametersCollection parameters;
 
47
                        if (accessor != null) {
 
48
                                name = accessor.Name;
 
49
                                parameters = accessor.Parameters;
 
50
                        } else {
 
51
                                name = prefix + ShortName;
 
52
                                if (IsExplicitImpl)
 
53
                                        name = MemberName.Left + "." + name;
 
54
 
 
55
                                if (this is Indexer) {
 
56
                                        parameters = ((Indexer) this).ParameterInfo;
 
57
                                        if (prefix[0] == 's') {
 
58
                                                var data = new IParameterData[parameters.Count + 1];
 
59
                                                Array.Copy (parameters.FixedParameters, data, data.Length - 1);
 
60
                                                data[data.Length - 1] = new ParameterData ("value", Parameter.Modifier.NONE);
 
61
                                                var types = new TypeSpec[data.Length];
 
62
                                                Array.Copy (parameters.Types, types, data.Length - 1);
 
63
                                                types[data.Length - 1] = member_type;
 
64
 
 
65
                                                parameters = new ParametersImported (data, types, false);
 
66
                                        }
 
67
                                } else {
 
68
                                        if (prefix[0] == 's')
 
69
                                                parameters = ParametersCompiled.CreateFullyResolved (new[] { member_type });
 
70
                                        else
 
71
                                                parameters = ParametersCompiled.EmptyReadOnlyParameters;
 
72
                                }
 
73
                        }
 
74
 
 
75
                        var conflict = MemberCache.FindMember (Parent.Definition,
 
76
                                new MemberFilter (name, 0, MemberKind.Method, parameters, null),
 
77
                                BindingRestriction.DeclaredOnly | BindingRestriction.NoAccessors);
 
78
 
 
79
                        if (conflict != null) {
 
80
                                Report.SymbolRelatedToPreviousError (conflict);
 
81
                                Report.Error (82, Location, "A member `{0}' is already reserved", conflict.GetSignatureForError ());
 
82
                        }
 
83
                }
 
84
 
 
85
                protected override bool VerifyClsCompliance ()
 
86
                {
 
87
                        if (!base.VerifyClsCompliance ())
 
88
                                return false;
 
89
 
 
90
                        if (!MemberType.IsCLSCompliant ()) {
 
91
                                Report.Warning (3003, 1, Location, "Type of `{0}' is not CLS-compliant",
 
92
                                        GetSignatureForError ());
 
93
                        }
 
94
                        return true;
 
95
                }
 
96
 
 
97
        }
 
98
 
 
99
        public class PropertySpec : MemberSpec, IInterfaceMemberSpec
 
100
        {
 
101
                PropertyInfo info;
 
102
                TypeSpec memberType;
 
103
                MethodSpec set, get;
 
104
 
 
105
                public PropertySpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, PropertyInfo info, Modifiers modifiers)
 
106
                        : base (kind, declaringType, definition, modifiers)
 
107
                {
 
108
                        this.info = info;
 
109
                        this.memberType = memberType;
 
110
                }
 
111
 
 
112
                #region Properties
 
113
 
 
114
                public MethodSpec Get {
 
115
                        get {
 
116
                                return get;
 
117
                        }
 
118
                        set {
 
119
                                get = value;
 
120
                                get.IsAccessor = true;
 
121
                        }
 
122
                }
 
123
 
 
124
                public MethodSpec Set { 
 
125
                        get {
 
126
                                return set;
 
127
                        }
 
128
                        set {
 
129
                                set = value;
 
130
                                set.IsAccessor = true;
 
131
                        }
 
132
                }
 
133
 
 
134
                public bool HasDifferentAccessibility {
 
135
                        get {
 
136
                                return HasGet && HasSet && 
 
137
                                        (Get.Modifiers & Modifiers.AccessibilityMask) != (Set.Modifiers & Modifiers.AccessibilityMask);
 
138
                        }
 
139
                }
 
140
 
 
141
                public bool HasGet {
 
142
                        get {
 
143
                                return Get != null;
 
144
                        }
 
145
                }
 
146
 
 
147
                public bool HasSet {
 
148
                        get {
 
149
                                return Set != null;
 
150
                        }
 
151
                }
 
152
 
 
153
                public PropertyInfo MetaInfo {
 
154
                        get {
 
155
                                if ((state & StateFlags.PendingMetaInflate) != 0)
 
156
                                        throw new NotSupportedException ();
 
157
 
 
158
                                return info;
 
159
                        }
 
160
                }
 
161
 
 
162
                public TypeSpec MemberType {
 
163
                        get {
 
164
                                return memberType;
 
165
                        }
 
166
                }
 
167
 
 
168
                #endregion
 
169
 
 
170
                public override MemberSpec InflateMember (TypeParameterInflator inflator)
 
171
                {
 
172
                        var ps = (PropertySpec) base.InflateMember (inflator);
 
173
                        ps.memberType = inflator.Inflate (memberType);
 
174
                        return ps;
 
175
                }
 
176
 
 
177
                public override List<TypeSpec> ResolveMissingDependencies ()
 
178
                {
 
179
                        return memberType.ResolveMissingDependencies ();
 
180
                }
 
181
        }
 
182
 
 
183
        //
 
184
        // Properties and Indexers both generate PropertyBuilders, we use this to share 
 
185
        // their common bits.
 
186
        //
 
187
        abstract public class PropertyBase : PropertyBasedMember {
 
188
 
 
189
                public class GetMethod : PropertyMethod
 
190
                {
 
191
                        static readonly string[] attribute_targets = new string [] { "method", "return" };
 
192
 
 
193
                        internal const string Prefix = "get_";
 
194
 
 
195
                        public GetMethod (PropertyBase method, Modifiers modifiers, Attributes attrs, Location loc)
 
196
                                : base (method, Prefix, modifiers, attrs, loc)
 
197
                        {
 
198
                        }
 
199
 
 
200
                        public override MethodBuilder Define (TypeContainer parent)
 
201
                        {
 
202
                                base.Define (parent);
 
203
 
 
204
                                Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);
 
205
 
 
206
                                method_data = new MethodData (method, ModFlags, flags, this);
 
207
 
 
208
                                if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
 
209
                                        return null;
 
210
 
 
211
                                Spec.SetMetaInfo (method_data.MethodBuilder);
 
212
 
 
213
                                return method_data.MethodBuilder;
 
214
                        }
 
215
 
 
216
                        public override TypeSpec ReturnType {
 
217
                                get {
 
218
                                        return method.MemberType;
 
219
                                }
 
220
                        }
 
221
 
 
222
                        public override ParametersCompiled ParameterInfo {
 
223
                                get {
 
224
                                        return ParametersCompiled.EmptyReadOnlyParameters;
 
225
                                }
 
226
                        }
 
227
 
 
228
                        public override string[] ValidAttributeTargets {
 
229
                                get {
 
230
                                        return attribute_targets;
 
231
                                }
 
232
                        }
 
233
                }
 
234
 
 
235
                public class SetMethod : PropertyMethod {
 
236
 
 
237
                        static readonly string[] attribute_targets = new string[] { "method", "param", "return" };
 
238
 
 
239
                        internal const string Prefix = "set_";
 
240
 
 
241
                        protected ParametersCompiled parameters;
 
242
 
 
243
                        public SetMethod (PropertyBase method, Modifiers modifiers, ParametersCompiled parameters, Attributes attrs, Location loc)
 
244
                                : base (method, Prefix, modifiers, attrs, loc)
 
245
                        {
 
246
                                this.parameters = parameters;
 
247
                        }
 
248
 
 
249
                        protected override void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
250
                        {
 
251
                                if (a.Target == AttributeTargets.Parameter) {
 
252
                                        parameters[0].ApplyAttributeBuilder (a, ctor, cdata, pa);
 
253
                                        return;
 
254
                                }
 
255
 
 
256
                                base.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
257
                        }
 
258
 
 
259
                        public override ParametersCompiled ParameterInfo {
 
260
                            get {
 
261
                                return parameters;
 
262
                            }
 
263
                        }
 
264
 
 
265
                        public override MethodBuilder Define (TypeContainer parent)
 
266
                        {
 
267
                                parameters.Resolve (this);
 
268
                                
 
269
                                base.Define (parent);
 
270
 
 
271
                                Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);
 
272
 
 
273
                                method_data = new MethodData (method, ModFlags, flags, this);
 
274
 
 
275
                                if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
 
276
                                        return null;
 
277
 
 
278
                                Spec.SetMetaInfo (method_data.MethodBuilder);
 
279
 
 
280
                                return method_data.MethodBuilder;
 
281
                        }
 
282
 
 
283
                        public override TypeSpec ReturnType {
 
284
                                get {
 
285
                                        return Parent.Compiler.BuiltinTypes.Void;
 
286
                                }
 
287
                        }
 
288
 
 
289
                        public override string[] ValidAttributeTargets {
 
290
                                get {
 
291
                                        return attribute_targets;
 
292
                                }
 
293
                        }
 
294
                }
 
295
 
 
296
                static readonly string[] attribute_targets = new string[] { "property" };
 
297
 
 
298
                public abstract class PropertyMethod : AbstractPropertyEventMethod
 
299
                {
 
300
                        const Modifiers AllowedModifiers =
 
301
                                Modifiers.PUBLIC |
 
302
                                Modifiers.PROTECTED |
 
303
                                Modifiers.INTERNAL |
 
304
                                Modifiers.PRIVATE;
 
305
                
 
306
                        protected readonly PropertyBase method;
 
307
                        protected MethodAttributes flags;
 
308
 
 
309
                        public PropertyMethod (PropertyBase method, string prefix, Modifiers modifiers, Attributes attrs, Location loc)
 
310
                                : base (method, prefix, attrs, loc)
 
311
                        {
 
312
                                this.method = method;
 
313
                                this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, modifiers, 0, loc, Report);
 
314
                                this.ModFlags |= (method.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE));
 
315
                        }
 
316
 
 
317
                        public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
318
                        {
 
319
                                if (a.Type == pa.MethodImpl) {
 
320
                                        method.is_external_implementation = a.IsInternalCall ();
 
321
                                }
 
322
 
 
323
                                base.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
324
                        }
 
325
 
 
326
                        public override AttributeTargets AttributeTargets {
 
327
                                get {
 
328
                                        return AttributeTargets.Method;
 
329
                                }
 
330
                        }
 
331
 
 
332
                        public override bool IsClsComplianceRequired ()
 
333
                        {
 
334
                                return method.IsClsComplianceRequired ();
 
335
                        }
 
336
 
 
337
                        public virtual MethodBuilder Define (TypeContainer parent)
 
338
                        {
 
339
                                var container = parent.PartialContainer;
 
340
 
 
341
                                //
 
342
                                // Check for custom access modifier
 
343
                                //
 
344
                                if ((ModFlags & Modifiers.AccessibilityMask) == 0) {
 
345
                                        ModFlags |= method.ModFlags;
 
346
                                        flags = method.flags;
 
347
                                } else {
 
348
                                        if (container.Kind == MemberKind.Interface)
 
349
                                                Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
 
350
                                                        GetSignatureForError ());
 
351
                                        else if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
 
352
                                                Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
 
353
                                        }
 
354
 
 
355
                                        CheckModifiers (ModFlags);
 
356
                                        ModFlags |= (method.ModFlags & (~Modifiers.AccessibilityMask));
 
357
                                        ModFlags |= Modifiers.PROPERTY_CUSTOM;
 
358
                                        flags = ModifiersExtensions.MethodAttr (ModFlags);
 
359
                                        flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
 
360
                                }
 
361
 
 
362
                                CheckAbstractAndExtern (block != null);
 
363
                                CheckProtectedModifier ();
 
364
 
 
365
                                if (block != null) {
 
366
                                        if (block.IsIterator)
 
367
                                                Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
 
368
 
 
369
                                        if (Compiler.Settings.WriteMetadataOnly)
 
370
                                                block = null;
 
371
                                }
 
372
 
 
373
                                return null;
 
374
                        }
 
375
 
 
376
                        public bool HasCustomAccessModifier {
 
377
                                get {
 
378
                                        return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
 
379
                                }
 
380
                        }
 
381
 
 
382
                        public PropertyBase Property {
 
383
                                get {
 
384
                                        return method;
 
385
                                }
 
386
                        }
 
387
 
 
388
                        public override ObsoleteAttribute GetAttributeObsolete ()
 
389
                        {
 
390
                                return method.GetAttributeObsolete ();
 
391
                        }
 
392
 
 
393
                        public override string GetSignatureForError()
 
394
                        {
 
395
                                return method.GetSignatureForError () + "." + prefix.Substring (0, 3);
 
396
                        }
 
397
 
 
398
                        void CheckModifiers (Modifiers modflags)
 
399
                        {
 
400
                                if (!ModifiersExtensions.IsRestrictedModifier (modflags & Modifiers.AccessibilityMask, method.ModFlags & Modifiers.AccessibilityMask)) {
 
401
                                        Report.Error (273, Location,
 
402
                                                "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
 
403
                                                GetSignatureForError (), method.GetSignatureForError ());
 
404
                                }
 
405
                        }
 
406
                }
 
407
 
 
408
                PropertyMethod get, set, first;
 
409
                PropertyBuilder PropertyBuilder;
 
410
 
 
411
                public PropertyBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, Modifiers allowed_mod, MemberName name, Attributes attrs)
 
412
                        : base (parent, type, mod_flags, allowed_mod, name, attrs)
 
413
                {
 
414
                }
 
415
 
 
416
                #region Properties
 
417
 
 
418
                public override AttributeTargets AttributeTargets {
 
419
                        get {
 
420
                                return AttributeTargets.Property;
 
421
                        }
 
422
                }
 
423
 
 
424
                public PropertyMethod AccessorFirst {
 
425
                        get {
 
426
                                return first;
 
427
                        }
 
428
                }
 
429
 
 
430
                public PropertyMethod AccessorSecond {
 
431
                        get {
 
432
                                return first == get ? set : get;
 
433
                        }
 
434
                }
 
435
 
 
436
                public override Variance ExpectedMemberTypeVariance {
 
437
                        get {
 
438
                                return (get != null && set != null) ?
 
439
                                        Variance.None : set == null ?
 
440
                                        Variance.Covariant :
 
441
                                        Variance.Contravariant;
 
442
                        }
 
443
                }
 
444
 
 
445
                public PropertyMethod Get {
 
446
                        get {
 
447
                                return get;
 
448
                        }
 
449
                        set {
 
450
                                get = value;
 
451
                                if (first == null)
 
452
                                        first = value;
 
453
 
 
454
                                Parent.AddNameToContainer (get, get.MemberName.Basename);
 
455
                        }
 
456
                }
 
457
 
 
458
                public PropertyMethod Set {
 
459
                        get {
 
460
                                return set;
 
461
                        }
 
462
                        set {
 
463
                                set = value;
 
464
                                if (first == null)
 
465
                                        first = value;
 
466
 
 
467
                                Parent.AddNameToContainer (set, set.MemberName.Basename);
 
468
                        }
 
469
                }
 
470
 
 
471
                public override string[] ValidAttributeTargets {
 
472
                        get {
 
473
                                return attribute_targets;
 
474
                        }
 
475
                }
 
476
 
 
477
                #endregion
 
478
 
 
479
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
480
                {
 
481
                        if (a.HasSecurityAttribute) {
 
482
                                a.Error_InvalidSecurityParent ();
 
483
                                return;
 
484
                        }
 
485
 
 
486
                        if (a.Type == pa.Dynamic) {
 
487
                                a.Error_MisusedDynamicAttribute ();
 
488
                                return;
 
489
                        }
 
490
 
 
491
                        PropertyBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
 
492
                }
 
493
 
 
494
                void CheckMissingAccessor (MemberKind kind, ParametersCompiled parameters, bool get)
 
495
                {
 
496
                        if (IsExplicitImpl) {
 
497
                                MemberFilter filter;
 
498
                                if (kind == MemberKind.Indexer)
 
499
                                        filter = new MemberFilter (MemberCache.IndexerNameAlias, 0, kind, parameters, null);
 
500
                                else
 
501
                                        filter = new MemberFilter (MemberName.Name, 0, kind, null, null);
 
502
 
 
503
                                var implementing = MemberCache.FindMember (InterfaceType, filter, BindingRestriction.DeclaredOnly) as PropertySpec;
 
504
 
 
505
                                if (implementing == null)
 
506
                                        return;
 
507
 
 
508
                                var accessor = get ? implementing.Get : implementing.Set;
 
509
                                if (accessor != null) {
 
510
                                        Report.SymbolRelatedToPreviousError (accessor);
 
511
                                        Report.Error (551, Location, "Explicit interface implementation `{0}' is missing accessor `{1}'",
 
512
                                                GetSignatureForError (), accessor.GetSignatureForError ());
 
513
                                }
 
514
                        }
 
515
                }
 
516
 
 
517
                protected override bool CheckOverrideAgainstBase (MemberSpec base_member)
 
518
                {
 
519
                        var ok = base.CheckOverrideAgainstBase (base_member);
 
520
 
 
521
                        //
 
522
                        // Check base property accessors conflict
 
523
                        //
 
524
                        var base_prop = (PropertySpec) base_member;
 
525
                        if (Get != null) {
 
526
                                if (!base_prop.HasGet) {
 
527
                                        if (ok) {
 
528
                                                Report.SymbolRelatedToPreviousError (base_prop);
 
529
                                                Report.Error (545, Get.Location,
 
530
                                                        "`{0}': cannot override because `{1}' does not have an overridable get accessor",
 
531
                                                        Get.GetSignatureForError (), base_prop.GetSignatureForError ());
 
532
                                                ok = false;
 
533
                                        }
 
534
                                } else if (Get.HasCustomAccessModifier || base_prop.HasDifferentAccessibility) {
 
535
                                        if (!CheckAccessModifiers (Get, base_prop.Get)) {
 
536
                                                Error_CannotChangeAccessModifiers (Get, base_prop.Get);
 
537
                                                ok = false;
 
538
                                        }
 
539
                                }
 
540
                        }
 
541
 
 
542
                        if (Set != null) {
 
543
                                if (!base_prop.HasSet) {
 
544
                                        if (ok) {
 
545
                                                Report.SymbolRelatedToPreviousError (base_prop);
 
546
                                                Report.Error (546, Set.Location,
 
547
                                                        "`{0}': cannot override because `{1}' does not have an overridable set accessor",
 
548
                                                        Set.GetSignatureForError (), base_prop.GetSignatureForError ());
 
549
                                                ok = false;
 
550
                                        }
 
551
                                } else if (Set.HasCustomAccessModifier || base_prop.HasDifferentAccessibility) {
 
552
                                        if (!CheckAccessModifiers (Set, base_prop.Set)) {
 
553
                                                Error_CannotChangeAccessModifiers (Set, base_prop.Set);
 
554
                                                ok = false;
 
555
                                        }
 
556
                                }
 
557
                        }
 
558
 
 
559
                        if ((Set == null || !Set.HasCustomAccessModifier) && (Get == null || !Get.HasCustomAccessModifier)) {
 
560
                                if (!CheckAccessModifiers (this, base_prop)) {
 
561
                                        Error_CannotChangeAccessModifiers (this, base_prop);
 
562
                                        ok = false;
 
563
                                }
 
564
                        }
 
565
 
 
566
                        return ok;
 
567
                }
 
568
 
 
569
                protected override void DoMemberTypeDependentChecks ()
 
570
                {
 
571
                        base.DoMemberTypeDependentChecks ();
 
572
 
 
573
                        IsTypePermitted ();
 
574
 
 
575
                        if (MemberType.IsStatic)
 
576
                                Error_StaticReturnType ();
 
577
                }
 
578
 
 
579
                protected override void DoMemberTypeIndependentChecks ()
 
580
                {
 
581
                        base.DoMemberTypeIndependentChecks ();
 
582
 
 
583
                        //
 
584
                        // Accessors modifiers check
 
585
                        //
 
586
                        if (AccessorSecond != null) {
 
587
                                if ((Get.ModFlags & Modifiers.AccessibilityMask) != 0 && (Set.ModFlags & Modifiers.AccessibilityMask) != 0) {
 
588
                                        Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
 
589
                                                GetSignatureForError ());
 
590
                                }
 
591
                        } else if ((ModFlags & Modifiers.OVERRIDE) == 0 && 
 
592
                                (Get == null && (Set.ModFlags & Modifiers.AccessibilityMask) != 0) ||
 
593
                                (Set == null && (Get.ModFlags & Modifiers.AccessibilityMask) != 0)) {
 
594
                                Report.Error (276, Location, 
 
595
                                              "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
 
596
                                              GetSignatureForError ());
 
597
                        }
 
598
                }
 
599
 
 
600
                protected bool DefineAccessors ()
 
601
                {
 
602
                        first.Define (Parent);
 
603
                        if (AccessorSecond != null)
 
604
                                AccessorSecond.Define (Parent);
 
605
 
 
606
                        return true;
 
607
                }
 
608
 
 
609
                protected void DefineBuilders (MemberKind kind, ParametersCompiled parameters)
 
610
                {
 
611
                        PropertyBuilder = Parent.TypeBuilder.DefineProperty (
 
612
                                GetFullName (MemberName), PropertyAttributes.None,
 
613
#if !BOOTSTRAP_BASIC    // Requires trunk version mscorlib
 
614
                                IsStatic ? 0 : CallingConventions.HasThis,
 
615
#endif
 
616
                                MemberType.GetMetaInfo (), null, null,
 
617
                                parameters.GetMetaInfo (), null, null);
 
618
 
 
619
                        PropertySpec spec;
 
620
                        if (kind == MemberKind.Indexer)
 
621
                                spec = new IndexerSpec (Parent.Definition, this, MemberType, parameters, PropertyBuilder, ModFlags);
 
622
                        else
 
623
                                spec = new PropertySpec (kind, Parent.Definition, this, MemberType, PropertyBuilder, ModFlags);
 
624
 
 
625
                        if (Get != null) {
 
626
                                spec.Get = Get.Spec;
 
627
 
 
628
                                var method = Get.Spec.GetMetaInfo () as MethodBuilder;
 
629
                                if (method != null) {
 
630
                                        PropertyBuilder.SetGetMethod (method);
 
631
                                        Parent.MemberCache.AddMember (this, method.Name, Get.Spec);
 
632
                                }
 
633
                        } else {
 
634
                                CheckMissingAccessor (kind, parameters, true);
 
635
                        }
 
636
 
 
637
                        if (Set != null) {
 
638
                                spec.Set = Set.Spec;
 
639
 
 
640
                                var method = Set.Spec.GetMetaInfo () as MethodBuilder;
 
641
                                if (method != null) {
 
642
                                        PropertyBuilder.SetSetMethod (method);
 
643
                                        Parent.MemberCache.AddMember (this, method.Name, Set.Spec);
 
644
                                }
 
645
                        } else {
 
646
                                CheckMissingAccessor (kind, parameters, false);
 
647
                        }
 
648
 
 
649
                        Parent.MemberCache.AddMember (this, PropertyBuilder.Name, spec);
 
650
                }
 
651
 
 
652
                public override void Emit ()
 
653
                {
 
654
                        CheckReservedNameConflict (GetMethod.Prefix, get == null ? null : get.Spec);
 
655
                        CheckReservedNameConflict (SetMethod.Prefix, set == null ? null : set.Spec);
 
656
 
 
657
                        if (OptAttributes != null)
 
658
                                OptAttributes.Emit ();
 
659
 
 
660
                        if (member_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
 
661
                                Module.PredefinedAttributes.Dynamic.EmitAttribute (PropertyBuilder);
 
662
                        } else if (member_type.HasDynamicElement) {
 
663
                                Module.PredefinedAttributes.Dynamic.EmitAttribute (PropertyBuilder, member_type, Location);
 
664
                        }
 
665
 
 
666
                        ConstraintChecker.Check (this, member_type, type_expr.Location);
 
667
 
 
668
                        first.Emit (Parent);
 
669
                        if (AccessorSecond != null)
 
670
                                AccessorSecond.Emit (Parent);
 
671
 
 
672
                        base.Emit ();
 
673
                }
 
674
 
 
675
                public override bool IsUsed {
 
676
                        get {
 
677
                                if (IsExplicitImpl)
 
678
                                        return true;
 
679
 
 
680
                                return Get.IsUsed | Set.IsUsed;
 
681
                        }
 
682
                }
 
683
 
 
684
                protected override void SetMemberName (MemberName new_name)
 
685
                {
 
686
                        base.SetMemberName (new_name);
 
687
 
 
688
                        if (Get != null)
 
689
                                Get.UpdateName (this);
 
690
 
 
691
                        if (Set != null)
 
692
                                Set.UpdateName (this);
 
693
                }
 
694
 
 
695
                public override void WriteDebugSymbol (MonoSymbolFile file)
 
696
                {
 
697
                        if (get != null)
 
698
                                get.WriteDebugSymbol (file);
 
699
 
 
700
                        if (set != null)
 
701
                                set.WriteDebugSymbol (file);
 
702
                }
 
703
 
 
704
                //
 
705
                //   Represents header string for documentation comment.
 
706
                //
 
707
                public override string DocCommentHeader {
 
708
                        get { return "P:"; }
 
709
                }
 
710
        }
 
711
                        
 
712
        public class Property : PropertyBase
 
713
        {
 
714
                public sealed class BackingField : Field
 
715
                {
 
716
                        readonly Property property;
 
717
 
 
718
                        public BackingField (Property p)
 
719
                                : base (p.Parent, p.type_expr,
 
720
                                Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (p.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
 
721
                                new MemberName ("<" + p.GetFullName (p.MemberName) + ">k__BackingField", p.Location), null)
 
722
                        {
 
723
                                this.property = p;
 
724
                        }
 
725
 
 
726
                        public Property OriginalProperty {
 
727
                                get {
 
728
                                        return property;
 
729
                                }
 
730
                        }
 
731
 
 
732
                        public override string GetSignatureForError ()
 
733
                        {
 
734
                                return property.GetSignatureForError ();
 
735
                        }
 
736
                }
 
737
 
 
738
                public Property (TypeDefinition parent, FullNamedExpression type, Modifiers mod,
 
739
                                 MemberName name, Attributes attrs)
 
740
                        : base (parent, type, mod,
 
741
                                parent.PartialContainer.Kind == MemberKind.Interface ? AllowedModifiersInterface :
 
742
                                parent.PartialContainer.Kind == MemberKind.Struct ? AllowedModifiersStruct :
 
743
                                AllowedModifiersClass,
 
744
                                name, attrs)
 
745
                {
 
746
                }
 
747
 
 
748
                public override void Accept (StructuralVisitor visitor)
 
749
                {
 
750
                        visitor.Visit (this);
 
751
                }
 
752
                
 
753
 
 
754
                void CreateAutomaticProperty ()
 
755
                {
 
756
                        // Create backing field
 
757
                        Field field = new BackingField (this);
 
758
                        if (!field.Define ())
 
759
                                return;
 
760
 
 
761
                        Parent.PartialContainer.Members.Add (field);
 
762
 
 
763
                        FieldExpr fe = new FieldExpr (field, Location);
 
764
                        if ((field.ModFlags & Modifiers.STATIC) == 0)
 
765
                                fe.InstanceExpression = new CompilerGeneratedThis (Parent.CurrentType, Location);
 
766
 
 
767
                        //
 
768
                        // Create get block but we careful with location to
 
769
                        // emit only single sequence point per accessor. This allow
 
770
                        // to set a breakpoint on it even with no user code
 
771
                        //
 
772
                        Get.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location.Null);
 
773
                        Return r = new Return (fe, Get.Location);
 
774
                        Get.Block.AddStatement (r);
 
775
 
 
776
                        // Create set block
 
777
                        Set.Block = new ToplevelBlock (Compiler, Set.ParameterInfo, Location.Null);
 
778
                        Assign a = new SimpleAssign (fe, new SimpleName ("value", Location.Null), Location.Null);
 
779
                        Set.Block.AddStatement (new StatementExpression (a, Set.Location));
 
780
                }
 
781
                
 
782
                public override bool Define ()
 
783
                {
 
784
                        if (!base.Define ())
 
785
                                return false;
 
786
 
 
787
                        flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
 
788
 
 
789
                        if (!IsInterface && (ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
 
790
                                AccessorSecond != null && Get.Block == null && Set.Block == null) {
 
791
                                if (Compiler.Settings.Version <= LanguageVersion.ISO_2)
 
792
                                        Report.FeatureIsNotAvailable (Compiler, Location, "automatically implemented properties");
 
793
 
 
794
                                Get.ModFlags |= Modifiers.COMPILER_GENERATED;
 
795
                                Set.ModFlags |= Modifiers.COMPILER_GENERATED;
 
796
                                CreateAutomaticProperty ();
 
797
                        }
 
798
 
 
799
                        if (!DefineAccessors ())
 
800
                                return false;
 
801
 
 
802
                        if (AccessorSecond == null) {
 
803
                                PropertyMethod pm;
 
804
                                if (AccessorFirst is GetMethod)
 
805
                                        pm = new SetMethod (this, 0, ParametersCompiled.EmptyReadOnlyParameters, null, Location);
 
806
                                else
 
807
                                        pm = new GetMethod (this, 0, null, Location);
 
808
 
 
809
                                Parent.AddNameToContainer (pm, pm.MemberName.Basename);
 
810
                        }
 
811
 
 
812
                        if (!CheckBase ())
 
813
                                return false;
 
814
 
 
815
                        DefineBuilders (MemberKind.Property, ParametersCompiled.EmptyReadOnlyParameters);
 
816
                        return true;
 
817
                }
 
818
 
 
819
                public override void Emit ()
 
820
                {
 
821
                        if ((AccessorFirst.ModFlags & (Modifiers.STATIC | Modifiers.COMPILER_GENERATED)) == Modifiers.COMPILER_GENERATED && Parent.PartialContainer.HasExplicitLayout) {
 
822
                                Report.Error (842, Location,
 
823
                                        "Automatically implemented property `{0}' cannot be used inside a type with an explicit StructLayout attribute",
 
824
                                        GetSignatureForError ());
 
825
                        }
 
826
 
 
827
                        base.Emit ();
 
828
                }
 
829
        }
 
830
 
 
831
        /// <summary>
 
832
        /// For case when event is declared like property (with add and remove accessors).
 
833
        /// </summary>
 
834
        public class EventProperty: Event {
 
835
                public abstract class AEventPropertyAccessor : AEventAccessor
 
836
                {
 
837
                        protected AEventPropertyAccessor (EventProperty method, string prefix, Attributes attrs, Location loc)
 
838
                                : base (method, prefix, attrs, loc)
 
839
                        {
 
840
                        }
 
841
 
 
842
                        public override MethodBuilder Define (TypeContainer ds)
 
843
                        {
 
844
                                CheckAbstractAndExtern (block != null);
 
845
                                return base.Define (ds);
 
846
                        }
 
847
                        
 
848
                        public override string GetSignatureForError ()
 
849
                        {
 
850
                                return method.GetSignatureForError () + "." + prefix.Substring (0, prefix.Length - 1);
 
851
                        }
 
852
                }
 
853
 
 
854
                public sealed class AddDelegateMethod: AEventPropertyAccessor
 
855
                {
 
856
                        public AddDelegateMethod (EventProperty method, Attributes attrs, Location loc)
 
857
                                : base (method, AddPrefix, attrs, loc)
 
858
                        {
 
859
                        }
 
860
                }
 
861
 
 
862
                public sealed class RemoveDelegateMethod: AEventPropertyAccessor
 
863
                {
 
864
                        public RemoveDelegateMethod (EventProperty method, Attributes attrs, Location loc)
 
865
                                : base (method, RemovePrefix, attrs, loc)
 
866
                        {
 
867
                        }
 
868
                }
 
869
 
 
870
                static readonly string[] attribute_targets = new string [] { "event" };
 
871
 
 
872
                public EventProperty (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
 
873
                        : base (parent, type, mod_flags, name, attrs)
 
874
                {
 
875
                }
 
876
 
 
877
                public override void Accept (StructuralVisitor visitor)
 
878
                {
 
879
                        visitor.Visit (this);
 
880
                }
 
881
                
 
882
                public override bool Define()
 
883
                {
 
884
                        if (!base.Define ())
 
885
                                return false;
 
886
 
 
887
                        SetIsUsed ();
 
888
                        return true;
 
889
                }
 
890
 
 
891
                public override string[] ValidAttributeTargets {
 
892
                        get {
 
893
                                return attribute_targets;
 
894
                        }
 
895
                }
 
896
        }
 
897
 
 
898
        /// <summary>
 
899
        /// Event is declared like field.
 
900
        /// </summary>
 
901
        public class EventField : Event
 
902
        {
 
903
                abstract class EventFieldAccessor : AEventAccessor
 
904
                {
 
905
                        protected EventFieldAccessor (EventField method, string prefix)
 
906
                                : base (method, prefix, null, method.Location)
 
907
                        {
 
908
                        }
 
909
 
 
910
                        protected abstract MethodSpec GetOperation (Location loc);
 
911
 
 
912
                        public override void Emit (TypeDefinition parent)
 
913
                        {
 
914
                                if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 && !Compiler.Settings.WriteMetadataOnly) {
 
915
                                        block = new ToplevelBlock (Compiler, ParameterInfo, Location) {
 
916
                                                IsCompilerGenerated = true
 
917
                                        };
 
918
                                        FabricateBodyStatement ();
 
919
                                }
 
920
 
 
921
                                base.Emit (parent);
 
922
                        }
 
923
 
 
924
                        void FabricateBodyStatement ()
 
925
                        {
 
926
                                //
 
927
                                // Delegate obj1 = backing_field
 
928
                                // do {
 
929
                                //   Delegate obj2 = obj1;
 
930
                                //   obj1 = Interlocked.CompareExchange (ref backing_field, Delegate.Combine|Remove(obj2, value), obj1);
 
931
                                // } while ((object)obj1 != (object)obj2)
 
932
                                //
 
933
 
 
934
                                var field_info = ((EventField) method).backing_field;
 
935
                                FieldExpr f_expr = new FieldExpr (field_info, Location);
 
936
                                if (!IsStatic)
 
937
                                        f_expr.InstanceExpression = new CompilerGeneratedThis (Parent.CurrentType, Location);
 
938
 
 
939
                                var obj1 = LocalVariable.CreateCompilerGenerated (field_info.MemberType, block, Location);
 
940
                                var obj2 = LocalVariable.CreateCompilerGenerated (field_info.MemberType, block, Location);
 
941
 
 
942
                                block.AddStatement (new StatementExpression (new SimpleAssign (new LocalVariableReference (obj1, Location), f_expr)));
 
943
 
 
944
                                var cond = new BooleanExpression (new Binary (Binary.Operator.Inequality,
 
945
                                        new Cast (new TypeExpression (Module.Compiler.BuiltinTypes.Object, Location), new LocalVariableReference (obj1, Location), Location),
 
946
                                        new Cast (new TypeExpression (Module.Compiler.BuiltinTypes.Object, Location), new LocalVariableReference (obj2, Location), Location)));
 
947
 
 
948
                                var body = new ExplicitBlock (block, Location, Location);
 
949
                                block.AddStatement (new Do (body, cond, Location, Location));
 
950
 
 
951
                                body.AddStatement (new StatementExpression (
 
952
                                        new SimpleAssign (new LocalVariableReference (obj2, Location), new LocalVariableReference (obj1, Location))));
 
953
 
 
954
                                var args_oper = new Arguments (2);
 
955
                                args_oper.Add (new Argument (new LocalVariableReference (obj2, Location)));
 
956
                                args_oper.Add (new Argument (block.GetParameterReference (0, Location)));
 
957
 
 
958
                                var op_method = GetOperation (Location);
 
959
 
 
960
                                var args = new Arguments (3);
 
961
                                args.Add (new Argument (f_expr, Argument.AType.Ref));
 
962
                                args.Add (new Argument (new Cast (
 
963
                                        new TypeExpression (field_info.MemberType, Location),
 
964
                                        new Invocation (MethodGroupExpr.CreatePredefined (op_method, op_method.DeclaringType, Location), args_oper),
 
965
                                        Location)));
 
966
                                args.Add (new Argument (new LocalVariableReference (obj1, Location)));
 
967
 
 
968
                                var cas = Module.PredefinedMembers.InterlockedCompareExchange_T.Resolve (Location);
 
969
                                if (cas == null)
 
970
                                        return;
 
971
 
 
972
                                body.AddStatement (new StatementExpression (new SimpleAssign (
 
973
                                        new LocalVariableReference (obj1, Location),
 
974
                                        new Invocation (MethodGroupExpr.CreatePredefined (cas, cas.DeclaringType, Location), args))));
 
975
                        }
 
976
                }
 
977
 
 
978
                sealed class AddDelegateMethod: EventFieldAccessor
 
979
                {
 
980
                        public AddDelegateMethod (EventField method):
 
981
                                base (method, AddPrefix)
 
982
                        {
 
983
                        }
 
984
 
 
985
                        protected override MethodSpec GetOperation (Location loc)
 
986
                        {
 
987
                                return Module.PredefinedMembers.DelegateCombine.Resolve (loc);
 
988
                        }
 
989
                }
 
990
 
 
991
                sealed class RemoveDelegateMethod: EventFieldAccessor
 
992
                {
 
993
                        public RemoveDelegateMethod (EventField method):
 
994
                                base (method, RemovePrefix)
 
995
                        {
 
996
                        }
 
997
 
 
998
                        protected override MethodSpec GetOperation (Location loc)
 
999
                        {
 
1000
                                return Module.PredefinedMembers.DelegateRemove.Resolve (loc);
 
1001
                        }
 
1002
                }
 
1003
 
 
1004
 
 
1005
                static readonly string[] attribute_targets = new string [] { "event", "field", "method" };
 
1006
                static readonly string[] attribute_targets_interface = new string[] { "event", "method" };
 
1007
 
 
1008
                Expression initializer;
 
1009
                Field backing_field;
 
1010
                List<FieldDeclarator> declarators;
 
1011
 
 
1012
                public EventField (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
 
1013
                        : base (parent, type, mod_flags, name, attrs)
 
1014
                {
 
1015
                        Add = new AddDelegateMethod (this);
 
1016
                        Remove = new RemoveDelegateMethod (this);
 
1017
                }
 
1018
 
 
1019
                #region Properties
 
1020
 
 
1021
                public List<FieldDeclarator> Declarators {
 
1022
                        get {
 
1023
                                return this.declarators;
 
1024
                        }
 
1025
                }
 
1026
 
 
1027
                bool HasBackingField {
 
1028
                        get {
 
1029
                                return !IsInterface && (ModFlags & Modifiers.ABSTRACT) == 0;
 
1030
                        }
 
1031
                }
 
1032
 
 
1033
                public Expression Initializer {
 
1034
                        get {
 
1035
                                return initializer;
 
1036
                        }
 
1037
                        set {
 
1038
                                initializer = value;
 
1039
                        }
 
1040
                }
 
1041
 
 
1042
                public override string[] ValidAttributeTargets {
 
1043
                        get {
 
1044
                                return HasBackingField ? attribute_targets : attribute_targets_interface;
 
1045
                        }
 
1046
                }
 
1047
 
 
1048
                #endregion
 
1049
 
 
1050
                
 
1051
                public override void Accept (StructuralVisitor visitor)
 
1052
                {
 
1053
                        visitor.Visit (this);
 
1054
                }
 
1055
 
 
1056
                public void AddDeclarator (FieldDeclarator declarator)
 
1057
                {
 
1058
                        if (declarators == null)
 
1059
                                declarators = new List<FieldDeclarator> (2);
 
1060
 
 
1061
                        declarators.Add (declarator);
 
1062
 
 
1063
                        Parent.AddNameToContainer (this, declarator.Name.Value);
 
1064
                }
 
1065
 
 
1066
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
1067
                {
 
1068
                        if (a.Target == AttributeTargets.Field) {
 
1069
                                backing_field.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
1070
                                return;
 
1071
                        }
 
1072
 
 
1073
                        if (a.Target == AttributeTargets.Method) {
 
1074
                                int errors = Report.Errors;
 
1075
                                Add.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
1076
                                if (errors == Report.Errors)
 
1077
                                        Remove.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
1078
                                return;
 
1079
                        }
 
1080
 
 
1081
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
1082
                }
 
1083
 
 
1084
                public override bool Define()
 
1085
                {
 
1086
                        var mod_flags_src = ModFlags;
 
1087
 
 
1088
                        if (!base.Define ())
 
1089
                                return false;
 
1090
 
 
1091
                        if (declarators != null) {
 
1092
                                if ((mod_flags_src & Modifiers.DEFAULT_ACCESS_MODIFER) != 0)
 
1093
                                        mod_flags_src &= ~(Modifiers.AccessibilityMask | Modifiers.DEFAULT_ACCESS_MODIFER);
 
1094
 
 
1095
                                var t = new TypeExpression (MemberType, TypeExpression.Location);
 
1096
                                foreach (var d in declarators) {
 
1097
                                        var ef = new EventField (Parent, t, mod_flags_src, new MemberName (d.Name.Value, d.Name.Location), OptAttributes);
 
1098
 
 
1099
                                        if (d.Initializer != null)
 
1100
                                                ef.initializer = d.Initializer;
 
1101
 
 
1102
                                        ef.Define ();
 
1103
                                        Parent.PartialContainer.Members.Add (ef);
 
1104
                                }
 
1105
                        }
 
1106
 
 
1107
                        if (!HasBackingField) {
 
1108
                                SetIsUsed ();
 
1109
                                return true;
 
1110
                        }
 
1111
 
 
1112
                        if (Add.IsInterfaceImplementation)
 
1113
                                SetIsUsed ();
 
1114
 
 
1115
                        backing_field = new Field (Parent,
 
1116
                                new TypeExpression (MemberType, Location),
 
1117
                                Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
 
1118
                                MemberName, null);
 
1119
 
 
1120
                        Parent.PartialContainer.Members.Add (backing_field);
 
1121
                        backing_field.Initializer = Initializer;
 
1122
                        backing_field.ModFlags &= ~Modifiers.COMPILER_GENERATED;
 
1123
 
 
1124
                        // Call define because we passed fields definition
 
1125
                        backing_field.Define ();
 
1126
 
 
1127
                        // Set backing field for event fields
 
1128
                        spec.BackingField = backing_field.Spec;
 
1129
 
 
1130
                        return true;
 
1131
                }
 
1132
        }
 
1133
 
 
1134
        public abstract class Event : PropertyBasedMember
 
1135
        {
 
1136
                public abstract class AEventAccessor : AbstractPropertyEventMethod
 
1137
                {
 
1138
                        protected readonly Event method;
 
1139
                        readonly ParametersCompiled parameters;
 
1140
 
 
1141
                        static readonly string[] attribute_targets = new string [] { "method", "param", "return" };
 
1142
 
 
1143
                        public const string AddPrefix = "add_";
 
1144
                        public const string RemovePrefix = "remove_";
 
1145
 
 
1146
                        protected AEventAccessor (Event method, string prefix, Attributes attrs, Location loc)
 
1147
                                : base (method, prefix, attrs, loc)
 
1148
                        {
 
1149
                                this.method = method;
 
1150
                                this.ModFlags = method.ModFlags;
 
1151
                                this.parameters = ParametersCompiled.CreateImplicitParameter (method.TypeExpression, loc);
 
1152
                        }
 
1153
 
 
1154
                        public bool IsInterfaceImplementation {
 
1155
                                get { return method_data.implementing != null; }
 
1156
                        }
 
1157
 
 
1158
                        public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
1159
                        {
 
1160
                                if (a.Type == pa.MethodImpl) {
 
1161
                                        method.is_external_implementation = a.IsInternalCall ();
 
1162
                                }
 
1163
 
 
1164
                                base.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
1165
                        }
 
1166
 
 
1167
                        protected override void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
1168
                        {
 
1169
                                if (a.Target == AttributeTargets.Parameter) {
 
1170
                                        parameters[0].ApplyAttributeBuilder (a, ctor, cdata, pa);
 
1171
                                        return;
 
1172
                                }
 
1173
 
 
1174
                                base.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
1175
                        }
 
1176
 
 
1177
                        public override AttributeTargets AttributeTargets {
 
1178
                                get {
 
1179
                                        return AttributeTargets.Method;
 
1180
                                }
 
1181
                        }
 
1182
 
 
1183
                        public override bool IsClsComplianceRequired ()
 
1184
                        {
 
1185
                                return method.IsClsComplianceRequired ();
 
1186
                        }
 
1187
 
 
1188
                        public virtual MethodBuilder Define (TypeContainer parent)
 
1189
                        {
 
1190
                                // Fill in already resolved event type to speed things up and
 
1191
                                // avoid confusing duplicate errors
 
1192
                                ((Parameter) parameters.FixedParameters[0]).Type = method.member_type;
 
1193
                                parameters.Types = new TypeSpec[] { method.member_type };
 
1194
 
 
1195
                                method_data = new MethodData (method, method.ModFlags,
 
1196
                                        method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
 
1197
 
 
1198
                                if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
 
1199
                                        return null;
 
1200
 
 
1201
                                if (Compiler.Settings.WriteMetadataOnly)
 
1202
                                        block = null;
 
1203
 
 
1204
                                MethodBuilder mb = method_data.MethodBuilder;
 
1205
 
 
1206
                                Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, mb, ParameterInfo, method.ModFlags);
 
1207
                                Spec.IsAccessor = true;
 
1208
 
 
1209
                                return mb;
 
1210
                        }
 
1211
 
 
1212
                        public override TypeSpec ReturnType {
 
1213
                                get {
 
1214
                                        return Parent.Compiler.BuiltinTypes.Void;
 
1215
                                }
 
1216
                        }
 
1217
 
 
1218
                        public override ObsoleteAttribute GetAttributeObsolete ()
 
1219
                        {
 
1220
                                return method.GetAttributeObsolete ();
 
1221
                        }
 
1222
 
 
1223
                        public override string[] ValidAttributeTargets {
 
1224
                                get {
 
1225
                                        return attribute_targets;
 
1226
                                }
 
1227
                        }
 
1228
 
 
1229
                        public override ParametersCompiled ParameterInfo {
 
1230
                                get {
 
1231
                                        return parameters;
 
1232
                                }
 
1233
                        }
 
1234
                }
 
1235
 
 
1236
                AEventAccessor add, remove;
 
1237
                EventBuilder EventBuilder;
 
1238
                protected EventSpec spec;
 
1239
 
 
1240
                protected Event (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
 
1241
                        : base (parent, type, mod_flags,
 
1242
                                parent.PartialContainer.Kind == MemberKind.Interface ? AllowedModifiersInterface :
 
1243
                                parent.PartialContainer.Kind == MemberKind.Struct ? AllowedModifiersStruct :
 
1244
                                AllowedModifiersClass,
 
1245
                                name, attrs)
 
1246
                {
 
1247
                }
 
1248
 
 
1249
                #region Properties
 
1250
 
 
1251
                public override AttributeTargets AttributeTargets {
 
1252
                        get {
 
1253
                                return AttributeTargets.Event;
 
1254
                        }
 
1255
                }
 
1256
 
 
1257
                public AEventAccessor Add {
 
1258
                        get {
 
1259
                                return this.add;
 
1260
                        }
 
1261
                        set {
 
1262
                                add = value;
 
1263
                                Parent.AddNameToContainer (value, value.MemberName.Basename);
 
1264
                        }
 
1265
                }
 
1266
 
 
1267
                public override Variance ExpectedMemberTypeVariance {
 
1268
                        get {
 
1269
                                return Variance.Contravariant;
 
1270
                        }
 
1271
                }
 
1272
 
 
1273
                public AEventAccessor Remove {
 
1274
                        get {
 
1275
                                return this.remove;
 
1276
                        }
 
1277
                        set {
 
1278
                                remove = value;
 
1279
                                Parent.AddNameToContainer (value, value.MemberName.Basename);
 
1280
                        }
 
1281
                }
 
1282
                #endregion
 
1283
 
 
1284
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
1285
                {
 
1286
                        if ((a.HasSecurityAttribute)) {
 
1287
                                a.Error_InvalidSecurityParent ();
 
1288
                                return;
 
1289
                        }
 
1290
 
 
1291
                        EventBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
 
1292
                }
 
1293
 
 
1294
                protected override bool CheckOverrideAgainstBase (MemberSpec base_member)
 
1295
                {
 
1296
                        var ok = base.CheckOverrideAgainstBase (base_member);
 
1297
 
 
1298
                        if (!CheckAccessModifiers (this, base_member)) {
 
1299
                                Error_CannotChangeAccessModifiers (this, base_member);
 
1300
                                ok = false;
 
1301
                        }
 
1302
 
 
1303
                        return ok;
 
1304
                }
 
1305
 
 
1306
                public override bool Define ()
 
1307
                {
 
1308
                        if (!base.Define ())
 
1309
                                return false;
 
1310
 
 
1311
                        if (!MemberType.IsDelegate) {
 
1312
                                Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
 
1313
                        }
 
1314
 
 
1315
                        if (!CheckBase ())
 
1316
                                return false;
 
1317
 
 
1318
                        //
 
1319
                        // Now define the accessors
 
1320
                        //
 
1321
                        var AddBuilder = Add.Define (Parent);
 
1322
                        if (AddBuilder == null)
 
1323
                                return false;
 
1324
 
 
1325
                        var RemoveBuilder = remove.Define (Parent);
 
1326
                        if (RemoveBuilder == null)
 
1327
                                return false;
 
1328
 
 
1329
                        EventBuilder = Parent.TypeBuilder.DefineEvent (GetFullName (MemberName), EventAttributes.None, MemberType.GetMetaInfo ());
 
1330
                        EventBuilder.SetAddOnMethod (AddBuilder);
 
1331
                        EventBuilder.SetRemoveOnMethod (RemoveBuilder);
 
1332
 
 
1333
                        spec = new EventSpec (Parent.Definition, this, MemberType, ModFlags, Add.Spec, remove.Spec);
 
1334
 
 
1335
                        Parent.MemberCache.AddMember (this, GetFullName (MemberName), spec);
 
1336
                        Parent.MemberCache.AddMember (this, AddBuilder.Name, Add.Spec);
 
1337
                        Parent.MemberCache.AddMember (this, RemoveBuilder.Name, remove.Spec);
 
1338
 
 
1339
                        return true;
 
1340
                }
 
1341
 
 
1342
                public override void Emit ()
 
1343
                {
 
1344
                        CheckReservedNameConflict (null, add.Spec);
 
1345
                        CheckReservedNameConflict (null, remove.Spec);
 
1346
 
 
1347
                        if (OptAttributes != null) {
 
1348
                                OptAttributes.Emit ();
 
1349
                        }
 
1350
 
 
1351
                        ConstraintChecker.Check (this, member_type, type_expr.Location);
 
1352
 
 
1353
                        Add.Emit (Parent);
 
1354
                        Remove.Emit (Parent);
 
1355
 
 
1356
                        base.Emit ();
 
1357
                }
 
1358
 
 
1359
                public override void WriteDebugSymbol (MonoSymbolFile file)
 
1360
                {
 
1361
                        add.WriteDebugSymbol (file);
 
1362
                        remove.WriteDebugSymbol (file);
 
1363
                }
 
1364
 
 
1365
                //
 
1366
                //   Represents header string for documentation comment.
 
1367
                //
 
1368
                public override string DocCommentHeader {
 
1369
                        get { return "E:"; }
 
1370
                }
 
1371
        }
 
1372
 
 
1373
        public class EventSpec : MemberSpec, IInterfaceMemberSpec
 
1374
        {
 
1375
                MethodSpec add, remove;
 
1376
                FieldSpec backing_field;
 
1377
 
 
1378
                public EventSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec eventType, Modifiers modifiers, MethodSpec add, MethodSpec remove)
 
1379
                        : base (MemberKind.Event, declaringType, definition, modifiers)
 
1380
                {
 
1381
                        this.AccessorAdd = add;
 
1382
                        this.AccessorRemove = remove;
 
1383
                        this.MemberType = eventType;
 
1384
                }
 
1385
 
 
1386
                #region Properties
 
1387
 
 
1388
                public MethodSpec AccessorAdd { 
 
1389
                        get {
 
1390
                                return add;
 
1391
                        }
 
1392
                        set {
 
1393
                                add = value;
 
1394
                        }
 
1395
                }
 
1396
 
 
1397
                public MethodSpec AccessorRemove {
 
1398
                        get {
 
1399
                                return remove;
 
1400
                        }
 
1401
                        set {
 
1402
                                remove = value;
 
1403
                        }
 
1404
                }
 
1405
 
 
1406
                public FieldSpec BackingField {
 
1407
                        get {
 
1408
                                return backing_field;
 
1409
                        }
 
1410
                        set {
 
1411
                                backing_field = value;
 
1412
                        }
 
1413
                }
 
1414
 
 
1415
                public TypeSpec MemberType { get; private set; }
 
1416
 
 
1417
                #endregion
 
1418
 
 
1419
                public override MemberSpec InflateMember (TypeParameterInflator inflator)
 
1420
                {
 
1421
                        var es = (EventSpec) base.InflateMember (inflator);
 
1422
                        es.MemberType = inflator.Inflate (MemberType);
 
1423
 
 
1424
                        if (backing_field != null)
 
1425
                                es.backing_field = (FieldSpec) backing_field.InflateMember (inflator);
 
1426
 
 
1427
                        return es;
 
1428
                }
 
1429
 
 
1430
                public override List<TypeSpec> ResolveMissingDependencies ()
 
1431
                {
 
1432
                        return MemberType.ResolveMissingDependencies ();
 
1433
                }
 
1434
        }
 
1435
 
 
1436
        public class Indexer : PropertyBase, IParametersMember
 
1437
        {
 
1438
                public class GetIndexerMethod : GetMethod, IParametersMember
 
1439
                {
 
1440
                        ParametersCompiled parameters;
 
1441
 
 
1442
                        public GetIndexerMethod (PropertyBase property, Modifiers modifiers, ParametersCompiled parameters, Attributes attrs, Location loc)
 
1443
                                : base (property, modifiers, attrs, loc)
 
1444
                        {
 
1445
                                this.parameters = parameters;
 
1446
                        }
 
1447
 
 
1448
                        public override MethodBuilder Define (TypeContainer parent)
 
1449
                        {
 
1450
                                // Disable reporting, parameters are resolved twice
 
1451
                                Report.DisableReporting ();
 
1452
                                try {
 
1453
                                        parameters.Resolve (this);
 
1454
                                } finally {
 
1455
                                        Report.EnableReporting ();
 
1456
                                }
 
1457
 
 
1458
                                return base.Define (parent);
 
1459
                        }
 
1460
 
 
1461
                        public override ParametersCompiled ParameterInfo {
 
1462
                                get {
 
1463
                                        return parameters;
 
1464
                                }
 
1465
                        }
 
1466
 
 
1467
                        #region IParametersMember Members
 
1468
 
 
1469
                        AParametersCollection IParametersMember.Parameters {
 
1470
                                get {
 
1471
                                        return parameters;
 
1472
                                }
 
1473
                        }
 
1474
 
 
1475
                        TypeSpec IInterfaceMemberSpec.MemberType {
 
1476
                                get {
 
1477
                                        return ReturnType;
 
1478
                                }
 
1479
                        }
 
1480
 
 
1481
                        #endregion
 
1482
                }
 
1483
 
 
1484
                public class SetIndexerMethod : SetMethod, IParametersMember
 
1485
                {
 
1486
                        public SetIndexerMethod (PropertyBase property, Modifiers modifiers, ParametersCompiled parameters, Attributes attrs, Location loc)
 
1487
                                : base (property, modifiers, parameters, attrs, loc)
 
1488
                        {
 
1489
                        }
 
1490
 
 
1491
                        #region IParametersMember Members
 
1492
 
 
1493
                        AParametersCollection IParametersMember.Parameters {
 
1494
                                get {
 
1495
                                        return parameters;
 
1496
                                }
 
1497
                        }
 
1498
 
 
1499
                        TypeSpec IInterfaceMemberSpec.MemberType {
 
1500
                                get {
 
1501
                                        return ReturnType;
 
1502
                                }
 
1503
                        }
 
1504
 
 
1505
                        #endregion
 
1506
                }
 
1507
 
 
1508
                const Modifiers AllowedModifiers =
 
1509
                        Modifiers.NEW |
 
1510
                        Modifiers.PUBLIC |
 
1511
                        Modifiers.PROTECTED |
 
1512
                        Modifiers.INTERNAL |
 
1513
                        Modifiers.PRIVATE |
 
1514
                        Modifiers.VIRTUAL |
 
1515
                        Modifiers.SEALED |
 
1516
                        Modifiers.OVERRIDE |
 
1517
                        Modifiers.UNSAFE |
 
1518
                        Modifiers.EXTERN |
 
1519
                        Modifiers.ABSTRACT;
 
1520
 
 
1521
                const Modifiers AllowedInterfaceModifiers =
 
1522
                        Modifiers.NEW;
 
1523
 
 
1524
                readonly ParametersCompiled parameters;
 
1525
 
 
1526
                public Indexer (TypeDefinition parent, FullNamedExpression type, MemberName name, Modifiers mod, ParametersCompiled parameters, Attributes attrs)
 
1527
                        : base (parent, type, mod,
 
1528
                                parent.PartialContainer.Kind == MemberKind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
 
1529
                                name, attrs)
 
1530
                {
 
1531
                        this.parameters = parameters;
 
1532
                }
 
1533
 
 
1534
                #region Properties
 
1535
 
 
1536
                AParametersCollection IParametersMember.Parameters {
 
1537
                        get {
 
1538
                                return parameters;
 
1539
                        }
 
1540
                }
 
1541
 
 
1542
                public ParametersCompiled ParameterInfo {
 
1543
                        get {
 
1544
                                return parameters;
 
1545
                        }
 
1546
                }
 
1547
 
 
1548
                #endregion
 
1549
 
 
1550
                
 
1551
                public override void Accept (StructuralVisitor visitor)
 
1552
                {
 
1553
                        visitor.Visit (this);
 
1554
                }
 
1555
 
 
1556
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
 
1557
                {
 
1558
                        if (a.Type == pa.IndexerName) {
 
1559
                                // Attribute was copied to container
 
1560
                                return;
 
1561
                        }
 
1562
 
 
1563
                        base.ApplyAttributeBuilder (a, ctor, cdata, pa);
 
1564
                }
 
1565
 
 
1566
                protected override bool CheckForDuplications ()
 
1567
                {
 
1568
                        return Parent.MemberCache.CheckExistingMembersOverloads (this, parameters);
 
1569
                }
 
1570
                
 
1571
                public override bool Define ()
 
1572
                {
 
1573
                        if (!base.Define ())
 
1574
                                return false;
 
1575
 
 
1576
                        if (!DefineParameters (parameters))
 
1577
                                return false;
 
1578
 
 
1579
                        if (OptAttributes != null) {
 
1580
                                Attribute indexer_attr = OptAttributes.Search (Module.PredefinedAttributes.IndexerName);
 
1581
                                if (indexer_attr != null) {
 
1582
                                        var compiling = indexer_attr.Type.MemberDefinition as TypeContainer;
 
1583
                                        if (compiling != null)
 
1584
                                                compiling.Define ();
 
1585
 
 
1586
                                        if (IsExplicitImpl) {
 
1587
                                                Report.Error (415, indexer_attr.Location,
 
1588
                                                        "The `{0}' attribute is valid only on an indexer that is not an explicit interface member declaration",
 
1589
                                                        indexer_attr.Type.GetSignatureForError ());
 
1590
                                        } else if ((ModFlags & Modifiers.OVERRIDE) != 0) {
 
1591
                                                Report.Error (609, indexer_attr.Location,
 
1592
                                                        "Cannot set the `IndexerName' attribute on an indexer marked override");
 
1593
                                        } else {
 
1594
                                                string name = indexer_attr.GetIndexerAttributeValue ();
 
1595
 
 
1596
                                                if (!string.IsNullOrEmpty (name)) {
 
1597
                                                        SetMemberName (new MemberName (MemberName.Left, name, Location));
 
1598
                                                }
 
1599
                                        }
 
1600
                                }
 
1601
                        }
 
1602
 
 
1603
                        if (InterfaceType != null) {
 
1604
                                string base_IndexerName = InterfaceType.MemberDefinition.GetAttributeDefaultMember ();
 
1605
                                if (base_IndexerName != ShortName) {
 
1606
                                        SetMemberName (new MemberName (MemberName.Left, base_IndexerName, new TypeExpression (InterfaceType, Location), Location));
 
1607
                                }
 
1608
                        }
 
1609
 
 
1610
                        Parent.AddNameToContainer (this, MemberName.Basename);
 
1611
 
 
1612
                        flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
 
1613
                        
 
1614
                        if (!DefineAccessors ())
 
1615
                                return false;
 
1616
 
 
1617
                        if (!CheckBase ())
 
1618
                                return false;
 
1619
 
 
1620
                        DefineBuilders (MemberKind.Indexer, parameters);
 
1621
                        return true;
 
1622
                }
 
1623
 
 
1624
                public override bool EnableOverloadChecks (MemberCore overload)
 
1625
                {
 
1626
                        if (overload is Indexer) {
 
1627
                                caching_flags |= Flags.MethodOverloadsExist;
 
1628
                                return true;
 
1629
                        }
 
1630
 
 
1631
                        return base.EnableOverloadChecks (overload);
 
1632
                }
 
1633
 
 
1634
                public override void Emit ()
 
1635
                {
 
1636
                        parameters.CheckConstraints (this);
 
1637
 
 
1638
                        base.Emit ();
 
1639
                }
 
1640
 
 
1641
                public override string GetSignatureForError ()
 
1642
                {
 
1643
                        StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
 
1644
                        if (MemberName.ExplicitInterface != null) {
 
1645
                                sb.Append (".");
 
1646
                                sb.Append (MemberName.ExplicitInterface.GetSignatureForError ());
 
1647
                        }
 
1648
 
 
1649
                        sb.Append (".this");
 
1650
                        sb.Append (parameters.GetSignatureForError ("[", "]", parameters.Count));
 
1651
                        return sb.ToString ();
 
1652
                }
 
1653
 
 
1654
                public override string GetSignatureForDocumentation ()
 
1655
                {
 
1656
                        return base.GetSignatureForDocumentation () + parameters.GetSignatureForDocumentation ();
 
1657
                }
 
1658
 
 
1659
                protected override bool VerifyClsCompliance ()
 
1660
                {
 
1661
                        if (!base.VerifyClsCompliance ())
 
1662
                                return false;
 
1663
 
 
1664
                        parameters.VerifyClsCompliance (this);
 
1665
                        return true;
 
1666
                }
 
1667
        }
 
1668
 
 
1669
        public class IndexerSpec : PropertySpec, IParametersMember
 
1670
        {
 
1671
                AParametersCollection parameters;
 
1672
 
 
1673
                public IndexerSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, AParametersCollection parameters, PropertyInfo info, Modifiers modifiers)
 
1674
                        : base (MemberKind.Indexer, declaringType, definition, memberType, info, modifiers)
 
1675
                {
 
1676
                        this.parameters = parameters;
 
1677
                }
 
1678
 
 
1679
                #region Properties
 
1680
                public AParametersCollection Parameters {
 
1681
                        get {
 
1682
                                return parameters;
 
1683
                        }
 
1684
                }
 
1685
                #endregion
 
1686
 
 
1687
                public override string GetSignatureForDocumentation ()
 
1688
                {
 
1689
                        return base.GetSignatureForDocumentation () + parameters.GetSignatureForDocumentation ();
 
1690
                }
 
1691
 
 
1692
                public override string GetSignatureForError ()
 
1693
                {
 
1694
                        return DeclaringType.GetSignatureForError () + ".this" + parameters.GetSignatureForError ("[", "]", parameters.Count);
 
1695
                }
 
1696
 
 
1697
                public override MemberSpec InflateMember (TypeParameterInflator inflator)
 
1698
                {
 
1699
                        var spec = (IndexerSpec) base.InflateMember (inflator);
 
1700
                        spec.parameters = parameters.Inflate (inflator);
 
1701
                        return spec;
 
1702
                }
 
1703
 
 
1704
                public override List<TypeSpec> ResolveMissingDependencies ()
 
1705
                {
 
1706
                        var missing = base.ResolveMissingDependencies ();
 
1707
                        foreach (var pt in parameters.Types) {
 
1708
                                var m = pt.GetMissingDependencies ();
 
1709
                                if (m == null)
 
1710
                                        continue;
 
1711
 
 
1712
                                if (missing == null)
 
1713
                                        missing = new List<TypeSpec> ();
 
1714
 
 
1715
                                missing.AddRange (m);
 
1716
                        }
 
1717
 
 
1718
                        return missing;
 
1719
                }
 
1720
        }
 
1721
}