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