2010-07-14 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / mcs / property.cs
index 6ac5e0450931ada87ba3a73faeb3b8e987a31bb8..c92598d0fd6efc3610c5463f1dbb6504ae6f98ac 100644 (file)
@@ -42,6 +42,48 @@ namespace Mono.CSharp
                {
                }
 
+               protected void CheckReservedNameConflict (string prefix, MethodSpec accessor)
+               {
+                       string name;
+                       AParametersCollection parameters;
+                       if (accessor != null) {
+                               name = accessor.Name;
+                               parameters = accessor.Parameters;
+                       } else {
+                               name = prefix + ShortName;
+                               if (IsExplicitImpl)
+                                       name = MemberName.Left + "." + name;
+
+                               if (this is Indexer) {
+                                       parameters = ((Indexer) this).ParameterInfo;
+                                       if (prefix[0] == 's') {
+                                               var data = new IParameterData[parameters.Count + 1];
+                                               Array.Copy (parameters.FixedParameters, data, data.Length - 1);
+                                               data[data.Length - 1] = new ParameterData ("value", Parameter.Modifier.NONE);
+                                               var types = new TypeSpec[data.Length];
+                                               Array.Copy (parameters.Types, types, data.Length - 1);
+                                               types[data.Length - 1] = member_type;
+
+                                               parameters = new ParametersImported (data, types, false);
+                                       }
+                               } else {
+                                       if (prefix[0] == 's')
+                                               parameters = ParametersCompiled.CreateFullyResolved (new[] { member_type });
+                                       else
+                                               parameters = ParametersCompiled.EmptyReadOnlyParameters;
+                               }
+                       }
+
+                       var conflict = MemberCache.FindMember (Parent.Definition,
+                               new MemberFilter (name, 0, MemberKind.Method, parameters, null),
+                               BindingRestriction.DeclaredOnly | BindingRestriction.NoAccessors);
+
+                       if (conflict != null) {
+                               Report.SymbolRelatedToPreviousError (conflict);
+                               Report.Error (82, Location, "A member `{0}' is already reserved", conflict.GetSignatureForError ());
+                       }
+               }
+
                protected override bool VerifyClsCompliance ()
                {
                        if (!base.VerifyClsCompliance ())
@@ -56,35 +98,6 @@ namespace Mono.CSharp
 
        }
 
-       //
-       // `set' and `get' accessors are represented with an Accessor.
-       // 
-       public class Accessor {
-               //
-               // Null if the accessor is empty, or a Block if not
-               //
-               public const Modifiers AllowedModifiers = 
-                       Modifiers.PUBLIC |
-                       Modifiers.PROTECTED |
-                       Modifiers.INTERNAL |
-                       Modifiers.PRIVATE;
-               
-               public ToplevelBlock Block;
-               public Attributes Attributes;
-               public Location Location;
-               public Modifiers ModFlags;
-               public ParametersCompiled Parameters;
-               
-               public Accessor (ToplevelBlock b, Modifiers mod, Attributes attrs, ParametersCompiled p, Location loc)
-               {
-                       Block = b;
-                       Attributes = attrs;
-                       Location = loc;
-                       Parameters = p;
-                       ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, 0, loc, RootContext.ToplevelTypes.Compiler.Report);
-               }
-       }
-
        public class PropertySpec : MemberSpec, IInterfaceMemberSpec
        {
                PropertyInfo info;
@@ -138,13 +151,13 @@ namespace Mono.CSharp
 
                public bool HasGet {
                        get {
-                               return Get != null && Get.Kind != MemberKind.FakeMethod;
+                               return Get != null;
                        }
                }
 
                public bool HasSet {
                        get {
-                               return Set != null && Set.Kind != MemberKind.FakeMethod;
+                               return Set != null;
                        }
                }
 
@@ -183,13 +196,10 @@ namespace Mono.CSharp
                {
                        static string[] attribute_targets = new string [] { "method", "return" };
 
-                       public GetMethod (PropertyBase method):
-                               base (method, "get_")
-                       {
-                       }
+                       internal const string Prefix = "get_";
 
-                       public GetMethod (PropertyBase method, Accessor accessor):
-                               base (method, accessor, "get_")
+                       public GetMethod (PropertyBase method, Modifiers modifiers, Attributes attrs, Location loc)
+                               : base (method, Prefix, modifiers, attrs, loc)
                        {
                        }
 
@@ -197,11 +207,8 @@ namespace Mono.CSharp
                        {
                                base.Define (parent);
 
-                               Spec = new MethodSpec (IsDummy ? MemberKind.FakeMethod : MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);
+                               Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);
 
-                               if (IsDummy)
-                                       return null;
-                               
                                method_data = new MethodData (method, ModFlags, flags, this);
 
                                if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
@@ -234,19 +241,16 @@ namespace Mono.CSharp
                public class SetMethod : PropertyMethod {
 
                        static string[] attribute_targets = new string [] { "method", "param", "return" };
+
+                       internal const string Prefix = "set_";
+
                        ImplicitParameter param_attr;
                        protected ParametersCompiled parameters;
 
-                       public SetMethod (PropertyBase method) :
-                               base (method, "set_")
+                       public SetMethod (PropertyBase method, Modifiers modifiers, ParametersCompiled parameters, Attributes attrs, Location loc)
+                               : base (method, Prefix, modifiers, attrs, loc)
                        {
-                               parameters = ParametersCompiled.CreateImplicitParameter (method.type_expr, Location);
-                       }
-
-                       public SetMethod (PropertyBase method, Accessor accessor):
-                               base (method, accessor, "set_")
-                       {
-                               this.parameters = accessor.Parameters;
+                               this.parameters = parameters;
                        }
 
                        protected override void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
@@ -274,10 +278,7 @@ namespace Mono.CSharp
                                
                                base.Define (parent);
 
-                               Spec = new MethodSpec (IsDummy ? MemberKind.FakeMethod : MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);
-
-                               if (IsDummy)
-                                       return null;
+                               Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);
 
                                method_data = new MethodData (method, ModFlags, flags, this);
 
@@ -306,26 +307,20 @@ namespace Mono.CSharp
 
                public abstract class PropertyMethod : AbstractPropertyEventMethod
                {
+                       public const Modifiers AllowedModifiers =
+                               Modifiers.PUBLIC |
+                               Modifiers.PROTECTED |
+                               Modifiers.INTERNAL |
+                               Modifiers.PRIVATE;
+               
                        protected readonly PropertyBase method;
                        protected MethodAttributes flags;
 
-                       public PropertyMethod (PropertyBase method, string prefix)
-                               : base (method, prefix)
+                       public PropertyMethod (PropertyBase method, string prefix, Modifiers modifiers, Attributes attrs, Location loc)
+                               : base (method, prefix, attrs, loc)
                        {
                                this.method = method;
-                               this.ModFlags = method.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE);                                
-                       }
-
-                       public PropertyMethod (PropertyBase method, Accessor accessor,
-                                              string prefix)
-                               : base (method, accessor, prefix)
-                       {
-                               this.method = method;
-                               this.ModFlags = accessor.ModFlags | (method.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE));
-
-                               if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
-                                       Report.FeatureIsNotAvailable (Location, "access modifiers on properties");
-                               }
+                               this.ModFlags = modifiers | (method.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE));
                        }
 
                        public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
@@ -350,21 +345,6 @@ namespace Mono.CSharp
 
                        public virtual MethodBuilder Define (DeclSpace parent)
                        {
-                               CheckForDuplications ();
-
-                               if (IsDummy) {
-                                       if (method.InterfaceType != null && parent.PartialContainer.PendingImplementations != null) {
-                                               var mi = parent.PartialContainer.PendingImplementations.IsInterfaceMethod (
-                                                       MethodName, method.InterfaceType, new MethodData (method, ModFlags, flags, this));
-                                               if (mi != null) {
-                                                       Report.SymbolRelatedToPreviousError (mi);
-                                                       Report.Error (551, Location, "Explicit interface implementation `{0}' is missing accessor `{1}'",
-                                                               method.GetSignatureForError (), mi.GetSignatureForError ());
-                                               }
-                                       }
-                                       return null;
-                               }
-
                                TypeContainer container = parent.PartialContainer;
 
                                //
@@ -428,30 +408,71 @@ namespace Mono.CSharp
                                                GetSignatureForError (), method.GetSignatureForError ());
                                }
                        }
+               }
 
-                       protected bool CheckForDuplications ()
-                       {
-                               if ((caching_flags & Flags.MethodOverloadsExist) == 0)
-                                       return true;
+               PropertyMethod get, set, first;
+               PropertyBuilder PropertyBuilder;
+
+               public PropertyBase (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags,
+                                    Modifiers allowed_mod, MemberName name, Attributes attrs)
+                       : base (parent, null, type, mod_flags, allowed_mod, name, attrs)
+               {
+               }
 
-                               return Parent.MemberCache.CheckExistingMembersOverloads (this, ParameterInfo);
+               #region Properties
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Property;
                        }
                }
 
-               public PropertyMethod Get, Set;
-               public PropertyBuilder PropertyBuilder;
-               public MethodBuilder GetBuilder, SetBuilder;
+               public PropertyMethod AccessorFirst {
+                       get {
+                               return first;
+                       }
+               }
 
-               protected bool define_set_first = false;
+               public PropertyMethod AccessorSecond {
+                       get {
+                               return first == get ? set : get;
+                       }
+               }
 
-               public PropertyBase (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags,
-                                    Modifiers allowed_mod, MemberName name,
-                                    Attributes attrs, bool define_set_first)
-                       : base (parent, null, type, mod_flags, allowed_mod, name, attrs)
-               {
-                        this.define_set_first = define_set_first;
+               public PropertyMethod Get {
+                       get {
+                               return get;
+                       }
+                       set {
+                               get = value;
+                               if (first == null)
+                                       first = value;
+
+                               Parent.AddMember (get);
+                       }
+               }
+
+               public PropertyMethod Set {
+                       get {
+                               return set;
+                       }
+                       set {
+                               set = value;
+                               if (first == null)
+                                       first = value;
+
+                               Parent.AddMember (set);
+                       }
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
                }
 
+               #endregion
+
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.HasSecurityAttribute) {
@@ -467,9 +488,26 @@ namespace Mono.CSharp
                        PropertyBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                }
 
-               public override AttributeTargets AttributeTargets {
-                       get {
-                               return AttributeTargets.Property;
+               void CheckMissingAccessor (MemberKind kind, ParametersCompiled parameters, bool get)
+               {
+                       if (IsExplicitImpl) {
+                               MemberFilter filter;
+                               if (kind == MemberKind.Indexer)
+                                       filter = new MemberFilter (MemberCache.IndexerNameAlias, 0, kind, parameters, null);
+                               else
+                                       filter = new MemberFilter (MemberName.Name, 0, kind, null, null);
+
+                               var implementing = MemberCache.FindMember (InterfaceType, filter, BindingRestriction.DeclaredOnly) as PropertySpec;
+
+                               if (implementing == null)
+                                       return;
+
+                               var accessor = get ? implementing.Get : implementing.Set;
+                               if (accessor != null) {
+                                       Report.SymbolRelatedToPreviousError (accessor);
+                                       Report.Error (551, Location, "Explicit interface implementation `{0}' is missing accessor `{1}'",
+                                               GetSignatureForError (), accessor.GetSignatureForError ());
+                               }
                        }
                }
 
@@ -481,13 +519,15 @@ namespace Mono.CSharp
                        // Check base property accessors conflict
                        //
                        var base_prop = (PropertySpec) base_member;
-                       if (!Get.IsDummy) {
+                       if (Get != null) {
                                if (!base_prop.HasGet) {
-                                       Report.SymbolRelatedToPreviousError (base_prop);
-                                       Report.Error (545, Get.Location,
-                                               "`{0}': cannot override because `{1}' does not have an overridable get accessor",
-                                               Get.GetSignatureForError (), base_prop.GetSignatureForError ());
-                                       ok = false;
+                                       if (ok) {
+                                               Report.SymbolRelatedToPreviousError (base_prop);
+                                               Report.Error (545, Get.Location,
+                                                       "`{0}': cannot override because `{1}' does not have an overridable get accessor",
+                                                       Get.GetSignatureForError (), base_prop.GetSignatureForError ());
+                                               ok = false;
+                                       }
                                } else if (Get.HasCustomAccessModifier || base_prop.HasDifferentAccessibility) {
                                        if (!CheckAccessModifiers (Get, base_prop.Get)) {
                                                Error_CannotChangeAccessModifiers (Get, base_prop.Get);
@@ -496,13 +536,15 @@ namespace Mono.CSharp
                                }
                        }
 
-                       if (!Set.IsDummy) {
+                       if (Set != null) {
                                if (!base_prop.HasSet) {
-                                       Report.SymbolRelatedToPreviousError (base_prop);
-                                       Report.Error (546, Set.Location,
-                                               "`{0}': cannot override because `{1}' does not have an overridable set accessor",
-                                               Set.GetSignatureForError (), base_prop.GetSignatureForError ());
-                                       ok = false;
+                                       if (ok) {
+                                               Report.SymbolRelatedToPreviousError (base_prop);
+                                               Report.Error (546, Set.Location,
+                                                       "`{0}': cannot override because `{1}' does not have an overridable set accessor",
+                                                       Set.GetSignatureForError (), base_prop.GetSignatureForError ());
+                                               ok = false;
+                                       }
                                } else if (Set.HasCustomAccessModifier || base_prop.HasDifferentAccessibility) {
                                        if (!CheckAccessModifiers (Set, base_prop.Set)) {
                                                Error_CannotChangeAccessModifiers (Set, base_prop.Set);
@@ -511,7 +553,7 @@ namespace Mono.CSharp
                                }
                        }
 
-                       if (!Set.HasCustomAccessModifier && !Get.HasCustomAccessModifier) {
+                       if ((Set == null || !Set.HasCustomAccessModifier) && (Get == null || !Get.HasCustomAccessModifier)) {
                                if (!CheckAccessModifiers (this, base_prop)) {
                                        Error_CannotChangeAccessModifiers (this, base_prop);
                                        ok = false;
@@ -538,49 +580,38 @@ namespace Mono.CSharp
                        //
                        // Accessors modifiers check
                        //
-                       if ((Get.ModFlags & Modifiers.AccessibilityMask) != 0 &&
-                               (Set.ModFlags & Modifiers.AccessibilityMask) != 0) {
-                               Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
+                       if (AccessorSecond != null) {
+                               if ((Get.ModFlags & Modifiers.AccessibilityMask) != 0 && (Set.ModFlags & Modifiers.AccessibilityMask) != 0) {
+                                       Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
                                                GetSignatureForError ());
-                       }
-
-                       if ((ModFlags & Modifiers.OVERRIDE) == 0 && 
-                               (Get.IsDummy && (Set.ModFlags & Modifiers.AccessibilityMask) != 0) ||
-                               (Set.IsDummy && (Get.ModFlags & Modifiers.AccessibilityMask) != 0)) {
+                               }
+                       } else if ((ModFlags & Modifiers.OVERRIDE) == 0 && 
+                               (Get == null && (Set.ModFlags & Modifiers.AccessibilityMask) != 0) ||
+                               (Set == null && (Get.ModFlags & Modifiers.AccessibilityMask) != 0)) {
                                Report.Error (276, Location, 
                                              "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
                                              GetSignatureForError ());
                        }
                }
 
-               bool DefineGet ()
-               {
-                       GetBuilder = Get.Define (Parent);
-                       return (Get.IsDummy) ? true : GetBuilder != null;
-               }
-
-               bool DefineSet (bool define)
-               {
-                       if (!define)
-                               return true;
-
-                       SetBuilder = Set.Define (Parent);
-                       return (Set.IsDummy) ? true : SetBuilder != null;
-               }
-
                protected bool DefineAccessors ()
                {
-                       return DefineSet (define_set_first) &&
-                               DefineGet () &&
-                               DefineSet (!define_set_first);
+                       first.Define (Parent);
+                       if (AccessorSecond != null)
+                               AccessorSecond.Define (Parent);
+
+                       return true;
                }
 
                protected void DefineBuilders (MemberKind kind, ParametersCompiled parameters)
                {
-                       // FIXME - PropertyAttributes.HasDefault ?
-
                        PropertyBuilder = Parent.TypeBuilder.DefineProperty (
-                               GetFullName (MemberName), PropertyAttributes.None, MemberType.GetMetaInfo (), parameters.GetMetaInfo ());
+                               GetFullName (MemberName), PropertyAttributes.None,
+#if !BOOTSTRAP_BASIC   // Requires trunk version mscorlib
+                               IsStatic ? 0 : CallingConventions.HasThis,
+#endif
+                               MemberType.GetMetaInfo (), null, null,
+                               parameters.GetMetaInfo (), null, null);
 
                        PropertySpec spec;
                        if (kind == MemberKind.Indexer)
@@ -588,64 +619,61 @@ namespace Mono.CSharp
                        else
                                spec = new PropertySpec (kind, Parent.Definition, this, MemberType, PropertyBuilder, ModFlags);
 
-                       spec.Get = Get.Spec;
-                       spec.Set = Set.Spec;
+                       if (Get != null) {
+                               spec.Get = Get.Spec;
 
-                       if (!Get.IsDummy) {
-                               PropertyBuilder.SetGetMethod (GetBuilder);
+                               var method = Get.Spec.GetMetaInfo () as MethodBuilder;
+                               if (method != null) {
+                                       PropertyBuilder.SetGetMethod (method);
+                                       Parent.MemberCache.AddMember (this, method.Name, Get.Spec);
+                               }
+                       } else {
+                               CheckMissingAccessor (kind, parameters, true);
                        }
 
-                       if (!Set.IsDummy) {
-                               PropertyBuilder.SetSetMethod (SetBuilder);
+                       if (Set != null) {
+                               spec.Set = Set.Spec;
+
+                               var method = Set.Spec.GetMetaInfo () as MethodBuilder;
+                               if (method != null) {
+                                       PropertyBuilder.SetSetMethod (method);
+                                       Parent.MemberCache.AddMember (this, method.Name, Set.Spec);
+                               }
+                       } else {
+                               CheckMissingAccessor (kind, parameters, false);
                        }
 
-                       Parent.MemberCache.AddMember (this, Get.IsDummy ? Get.Name : GetBuilder.Name, Get.Spec);
-                       Parent.MemberCache.AddMember (this, Set.IsDummy ? Set.Name : SetBuilder.Name, Set.Spec);
                        Parent.MemberCache.AddMember (this, PropertyBuilder.Name, spec);
                }
 
                public override void Emit ()
                {
-                       //
-                       // The PropertyBuilder can be null for explicit implementations, in that
-                       // case, we do not actually emit the ".property", so there is nowhere to
-                       // put the attribute
-                       //
-                       if (PropertyBuilder != null) {
-                               if (OptAttributes != null)
-                                       OptAttributes.Emit ();
+                       CheckReservedNameConflict (GetMethod.Prefix, get == null ? null : get.Spec);
+                       CheckReservedNameConflict (SetMethod.Prefix, set == null ? null : set.Spec);
 
-                               if (member_type == InternalType.Dynamic) {
-                                       PredefinedAttributes.Get.Dynamic.EmitAttribute (PropertyBuilder);
-                               } else {
-                                       var trans_flags = TypeManager.HasDynamicTypeUsed (member_type);
-                                       if (trans_flags != null) {
-                                               var pa = PredefinedAttributes.Get.DynamicTransform;
-                                               if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
-                                                       PropertyBuilder.SetCustomAttribute (
-                                                               new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
-                                               }
+                       if (OptAttributes != null)
+                               OptAttributes.Emit ();
+
+                       if (member_type == InternalType.Dynamic) {
+                               PredefinedAttributes.Get.Dynamic.EmitAttribute (PropertyBuilder);
+                       } else {
+                               var trans_flags = TypeManager.HasDynamicTypeUsed (member_type);
+                               if (trans_flags != null) {
+                                       var pa = PredefinedAttributes.Get.DynamicTransform;
+                                       if (pa.Constructor != null || pa.ResolveConstructor (Location, ArrayContainer.MakeType (TypeManager.bool_type))) {
+                                               PropertyBuilder.SetCustomAttribute (
+                                                       new CustomAttributeBuilder (pa.Constructor, new object[] { trans_flags }));
                                        }
                                }
                        }
 
-                       if (!Get.IsDummy)
-                               Get.Emit (Parent);
-
-                       if (!Set.IsDummy)
-                               Set.Emit (Parent);
+                       first.Emit (Parent);
+                       if (AccessorSecond != null)
+                               AccessorSecond.Emit (Parent);
 
                        base.Emit ();
                }
 
-               /// <summary>
-               /// Tests whether accessors are not in collision with some method (CS0111)
-               /// </summary>
-               public bool AreAccessorsDuplicateImplementation (MethodCore mc)
-               {
-                       return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
-               }
-
                public override bool IsUsed {
                        get {
                                if (IsExplicitImpl)
@@ -659,14 +687,11 @@ namespace Mono.CSharp
                {
                        base.SetMemberName (new_name);
 
-                       Get.UpdateName (this);
-                       Set.UpdateName (this);
-               }
+                       if (Get != null)
+                               Get.UpdateName (this);
 
-               public override string[] ValidAttributeTargets {
-                       get {
-                               return attribute_targets;
-                       }
+                       if (Set != null)
+                               Set.UpdateName (this);
                }
 
                //
@@ -721,39 +746,11 @@ namespace Mono.CSharp
                        Modifiers.NEW;
 
                public Property (DeclSpace parent, FullNamedExpression type, Modifiers mod,
-                                MemberName name, Attributes attrs, Accessor get_block,
-                                Accessor set_block, bool define_set_first)
-                       : this (parent, type, mod, name, attrs, get_block, set_block,
-                               define_set_first, null)
-               {
-               }
-               
-               public Property (DeclSpace parent, FullNamedExpression type, Modifiers mod,
-                                MemberName name, Attributes attrs, Accessor get_block,
-                                Accessor set_block, bool define_set_first, Block current_block)
+                                MemberName name, Attributes attrs)
                        : base (parent, type, mod,
                                parent.PartialContainer.Kind == MemberKind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
-                               name, attrs, define_set_first)
+                               name, attrs)
                {
-                       if (get_block == null)
-                               Get = new GetMethod (this);
-                       else
-                               Get = new GetMethod (this, get_block);
-
-                       if (set_block == null)
-                               Set = new SetMethod (this);
-                       else
-                               Set = new SetMethod (this, set_block);
-
-                       if (!IsInterface && (mod & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
-                               get_block != null && get_block.Block == null &&
-                               set_block != null && set_block.Block == null) {
-                               if (RootContext.Version <= LanguageVersion.ISO_2)
-                                       Report.FeatureIsNotAvailable (Location, "automatically implemented properties");
-
-                               Get.ModFlags |= Modifiers.COMPILER_GENERATED;
-                               Set.ModFlags |= Modifiers.COMPILER_GENERATED;
-                       }
                }
 
                void CreateAutomaticProperty ()
@@ -787,8 +784,15 @@ namespace Mono.CSharp
 
                        flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
 
-                       if ((Get.ModFlags & Modifiers.COMPILER_GENERATED) != 0)
+                       if (!IsInterface && (ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
+                               AccessorSecond != null && Get.Block == null && Set.Block == null) {
+                               if (RootContext.Version <= LanguageVersion.ISO_2)
+                                       Report.FeatureIsNotAvailable (Location, "automatically implemented properties");
+
+                               Get.ModFlags |= Modifiers.COMPILER_GENERATED;
+                               Set.ModFlags |= Modifiers.COMPILER_GENERATED;
                                CreateAutomaticProperty ();
+                       }
 
                        if (!DefineAccessors ())
                                return false;
@@ -802,7 +806,7 @@ namespace Mono.CSharp
 
                public override void Emit ()
                {
-                       if (((Set.ModFlags | Get.ModFlags) & (Modifiers.STATIC | Modifiers.COMPILER_GENERATED)) == Modifiers.COMPILER_GENERATED && Parent.PartialContainer.HasExplicitLayout) {
+                       if ((AccessorFirst.ModFlags & (Modifiers.STATIC | Modifiers.COMPILER_GENERATED)) == Modifiers.COMPILER_GENERATED && Parent.PartialContainer.HasExplicitLayout) {
                                Report.Error (842, Location,
                                        "Automatically implemented property `{0}' cannot be used inside a type with an explicit StructLayout attribute",
                                        GetSignatureForError ());
@@ -816,10 +820,10 @@ namespace Mono.CSharp
        /// For case when event is declared like property (with add and remove accessors).
        /// </summary>
        public class EventProperty: Event {
-               abstract class AEventPropertyAccessor : AEventAccessor
+               public abstract class AEventPropertyAccessor : AEventAccessor
                {
-                       protected AEventPropertyAccessor (EventProperty method, Accessor accessor, string prefix)
-                               : base (method, accessor, prefix)
+                       protected AEventPropertyAccessor (EventProperty method, string prefix, Attributes attrs, Location loc)
+                               : base (method, prefix, attrs, loc)
                        {
                        }
 
@@ -835,32 +839,27 @@ namespace Mono.CSharp
                        }
                }
 
-               sealed class AddDelegateMethod: AEventPropertyAccessor
+               public sealed class AddDelegateMethod: AEventPropertyAccessor
                {
-                       public AddDelegateMethod (EventProperty method, Accessor accessor):
-                               base (method, accessor, AddPrefix)
+                       public AddDelegateMethod (EventProperty method, Attributes attrs, Location loc)
+                               : base (method, AddPrefix, attrs, loc)
                        {
                        }
                }
 
-               sealed class RemoveDelegateMethod: AEventPropertyAccessor
+               public sealed class RemoveDelegateMethod: AEventPropertyAccessor
                {
-                       public RemoveDelegateMethod (EventProperty method, Accessor accessor):
-                               base (method, accessor, RemovePrefix)
+                       public RemoveDelegateMethod (EventProperty method, Attributes attrs, Location loc)
+                               : base (method, RemovePrefix, attrs, loc)
                        {
                        }
                }
 
-
                static readonly string[] attribute_targets = new string [] { "event" };
 
-               public EventProperty (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags,
-                                     MemberName name,
-                                     Attributes attrs, Accessor add, Accessor remove)
+               public EventProperty (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
                        : base (parent, type, mod_flags, name, attrs)
                {
-                       Add = new AddDelegateMethod (this, add);
-                       Remove = new RemoveDelegateMethod (this, remove);
                }
 
                public override bool Define()
@@ -886,7 +885,7 @@ namespace Mono.CSharp
                abstract class EventFieldAccessor : AEventAccessor
                {
                        protected EventFieldAccessor (EventField method, string prefix)
-                               : base (method, prefix)
+                               : base (method, prefix, null, Location.Null)
                        {
                        }
 
@@ -898,7 +897,7 @@ namespace Mono.CSharp
                                                mb.SetImplementationFlags (mb.GetMethodImplementationFlags () | MethodImplAttributes.Synchronized);
                                        }
 
-                                       var field_info = ((EventField) method).BackingField;
+                                       var field_info = ((EventField) method).backing_field;
                                        FieldExpr f_expr = new FieldExpr (field_info, Location);
                                        if ((method.ModFlags & Modifiers.STATIC) == 0)
                                                f_expr.InstanceExpression = new CompilerGeneratedThis (field_info.Spec.MemberType, Location);
@@ -945,8 +944,9 @@ namespace Mono.CSharp
                static readonly string[] attribute_targets = new string [] { "event", "field", "method" };
                static readonly string[] attribute_targets_interface = new string[] { "event", "method" };
 
-               public Field BackingField;
-               public Expression Initializer;
+               Expression initializer;
+               Field backing_field;
+               List<FieldDeclarator> declarators;
 
                public EventField (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
                        : base (parent, type, mod_flags, name, attrs)
@@ -955,10 +955,46 @@ namespace Mono.CSharp
                        Remove = new RemoveDelegateMethod (this);
                }
 
+               #region Properties
+
+               bool HasBackingField {
+                       get {
+                               return !IsInterface && (ModFlags & Modifiers.ABSTRACT) == 0;
+                       }
+               }
+
+               public Expression Initializer {
+                       get {
+                               return initializer;
+                       }
+                       set {
+                               initializer = value;
+                       }
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return HasBackingField ? attribute_targets : attribute_targets_interface;
+                       }
+               }
+
+               #endregion
+
+               public void AddDeclarator (FieldDeclarator declarator)
+               {
+                       if (declarators == null)
+                               declarators = new List<FieldDeclarator> (2);
+
+                       declarators.Add (declarator);
+
+                       // TODO: This will probably break
+                       Parent.AddMember (this, declarator.Name.Value);
+               }
+
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Target == AttributeTargets.Field) {
-                               BackingField.ApplyAttributeBuilder (a, ctor, cdata, pa);
+                               backing_field.ApplyAttributeBuilder (a, ctor, cdata, pa);
                                return;
                        }
 
@@ -978,9 +1014,17 @@ namespace Mono.CSharp
                        if (!base.Define ())
                                return false;
 
-                       if (Initializer != null && (ModFlags & Modifiers.ABSTRACT) != 0) {
-                               Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
-                                       GetSignatureForError ());
+                       if (declarators != null) {
+                               var t = new TypeExpression (MemberType, TypeExpression.Location);
+                               int index = Parent.PartialContainer.Events.IndexOf (this);
+                               foreach (var d in declarators) {
+                                       var ef = new EventField (Parent, t, ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes);
+
+                                       if (d.Initializer != null)
+                                               ef.initializer = d.Initializer;
+
+                                       Parent.PartialContainer.Events.Insert (++index, ef);
+                               }
                        }
 
                        if (!HasBackingField) {
@@ -988,38 +1032,25 @@ namespace Mono.CSharp
                                return true;
                        }
 
-                       // FIXME: We are unable to detect whether generic event is used because
-                       // we are using FieldExpr instead of EventExpr for event access in that
-                       // case.  When this issue will be fixed this hack can be removed.
-                       if (TypeManager.IsGenericType (MemberType) || Parent.IsGeneric)
-                               SetIsUsed ();
-
                        if (Add.IsInterfaceImplementation)
                                SetIsUsed ();
 
-                       BackingField = new Field (Parent,
+                       backing_field = new Field (Parent,
                                new TypeExpression (MemberType, Location),
                                Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
                                MemberName, null);
 
-                       Parent.PartialContainer.AddField (BackingField);
-                       BackingField.Initializer = Initializer;
-                       BackingField.ModFlags &= ~Modifiers.COMPILER_GENERATED;
+                       Parent.PartialContainer.AddField (backing_field);
+                       backing_field.Initializer = Initializer;
+                       backing_field.ModFlags &= ~Modifiers.COMPILER_GENERATED;
 
                        // Call define because we passed fields definition
-                       return BackingField.Define ();
-               }
+                       backing_field.Define ();
 
-               public bool HasBackingField {
-                       get {
-                               return !IsInterface && (ModFlags & Modifiers.ABSTRACT) == 0;
-                       }
-               }
+                       // Set backing field for event fields
+                       spec.BackingField = backing_field.Spec;
 
-               public override string[] ValidAttributeTargets {
-                       get {
-                               return HasBackingField ? attribute_targets : attribute_targets_interface;
-                       }
+                       return true;
                }
        }
 
@@ -1035,20 +1066,12 @@ namespace Mono.CSharp
                        public const string AddPrefix = "add_";
                        public const string RemovePrefix = "remove_";
 
-                       protected AEventAccessor (Event method, string prefix)
-                               : base (method, prefix)
-                       {
-                               this.method = method;
-                               this.ModFlags = method.ModFlags;
-                               this.parameters = ParametersCompiled.CreateImplicitParameter (method.type_expr, Location);
-                       }
-
-                       protected AEventAccessor (Event method, Accessor accessor, string prefix)
-                               : base (method, accessor, prefix)
+                       protected AEventAccessor (Event method, string prefix, Attributes attrs, Location loc)
+                               : base (method, prefix, attrs, loc)
                        {
                                this.method = method;
                                this.ModFlags = method.ModFlags;
-                               this.parameters = accessor.Parameters;
+                               this.parameters = ParametersCompiled.CreateImplicitParameter (method.TypeExpression, loc);;
                        }
 
                        public bool IsInterfaceImplementation {
@@ -1148,9 +1171,9 @@ namespace Mono.CSharp
                const Modifiers AllowedInterfaceModifiers =
                        Modifiers.NEW;
 
-               public AEventAccessor Add, Remove;
-               public EventBuilder     EventBuilder;
-               public MethodBuilder AddBuilder, RemoveBuilder;
+               AEventAccessor add, remove;
+               EventBuilder EventBuilder;
+               protected EventSpec spec;
 
                protected Event (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
                        : base (parent, null, type, mod_flags,
@@ -1159,6 +1182,35 @@ namespace Mono.CSharp
                {
                }
 
+               #region Properties
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Event;
+                       }
+               }
+
+               public AEventAccessor Add {
+                       get {
+                               return this.add;
+                       }
+                       set {
+                               add = value;
+                               Parent.AddMember (value);
+                       }
+               }
+
+               public AEventAccessor Remove {
+                       get {
+                               return this.remove;
+                       }
+                       set {
+                               remove = value;
+                               Parent.AddMember (value);
+                       }
+               }
+               #endregion
+
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if ((a.HasSecurityAttribute)) {
@@ -1169,17 +1221,6 @@ namespace Mono.CSharp
                        EventBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                }
 
-               public bool AreAccessorsDuplicateImplementation (MethodCore mc)
-               {
-                       return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
-               }
-
-               public override AttributeTargets AttributeTargets {
-                       get {
-                               return AttributeTargets.Event;
-                       }
-               }
-
                protected override bool CheckOverrideAgainstBase (MemberSpec base_member)
                {
                        var ok = base.CheckOverrideAgainstBase (base_member);
@@ -1207,11 +1248,11 @@ namespace Mono.CSharp
                        //
                        // Now define the accessors
                        //
-                       AddBuilder = Add.Define (Parent);
+                       var AddBuilder = Add.Define (Parent);
                        if (AddBuilder == null)
                                return false;
 
-                       RemoveBuilder = Remove.Define (Parent);
+                       var RemoveBuilder = remove.Define (Parent);
                        if (RemoveBuilder == null)
                                return false;
 
@@ -1219,17 +1260,20 @@ namespace Mono.CSharp
                        EventBuilder.SetAddOnMethod (AddBuilder);
                        EventBuilder.SetRemoveOnMethod (RemoveBuilder);
 
-                       var spec = new EventSpec (Parent.Definition, this, MemberType, ModFlags, Add.Spec, Remove.Spec);
+                       spec = new EventSpec (Parent.Definition, this, MemberType, ModFlags, Add.Spec, remove.Spec);
 
                        Parent.MemberCache.AddMember (this, Name, spec);
                        Parent.MemberCache.AddMember (this, AddBuilder.Name, Add.Spec);
-                       Parent.MemberCache.AddMember (this, RemoveBuilder.Name, Remove.Spec);
+                       Parent.MemberCache.AddMember (this, RemoveBuilder.Name, remove.Spec);
 
                        return true;
                }
 
                public override void Emit ()
                {
+                       CheckReservedNameConflict (null, add.Spec);
+                       CheckReservedNameConflict (null, remove.Spec);
+
                        if (OptAttributes != null) {
                                OptAttributes.Emit ();
                        }
@@ -1251,6 +1295,7 @@ namespace Mono.CSharp
        public class EventSpec : MemberSpec, IInterfaceMemberSpec
        {
                MethodSpec add, remove;
+               FieldSpec backing_field;
 
                public EventSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec eventType, Modifiers modifiers, MethodSpec add, MethodSpec remove)
                        : base (MemberKind.Event, declaringType, definition, modifiers)
@@ -1280,6 +1325,15 @@ namespace Mono.CSharp
                        }
                }
 
+               public FieldSpec BackingField {
+                       get {
+                               return backing_field;
+                       }
+                       set {
+                               backing_field = value;
+                       }
+               }
+
                public TypeSpec MemberType { get; private set; }
 
                #endregion
@@ -1298,16 +1352,10 @@ namespace Mono.CSharp
                {
                        ParametersCompiled parameters;
 
-                       public GetIndexerMethod (Indexer method):
-                               base (method)
+                       public GetIndexerMethod (PropertyBase property, Modifiers modifiers, ParametersCompiled parameters, Attributes attrs, Location loc)
+                               : base (property, modifiers, attrs, loc)
                        {
-                               this.parameters = method.parameters;
-                       }
-
-                       public GetIndexerMethod (PropertyBase method, Accessor accessor):
-                               base (method, accessor)
-                       {
-                               parameters = accessor.Parameters;
+                               this.parameters = parameters;
                        }
 
                        public override MethodBuilder Define (DeclSpace parent)
@@ -1315,16 +1363,6 @@ namespace Mono.CSharp
                                parameters.Resolve (this);
                                return base.Define (parent);
                        }
-                       
-                       public override bool EnableOverloadChecks (MemberCore overload)
-                       {
-                               if (base.EnableOverloadChecks (overload)) {
-                                       overload.caching_flags |= Flags.MethodOverloadsExist;
-                                       return true;
-                               }
-
-                               return false;
-                       }                       
 
                        public override ParametersCompiled ParameterInfo {
                                get {
@@ -1351,26 +1389,9 @@ namespace Mono.CSharp
 
                public class SetIndexerMethod : SetMethod, IParametersMember
                {
-                       public SetIndexerMethod (Indexer method):
-                               base (method)
-                       {
-                               parameters = ParametersCompiled.MergeGenerated (Compiler, method.parameters, false, parameters [0], null);
-                       }
-
-                       public SetIndexerMethod (PropertyBase method, Accessor accessor):
-                               base (method, accessor)
+                       public SetIndexerMethod (PropertyBase property, Modifiers modifiers, ParametersCompiled parameters, Attributes attrs, Location loc)
+                               : base (property, modifiers, parameters, attrs, loc)
                        {
-                               parameters = method.Get.IsDummy ? accessor.Parameters : accessor.Parameters.Clone ();                   
-                       }
-
-                       public override bool EnableOverloadChecks (MemberCore overload)
-                       {
-                               if (base.EnableOverloadChecks (overload)) {
-                                       overload.caching_flags |= Flags.MethodOverloadsExist;
-                                       return true;
-                               }
-
-                               return false;
                        }
 
                        #region IParametersMember Members
@@ -1409,23 +1430,12 @@ namespace Mono.CSharp
                readonly ParametersCompiled parameters;
 
                public Indexer (DeclSpace parent, FullNamedExpression type, MemberName name, Modifiers mod,
-                               ParametersCompiled parameters, Attributes attrs,
-                               Accessor get_block, Accessor set_block, bool define_set_first)
+                               ParametersCompiled parameters, Attributes attrs)
                        : base (parent, type, mod,
                                parent.PartialContainer.Kind == MemberKind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
-                               name, attrs, define_set_first)
+                               name, attrs)
                {
                        this.parameters = parameters;
-
-                       if (get_block == null)
-                               Get = new GetIndexerMethod (this);
-                       else
-                               Get = new GetIndexerMethod (this, get_block);
-
-                       if (set_block == null)
-                               Set = new SetIndexerMethod (this);
-                       else
-                               Set = new SetIndexerMethod (this, set_block);
                }
 
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
@@ -1481,8 +1491,7 @@ namespace Mono.CSharp
                                        ShortName = base_IndexerName;
                        }
 
-                       if (!Parent.PartialContainer.AddMember (this) ||
-                               !Parent.PartialContainer.AddMember (Get) || !Parent.PartialContainer.AddMember (Set))
+                       if (!Parent.PartialContainer.AddMember (this))
                                return false;
 
                        flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
@@ -1557,15 +1566,24 @@ namespace Mono.CSharp
                        this.parameters = parameters;
                }
 
+               #region Properties
+               public AParametersCollection Parameters {
+                       get {
+                               return parameters;
+                       }
+               }
+               #endregion
+
                public override string GetSignatureForError ()
                {
                        return DeclaringType.GetSignatureForError () + ".this" + parameters.GetSignatureForError ("[", "]", parameters.Count);
                }
 
-               public AParametersCollection Parameters {
-                       get {
-                               return parameters;
-                       }
+               public override MemberSpec InflateMember (TypeParameterInflator inflator)
+               {
+                       var spec = (IndexerSpec) base.InflateMember (inflator);
+                       spec.parameters = parameters.Inflate (inflator);
+                       return spec;
                }
        }
 }