2 // property.cs: Property based handlers
4 // Authors: Miguel de Icaza (miguel@gnu.org)
5 // Martin Baulig (martin@ximian.com)
6 // Marek Safar (marek.safar@seznam.cz)
8 // Dual licensed under the terms of the MIT X11 or GNU GPL
10 // Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
11 // Copyright 2004-2008 Novell, Inc
12 // Copyright 2011 Xamarin Inc
16 using System
.Collections
.Generic
;
18 using Mono
.CompilerServices
.SymbolWriter
;
21 using XmlElement
= System
.Object
;
25 using IKVM
.Reflection
;
26 using IKVM
.Reflection
.Emit
;
28 using System
.Reflection
;
29 using System
.Reflection
.Emit
;
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
38 protected PropertyBasedMember (TypeDefinition parent
, FullNamedExpression type
, Modifiers mod
, Modifiers allowed_mod
, MemberName name
, Attributes attrs
)
39 : base (parent
, type
, mod
, allowed_mod
, name
, attrs
)
43 protected void CheckReservedNameConflict (string prefix
, MethodSpec accessor
)
46 AParametersCollection parameters
;
47 if (accessor
!= null) {
49 parameters
= accessor
.Parameters
;
51 name
= prefix
+ ShortName
;
53 name
= MemberName
.Left
+ "." + name
;
55 if (this is Indexer
) {
56 parameters
= ((Indexer
) this).ParameterInfo
;
57 if (prefix
[0] == 's') {
58 var data
= new IParameterData
[parameters
.Count
+ 1];
59 Array
.Copy (parameters
.FixedParameters
, data
, data
.Length
- 1);
60 data
[data
.Length
- 1] = new ParameterData ("value", Parameter
.Modifier
.NONE
);
61 var types
= new TypeSpec
[data
.Length
];
62 Array
.Copy (parameters
.Types
, types
, data
.Length
- 1);
63 types
[data
.Length
- 1] = member_type
;
65 parameters
= new ParametersImported (data
, types
, false);
69 parameters
= ParametersCompiled
.CreateFullyResolved (new[] { member_type }
);
71 parameters
= ParametersCompiled
.EmptyReadOnlyParameters
;
75 var conflict
= MemberCache
.FindMember (Parent
.Definition
,
76 new MemberFilter (name
, 0, MemberKind
.Method
, parameters
, null),
77 BindingRestriction
.DeclaredOnly
| BindingRestriction
.NoAccessors
);
79 if (conflict
!= null) {
80 Report
.SymbolRelatedToPreviousError (conflict
);
81 Report
.Error (82, Location
, "A member `{0}' is already reserved", conflict
.GetSignatureForError ());
85 protected override bool VerifyClsCompliance ()
87 if (!base.VerifyClsCompliance ())
90 if (!MemberType
.IsCLSCompliant ()) {
91 Report
.Warning (3003, 1, Location
, "Type of `{0}' is not CLS-compliant",
92 GetSignatureForError ());
99 public class PropertySpec
: MemberSpec
, IInterfaceMemberSpec
105 public PropertySpec (MemberKind kind
, TypeSpec declaringType
, IMemberDefinition definition
, TypeSpec memberType
, PropertyInfo info
, Modifiers modifiers
)
106 : base (kind
, declaringType
, definition
, modifiers
)
109 this.memberType
= memberType
;
114 public MethodSpec Get
{
120 get.IsAccessor
= true;
124 public MethodSpec Set
{
130 set.IsAccessor
= true;
134 public bool HasDifferentAccessibility
{
136 return HasGet
&& HasSet
&&
137 (Get
.Modifiers
& Modifiers
.AccessibilityMask
) != (Set
.Modifiers
& Modifiers
.AccessibilityMask
);
153 public PropertyInfo MetaInfo
{
155 if ((state
& StateFlags
.PendingMetaInflate
) != 0)
156 throw new NotSupportedException ();
162 public TypeSpec MemberType
{
170 public override MemberSpec
InflateMember (TypeParameterInflator inflator
)
172 var ps
= (PropertySpec
) base.InflateMember (inflator
);
173 ps
.memberType
= inflator
.Inflate (memberType
);
177 public override List
<MissingTypeSpecReference
> ResolveMissingDependencies (MemberSpec caller
)
179 return memberType
.ResolveMissingDependencies (this);
184 // Properties and Indexers both generate PropertyBuilders, we use this to share
185 // their common bits.
187 abstract public class PropertyBase
: PropertyBasedMember
{
189 public class GetMethod
: PropertyMethod
191 static readonly string[] attribute_targets
= new string [] { "method", "return" }
;
193 internal const string Prefix
= "get_";
195 public GetMethod (PropertyBase method
, Modifiers modifiers
, Attributes attrs
, Location loc
)
196 : base (method
, Prefix
, modifiers
, attrs
, loc
)
200 public override void Define (TypeContainer parent
)
202 base.Define (parent
);
204 Spec
= new MethodSpec (MemberKind
.Method
, parent
.PartialContainer
.Definition
, this, ReturnType
, ParameterInfo
, ModFlags
);
206 method_data
= new MethodData (method
, ModFlags
, flags
, this);
208 method_data
.Define (parent
.PartialContainer
, method
.GetFullName (MemberName
));
211 public override TypeSpec ReturnType
{
213 return method
.MemberType
;
217 public override ParametersCompiled ParameterInfo
{
219 return ParametersCompiled
.EmptyReadOnlyParameters
;
223 public override string[] ValidAttributeTargets
{
225 return attribute_targets
;
230 public class SetMethod
: PropertyMethod
{
232 static readonly string[] attribute_targets
= new string[] { "method", "param", "return" }
;
234 internal const string Prefix
= "set_";
236 protected ParametersCompiled parameters
;
238 public SetMethod (PropertyBase method
, Modifiers modifiers
, ParametersCompiled parameters
, Attributes attrs
, Location loc
)
239 : base (method
, Prefix
, modifiers
, attrs
, loc
)
241 this.parameters
= parameters
;
244 protected override void ApplyToExtraTarget (Attribute a
, MethodSpec ctor
, byte[] cdata
, PredefinedAttributes pa
)
246 if (a
.Target
== AttributeTargets
.Parameter
) {
247 parameters
[parameters
.Count
- 1].ApplyAttributeBuilder (a
, ctor
, cdata
, pa
);
251 base.ApplyToExtraTarget (a
, ctor
, cdata
, pa
);
254 public override ParametersCompiled ParameterInfo
{
260 public override void Define (TypeContainer parent
)
262 parameters
.Resolve (this);
264 base.Define (parent
);
266 Spec
= new MethodSpec (MemberKind
.Method
, parent
.PartialContainer
.Definition
, this, ReturnType
, ParameterInfo
, ModFlags
);
268 method_data
= new MethodData (method
, ModFlags
, flags
, this);
270 method_data
.Define (parent
.PartialContainer
, method
.GetFullName (MemberName
));
273 public override TypeSpec ReturnType
{
275 return Parent
.Compiler
.BuiltinTypes
.Void
;
279 public override string[] ValidAttributeTargets
{
281 return attribute_targets
;
286 static readonly string[] attribute_targets
= new string[] { "property" }
;
288 public abstract class PropertyMethod
: AbstractPropertyEventMethod
290 const Modifiers AllowedModifiers
=
292 Modifiers
.PROTECTED
|
296 protected readonly PropertyBase method
;
297 protected MethodAttributes flags
;
299 public PropertyMethod (PropertyBase method
, string prefix
, Modifiers modifiers
, Attributes attrs
, Location loc
)
300 : base (method
, prefix
, attrs
, loc
)
302 this.method
= method
;
303 this.ModFlags
= ModifiersExtensions
.Check (AllowedModifiers
, modifiers
, 0, loc
, Report
);
304 this.ModFlags
|= (method
.ModFlags
& (Modifiers
.STATIC
| Modifiers
.UNSAFE
));
307 public override void ApplyAttributeBuilder (Attribute a
, MethodSpec ctor
, byte[] cdata
, PredefinedAttributes pa
)
309 if (a
.Type
== pa
.MethodImpl
) {
310 method
.is_external_implementation
= a
.IsInternalCall ();
313 base.ApplyAttributeBuilder (a
, ctor
, cdata
, pa
);
316 public override AttributeTargets AttributeTargets
{
318 return AttributeTargets
.Method
;
322 public override bool IsClsComplianceRequired ()
324 return method
.IsClsComplianceRequired ();
327 public virtual void Define (TypeContainer parent
)
329 var container
= parent
.PartialContainer
;
332 // Check for custom access modifier
334 if ((ModFlags
& Modifiers
.AccessibilityMask
) == 0) {
335 ModFlags
|= method
.ModFlags
;
336 flags
= method
.flags
;
338 CheckModifiers (ModFlags
);
339 ModFlags
|= (method
.ModFlags
& (~Modifiers
.AccessibilityMask
));
340 ModFlags
|= Modifiers
.PROPERTY_CUSTOM
;
342 if (container
.Kind
== MemberKind
.Interface
) {
343 Report
.Error (275, Location
, "`{0}': accessibility modifiers may not be used on accessors in an interface",
344 GetSignatureForError ());
345 } else if ((ModFlags
& Modifiers
.PRIVATE
) != 0) {
346 if ((method
.ModFlags
& Modifiers
.ABSTRACT
) != 0) {
347 Report
.Error (442, Location
, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
350 ModFlags
&= ~Modifiers
.VIRTUAL
;
353 flags
= ModifiersExtensions
.MethodAttr (ModFlags
) | MethodAttributes
.SpecialName
;
356 CheckAbstractAndExtern (block
!= null);
357 CheckProtectedModifier ();
360 if (block
.IsIterator
)
361 Iterator
.CreateIterator (this, Parent
.PartialContainer
, ModFlags
);
363 if (Compiler
.Settings
.WriteMetadataOnly
)
368 public bool HasCustomAccessModifier
{
370 return (ModFlags
& Modifiers
.PROPERTY_CUSTOM
) != 0;
374 public PropertyBase Property
{
380 public override ObsoleteAttribute
GetAttributeObsolete ()
382 return method
.GetAttributeObsolete ();
385 public override string GetSignatureForError()
387 return method
.GetSignatureForError () + "." + prefix
.Substring (0, 3);
390 void CheckModifiers (Modifiers modflags
)
392 if (!ModifiersExtensions
.IsRestrictedModifier (modflags
& Modifiers
.AccessibilityMask
, method
.ModFlags
& Modifiers
.AccessibilityMask
)) {
393 Report
.Error (273, Location
,
394 "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
395 GetSignatureForError (), method
.GetSignatureForError ());
400 PropertyMethod
get, set, first
;
401 PropertyBuilder PropertyBuilder
;
403 protected PropertyBase (TypeDefinition parent
, FullNamedExpression type
, Modifiers mod_flags
, Modifiers allowed_mod
, MemberName name
, Attributes attrs
)
404 : base (parent
, type
, mod_flags
, allowed_mod
, name
, attrs
)
410 public override AttributeTargets AttributeTargets
{
412 return AttributeTargets
.Property
;
416 public PropertyMethod AccessorFirst
{
422 public PropertyMethod AccessorSecond
{
424 return first
== get ? set : get;
428 public override Variance ExpectedMemberTypeVariance
{
430 return (get != null && set != null) ?
431 Variance
.None
: set == null ?
433 Variance
.Contravariant
;
437 public PropertyMethod Get
{
446 Parent
.AddNameToContainer (get, get.MemberName
.Basename
);
450 public PropertyMethod Set
{
459 Parent
.AddNameToContainer (set, set.MemberName
.Basename
);
463 public override string[] ValidAttributeTargets
{
465 return attribute_targets
;
471 public override void ApplyAttributeBuilder (Attribute a
, MethodSpec ctor
, byte[] cdata
, PredefinedAttributes pa
)
473 if (a
.HasSecurityAttribute
) {
474 a
.Error_InvalidSecurityParent ();
478 if (a
.Type
== pa
.Dynamic
) {
479 a
.Error_MisusedDynamicAttribute ();
483 PropertyBuilder
.SetCustomAttribute ((ConstructorInfo
) ctor
.GetMetaInfo (), cdata
);
486 void CheckMissingAccessor (MemberKind kind
, ParametersCompiled parameters
, bool get)
488 if (IsExplicitImpl
) {
490 if (kind
== MemberKind
.Indexer
)
491 filter
= new MemberFilter (MemberCache
.IndexerNameAlias
, 0, kind
, parameters
, null);
493 filter
= new MemberFilter (MemberName
.Name
, 0, kind
, null, null);
495 var implementing
= MemberCache
.FindMember (InterfaceType
, filter
, BindingRestriction
.DeclaredOnly
) as PropertySpec
;
497 if (implementing
== null)
500 var accessor
= get ? implementing
.Get
: implementing
.Set
;
501 if (accessor
!= null) {
502 Report
.SymbolRelatedToPreviousError (accessor
);
503 Report
.Error (551, Location
, "Explicit interface implementation `{0}' is missing accessor `{1}'",
504 GetSignatureForError (), accessor
.GetSignatureForError ());
509 protected override bool CheckOverrideAgainstBase (MemberSpec base_member
)
511 var ok
= base.CheckOverrideAgainstBase (base_member
);
514 // Check base property accessors conflict
516 var base_prop
= (PropertySpec
) base_member
;
518 if ((ModFlags
& Modifiers
.SEALED
) != 0 && base_prop
.HasGet
&& !base_prop
.Get
.IsAccessible (this)) {
519 // TODO: Should be different error code but csc uses for some reason same
520 Report
.SymbolRelatedToPreviousError (base_prop
);
521 Report
.Error (545, Location
,
522 "`{0}': cannot override because `{1}' does not have accessible get accessor",
523 GetSignatureForError (), base_prop
.GetSignatureForError ());
527 if (!base_prop
.HasGet
) {
529 Report
.SymbolRelatedToPreviousError (base_prop
);
530 Report
.Error (545, Get
.Location
,
531 "`{0}': cannot override because `{1}' does not have an overridable get accessor",
532 Get
.GetSignatureForError (), base_prop
.GetSignatureForError ());
535 } else if (Get
.HasCustomAccessModifier
|| base_prop
.HasDifferentAccessibility
) {
536 if (!base_prop
.Get
.IsAccessible (this)) {
537 // Same as csc but it should be different error code
538 Report
.Error (115, Get
.Location
, "`{0}' is marked as an override but no accessible `get' accessor found to override",
539 GetSignatureForError ());
541 } else if (!CheckAccessModifiers (Get
, base_prop
.Get
)) {
542 Error_CannotChangeAccessModifiers (Get
, base_prop
.Get
);
549 if (base_prop
.HasSet
) {
550 if ((ModFlags
& Modifiers
.SEALED
) != 0 && !base_prop
.Set
.IsAccessible (this)) {
551 // TODO: Should be different error code but csc uses for some reason same
552 Report
.SymbolRelatedToPreviousError (base_prop
);
553 Report
.Error (546, Location
,
554 "`{0}': cannot override because `{1}' does not have accessible set accessor",
555 GetSignatureForError (), base_prop
.GetSignatureForError ());
559 if ((ModFlags
& Modifiers
.AutoProperty
) != 0) {
560 Report
.Error (8080, Location
, "`{0}': Auto-implemented properties must override all accessors of the overridden property",
561 GetSignatureForError ());
566 if (!base_prop
.HasSet
) {
568 Report
.SymbolRelatedToPreviousError (base_prop
);
569 Report
.Error (546, Set
.Location
,
570 "`{0}': cannot override because `{1}' does not have an overridable set accessor",
571 Set
.GetSignatureForError (), base_prop
.GetSignatureForError ());
574 } else if (Set
.HasCustomAccessModifier
|| base_prop
.HasDifferentAccessibility
) {
575 if (!base_prop
.Set
.IsAccessible (this)) {
576 // Same as csc but it should be different error code
577 Report
.Error (115, Set
.Location
, "`{0}' is marked as an override but no accessible `set' accessor found to override",
578 GetSignatureForError ());
580 } else if (!CheckAccessModifiers (Set
, base_prop
.Set
)) {
581 Error_CannotChangeAccessModifiers (Set
, base_prop
.Set
);
587 if ((Set
== null || !Set
.HasCustomAccessModifier
) && (Get
== null || !Get
.HasCustomAccessModifier
)) {
588 if (!CheckAccessModifiers (this, base_prop
)) {
589 Error_CannotChangeAccessModifiers (this, base_prop
);
597 protected override void DoMemberTypeDependentChecks ()
599 base.DoMemberTypeDependentChecks ();
603 if (MemberType
.IsStatic
)
604 Error_StaticReturnType ();
607 protected override void DoMemberTypeIndependentChecks ()
609 base.DoMemberTypeIndependentChecks ();
612 // Accessors modifiers check
614 if (AccessorSecond
!= null) {
615 if ((Get
.ModFlags
& Modifiers
.AccessibilityMask
) != 0 && (Set
.ModFlags
& Modifiers
.AccessibilityMask
) != 0) {
616 Report
.Error (274, Location
, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
617 GetSignatureForError ());
619 } else if ((ModFlags
& Modifiers
.OVERRIDE
) == 0 &&
620 ((Get
== null && (Set
.ModFlags
& Modifiers
.AccessibilityMask
) != 0) || (Set
== null && (Get
.ModFlags
& Modifiers
.AccessibilityMask
) != 0))) {
621 Report
.Error (276, Location
,
622 "`{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor",
623 GetSignatureForError ());
627 protected bool DefineAccessors ()
629 first
.Define (Parent
);
630 if (AccessorSecond
!= null)
631 AccessorSecond
.Define (Parent
);
636 protected void DefineBuilders (MemberKind kind
, ParametersCompiled parameters
)
638 PropertyBuilder
= Parent
.TypeBuilder
.DefineProperty (
639 GetFullName (MemberName
), PropertyAttributes
.None
,
640 #if !BOOTSTRAP_BASIC // Requires trunk version mscorlib
641 IsStatic
? 0 : CallingConventions
.HasThis
,
643 MemberType
.GetMetaInfo (), null, null,
644 parameters
.GetMetaInfo (), null, null);
647 if (kind
== MemberKind
.Indexer
)
648 spec
= new IndexerSpec (Parent
.Definition
, this, MemberType
, parameters
, PropertyBuilder
, ModFlags
);
650 spec
= new PropertySpec (kind
, Parent
.Definition
, this, MemberType
, PropertyBuilder
, ModFlags
);
654 Parent
.MemberCache
.AddMember (this, Get
.Spec
.Name
, Get
.Spec
);
656 CheckMissingAccessor (kind
, parameters
, true);
661 Parent
.MemberCache
.AddMember (this, Set
.Spec
.Name
, Set
.Spec
);
663 CheckMissingAccessor (kind
, parameters
, false);
666 Parent
.MemberCache
.AddMember (this, PropertyBuilder
.Name
, spec
);
669 public override void Emit ()
671 CheckReservedNameConflict (GetMethod
.Prefix
, get == null ? null : get.Spec
);
672 CheckReservedNameConflict (SetMethod
.Prefix
, set == null ? null : set.Spec
);
674 if (OptAttributes
!= null)
675 OptAttributes
.Emit ();
677 if (member_type
.BuiltinType
== BuiltinTypeSpec
.Type
.Dynamic
) {
678 Module
.PredefinedAttributes
.Dynamic
.EmitAttribute (PropertyBuilder
);
679 } else if (member_type
.HasDynamicElement
) {
680 Module
.PredefinedAttributes
.Dynamic
.EmitAttribute (PropertyBuilder
, member_type
, Location
);
683 ConstraintChecker
.Check (this, member_type
, type_expr
.Location
);
686 if (AccessorSecond
!= null)
687 AccessorSecond
.Emit (Parent
);
692 public override bool IsUsed
{
697 return Get
.IsUsed
| Set
.IsUsed
;
701 public override void PrepareEmit ()
703 AccessorFirst
.PrepareEmit ();
704 if (AccessorSecond
!= null)
705 AccessorSecond
.PrepareEmit ();
708 var method
= Get
.Spec
.GetMetaInfo () as MethodBuilder
;
710 PropertyBuilder
.SetGetMethod (method
);
714 var method
= Set
.Spec
.GetMetaInfo () as MethodBuilder
;
716 PropertyBuilder
.SetSetMethod (method
);
720 protected override void SetMemberName (MemberName new_name
)
722 base.SetMemberName (new_name
);
725 Get
.UpdateName (this);
728 Set
.UpdateName (this);
731 public override void WriteDebugSymbol (MonoSymbolFile file
)
734 get.WriteDebugSymbol (file
);
737 set.WriteDebugSymbol (file
);
741 // Represents header string for documentation comment.
743 public override string DocCommentHeader
{
748 public class Property
: PropertyBase
750 public sealed class BackingFieldDeclaration
: Field
752 readonly Property property
;
753 const Modifiers DefaultModifiers
= Modifiers
.BACKING_FIELD
| Modifiers
.COMPILER_GENERATED
| Modifiers
.PRIVATE
| Modifiers
.DEBUGGER_HIDDEN
;
755 public BackingFieldDeclaration (Property p
, bool readOnly
)
756 : base (p
.Parent
, p
.type_expr
, DefaultModifiers
| (p
.ModFlags
& (Modifiers
.STATIC
| Modifiers
.UNSAFE
)),
757 new MemberName ("<" + p
.GetFullName (p
.MemberName
) + ">k__BackingField", p
.Location
), null)
761 ModFlags
|= Modifiers
.READONLY
;
764 public Property OriginalProperty
{
770 public override string GetSignatureForError ()
772 return property
.GetSignatureForError ();
776 static readonly string[] attribute_target_auto
= new string[] { "property", "field" }
;
778 public Property (TypeDefinition parent
, FullNamedExpression type
, Modifiers mod
,
779 MemberName name
, Attributes attrs
)
780 : base (parent
, type
, mod
,
781 parent
.PartialContainer
.Kind
== MemberKind
.Interface
? AllowedModifiersInterface
:
782 parent
.PartialContainer
.Kind
== MemberKind
.Struct
? AllowedModifiersStruct
:
783 AllowedModifiersClass
,
788 public BackingFieldDeclaration BackingField { get; private set; }
790 public Expression Initializer { get; set; }
792 public override void Accept (StructuralVisitor visitor
)
794 visitor
.Visit (this);
797 public override void ApplyAttributeBuilder (Attribute a
, MethodSpec ctor
, byte[] cdata
, PredefinedAttributes pa
)
799 if (a
.Target
== AttributeTargets
.Field
) {
800 BackingField
.ApplyAttributeBuilder (a
, ctor
, cdata
, pa
);
804 base.ApplyAttributeBuilder (a
, ctor
, cdata
, pa
);
807 void CreateAutomaticProperty ()
809 // Create backing field
810 BackingField
= new BackingFieldDeclaration (this, Initializer
== null && Set
== null);
811 if (!BackingField
.Define ())
814 if (Initializer
!= null) {
815 BackingField
.Initializer
= Initializer
;
816 Parent
.RegisterFieldForInitialization (BackingField
, new FieldInitializer (BackingField
, Initializer
, Location
));
817 BackingField
.ModFlags
|= Modifiers
.READONLY
;
820 Parent
.PartialContainer
.Members
.Add (BackingField
);
822 FieldExpr fe
= new FieldExpr (BackingField
, Location
);
823 if ((BackingField
.ModFlags
& Modifiers
.STATIC
) == 0)
824 fe
.InstanceExpression
= new CompilerGeneratedThis (Parent
.CurrentType
, Location
);
827 // Create get block but we careful with location to
828 // emit only single sequence point per accessor. This allow
829 // to set a breakpoint on it even with no user code
831 Get
.Block
= new ToplevelBlock (Compiler
, ParametersCompiled
.EmptyReadOnlyParameters
, Location
.Null
);
832 Return r
= new Return (fe
, Get
.Location
);
833 Get
.Block
.AddStatement (r
);
834 Get
.ModFlags
|= Modifiers
.COMPILER_GENERATED
;
838 Set
.Block
= new ToplevelBlock (Compiler
, Set
.ParameterInfo
, Location
.Null
);
839 Assign a
= new SimpleAssign (fe
, new SimpleName ("value", Location
.Null
), Location
.Null
);
840 Set
.Block
.AddStatement (new StatementExpression (a
, Set
.Location
));
841 Set
.ModFlags
|= Modifiers
.COMPILER_GENERATED
;
845 public override bool Define ()
850 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
852 bool auto
= AccessorFirst
.Block
== null && (AccessorSecond
== null || AccessorSecond
.Block
== null) &&
853 (ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) == 0;
855 if (Initializer
!= null) {
857 Report
.Error (8050, Location
, "`{0}': Only auto-implemented properties can have initializers",
858 GetSignatureForError ());
861 Report
.Error (8052, Location
, "`{0}': Properties inside interfaces cannot have initializers",
862 GetSignatureForError ());
864 if (Compiler
.Settings
.Version
< LanguageVersion
.V_6
)
865 Report
.FeatureIsNotAvailable (Compiler
, Location
, "auto-implemented property initializer");
869 ModFlags
|= Modifiers
.AutoProperty
;
871 Report
.Error (8051, Location
, "Auto-implemented property `{0}' must have get accessor",
872 GetSignatureForError ());
876 if (Compiler
.Settings
.Version
< LanguageVersion
.V_3
&& Initializer
== null)
877 Report
.FeatureIsNotAvailable (Compiler
, Location
, "auto-implemented properties");
879 CreateAutomaticProperty ();
882 if (!DefineAccessors ())
885 if (AccessorSecond
== null) {
887 if (AccessorFirst
is GetMethod
)
888 pm
= new SetMethod (this, 0, ParametersCompiled
.EmptyReadOnlyParameters
, null, Location
);
890 pm
= new GetMethod (this, 0, null, Location
);
892 Parent
.AddNameToContainer (pm
, pm
.MemberName
.Basename
);
898 DefineBuilders (MemberKind
.Property
, ParametersCompiled
.EmptyReadOnlyParameters
);
902 public override void Emit ()
904 if ((AccessorFirst
.ModFlags
& (Modifiers
.STATIC
| Modifiers
.AutoProperty
)) == Modifiers
.AutoProperty
&& Parent
.PartialContainer
.HasExplicitLayout
) {
905 Report
.Error (842, Location
,
906 "Automatically implemented property `{0}' cannot be used inside a type with an explicit StructLayout attribute",
907 GetSignatureForError ());
913 public override string[] ValidAttributeTargets
{
915 return Get
!= null && ((Get
.ModFlags
& Modifiers
.COMPILER_GENERATED
) != 0) ?
916 attribute_target_auto
: base.ValidAttributeTargets
;
922 /// For case when event is declared like property (with add and remove accessors).
924 public class EventProperty
: Event
{
925 public abstract class AEventPropertyAccessor
: AEventAccessor
927 protected AEventPropertyAccessor (EventProperty method
, string prefix
, Attributes attrs
, Location loc
)
928 : base (method
, prefix
, attrs
, loc
)
932 public override void Define (TypeContainer ds
)
934 CheckAbstractAndExtern (block
!= null);
938 public override string GetSignatureForError ()
940 return method
.GetSignatureForError () + "." + prefix
.Substring (0, prefix
.Length
- 1);
944 public sealed class AddDelegateMethod
: AEventPropertyAccessor
946 public AddDelegateMethod (EventProperty method
, Attributes attrs
, Location loc
)
947 : base (method
, AddPrefix
, attrs
, loc
)
952 public sealed class RemoveDelegateMethod
: AEventPropertyAccessor
954 public RemoveDelegateMethod (EventProperty method
, Attributes attrs
, Location loc
)
955 : base (method
, RemovePrefix
, attrs
, loc
)
960 static readonly string[] attribute_targets
= new string [] { "event" }
;
962 public EventProperty (TypeDefinition parent
, FullNamedExpression type
, Modifiers mod_flags
, MemberName name
, Attributes attrs
)
963 : base (parent
, type
, mod_flags
, name
, attrs
)
967 public override void Accept (StructuralVisitor visitor
)
969 visitor
.Visit (this);
972 public override bool Define()
981 public override string[] ValidAttributeTargets
{
983 return attribute_targets
;
989 /// Event is declared like field.
991 public class EventField
: Event
993 abstract class EventFieldAccessor
: AEventAccessor
995 protected EventFieldAccessor (EventField method
, string prefix
)
996 : base (method
, prefix
, null, method
.Location
)
1000 protected abstract MethodSpec
GetOperation (Location loc
);
1002 public override void Emit (TypeDefinition parent
)
1004 if ((method
.ModFlags
& (Modifiers
.ABSTRACT
| Modifiers
.EXTERN
)) == 0 && !Compiler
.Settings
.WriteMetadataOnly
) {
1005 block
= new ToplevelBlock (Compiler
, ParameterInfo
, Location
) {
1006 IsCompilerGenerated
= true
1008 FabricateBodyStatement ();
1014 void FabricateBodyStatement ()
1017 // Delegate obj1 = backing_field
1019 // Delegate obj2 = obj1;
1020 // obj1 = Interlocked.CompareExchange (ref backing_field, Delegate.Combine|Remove(obj2, value), obj1);
1021 // } while ((object)obj1 != (object)obj2)
1024 var field_info
= ((EventField
) method
).backing_field
;
1025 FieldExpr f_expr
= new FieldExpr (field_info
, Location
);
1027 f_expr
.InstanceExpression
= new CompilerGeneratedThis (Parent
.CurrentType
, Location
);
1029 var obj1
= LocalVariable
.CreateCompilerGenerated (field_info
.MemberType
, block
, Location
);
1030 var obj2
= LocalVariable
.CreateCompilerGenerated (field_info
.MemberType
, block
, Location
);
1032 block
.AddStatement (new StatementExpression (new SimpleAssign (new LocalVariableReference (obj1
, Location
), f_expr
)));
1034 var cond
= new BooleanExpression (new Binary (Binary
.Operator
.Inequality
,
1035 new Cast (new TypeExpression (Module
.Compiler
.BuiltinTypes
.Object
, Location
), new LocalVariableReference (obj1
, Location
), Location
),
1036 new Cast (new TypeExpression (Module
.Compiler
.BuiltinTypes
.Object
, Location
), new LocalVariableReference (obj2
, Location
), Location
)));
1038 var body
= new ExplicitBlock (block
, Location
, Location
);
1039 block
.AddStatement (new Do (body
, cond
, Location
, Location
));
1041 body
.AddStatement (new StatementExpression (
1042 new SimpleAssign (new LocalVariableReference (obj2
, Location
), new LocalVariableReference (obj1
, Location
))));
1044 var args_oper
= new Arguments (2);
1045 args_oper
.Add (new Argument (new LocalVariableReference (obj2
, Location
)));
1046 args_oper
.Add (new Argument (block
.GetParameterReference (0, Location
)));
1048 var op_method
= GetOperation (Location
);
1050 var args
= new Arguments (3);
1051 args
.Add (new Argument (f_expr
, Argument
.AType
.Ref
));
1052 args
.Add (new Argument (new Cast (
1053 new TypeExpression (field_info
.MemberType
, Location
),
1054 new Invocation (MethodGroupExpr
.CreatePredefined (op_method
, op_method
.DeclaringType
, Location
), args_oper
),
1056 args
.Add (new Argument (new LocalVariableReference (obj1
, Location
)));
1058 var cas
= Module
.PredefinedMembers
.InterlockedCompareExchange_T
.Get ();
1060 if (Module
.PredefinedMembers
.MonitorEnter_v4
.Get () != null || Module
.PredefinedMembers
.MonitorEnter
.Get () != null) {
1061 // Workaround for cripled (e.g. microframework) mscorlib without CompareExchange
1062 body
.AddStatement (new Lock (
1063 block
.GetParameterReference (0, Location
),
1064 new StatementExpression (new SimpleAssign (
1065 f_expr
, args
[1].Expr
, Location
), Location
), Location
));
1067 Module
.PredefinedMembers
.InterlockedCompareExchange_T
.Resolve (Location
);
1070 body
.AddStatement (new StatementExpression (new SimpleAssign (
1071 new LocalVariableReference (obj1
, Location
),
1072 new Invocation (MethodGroupExpr
.CreatePredefined (cas
, cas
.DeclaringType
, Location
), args
))));
1077 sealed class AddDelegateMethod
: EventFieldAccessor
1079 public AddDelegateMethod (EventField method
):
1080 base (method
, AddPrefix
)
1084 protected override MethodSpec
GetOperation (Location loc
)
1086 return Module
.PredefinedMembers
.DelegateCombine
.Resolve (loc
);
1090 sealed class RemoveDelegateMethod
: EventFieldAccessor
1092 public RemoveDelegateMethod (EventField method
):
1093 base (method
, RemovePrefix
)
1097 protected override MethodSpec
GetOperation (Location loc
)
1099 return Module
.PredefinedMembers
.DelegateRemove
.Resolve (loc
);
1104 static readonly string[] attribute_targets
= new string [] { "event", "field", "method" }
;
1105 static readonly string[] attribute_targets_interface
= new string[] { "event", "method" }
;
1107 Expression initializer
;
1108 Field backing_field
;
1109 List
<FieldDeclarator
> declarators
;
1111 public EventField (TypeDefinition parent
, FullNamedExpression type
, Modifiers mod_flags
, MemberName name
, Attributes attrs
)
1112 : base (parent
, type
, mod_flags
, name
, attrs
)
1114 Add
= new AddDelegateMethod (this);
1115 Remove
= new RemoveDelegateMethod (this);
1120 public List
<FieldDeclarator
> Declarators
{
1122 return this.declarators
;
1126 bool HasBackingField
{
1128 return !IsInterface
&& (ModFlags
& Modifiers
.ABSTRACT
) == 0;
1132 public Expression Initializer
{
1137 initializer
= value;
1141 public override string[] ValidAttributeTargets
{
1143 return HasBackingField
? attribute_targets
: attribute_targets_interface
;
1150 public override void Accept (StructuralVisitor visitor
)
1152 visitor
.Visit (this);
1155 public void AddDeclarator (FieldDeclarator declarator
)
1157 if (declarators
== null)
1158 declarators
= new List
<FieldDeclarator
> (2);
1160 declarators
.Add (declarator
);
1162 Parent
.AddNameToContainer (this, declarator
.Name
.Value
);
1165 public override void ApplyAttributeBuilder (Attribute a
, MethodSpec ctor
, byte[] cdata
, PredefinedAttributes pa
)
1167 if (a
.Target
== AttributeTargets
.Field
) {
1168 backing_field
.ApplyAttributeBuilder (a
, ctor
, cdata
, pa
);
1172 if (a
.Target
== AttributeTargets
.Method
) {
1173 int errors
= Report
.Errors
;
1174 Add
.ApplyAttributeBuilder (a
, ctor
, cdata
, pa
);
1175 if (errors
== Report
.Errors
)
1176 Remove
.ApplyAttributeBuilder (a
, ctor
, cdata
, pa
);
1180 base.ApplyAttributeBuilder (a
, ctor
, cdata
, pa
);
1183 public override bool Define()
1185 var mod_flags_src
= ModFlags
;
1187 if (!base.Define ())
1190 if (declarators
!= null) {
1191 if ((mod_flags_src
& Modifiers
.DEFAULT_ACCESS_MODIFIER
) != 0)
1192 mod_flags_src
&= ~
(Modifiers
.AccessibilityMask
| Modifiers
.DEFAULT_ACCESS_MODIFIER
);
1194 var t
= new TypeExpression (MemberType
, TypeExpression
.Location
);
1195 foreach (var d
in declarators
) {
1196 var ef
= new EventField (Parent
, t
, mod_flags_src
, new MemberName (d
.Name
.Value
, d
.Name
.Location
), OptAttributes
);
1198 if (d
.Initializer
!= null)
1199 ef
.initializer
= d
.Initializer
;
1202 Parent
.PartialContainer
.Members
.Add (ef
);
1206 if (!HasBackingField
) {
1211 backing_field
= new Field (Parent
,
1212 new TypeExpression (MemberType
, Location
),
1213 Modifiers
.BACKING_FIELD
| Modifiers
.COMPILER_GENERATED
| Modifiers
.PRIVATE
| (ModFlags
& (Modifiers
.STATIC
| Modifiers
.UNSAFE
)),
1216 Parent
.PartialContainer
.Members
.Add (backing_field
);
1217 backing_field
.Initializer
= Initializer
;
1218 backing_field
.ModFlags
&= ~Modifiers
.COMPILER_GENERATED
;
1220 // Call define because we passed fields definition
1221 backing_field
.Define ();
1223 // Set backing field for event fields
1224 spec
.BackingField
= backing_field
.Spec
;
1230 public abstract class Event
: PropertyBasedMember
1232 public abstract class AEventAccessor
: AbstractPropertyEventMethod
1234 protected readonly Event method
;
1235 readonly ParametersCompiled parameters
;
1237 static readonly string[] attribute_targets
= new string [] { "method", "param", "return" }
;
1239 public const string AddPrefix
= "add_";
1240 public const string RemovePrefix
= "remove_";
1242 protected AEventAccessor (Event method
, string prefix
, Attributes attrs
, Location loc
)
1243 : base (method
, prefix
, attrs
, loc
)
1245 this.method
= method
;
1246 this.ModFlags
= method
.ModFlags
;
1247 this.parameters
= ParametersCompiled
.CreateImplicitParameter (method
.TypeExpression
, loc
);
1250 public bool IsInterfaceImplementation
{
1251 get { return method_data.implementing != null; }
1254 public override void ApplyAttributeBuilder (Attribute a
, MethodSpec ctor
, byte[] cdata
, PredefinedAttributes pa
)
1256 if (a
.Type
== pa
.MethodImpl
) {
1257 method
.is_external_implementation
= a
.IsInternalCall ();
1260 base.ApplyAttributeBuilder (a
, ctor
, cdata
, pa
);
1263 protected override void ApplyToExtraTarget (Attribute a
, MethodSpec ctor
, byte[] cdata
, PredefinedAttributes pa
)
1265 if (a
.Target
== AttributeTargets
.Parameter
) {
1266 parameters
[0].ApplyAttributeBuilder (a
, ctor
, cdata
, pa
);
1270 base.ApplyToExtraTarget (a
, ctor
, cdata
, pa
);
1273 public override AttributeTargets AttributeTargets
{
1275 return AttributeTargets
.Method
;
1279 public override bool IsClsComplianceRequired ()
1281 return method
.IsClsComplianceRequired ();
1284 public virtual void Define (TypeContainer parent
)
1286 // Fill in already resolved event type to speed things up and
1287 // avoid confusing duplicate errors
1288 ((Parameter
) parameters
.FixedParameters
[0]).Type
= method
.member_type
;
1289 parameters
.Types
= new TypeSpec
[] { method.member_type }
;
1291 method_data
= new MethodData (method
, method
.ModFlags
,
1292 method
.flags
| MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
, this);
1294 if (!method_data
.Define (parent
.PartialContainer
, method
.GetFullName (MemberName
)))
1297 if (Compiler
.Settings
.WriteMetadataOnly
)
1300 Spec
= new MethodSpec (MemberKind
.Method
, parent
.PartialContainer
.Definition
, this, ReturnType
, ParameterInfo
, method
.ModFlags
);
1301 Spec
.IsAccessor
= true;
1304 public override TypeSpec ReturnType
{
1306 return Parent
.Compiler
.BuiltinTypes
.Void
;
1310 public override ObsoleteAttribute
GetAttributeObsolete ()
1312 return method
.GetAttributeObsolete ();
1315 public MethodData MethodData
{
1321 public override string[] ValidAttributeTargets
{
1323 return attribute_targets
;
1327 public override ParametersCompiled ParameterInfo
{
1334 AEventAccessor
add, remove;
1335 EventBuilder EventBuilder
;
1336 protected EventSpec spec
;
1338 protected Event (TypeDefinition parent
, FullNamedExpression type
, Modifiers mod_flags
, MemberName name
, Attributes attrs
)
1339 : base (parent
, type
, mod_flags
,
1340 parent
.PartialContainer
.Kind
== MemberKind
.Interface
? AllowedModifiersInterface
:
1341 parent
.PartialContainer
.Kind
== MemberKind
.Struct
? AllowedModifiersStruct
:
1342 AllowedModifiersClass
,
1349 public override AttributeTargets AttributeTargets
{
1351 return AttributeTargets
.Event
;
1355 public AEventAccessor Add
{
1361 Parent
.AddNameToContainer (value, value.MemberName
.Basename
);
1365 public override Variance ExpectedMemberTypeVariance
{
1367 return Variance
.Contravariant
;
1371 public AEventAccessor Remove
{
1377 Parent
.AddNameToContainer (value, value.MemberName
.Basename
);
1382 public override void ApplyAttributeBuilder (Attribute a
, MethodSpec ctor
, byte[] cdata
, PredefinedAttributes pa
)
1384 if ((a
.HasSecurityAttribute
)) {
1385 a
.Error_InvalidSecurityParent ();
1389 EventBuilder
.SetCustomAttribute ((ConstructorInfo
) ctor
.GetMetaInfo (), cdata
);
1392 protected override bool CheckOverrideAgainstBase (MemberSpec base_member
)
1394 var ok
= base.CheckOverrideAgainstBase (base_member
);
1396 if (!CheckAccessModifiers (this, base_member
)) {
1397 Error_CannotChangeAccessModifiers (this, base_member
);
1404 public override bool Define ()
1406 if (!base.Define ())
1409 if (!MemberType
.IsDelegate
) {
1410 Report
.Error (66, Location
, "`{0}': event must be of a delegate type", GetSignatureForError ());
1417 // Now define the accessors
1419 add.Define (Parent
);
1420 remove.Define (Parent
);
1422 EventBuilder
= Parent
.TypeBuilder
.DefineEvent (GetFullName (MemberName
), EventAttributes
.None
, MemberType
.GetMetaInfo ());
1424 spec
= new EventSpec (Parent
.Definition
, this, MemberType
, ModFlags
, Add
.Spec
, remove.Spec
);
1426 Parent
.MemberCache
.AddMember (this, GetFullName (MemberName
), spec
);
1427 Parent
.MemberCache
.AddMember (this, Add
.Spec
.Name
, Add
.Spec
);
1428 Parent
.MemberCache
.AddMember (this, Remove
.Spec
.Name
, remove.Spec
);
1433 public override void Emit ()
1435 CheckReservedNameConflict (null, add.Spec
);
1436 CheckReservedNameConflict (null, remove.Spec
);
1438 if (OptAttributes
!= null) {
1439 OptAttributes
.Emit ();
1442 ConstraintChecker
.Check (this, member_type
, type_expr
.Location
);
1445 Remove
.Emit (Parent
);
1450 public override void PrepareEmit ()
1452 base.PrepareEmit ();
1455 remove.PrepareEmit ();
1457 EventBuilder
.SetAddOnMethod (add.MethodData
.MethodBuilder
);
1458 EventBuilder
.SetRemoveOnMethod (remove.MethodData
.MethodBuilder
);
1461 public override void WriteDebugSymbol (MonoSymbolFile file
)
1463 add.WriteDebugSymbol (file
);
1464 remove.WriteDebugSymbol (file
);
1468 // Represents header string for documentation comment.
1470 public override string DocCommentHeader
{
1471 get { return "E:"; }
1475 public class EventSpec
: MemberSpec
, IInterfaceMemberSpec
1477 MethodSpec
add, remove;
1478 FieldSpec backing_field
;
1480 public EventSpec (TypeSpec declaringType
, IMemberDefinition definition
, TypeSpec eventType
, Modifiers modifiers
, MethodSpec
add, MethodSpec
remove)
1481 : base (MemberKind
.Event
, declaringType
, definition
, modifiers
)
1483 this.AccessorAdd
= add;
1484 this.AccessorRemove
= remove;
1485 this.MemberType
= eventType
;
1490 public MethodSpec AccessorAdd
{
1499 public MethodSpec AccessorRemove
{
1508 public FieldSpec BackingField
{
1510 return backing_field
;
1513 backing_field
= value;
1517 public TypeSpec MemberType { get; private set; }
1521 public override MemberSpec
InflateMember (TypeParameterInflator inflator
)
1523 var es
= (EventSpec
) base.InflateMember (inflator
);
1524 es
.MemberType
= inflator
.Inflate (MemberType
);
1526 if (backing_field
!= null)
1527 es
.backing_field
= (FieldSpec
) backing_field
.InflateMember (inflator
);
1532 public override List
<MissingTypeSpecReference
> ResolveMissingDependencies (MemberSpec caller
)
1534 return MemberType
.ResolveMissingDependencies (this);
1538 public class Indexer
: PropertyBase
, IParametersMember
1540 public class GetIndexerMethod
: GetMethod
, IParametersMember
1542 ParametersCompiled parameters
;
1544 public GetIndexerMethod (PropertyBase property
, Modifiers modifiers
, ParametersCompiled parameters
, Attributes attrs
, Location loc
)
1545 : base (property
, modifiers
, attrs
, loc
)
1547 this.parameters
= parameters
;
1550 public override void Define (TypeContainer parent
)
1552 // Disable reporting, parameters are resolved twice
1553 Report
.DisableReporting ();
1555 parameters
.Resolve (this);
1557 Report
.EnableReporting ();
1560 base.Define (parent
);
1563 public override ParametersCompiled ParameterInfo
{
1569 #region IParametersMember Members
1571 AParametersCollection IParametersMember
.Parameters
{
1577 TypeSpec IInterfaceMemberSpec
.MemberType
{
1586 public class SetIndexerMethod
: SetMethod
, IParametersMember
1588 public SetIndexerMethod (PropertyBase property
, Modifiers modifiers
, ParametersCompiled parameters
, Attributes attrs
, Location loc
)
1589 : base (property
, modifiers
, parameters
, attrs
, loc
)
1593 #region IParametersMember Members
1595 AParametersCollection IParametersMember
.Parameters
{
1601 TypeSpec IInterfaceMemberSpec
.MemberType
{
1610 const Modifiers AllowedModifiers
=
1613 Modifiers
.PROTECTED
|
1614 Modifiers
.INTERNAL
|
1618 Modifiers
.OVERRIDE
|
1623 const Modifiers AllowedInterfaceModifiers
=
1626 readonly ParametersCompiled parameters
;
1628 public Indexer (TypeDefinition parent
, FullNamedExpression type
, MemberName name
, Modifiers mod
, ParametersCompiled parameters
, Attributes attrs
)
1629 : base (parent
, type
, mod
,
1630 parent
.PartialContainer
.Kind
== MemberKind
.Interface
? AllowedInterfaceModifiers
: AllowedModifiers
,
1633 this.parameters
= parameters
;
1638 AParametersCollection IParametersMember
.Parameters
{
1644 public ParametersCompiled ParameterInfo
{
1653 public override void Accept (StructuralVisitor visitor
)
1655 visitor
.Visit (this);
1658 public override void ApplyAttributeBuilder (Attribute a
, MethodSpec ctor
, byte[] cdata
, PredefinedAttributes pa
)
1660 if (a
.Type
== pa
.IndexerName
) {
1661 // Attribute was copied to container
1665 base.ApplyAttributeBuilder (a
, ctor
, cdata
, pa
);
1668 protected override bool CheckForDuplications ()
1670 return Parent
.MemberCache
.CheckExistingMembersOverloads (this, parameters
);
1673 public override bool Define ()
1675 if (!base.Define ())
1678 if (!DefineParameters (parameters
))
1681 if (OptAttributes
!= null) {
1682 Attribute indexer_attr
= OptAttributes
.Search (Module
.PredefinedAttributes
.IndexerName
);
1683 if (indexer_attr
!= null) {
1684 var compiling
= indexer_attr
.Type
.MemberDefinition
as TypeContainer
;
1685 if (compiling
!= null)
1686 compiling
.Define ();
1688 if (IsExplicitImpl
) {
1689 Report
.Error (415, indexer_attr
.Location
,
1690 "The `{0}' attribute is valid only on an indexer that is not an explicit interface member declaration",
1691 indexer_attr
.Type
.GetSignatureForError ());
1692 } else if ((ModFlags
& Modifiers
.OVERRIDE
) != 0) {
1693 Report
.Error (609, indexer_attr
.Location
,
1694 "Cannot set the `IndexerName' attribute on an indexer marked override");
1696 string name
= indexer_attr
.GetIndexerAttributeValue ();
1698 if (!string.IsNullOrEmpty (name
)) {
1699 SetMemberName (new MemberName (MemberName
.Left
, name
, Location
));
1705 if (InterfaceType
!= null) {
1706 string base_IndexerName
= InterfaceType
.MemberDefinition
.GetAttributeDefaultMember ();
1707 if (base_IndexerName
!= ShortName
) {
1708 SetMemberName (new MemberName (MemberName
.Left
, base_IndexerName
, new TypeExpression (InterfaceType
, Location
), Location
));
1712 Parent
.AddNameToContainer (this, MemberName
.Basename
);
1714 flags
|= MethodAttributes
.HideBySig
| MethodAttributes
.SpecialName
;
1716 if (!DefineAccessors ())
1722 DefineBuilders (MemberKind
.Indexer
, parameters
);
1726 public override bool EnableOverloadChecks (MemberCore overload
)
1728 if (overload
is Indexer
) {
1729 caching_flags
|= Flags
.MethodOverloadsExist
;
1733 return base.EnableOverloadChecks (overload
);
1736 public override void Emit ()
1738 parameters
.CheckConstraints (this);
1743 public override string GetSignatureForError ()
1745 StringBuilder sb
= new StringBuilder (Parent
.GetSignatureForError ());
1746 if (MemberName
.ExplicitInterface
!= null) {
1748 sb
.Append (MemberName
.ExplicitInterface
.GetSignatureForError ());
1751 sb
.Append (".this");
1752 sb
.Append (parameters
.GetSignatureForError ("[", "]", parameters
.Count
));
1753 return sb
.ToString ();
1756 public override string GetSignatureForDocumentation ()
1758 return base.GetSignatureForDocumentation () + parameters
.GetSignatureForDocumentation ();
1761 public override void PrepareEmit ()
1763 base.PrepareEmit ();
1764 parameters
.ResolveDefaultValues (this);
1767 protected override bool VerifyClsCompliance ()
1769 if (!base.VerifyClsCompliance ())
1772 parameters
.VerifyClsCompliance (this);
1777 public class IndexerSpec
: PropertySpec
, IParametersMember
1779 AParametersCollection parameters
;
1781 public IndexerSpec (TypeSpec declaringType
, IMemberDefinition definition
, TypeSpec memberType
, AParametersCollection parameters
, PropertyInfo info
, Modifiers modifiers
)
1782 : base (MemberKind
.Indexer
, declaringType
, definition
, memberType
, info
, modifiers
)
1784 this.parameters
= parameters
;
1788 public AParametersCollection Parameters
{
1795 public override string GetSignatureForDocumentation ()
1797 return base.GetSignatureForDocumentation () + parameters
.GetSignatureForDocumentation ();
1800 public override string GetSignatureForError ()
1802 return DeclaringType
.GetSignatureForError () + ".this" + parameters
.GetSignatureForError ("[", "]", parameters
.Count
);
1805 public override MemberSpec
InflateMember (TypeParameterInflator inflator
)
1807 var spec
= (IndexerSpec
) base.InflateMember (inflator
);
1808 spec
.parameters
= parameters
.Inflate (inflator
);
1812 public override List
<MissingTypeSpecReference
> ResolveMissingDependencies (MemberSpec caller
)
1814 var missing
= base.ResolveMissingDependencies (caller
);
1816 foreach (var pt
in parameters
.Types
) {
1817 var m
= pt
.GetMissingDependencies (caller
);
1821 if (missing
== null)
1822 missing
= new List
<MissingTypeSpecReference
> ();
1824 missing
.AddRange (m
);