using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
namespace Mono.CSharp {
bool members_defined;
bool members_defined_ok;
- // Information in the case we are an attribute type
-
- public AttributeTargets Targets = AttributeTargets.All;
- public bool AllowMultiple = false;
- public bool Inherited;
-
// The interfaces we implement.
TypeExpr [] ifaces;
Type[] base_inteface_types;
return AdditionResult.Success;
}
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Type == TypeManager.default_member_type) {
+ if (Indexers != null) {
+ Report.Error (646, a.Location,
+ "Cannot specify the DefaultMember attribute on" +
+ " a type containing an indexer");
+ return;
+ }
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ throw new NotSupportedException ();
+ }
+ }
+
public void RegisterOrder (Interface iface)
{
if (interface_order == null)
if ((parent != null) && parent.IsAttribute) {
RootContext.RegisterAttribute (this);
- TypeManager.RegisterAttrType (TypeBuilder, this);
} else
RootContext.RegisterOrder (this);
// Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
bool seen_normal_indexers = false;
foreach (Indexer i in Indexers) {
- if (i.MemberName.TypeName != null)
- seen_normal_indexers = true;
- else if (seen_normal_indexers)
- throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
- }
- foreach (Indexer i in Indexers){
string name;
i.Define (this);
name = i.IndexerName;
- if (i.InterfaceType != null)
+ if (i.InterfaceType != null) {
+ if (seen_normal_indexers)
+ throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
continue;
+ }
- if (class_indexer_name == null){
+ seen_normal_indexers = true;
+
+ if (class_indexer_name == null)
class_indexer_name = name;
- continue;
- }
-
- if (name == class_indexer_name)
- continue;
-
- Report.Error (
- 668, "Two indexers have different names, " +
- " you should use the same name for all your indexers");
+ else if (name != class_indexer_name)
+ Report.Error (668, "Two indexers have different names, " +
+ " you should use the same name for all your indexers");
}
if (seen_normal_indexers && class_indexer_name == null)
return;
}
+ protected virtual void VerifyMembers (EmitContext ec)
+ {
+ //
+ // Check for internal or private fields that were never assigned
+ //
+ if (RootContext.WarningLevel >= 3) {
+ if (fields != null){
+ foreach (Field f in fields) {
+ if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
+ continue;
+
+ if ((f.status & Field.Status.USED) == 0){
+ Report.Warning (
+ 169, f.Location, "Private field " +
+ MakeName (f.Name) + " is never used");
+ continue;
+ }
+
+ //
+ // Only report 649 on level 4
+ //
+ if (RootContext.WarningLevel < 4)
+ continue;
+
+ if ((f.status & Field.Status.ASSIGNED) != 0)
+ continue;
+
+ Report.Warning (
+ 649, f.Location,
+ "Field " + MakeName (f.Name) + " is never assigned " +
+ " to and will always have its default value");
+ }
+ }
+
+ if (events != null){
+ foreach (Event e in events){
+ if (e.status == 0)
+ Report.Warning (67, "The event " + MakeName (e.Name) + " is never used");
+ }
+ }
+ }
+ }
+
/// <summary>
/// Emits the code, this step is performed after all
/// the types, enumerations, constructors
/// </summary>
public void Emit ()
{
- Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes);
+ if (OptAttributes != null)
+ OptAttributes.Emit (ec, this);
Emit (this);
if (Pending != null)
if (Pending.VerifyPendingMethods ())
return;
-
- //
- // Check for internal or private fields that were never assigned
- //
- if (RootContext.WarningLevel >= 3) {
- if (fields != null){
- foreach (Field f in fields) {
- if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
- continue;
-
- if ((f.status & Field.Status.USED) == 0){
- Report.Warning (
- 169, f.Location, "Private field " +
- MakeName (f.Name) + " is never used");
- continue;
- }
-
- //
- // Only report 649 on level 4
- //
- if (RootContext.WarningLevel < 4)
- continue;
-
- if ((f.status & Field.Status.ASSIGNED) != 0)
- continue;
-
- Report.Warning (
- 649, f.Location,
- "Field " + MakeName (f.Name) + " is never assigned " +
- " to and will always have its default value");
- }
- }
- if (events != null){
- foreach (Event e in events){
- if (e.status == 0)
- Report.Warning (67, "The event " + MakeName (e.Name) + " is never used");
- }
- }
- }
+ VerifyMembers (ec);
// if (types != null)
// foreach (TypeContainer tc in types)
}
- public class Class : TypeContainer {
+ public class ClassOrStruct : TypeContainer {
+ bool hasExplicitLayout = false;
+ public ClassOrStruct (NamespaceEntry ns, TypeContainer parent, MemberName name,
+ Attributes attrs, Location l)
+ : base (ns, parent, name, attrs, l)
+ {
+ }
+
+ protected override void VerifyMembers (EmitContext ec)
+ {
+ if (Fields != null) {
+ foreach (Field f in Fields) {
+ if ((f.ModFlags & Modifiers.STATIC) != 0)
+ continue;
+ if (hasExplicitLayout) {
+ if (f.OptAttributes == null
+ || !f.OptAttributes.Contains (TypeManager.field_offset_attribute_type, ec)) {
+ Report.Error (625, f.Location,
+ "Instance field of type marked with"
+ + " StructLayout(LayoutKind.Explicit) must have a"
+ + " FieldOffset attribute.");
+ }
+ }
+ else {
+ if (f.OptAttributes != null
+ && f.OptAttributes.Contains (TypeManager.field_offset_attribute_type, ec)) {
+ Report.Error (636, f.Location,
+ "The FieldOffset attribute can only be placed on members of "
+ + "types marked with the StructLayout(LayoutKind.Explicit)");
+ }
+ }
+ }
+ }
+ base.VerifyMembers (ec);
+ }
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Type == TypeManager.struct_layout_attribute_type
+ && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit)
+ hasExplicitLayout = true;
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+ }
+
+ public class Class : ClassOrStruct {
// <summary>
// Modifiers allowed in a class declaration
// </summary>
Modifiers.SEALED |
Modifiers.UNSAFE;
+ // Information in the case we are an attribute type
+ AttributeUsageAttribute attribute_usage;
+
public Class (NamespaceEntry ns, TypeContainer parent, MemberName name,
int mod, Attributes attrs, Location l)
: base (ns, parent, name, attrs, l)
accmods = Modifiers.PRIVATE;
this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
+ attribute_usage = new AttributeUsageAttribute (AttributeTargets.All);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Class;
+ }
+ }
+
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.UsageAttribute != null)
+ attribute_usage = a.UsageAttribute;
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ public AttributeUsageAttribute AttributeUsage {
+ get {
+ return attribute_usage;
+ }
}
//
}
}
- public class Struct : TypeContainer {
+ public class Struct : ClassOrStruct {
// <summary>
// Modifiers allowed in a struct declaration
// </summary>
this.ModFlags |= Modifiers.SEALED;
}
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Struct;
+ }
+ }
+
+
//
// FIXME: Allow the user to specify a different set of attributes
// in some cases (Sealed for example is mandatory for a class,
this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
}
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Interface;
+ }
+ }
+
public override TypeAttributes TypeAttr {
get {
return base.TypeAttr |
// Whether this is an operator method.
public bool IsOperator;
+ static string[] attribute_targets = new string [] { "method", "return" };
+
public MethodCore (DeclSpace ds, Expression type, int mod, int allowed_mod,
bool is_interface, MemberName name, Attributes attrs,
Parameters parameters, Location loc)
return true;
}
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+
protected override bool VerifyClsCompliance (DeclSpace ds)
{
if (!base.VerifyClsCompliance (ds)) {
return cc;
}
-
- //
- // The method's attributes are passed in because we need to extract
- // the "return:" attribute from there to apply on the return type
- //
- static public void LabelParameters (EmitContext ec,
- MethodBase builder,
- Parameters parameters,
- Attributes method_attrs,
- Location loc)
- {
- //
- // Define each type attribute (in/out/ref) and
- // the argument names.
- //
- Parameter [] p = parameters.FixedParameters;
- int i = 0;
-
- MethodBuilder mb = null;
- ConstructorBuilder cb = null;
-
- if (builder is MethodBuilder)
- mb = (MethodBuilder) builder;
- else
- cb = (ConstructorBuilder) builder;
-
- if (p != null){
- for (i = 0; i < p.Length; i++) {
- ParameterBuilder pb;
- ParameterAttributes par_attr = p [i].Attributes;
-
- if (mb == null)
- pb = cb.DefineParameter (
- i + 1, par_attr, p [i].Name);
- else
- pb = mb.DefineParameter (
- i + 1, par_attr, p [i].Name);
-
- Attributes attr = p [i].OptAttributes;
- if (attr != null){
- Attribute.ApplyAttributes (ec, pb, pb, attr);
-
- if (par_attr == ParameterAttributes.Out){
- if (attr.Contains (TypeManager.in_attribute_type))
- Report.Error (36, loc,
- "Can not use [In] attribute on out parameter");
- }
- }
- }
- }
-
- if (parameters.ArrayParameter != null){
- ParameterBuilder pb;
- Parameter array_param = parameters.ArrayParameter;
-
- if (mb == null)
- pb = cb.DefineParameter (
- i + 1, array_param.Attributes,
- array_param.Name);
- else
- pb = mb.DefineParameter (
- i + 1, array_param.Attributes,
- array_param.Name);
-
- CustomAttributeBuilder a = new CustomAttributeBuilder (
- TypeManager.cons_param_array_attribute, new object [0]);
-
- pb.SetCustomAttribute (a);
- }
-
- //
- // And now for the return type attribute decoration
- //
- ParameterBuilder ret_pb;
- Attributes ret_attrs = null;
-
- if (mb == null || method_attrs == null)
- return;
-
- foreach (AttributeSection asec in method_attrs.AttributeSections) {
-
- if (asec.Target != "return")
- continue;
-
- if (ret_attrs == null)
- ret_attrs = new Attributes (asec);
- else
- ret_attrs.AddAttributeSection (asec);
- }
-
- if (ret_attrs != null) {
- try {
- ret_pb = mb.DefineParameter (0, ParameterAttributes.None, "");
- Attribute.ApplyAttributes (ec, ret_pb, ret_pb, ret_attrs);
-
- } catch (ArgumentOutOfRangeException) {
- Report.Warning (
- -24, loc,
- ".NET SDK 1.0 does not permit setting custom attributes" +
- " on the return type of a method");
- }
- }
- }
}
public class Method : MethodCore, IIteratorContainer, IMethodData {
public MethodBuilder MethodBuilder;
public MethodData MethodData;
+ ReturnParameter return_attributes;
/// <summary>
/// Modifiers allowed in a class declaration
Modifiers.EXTERN;
const int AllowedInterfaceModifiers =
- Modifiers.NEW;
+ Modifiers.NEW | Modifiers.UNSAFE;
//
// return_type can be "null" for VOID values.
{
}
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Method | AttributeTargets.ReturnValue;
+ }
+ }
+
//
// Returns the `System.Type' for the ReturnType of this
// function. Provides a nice cache. (used between semantic analysis
return false;
}
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == "return") {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (MethodBuilder, Location);
+
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
+ MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
+ }
+
+ if (a.Type == TypeManager.dllimport_type)
+ return;
+
+ MethodBuilder.SetCustomAttribute (cb);
+ }
+
//
// Checks our base implementation if any
//
t = ec.ContainerType;
parent_constructor_group = Expression.MemberLookup (
- ec, t, null, t, ".ctor",
- MemberTypes.Constructor,
+ ec, t, ".ctor", MemberTypes.Constructor,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
loc);
if (parent_constructor_group == null){
- Report.Error (1501, loc,
- "Can not find a constructor for this argument list");
+ parent_constructor_group = Expression.MemberLookup (
+ ec, t, ".ctor", MemberTypes.Constructor,
+ BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+ loc);
+
+ if (parent_constructor_group != null)
+ Report.Error (
+ 112, loc, "`{0}.{1}' is inaccessible due to " +
+ "its protection level", t.FullName, t.Name);
+ else
+ Report.Error (
+ 1501, loc, "Can not find a constructor for " +
+ "this argument list");
return false;
}
}
}
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Constructor;
+ }
+ }
+
+
//
// Returns true if this is a default constructor
//
(Initializer.Arguments == null);
}
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ ConstructorBuilder.SetCustomAttribute (cb);
+ }
+
protected override bool CheckBase (TypeContainer container)
{
base.CheckBase (container);
ec.IsStatic = false;
}
- MethodCore.LabelParameters (ec, ConstructorBuilder,
- Parameters, OptAttributes, Location);
+ Parameters.LabelParameters (ec, ConstructorBuilder, Location);
SymbolWriter sw = CodeGen.SymbolWriter;
bool generate_debugging = false;
if ((ModFlags & Modifiers.STATIC) != 0)
container.EmitFieldInitializers (ec);
- Attribute.ApplyAttributes (ec, ConstructorBuilder, this, OptAttributes);
+ if (OptAttributes != null)
+ OptAttributes.Emit (ec, this);
// If this is a non-static `struct' constructor and doesn't have any
// initializer, it must initialize all of the struct's fields.
protected override bool VerifyClsCompliance (DeclSpace ds)
{
- if (!base.VerifyClsCompliance (ds)) {
+ if (!base.VerifyClsCompliance (ds) || !IsExposedFromAssembly (ds)) {
return false;
}
string obsolete = null;
bool obsolete_error = false;
- public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method)
+ public virtual bool ApplyAttributes (Attributes opt_attrs, bool is_method, DeclSpace ds)
{
- if ((opt_attrs == null) || (opt_attrs.AttributeSections == null))
+ if ((opt_attrs == null) || (opt_attrs.Attrs == null))
return true;
- foreach (AttributeSection asec in opt_attrs.AttributeSections) {
- if (asec.Attributes == null)
- continue;
-
- foreach (Attribute a in asec.Attributes) {
- if (a.Name == "Conditional") {
- if (!ApplyConditionalAttribute (a))
- return false;
- } else if (a.Name == "Obsolete") {
- if (!ApplyObsoleteAttribute (a))
- return false;
- } else if (a.Name.IndexOf ("DllImport") != -1) {
- if (!is_method) {
- a.Type = TypeManager.dllimport_type;
- Attribute.Error_AttributeNotValidForElement (a, method.Location);
- return false;
- }
- if (!ApplyDllImportAttribute (a))
- return false;
+ foreach (Attribute a in opt_attrs.Attrs) {
+ Type attr_type = a.ResolveType (ec, true);
+ if (attr_type == TypeManager.conditional_attribute_type) {
+ if (!ApplyConditionalAttribute (a))
+ return false;
+ } else if (attr_type == TypeManager.obsolete_attribute_type) {
+ if (!ApplyObsoleteAttribute (a))
+ return false;
+ } else if (attr_type == TypeManager.dllimport_type) {
+ if (!is_method) {
+ Attribute.Error_AttributeNotValidForElement (a, method.Location);
+ return false;
}
+ if (!ApplyDllImportAttribute (a))
+ return false;
}
}
string prefix;
if (method.OptAttributes != null)
- if (!ApplyAttributes (method.OptAttributes, is_method))
+ if (!ApplyAttributes (method.OptAttributes, is_method, container))
return false;
if (member.IsExplicitImpl)
//
// Emits the code
//
- public void Emit (TypeContainer container, object kind)
+ public void Emit (TypeContainer container, Attributable kind)
{
EmitContext ec;
Attributes OptAttributes = method.OptAttributes;
if (OptAttributes != null)
- Attribute.ApplyAttributes (ec, builder, kind, OptAttributes);
+ OptAttributes.Emit (ec, kind);
if (member is MethodCore)
- MethodCore.LabelParameters (ec, MethodBuilder,
- ((MethodCore) member).Parameters,
- OptAttributes,
- loc);
+ ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
SymbolWriter sw = CodeGen.SymbolWriter;
Block block = method.Block;
bool error = false;
foreach (Type partype in parameters){
+ if (partype == TypeManager.void_type) {
+ Report.Error (
+ 1547, Location, "Keyword 'void' cannot " +
+ "be used in this context");
+ return false;
+ }
+
if (partype.IsPointer){
if (!UnsafeOK (ds))
error = true;
if (IsInterface) {
ModFlags = Modifiers.PUBLIC |
Modifiers.ABSTRACT |
- Modifiers.VIRTUAL;
+ Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE);
flags = MethodAttributes.Public |
MethodAttributes.Abstract |
return true;
}
- if (IsInterface && HasClsCompliantAttribute (ds) && ds.IsClsCompliaceRequired (ds)) {
+ if (IsInterface && HasClsCompliantAttribute && ds.IsClsCompliaceRequired (ds)) {
Report.Error_T (3010, Location, GetSignatureForError ());
}
return false;
[Flags]
public enum Status : byte { ASSIGNED = 1, USED = 2 }
+ static string[] attribute_targets = new string [] { "field" };
+
//
// The constructor is only exposed to our children
//
this.init = init;
}
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Field;
+ }
+ }
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Type == TypeManager.marshal_as_attr_type) {
+ UnmanagedMarshal marshal = a.GetMarshal ();
+ if (marshal != null) {
+ FieldBuilder.SetMarshal (marshal);
+ return;
+ }
+ Report.Warning_T (-24, a.Location);
+ return;
+ }
+
+
+ FieldBuilder.SetCustomAttribute (cb);
+ }
+
//
// Whether this field has an initializer.
//
return init_expr;
}
+ protected override bool DoDefine (DeclSpace ds, TypeContainer container)
+ {
+ if (!base.DoDefine (ds, container))
+ return false;
+
+ if (MemberType == TypeManager.void_type) {
+ Report.Error (1547, Location,
+ "Keyword 'void' cannot be used in this context");
+ return false;
+ }
+
+ return true;
+ }
+
public override string GetSignatureForError ()
{
return TypeManager.GetFullNameSignature (FieldBuilder);
}
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+
protected override bool VerifyClsCompliance (DeclSpace ds)
{
if (!base.VerifyClsCompliance (ds))
if (!((vt == TypeManager.bool_type) ||
(vt == TypeManager.sbyte_type) ||
(vt == TypeManager.byte_type) ||
- (vt == TypeManager.short_type) ||
+ (vt == TypeManager.short_type) ||
(vt == TypeManager.ushort_type) ||
- (vt == TypeManager.int32_type) ||
+ (vt == TypeManager.int32_type) ||
(vt == TypeManager.uint32_type) ||
- (vt == TypeManager.char_type) ||
- (vt == TypeManager.float_type))){
+ (vt == TypeManager.char_type) ||
+ (vt == TypeManager.float_type) ||
+ (!vt.IsValueType))){
Report.Error (
677, Location, container.MakeName (Name) +
" A volatile field can not be of type `" +
{
if (OptAttributes != null) {
EmitContext ec = new EmitContext (tc, Location, null, FieldBuilder.FieldType, ModFlags);
- Attribute.ApplyAttributes (ec, FieldBuilder, this, OptAttributes);
+ OptAttributes.Emit (ec, this);
}
base.Emit (tc);
// Null if the accessor is empty, or a Block if not
//
public Block Block;
- public Attributes OptAttributes;
+ public Attributes Attributes;
public Accessor (Block b, Attributes attrs)
{
Block = b;
- OptAttributes = attrs;
+ Attributes = attrs;
}
}
public class GetMethod: PropertyMethod
{
+ static string[] attribute_targets = new string [] { "method", "return" };
+
public GetMethod (MethodCore method, Accessor accessor):
base (method, accessor)
{
return method.MemberType;
}
}
+
+ protected 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, Accessor accessor):
base (method, accessor)
{
}
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == "param") {
+ 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];
return TypeManager.void_type;
}
}
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
}
- public abstract class PropertyMethod: IMethodData {
+ static string[] attribute_targets = new string [] { "property" };
+
+ public abstract class PropertyMethod: Attributable, IMethodData {
protected readonly MethodCore method;
- public readonly Accessor Accessor;
protected MethodData method_data;
+ Block block;
- public PropertyMethod (MethodCore method, Accessor accessor)
+ ReturnParameter return_attributes;
+
+ public PropertyMethod (MethodCore method, Accessor accessor):
+ base (accessor.Attributes)
{
this.method = method;
- this.Accessor = accessor;
+ this.block = accessor.Block;
}
- public InternalParameters ParameterInfo {
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Method | AttributeTargets.ReturnValue;
+ }
+ }
+
+ public override bool IsClsCompliaceRequired(DeclSpace ds)
+ {
+ return method.IsClsCompliaceRequired (ds);
+ }
+
+ public InternalParameters ParameterInfo
+ {
get {
return method_data.ParameterInfo;
}
public Block Block {
get {
- return Accessor.Block;
+ return block;
}
}
public void Emit (TypeContainer container)
{
- method_data.Emit (container, Accessor);
- Accessor.Block = null;
- }
+ method_data.Emit (container, this);
+ block = null;
- public Attributes OptAttributes {
- get {
- return Accessor.OptAttributes;
}
+
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == "return") {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
+
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ method_data.MethodBuilder.SetCustomAttribute (cb);
}
public virtual Type[] ParameterTypes {
{
}
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ PropertyBuilder.SetCustomAttribute (cb);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Property;
+ }
+ }
+
protected override bool DoDefine (DeclSpace decl, TypeContainer container)
{
if (!base.DoDefine (decl, container))
// case, we do not actually emit the ".property", so there is nowhere to
// put the attribute
//
- if (PropertyBuilder != null)
- Attribute.ApplyAttributes (ec, PropertyBuilder, this, OptAttributes);
+ if (PropertyBuilder != null && OptAttributes != null)
+ OptAttributes.Emit (ec, this);
if (Get != null)
Get.Emit (tc);
base.Emit (tc);
}
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
}
public class Property : PropertyBase, IIteratorContainer {
}
}
- public class Event : FieldBase {
+ /// <summary>
+ /// For case when event is declared like property (with add and remove accessors).
+ /// </summary>
+ public class EventProperty: Event {
+
+ static string[] attribute_targets = new string [] { "event", "property" };
+
+ public EventProperty (DeclSpace ds, Expression type, int mod_flags,
+ bool is_iface, MemberName name, Object init,
+ Attributes attrs, Accessor add, Accessor remove,
+ Location loc)
+ : base (ds, type, mod_flags, is_iface, name, init, attrs, loc)
+ {
+ Add = new AddDelegateMethod (this, add);
+ Remove = new RemoveDelegateMethod (this, remove);
+ }
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event is declared like field.
+ /// </summary>
+ public class EventField: Event {
+
+ static string[] attribute_targets = new string [] { "method", "field", "event" };
- sealed class AddDelegateMethod: DelegateMethod
+ public EventField (DeclSpace ds, Expression type, int mod_flags, bool is_iface,
+ MemberName name, Object init, Attributes attrs, Location loc)
+ : base (ds, type, mod_flags, is_iface, name, init, attrs, loc)
{
+ Add = new AddDelegateMethod (this);
+ Remove = new RemoveDelegateMethod (this);
+ }
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == "field") {
+ FieldBuilder.SetCustomAttribute (cb);
+ return;
+ }
+
+ if (a.Target == "method") {
+ AddBuilder.SetCustomAttribute (cb);
+ RemoveBuilder.SetCustomAttribute (cb);
+ return;
+ }
+
+ base.ApplyAttributeBuilder (a, cb);
+ }
+
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+ }
+
+ public abstract class Event : FieldBase {
+
+ protected sealed class AddDelegateMethod: DelegateMethod
+ {
+ public AddDelegateMethod (Event method):
+ base (method)
+ {
+ }
+
public AddDelegateMethod (Event method, Accessor accessor):
base (method, accessor)
{
protected override MethodInfo DelegateMethodInfo {
get {
- return TypeManager.delegate_combine_delegate_delegate;
+ return TypeManager.delegate_remove_delegate_delegate;
}
}
}
- sealed class RemoveDelegateMethod: DelegateMethod
+ protected sealed class RemoveDelegateMethod: DelegateMethod
{
+ public RemoveDelegateMethod (Event method):
+ base (method)
+ {
+ }
+
public RemoveDelegateMethod (Event method, Accessor accessor):
base (method, accessor)
{
}
- abstract class DelegateMethod: IMethodData
+ public abstract class DelegateMethod: Attributable, IMethodData
{
protected readonly Event method;
- public readonly Accessor Accessor;
protected MethodData method_data;
+ Block block;
+ ReturnParameter return_attributes;
+ ImplicitParameter param_attr;
- public DelegateMethod (Event method, Accessor accessor)
+ static string[] attribute_targets = new string [] { "method", "param", "return" };
+
+ public DelegateMethod (Event method):
+ base (null)
+ {
+ this.method = method;
+ }
+
+ public DelegateMethod (Event method, Accessor accessor):
+ base (accessor.Attributes)
{
this.method = method;
- this.Accessor = accessor;
+ this.block = accessor.Block;
+ }
+
+ public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+ {
+ if (a.Target == "return") {
+ if (return_attributes == null)
+ return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
+
+ return_attributes.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ if (a.Target == "param") {
+ if (param_attr == null)
+ param_attr = new ImplicitParameter (method_data.MethodBuilder);
+
+ param_attr.ApplyAttributeBuilder (a, cb);
+ return;
+ }
+
+ method_data.MethodBuilder.SetCustomAttribute (cb);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Method;
+ }
+ }
+
+ public override bool IsClsCompliaceRequired(DeclSpace ds)
+ {
+ return method.IsClsCompliaceRequired (ds);
}
public MethodBuilder Define (TypeContainer container, InternalParameters ip)
public Block Block {
get {
- return Accessor.Block;
+ return block;
}
}
public void Emit (TypeContainer tc)
{
- if (Accessor != null) {
- method_data.Emit (tc, Accessor);
- Accessor.Block = null;
+ if (block != null) {
+ method_data.Emit (tc, this);
+ block = null;
return;
}
protected abstract MethodInfo DelegateMethodInfo { get; }
- public Attributes OptAttributes {
- get {
- return Accessor == null ? null : Accessor.OptAttributes;
- }
- }
-
public Type[] ParameterTypes {
get {
return new Type[] { method.MemberType };
public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
{
- return new EmitContext (tc, method.ds, method.Location, ig, ReturnType, method.ModFlags, false);
+ return new EmitContext (tc, method.ds, Location, ig, ReturnType, method.ModFlags, false);
}
public abstract string MethodName { get; }
#endregion
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
}
const int AllowedInterfaceModifiers =
Modifiers.NEW;
- readonly DelegateMethod Add, Remove;
+ protected DelegateMethod Add, Remove;
public MyEventBuilder EventBuilder;
public MethodBuilder AddBuilder, RemoveBuilder;
public DeclSpace ds;
MethodData AddData, RemoveData;
public Event (DeclSpace ds, Expression type, int mod_flags, bool is_iface,
- MemberName name, Object init, Attributes attrs, Accessor add,
- Accessor remove, Location loc)
+ MemberName name, Object init, Attributes attrs, Location loc)
: base (type, mod_flags,
is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
name, init, attrs, loc)
{
- Add = new AddDelegateMethod (this, add);
- Remove = new RemoveDelegateMethod (this, remove);
IsInterface = is_iface;
this.ds = ds;
}
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ EventBuilder.SetCustomAttribute (cb);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Event;
+ }
+ }
+
public override bool Define (TypeContainer container)
{
- EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
+ EventAttributes e_attr;
+ if (IsInterface)
+ e_attr = EventAttributes.None;
+ else
+ e_attr = EventAttributes.RTSpecialName |
+ EventAttributes.SpecialName;
;
if (!DoDefine (container, container))
return false;
EventBuilder = new MyEventBuilder (this,
container.TypeBuilder, Name, e_attr, MemberType);
- if (Add.Accessor == null && Remove.Accessor == null) {
+ if (Add.Block == null && Remove.Block == null &&
+ !IsInterface) {
FieldBuilder = container.TypeBuilder.DefineField (
Name, MemberType,
FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
{
if (OptAttributes != null) {
EmitContext ec = new EmitContext (tc, Location, null, MemberType, ModFlags);
- Attribute.ApplyAttributes (ec, EventBuilder, this, OptAttributes);
+ OptAttributes.Emit (ec, this);
}
- Add.Emit (tc);
- Remove.Emit (tc);
+ if (!IsInterface) {
+ Add.Emit (tc);
+ Remove.Emit (tc);
+ }
base.Emit (tc);
}
-
}
//
if (!DoDefine (container, container))
return false;
- IndexerName = Attribute.ScanForIndexerName (ec, OptAttributes);
+ if (OptAttributes != null)
+ IndexerName = OptAttributes.ScanForIndexerName (ec);
+
if (IndexerName == null)
IndexerName = "Item";
else {
if (IsExplicitImpl) {
Report.Error (592, Location,
- "Attribute 'IndexerName' is not valid on explicit " +
- "implementations.");
-
+ "Attribute 'IndexerName' is not valid on explicit implementations.");
return false;
}
}
public string MethodName;
public Method OperatorMethod;
+ static string[] attribute_targets = new string [] { "param" };
+
public Operator (OpType type, Expression ret_type, int mod_flags,
Expression arg1type, string arg1name,
Expression arg2type, string arg2name,
return container.Name + ".operator " + OperatorType + " (" + FirstArgType + "," +
SecondArgType + ")";
}
+
+ public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+ {
+ OperatorMethod.ApplyAttributeBuilder (a, cb);
+ }
+
+ public override AttributeTargets AttributeTargets {
+ get {
+ return AttributeTargets.Method;
+ }
+ }
protected override bool CheckGenericOverride (MethodInfo method, string name)
{
param_types [0], param_types [1]);
}
+ protected override string[] ValidAttributeTargets {
+ get {
+ return attribute_targets;
+ }
+ }
+
public void SetYields ()
{
ModFlags |= Modifiers.METHOD_YIELDS;