X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fproperty.cs;h=325b8f118f4bab61e4995812fa54f66a22821e3f;hb=f3edca943070399b06d33f3ba3e99c76a9d9886d;hp=21182e8e9a4692c6f1e74ba8467d41d8880992d3;hpb=f53dd8b2649dd2b1c1ee6297d6c48a307b84b16e;p=mono.git diff --git a/mcs/mcs/property.cs b/mcs/mcs/property.cs index 21182e8e9a4..325b8f118f4 100644 --- a/mcs/mcs/property.cs +++ b/mcs/mcs/property.cs @@ -9,11 +9,13 @@ // // Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com) // Copyright 2004-2008 Novell, Inc +// Copyright 2011 Xamarin Inc // using System; using System.Collections.Generic; using System.Text; +using Mono.CompilerServices.SymbolWriter; #if NET_2_1 using XmlElement = System.Object; @@ -33,10 +35,8 @@ namespace Mono.CSharp // This includes properties, indexers, and events public abstract class PropertyBasedMember : InterfaceMemberBase { - public PropertyBasedMember (DeclSpace parent, GenericMethod generic, - FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, - MemberName name, Attributes attrs) - : base (parent, generic, type, mod, allowed_mod, name, attrs) + public PropertyBasedMember (TypeDefinition parent, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, MemberName name, Attributes attrs) + : base (parent, type, mod, allowed_mod, name, attrs) { } @@ -131,15 +131,6 @@ namespace Mono.CSharp } } - public bool IsNotRealProperty { - get { - return (state & StateFlags.IsNotRealProperty) != 0; - } - set { - state |= StateFlags.IsNotRealProperty; - } - } - public bool HasDifferentAccessibility { get { return HasGet && HasSet && @@ -206,7 +197,7 @@ namespace Mono.CSharp { } - public override MethodBuilder Define (DeclSpace parent) + public override MethodBuilder Define (TypeContainer parent) { base.Define (parent); @@ -214,7 +205,7 @@ namespace Mono.CSharp method_data = new MethodData (method, ModFlags, flags, this); - if (!method_data.Define (parent, method.GetFullName (MemberName), Report)) + if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName))) return null; Spec.SetMetaInfo (method_data.MethodBuilder); @@ -271,7 +262,7 @@ namespace Mono.CSharp } } - public override MethodBuilder Define (DeclSpace parent) + public override MethodBuilder Define (TypeContainer parent) { parameters.Resolve (this); @@ -281,7 +272,7 @@ namespace Mono.CSharp method_data = new MethodData (method, ModFlags, flags, this); - if (!method_data.Define (parent, method.GetFullName (MemberName), Report)) + if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName))) return null; Spec.SetMetaInfo (method_data.MethodBuilder); @@ -306,7 +297,7 @@ namespace Mono.CSharp public abstract class PropertyMethod : AbstractPropertyEventMethod { - public const Modifiers AllowedModifiers = + const Modifiers AllowedModifiers = Modifiers.PUBLIC | Modifiers.PROTECTED | Modifiers.INTERNAL | @@ -319,7 +310,8 @@ namespace Mono.CSharp : base (method, prefix, attrs, loc) { this.method = method; - this.ModFlags = modifiers | (method.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)); + this.ModFlags = ModifiersExtensions.Check (AllowedModifiers, modifiers, 0, loc, Report); + this.ModFlags |= (method.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)); } public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) @@ -342,9 +334,9 @@ namespace Mono.CSharp return method.IsClsComplianceRequired (); } - public virtual MethodBuilder Define (DeclSpace parent) + public virtual MethodBuilder Define (TypeContainer parent) { - TypeContainer container = parent.PartialContainer; + var container = parent.PartialContainer; // // Check for custom access modifier @@ -356,8 +348,7 @@ namespace Mono.CSharp if (container.Kind == MemberKind.Interface) Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface", GetSignatureForError ()); - - if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) { + else if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) { Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ()); } @@ -371,8 +362,13 @@ namespace Mono.CSharp CheckAbstractAndExtern (block != null); CheckProtectedModifier (); - if (block != null && block.IsIterator) - Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags); + if (block != null) { + if (block.IsIterator) + Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags); + + if (Compiler.Settings.WriteMetadataOnly) + block = null; + } return null; } @@ -412,9 +408,8 @@ namespace Mono.CSharp 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) + public PropertyBase (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, Modifiers allowed_mod, MemberName name, Attributes attrs) + : base (parent, type, mod_flags, allowed_mod, name, attrs) { } @@ -456,7 +451,7 @@ namespace Mono.CSharp if (first == null) first = value; - Parent.AddMember (get); + Parent.AddNameToContainer (get, get.MemberName.Basename); } } @@ -469,7 +464,7 @@ namespace Mono.CSharp if (first == null) first = value; - Parent.AddMember (set); + Parent.AddNameToContainer (set, set.MemberName.Basename); } } @@ -668,6 +663,8 @@ namespace Mono.CSharp Module.PredefinedAttributes.Dynamic.EmitAttribute (PropertyBuilder, member_type, Location); } + ConstraintChecker.Check (this, member_type, type_expr.Location); + first.Emit (Parent); if (AccessorSecond != null) AccessorSecond.Emit (Parent); @@ -695,6 +692,15 @@ namespace Mono.CSharp Set.UpdateName (this); } + public override void WriteDebugSymbol (MonoSymbolFile file) + { + if (get != null) + get.WriteDebugSymbol (file); + + if (set != null) + set.WriteDebugSymbol (file); + } + // // Represents header string for documentation comment. // @@ -717,9 +723,9 @@ namespace Mono.CSharp this.property = p; } - public string OriginalName { + public Property OriginalProperty { get { - return property.Name; + return property; } } @@ -729,7 +735,7 @@ namespace Mono.CSharp } } - public Property (DeclSpace parent, FullNamedExpression type, Modifiers mod, + public Property (TypeDefinition parent, FullNamedExpression type, Modifiers mod, MemberName name, Attributes attrs) : base (parent, type, mod, parent.PartialContainer.Kind == MemberKind.Interface ? AllowedModifiersInterface : @@ -739,6 +745,12 @@ namespace Mono.CSharp { } + public override void Accept (StructuralVisitor visitor) + { + visitor.Visit (this); + } + + void CreateAutomaticProperty () { // Create backing field @@ -746,21 +758,25 @@ namespace Mono.CSharp if (!field.Define ()) return; - Parent.PartialContainer.AddField (field); + Parent.PartialContainer.Members.Add (field); FieldExpr fe = new FieldExpr (field, Location); if ((field.ModFlags & Modifiers.STATIC) == 0) - fe.InstanceExpression = new CompilerGeneratedThis (fe.Type, Location); + fe.InstanceExpression = new CompilerGeneratedThis (Parent.CurrentType, Location); - // Create get block - Get.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location); - Return r = new Return (fe, Location); + // + // Create get block but we careful with location to + // emit only single sequence point per accessor. This allow + // to set a breakpoint on it even with no user code + // + Get.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location.Null); + Return r = new Return (fe, Get.Location); Get.Block.AddStatement (r); // Create set block - Set.Block = new ToplevelBlock (Compiler, Set.ParameterInfo, Location); - Assign a = new SimpleAssign (fe, new SimpleName ("value", Location)); - Set.Block.AddStatement (new StatementExpression (a)); + Set.Block = new ToplevelBlock (Compiler, Set.ParameterInfo, Location.Null); + Assign a = new SimpleAssign (fe, new SimpleName ("value", Location.Null), Location.Null); + Set.Block.AddStatement (new StatementExpression (a, Set.Location)); } public override bool Define () @@ -783,6 +799,16 @@ namespace Mono.CSharp if (!DefineAccessors ()) return false; + if (AccessorSecond == null) { + PropertyMethod pm; + if (AccessorFirst is GetMethod) + pm = new SetMethod (this, 0, ParametersCompiled.EmptyReadOnlyParameters, null, Location); + else + pm = new GetMethod (this, 0, null, Location); + + Parent.AddNameToContainer (pm, pm.MemberName.Basename); + } + if (!CheckBase ()) return false; @@ -813,7 +839,7 @@ namespace Mono.CSharp { } - public override MethodBuilder Define (DeclSpace ds) + public override MethodBuilder Define (TypeContainer ds) { CheckAbstractAndExtern (block != null); return base.Define (ds); @@ -843,11 +869,16 @@ namespace Mono.CSharp static readonly string[] attribute_targets = new string [] { "event" }; - public EventProperty (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs) + public EventProperty (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs) : base (parent, type, mod_flags, name, attrs) { } + public override void Accept (StructuralVisitor visitor) + { + visitor.Visit (this); + } + public override bool Define() { if (!base.Define ()) @@ -872,16 +903,18 @@ namespace Mono.CSharp abstract class EventFieldAccessor : AEventAccessor { protected EventFieldAccessor (EventField method, string prefix) - : base (method, prefix, null, Location.Null) + : base (method, prefix, null, method.Location) { } protected abstract MethodSpec GetOperation (Location loc); - public override void Emit (DeclSpace parent) + public override void Emit (TypeDefinition parent) { - if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0) { - block = new ToplevelBlock (Compiler, ParameterInfo, Location); + if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 && !Compiler.Settings.WriteMetadataOnly) { + block = new ToplevelBlock (Compiler, ParameterInfo, Location) { + IsCompilerGenerated = true + }; FabricateBodyStatement (); } @@ -894,8 +927,8 @@ namespace Mono.CSharp // Delegate obj1 = backing_field // do { // Delegate obj2 = obj1; - // obj1 = Interlocked.CompareExchange (ref backing_field, Delegate.Combine|Remove(obj2, value), obj1); - // } while (obj1 != obj2) + // obj1 = Interlocked.CompareExchange (ref backing_field, Delegate.Combine|Remove(obj2, value), obj1); + // } while ((object)obj1 != (object)obj2) // var field_info = ((EventField) method).backing_field; @@ -909,10 +942,11 @@ namespace Mono.CSharp block.AddStatement (new StatementExpression (new SimpleAssign (new LocalVariableReference (obj1, Location), f_expr))); var cond = new BooleanExpression (new Binary (Binary.Operator.Inequality, - new LocalVariableReference (obj1, Location), new LocalVariableReference (obj2, Location), Location)); + new Cast (new TypeExpression (Module.Compiler.BuiltinTypes.Object, Location), new LocalVariableReference (obj1, Location), Location), + new Cast (new TypeExpression (Module.Compiler.BuiltinTypes.Object, Location), new LocalVariableReference (obj2, Location), Location))); var body = new ExplicitBlock (block, Location, Location); - block.AddStatement (new Do (body, cond, Location)); + block.AddStatement (new Do (body, cond, Location, Location)); body.AddStatement (new StatementExpression ( new SimpleAssign (new LocalVariableReference (obj2, Location), new LocalVariableReference (obj1, Location)))); @@ -975,7 +1009,7 @@ namespace Mono.CSharp Field backing_field; List declarators; - public EventField (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs) + public EventField (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs) : base (parent, type, mod_flags, name, attrs) { Add = new AddDelegateMethod (this); @@ -984,6 +1018,12 @@ namespace Mono.CSharp #region Properties + public List Declarators { + get { + return this.declarators; + } + } + bool HasBackingField { get { return !IsInterface && (ModFlags & Modifiers.ABSTRACT) == 0; @@ -1007,6 +1047,12 @@ namespace Mono.CSharp #endregion + + public override void Accept (StructuralVisitor visitor) + { + visitor.Visit (this); + } + public void AddDeclarator (FieldDeclarator declarator) { if (declarators == null) @@ -1014,8 +1060,7 @@ namespace Mono.CSharp declarators.Add (declarator); - // TODO: This will probably break - Parent.AddMember (this, declarator.Name.Value); + Parent.AddNameToContainer (this, declarator.Name.Value); } public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) @@ -1048,14 +1093,14 @@ namespace Mono.CSharp mod_flags_src &= ~(Modifiers.AccessibilityMask | Modifiers.DEFAULT_ACCESS_MODIFER); 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, mod_flags_src, new MemberName (d.Name.Value, d.Name.Location), OptAttributes); if (d.Initializer != null) ef.initializer = d.Initializer; - Parent.PartialContainer.Events.Insert (++index, ef); + ef.Define (); + Parent.PartialContainer.Members.Add (ef); } } @@ -1072,7 +1117,7 @@ namespace Mono.CSharp Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)), MemberName, null); - Parent.PartialContainer.AddField (backing_field); + Parent.PartialContainer.Members.Add (backing_field); backing_field.Initializer = Initializer; backing_field.ModFlags &= ~Modifiers.COMPILER_GENERATED; @@ -1140,7 +1185,7 @@ namespace Mono.CSharp return method.IsClsComplianceRequired (); } - public virtual MethodBuilder Define (DeclSpace parent) + public virtual MethodBuilder Define (TypeContainer parent) { // Fill in already resolved event type to speed things up and // avoid confusing duplicate errors @@ -1150,9 +1195,12 @@ namespace Mono.CSharp method_data = new MethodData (method, method.ModFlags, method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this); - if (!method_data.Define (parent, method.GetFullName (MemberName), Report)) + if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName))) return null; + if (Compiler.Settings.WriteMetadataOnly) + block = null; + MethodBuilder mb = method_data.MethodBuilder; Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, mb, ParameterInfo, method.ModFlags); @@ -1189,8 +1237,8 @@ namespace Mono.CSharp EventBuilder EventBuilder; protected EventSpec spec; - protected Event (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs) - : base (parent, null, type, mod_flags, + protected Event (TypeDefinition parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs) + : base (parent, type, mod_flags, parent.PartialContainer.Kind == MemberKind.Interface ? AllowedModifiersInterface : parent.PartialContainer.Kind == MemberKind.Struct ? AllowedModifiersStruct : AllowedModifiersClass, @@ -1212,7 +1260,7 @@ namespace Mono.CSharp } set { add = value; - Parent.AddMember (value); + Parent.AddNameToContainer (value, value.MemberName.Basename); } } @@ -1228,7 +1276,7 @@ namespace Mono.CSharp } set { remove = value; - Parent.AddMember (value); + Parent.AddNameToContainer (value, value.MemberName.Basename); } } #endregion @@ -1260,7 +1308,7 @@ namespace Mono.CSharp if (!base.Define ()) return false; - if (!TypeManager.IsDelegateType (MemberType)) { + if (!MemberType.IsDelegate) { Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ()); } @@ -1284,7 +1332,7 @@ namespace Mono.CSharp spec = new EventSpec (Parent.Definition, this, MemberType, ModFlags, Add.Spec, remove.Spec); - Parent.MemberCache.AddMember (this, Name, spec); + Parent.MemberCache.AddMember (this, GetFullName (MemberName), spec); Parent.MemberCache.AddMember (this, AddBuilder.Name, Add.Spec); Parent.MemberCache.AddMember (this, RemoveBuilder.Name, remove.Spec); @@ -1300,12 +1348,20 @@ namespace Mono.CSharp OptAttributes.Emit (); } + ConstraintChecker.Check (this, member_type, type_expr.Location); + Add.Emit (Parent); Remove.Emit (Parent); base.Emit (); } + public override void WriteDebugSymbol (MonoSymbolFile file) + { + add.WriteDebugSymbol (file); + remove.WriteDebugSymbol (file); + } + // // Represents header string for documentation comment. // @@ -1389,9 +1445,16 @@ namespace Mono.CSharp this.parameters = parameters; } - public override MethodBuilder Define (DeclSpace parent) + public override MethodBuilder Define (TypeContainer parent) { - parameters.Resolve (this); + // Disable reporting, parameters are resolved twice + Report.DisableReporting (); + try { + parameters.Resolve (this); + } finally { + Report.EnableReporting (); + } + return base.Define (parent); } @@ -1460,8 +1523,7 @@ namespace Mono.CSharp readonly ParametersCompiled parameters; - public Indexer (DeclSpace parent, FullNamedExpression type, MemberName name, Modifiers mod, - ParametersCompiled parameters, Attributes attrs) + public Indexer (TypeDefinition parent, FullNamedExpression type, MemberName name, Modifiers mod, ParametersCompiled parameters, Attributes attrs) : base (parent, type, mod, parent.PartialContainer.Kind == MemberKind.Interface ? AllowedInterfaceModifiers : AllowedModifiers, name, attrs) @@ -1469,15 +1531,31 @@ namespace Mono.CSharp this.parameters = parameters; } + #region Properties + + AParametersCollection IParametersMember.Parameters { + get { + return parameters; + } + } + + public ParametersCompiled ParameterInfo { + get { + return parameters; + } + } + + #endregion + + + public override void Accept (StructuralVisitor visitor) + { + visitor.Visit (this); + } + public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) { if (a.Type == pa.IndexerName) { - if (IsExplicitImpl) { - Report.Error (415, a.Location, - "The `{0}' attribute is valid only on an indexer that is not an explicit interface member declaration", - TypeManager.CSharpName (a.Type)); - } - // Attribute was copied to container return; } @@ -1505,25 +1583,31 @@ namespace Mono.CSharp if (compiling != null) compiling.Define (); - string name = indexer_attr.GetIndexerAttributeValue (); - if ((ModFlags & Modifiers.OVERRIDE) != 0) { + if (IsExplicitImpl) { + Report.Error (415, indexer_attr.Location, + "The `{0}' attribute is valid only on an indexer that is not an explicit interface member declaration", + indexer_attr.Type.GetSignatureForError ()); + } else if ((ModFlags & Modifiers.OVERRIDE) != 0) { Report.Error (609, indexer_attr.Location, "Cannot set the `IndexerName' attribute on an indexer marked override"); - } + } else { + string name = indexer_attr.GetIndexerAttributeValue (); - if (!string.IsNullOrEmpty (name)) - ShortName = name; + if (!string.IsNullOrEmpty (name)) { + SetMemberName (new MemberName (MemberName.Left, name, Location)); + } + } } } if (InterfaceType != null) { string base_IndexerName = InterfaceType.MemberDefinition.GetAttributeDefaultMember (); - if (base_IndexerName != Name) - ShortName = base_IndexerName; + if (base_IndexerName != ShortName) { + SetMemberName (new MemberName (MemberName.Left, base_IndexerName, new TypeExpression (InterfaceType, Location), Location)); + } } - if (!Parent.PartialContainer.AddMember (this)) - return false; + Parent.AddNameToContainer (this, MemberName.Basename); flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName; @@ -1547,12 +1631,19 @@ namespace Mono.CSharp return base.EnableOverloadChecks (overload); } + public override void Emit () + { + parameters.CheckConstraints (this); + + base.Emit (); + } + public override string GetSignatureForError () { StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ()); - if (MemberName.Left != null) { + if (MemberName.ExplicitInterface != null) { sb.Append ("."); - sb.Append (MemberName.Left.GetSignatureForError ()); + sb.Append (MemberName.ExplicitInterface.GetSignatureForError ()); } sb.Append (".this"); @@ -1565,18 +1656,6 @@ namespace Mono.CSharp return base.GetSignatureForDocumentation () + parameters.GetSignatureForDocumentation (); } - public AParametersCollection Parameters { - get { - return parameters; - } - } - - public ParametersCompiled ParameterInfo { - get { - return parameters; - } - } - protected override bool VerifyClsCompliance () { if (!base.VerifyClsCompliance ())