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