+ public override void Emit ()
+ {
+ if (OptAttributes != null) {
+ EmitContext ec = new EmitContext (
+ Parent, Location, null, FieldBuilder.FieldType,
+ ModFlags);
+ OptAttributes.Emit (ec, this);
+ }
+
+ base.Emit ();
+ }
+ }
+
+ //
+ // `set' and `get' accessors are represented with an Accessor.
+ //
+ public class Accessor {
+ //
+ // Null if the accessor is empty, or a Block if not
+ //
+ public Block Block;
+ public Attributes Attributes;
+ public Location Location;
+
+ public Accessor (Block b, Attributes attrs, Location loc)
+ {
+ Block = b;
+ Attributes = attrs;
+ Location = loc;
+ }
+ }
+
+
+ // Ooouh Martin, templates are missing here.
+ // When it will be possible move here a lot of child code and template method type.
+ public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData {
+ protected MethodData method_data;
+ protected Block block;
+
+ // The accessor are created event if they are not wanted.
+ // But we need them because their names are reserved.
+ // Field says whether accessor will be emited or not
+ public readonly bool IsDummy;
+
+ protected readonly string prefix;
+
+ ReturnParameter return_attributes;
+
+ public AbstractPropertyEventMethod (MemberBase member, string prefix)
+ : base (null, SetupName (prefix, member), null, member.Location)
+ {
+ this.prefix = prefix;
+ IsDummy = true;
+ }
+
+ public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
+ string prefix)
+ : base (null, SetupName (prefix, member),
+ accessor.Attributes, accessor.Location)
+ {
+ this.prefix = prefix;
+ this.block = accessor.Block;
+ }
+
+ static MemberName SetupName (string prefix, MemberBase member)
+ {
+ MemberName name = member.MemberName.Clone ();
+ name.Name = prefix + member.ShortName;
+ return name;
+ }
+
+ public void UpdateName (MemberBase member)
+ {
+ MemberName.Name = prefix + member.ShortName;
+ }
+
+ #region IMethodData Members
+
+ public Block Block {
+ get {
+ return block;
+ }
+
+ set {
+ block = value;
+ }
+ }
+
+ public CallingConventions CallingConventions {
+ get {
+ return CallingConventions.Standard;
+ }
+ }
+
+ public bool IsExcluded (EmitContext ec)
+ {
+ return false;
+ }
+
+ GenericMethod IMethodData.GenericMethod {
+ get {
+ return null;
+ }
+ }
+
+ public MemberName MethodName {
+ get {
+ return MemberName;
+ }
+ }
+
+ public abstract ObsoleteAttribute GetObsoleteAttribute ();
+ public abstract Type[] ParameterTypes { get; }
+ public abstract Type ReturnType { get; }
+ public abstract EmitContext CreateEmitContext(TypeContainer tc, ILGenerator ig);
+
+ #endregion
+
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
+ a.Type == TypeManager.conditional_attribute_type) {
+ Report.Error (1667, a.Location, "'{0}' is not valid on property or event accessors. It is valid on '{1}' declarations only", TypeManager.CSharpName (a.Type), a.GetValidTargets ());
+ return;
+ }
+
+ if (a.Target == AttributeTargets.Method) {
+ method_data.MethodBuilder.SetCustomAttribute (cb);
+ return;
+ }
+
+ if (a.Target == AttributeTargets.ReturnValue) {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
+
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ ApplyToExtraTarget (a, cb);
+ }
+
+ virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
+ {
+ System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
+ }
+
+ public override bool Define()
+ {
+ return false;
+ }
+
+ public virtual void Emit (TypeContainer container)
+ {
+ method_data.Emit (container, this);
+ block = null;
+ }
+
+ public override bool IsClsCompliaceRequired(DeclSpace ds)
+ {
+ return false;
+ }
+
+ public bool IsDuplicateImplementation (MethodCore method)
+ {
+ if (Name != method.Name)
+ return false;
+
+ Type[] param_types = method.ParameterTypes;
+
+ if (param_types.Length != ParameterTypes.Length)
+ return false;
+
+ for (int i = 0; i < param_types.Length; i++)
+ if (param_types [i] != ParameterTypes [i])
+ return false;
+
+ Report.SymbolRelatedToPreviousError (method);
+ Report.Error (111, Location, "Type '{0}' already defines a member called '{1}' with " +
+ "the same parameter types", Parent.Name, Name);
+ return true;
+ }
+
+ public new Location Location {
+ get {
+ return base.Location;
+ }
+ }
+
+ protected override void VerifyObsoleteAttribute()
+ {
+ }
+
+ }
+
+ //
+ // Properties and Indexers both generate PropertyBuilders, we use this to share
+ // their common bits.
+ //
+ abstract public class PropertyBase : MethodCore {
+
+ public class GetMethod: PropertyMethod
+ {
+ static string[] attribute_targets = new string [] { "method", "return" };
+
+ public GetMethod (MethodCore method):
+ base (method, "get_")
+ {
+ }
+
+ public GetMethod (MethodCore method, Accessor accessor):
+ base (method, accessor, "get_")
+ {
+ }
+
+ public override MethodBuilder Define(TypeContainer container)
+ {
+ method_data = new MethodData (method, method.ParameterInfo, method.ModFlags, method.flags, this);
+
+ if (!method_data.Define (container))
+ return null;
+
+ return method_data.MethodBuilder;
+ }
+
+ public override string GetSignatureForError (TypeContainer tc)
+ {
+ return String.Concat (base.GetSignatureForError (tc), ".get");
+ }
+
+ public override Type ReturnType {
+ get {
+ return method.MemberType;
+ }
+ }
+
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+ public class SetMethod: PropertyMethod {
+
+ static string[] attribute_targets = new string [] { "method", "param", "return" };
+ ImplicitParameter param_attr;
+
+ public SetMethod (MethodCore method):
+ base (method, "set_")
+ {
+ }
+
+ public SetMethod (MethodCore method, Accessor accessor):
+ base (method, accessor, "set_")
+ {
+ }
+
+ protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == AttributeTargets.Parameter) {
+ if (param_attr == null)
+ param_attr = new ImplicitParameter (method_data.MethodBuilder);
+
+ param_attr.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ protected virtual InternalParameters GetParameterInfo (TypeContainer container)
+ {
+ Parameter [] parms = new Parameter [1];
+ parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null);
+ return new InternalParameters (
+ container, new Parameters (parms, null, method.Location));
+ }
+
+ public override MethodBuilder Define(TypeContainer container)
+ {
+ method_data = new MethodData (method, GetParameterInfo (container), method.ModFlags, method.flags, this);
+
+ if (!method_data.Define (container))
+ return null;
+
+ return method_data.MethodBuilder;
+ }
+
+ public override string GetSignatureForError (TypeContainer tc)
+ {
+ return String.Concat (base.GetSignatureForError (tc), ".set");
+ }
+
+ public override Type[] ParameterTypes {
+ get {
+ return new Type[] { method.MemberType };
+ }
+ }
+
+ public override Type ReturnType {
+ get {
+ return TypeManager.void_type;
+ }
+ }
+
+ public override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+ static string[] attribute_targets = new string [] { "property" };
+
+ public abstract class PropertyMethod: AbstractPropertyEventMethod {
+ protected readonly MethodCore method;
+
+ public PropertyMethod (MethodCore method, string prefix)
+ : base (method, prefix)
+ {
+ this.method = method;
+ }
+
+ public PropertyMethod (MethodCore method, Accessor accessor, string prefix)
+ : base (method, accessor, prefix)
+ {
+ this.method = method;
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Method;
+ }
+ }
+
+ public override bool IsClsCompliaceRequired(DeclSpace ds)
+ {
+ return method.IsClsCompliaceRequired (ds);
+ }
+
+ public InternalParameters ParameterInfo
+ {
+ get {
+ return method_data.ParameterInfo;
+ }
+ }
+
+ public abstract MethodBuilder Define (TypeContainer container);
+
+ public override Type[] ParameterTypes {
+ get {
+ return TypeManager.NoTypes;
+ }
+ }
+
+ public override EmitContext CreateEmitContext (TypeContainer tc,
+ ILGenerator ig)
+ {
+ return new EmitContext (
+ tc, method.ds, method.Location, ig, ReturnType,
+ method.ModFlags, false);
+ }