using System;
using System.Diagnostics;
using System.Collections;
+using System.Collections.Specialized;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
namespace Mono.MonoBASIC {
+ /// <summary>
+ /// Base class for objects that can have Attributes applied to them.
+ /// </summary>
+ public abstract class Attributable {
+ /// <summary>
+ /// Attributes for this type
+ /// </summary>
+ Attributes attributes;
+
+ public Attributable(Attributes attrs)
+ {
+ attributes = attrs;
+ }
+
+ public Attributes OptAttributes
+ {
+ get {
+ return attributes;
+ }
+ set {
+ attributes = value;
+ }
+ }
+
+ /// <summary>
+ /// Use member-specific procedure to apply attribute @a in @cb to the entity being built in @builder
+ /// </summary>
+ public abstract void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb);
+ /// <summary>
+ /// Returns one AttributeTarget for this element.
+ /// </summary>
+ public abstract AttributeTargets AttributeTargets { get; }
+ };
public class Attribute {
public readonly string ExplicitTarget;
public readonly string Name;
public readonly ArrayList Arguments;
- Location Location;
+ public Location Location;
public Type Type;
-
- //
- // The following are only meaningful when the attribute
- // being emitted is one of the builtin ones
- //
- AttributeTargets Targets;
- bool AllowMultiple;
- bool Inherited;
- bool UsageAttr = false;
+ // Is non-null if type is AttributeUsageAttribute
+ AttributeUsageAttribute usage_attribute;
+
+ public AttributeUsageAttribute UsageAttribute {
+ get {
+ return usage_attribute;
+ }
+ }
+
+ bool usage_attr = false;
MethodImplOptions ImplOptions;
- UnmanagedType UnmanagedType;
+ public UnmanagedType UnmanagedType;
CustomAttributeBuilder cb;
public Attribute (string name, ArrayList args, Location loc)
" missing a using directive or an assembly reference ?)");
return null;
}
+
public Type ResolveType (EmitContext ec)
{
bool MethodImplAttr = false;
bool MarshalAsAttr = false;
- UsageAttr = false;
+ usage_attr = false;
if (Type == TypeManager.attribute_usage_type)
- UsageAttr = true;
+ usage_attr = true;
if (Type == TypeManager.methodimpl_attr_type)
MethodImplAttr = true;
if (Type == TypeManager.marshal_as_attr_type)
return null;
}
- if (UsageAttr)
- this.Targets = (AttributeTargets) pos_values [0];
+ if (usage_attr)
+ usage_attribute = new AttributeUsageAttribute ((AttributeTargets) pos_values [0]);
if (MethodImplAttr)
this.ImplOptions = (MethodImplOptions) pos_values [0];
object o = ((Constant) e).GetValue ();
prop_values.Add (o);
- if (UsageAttr) {
+ if (usage_attr) {
if (member_name == "AllowMultiple")
- this.AllowMultiple = (bool) o;
+ usage_attribute.AllowMultiple = (bool) o;
if (member_name == "Inherited")
- this.Inherited = (bool) o;
+ usage_attribute.Inherited = (bool) o;
}
} else if (e is TypeOf) {
return cb;
}
- static string GetValidPlaces (Attribute attr)
+ public string GetValidTargets ()
{
StringBuilder sb = new StringBuilder ();
- AttributeTargets targets = 0;
-
- TypeContainer a = TypeManager.LookupAttr (attr.Type);
-
- if (a == null) {
-
- System.Attribute [] attrs = null;
-
- try {
- attrs = System.Attribute.GetCustomAttributes (attr.Type);
-
- } catch {
- Report.Error (-20, attr.Location, "Cannot find attribute type " + attr.Name +
- " (maybe you forgot to set the usage using the" +
- " AttributeUsage attribute ?).");
- return null;
- }
-
- foreach (System.Attribute tmp in attrs)
- if (tmp is AttributeUsageAttribute) {
- targets = ((AttributeUsageAttribute) tmp).ValidOn;
- break;
- }
- } else
- targets = a.Targets;
-
+ AttributeTargets targets = GetAttributeUsage ().ValidOn;
if ((targets & AttributeTargets.Assembly) != 0)
sb.Append ("'assembly' ");
public static void Error_AttributeNotValidForElement (Attribute a, Location loc)
{
Report.Error (
- 592, loc, "Attribute '" + a.Name +
+ 30662, loc, "Attribute '" + a.Name +
"' is not valid on this declaration type. " +
- "It is valid on " + GetValidPlaces (a) + "declarations only.");
+ "It is valid on " + a.GetValidTargets () + "declarations only.");
}
public static bool CheckAttribute (Attribute a, object element)
{
- TypeContainer attr = TypeManager.LookupAttr (a.Type);
- AttributeTargets targets = 0;
+ //TypeContainer attr = TypeManager.LookupClass (a.Type);
+ AttributeTargets targets = a.GetAttributeUsage ().ValidOn;
-
- if (attr == null) {
-
- System.Attribute [] attrs = null;
-
- try {
- attrs = System.Attribute.GetCustomAttributes (a.Type);
-
- } catch {
- Report.Error (-20, a.Location, "Cannot find attribute type " + a.Name +
- " (maybe you forgot to set the usage using the" +
- " AttributeUsage attribute ?).");
- return false;
- }
-
- foreach (System.Attribute tmp in attrs)
- if (tmp is AttributeUsageAttribute)
- targets = ((AttributeUsageAttribute) tmp).ValidOn;
- } else
- targets = attr.Targets;
if (element is Class) {
if ((targets & AttributeTargets.Class) != 0)
return true;
else
return false;
- } else if (element is Property || element is Indexer /*||
+ } else if (element is Property /* || element is Indexer ||
element is InterfaceProperty || element is InterfaceIndexer*/) {
if ((targets & AttributeTargets.Property) != 0)
return true;
return true;
else
return false;
- }
+ } else if (element is ModuleBuilder){
+ if ((targets & AttributeTargets.Module) != 0)
+ return true;
+ else
+ return false;
+ }
return false;
}
+ /// <summary>
+ /// Returns AttributeUsage attribute for this type
+ /// </summary>
+ public AttributeUsageAttribute GetAttributeUsage ()
+ {
+ Class attr_class = (Class) TypeManager.LookupClass (Type);
+
+ if (attr_class == null) {
+ object[] usage_attr = Type.GetCustomAttributes (TypeManager.attribute_usage_type, true);
+ return (AttributeUsageAttribute)usage_attr [0];
+ }
+
+ return attr_class.AttributeUsage;
+ }
+
//
- // This method should be invoked to pull the IndexerName attribute from an
+ // This method should be invoked to pull the DefaultPropName attribute from an
// Indexer if it exists.
//
public static string ScanForIndexerName (EmitContext ec, Attributes opt_attrs)
continue;
//
- // So we have found an IndexerName, pull the data out.
+ // So we have found an DefaultPropName, pull the data out.
//
if (a.Arguments == null || a.Arguments [0] == null){
Error_AttributeConstructorMismatch (a.Location);
return ((StringConstant) arg.Expr).Value;
}
+
+ /// <summary>
+ /// Emit attribute for Attributable symbol
+ /// </summary>
+ public void Emit (EmitContext ec, Attributable ias, ListDictionary emitted_attr)
+ {
+ CustomAttributeBuilder cb = Resolve (ec);
+ if (cb == null)
+ return;
+
+ AttributeUsageAttribute usage_attr = GetAttributeUsage ();
+ if ((usage_attr.ValidOn & ias.AttributeTargets) == 0) {
+ Report.Error (30662, Location, "Attribute" + Name + "is not valid on this declaration type. It is valid on " + GetValidTargets () + " declarations only.");
+ return;
+ }
+
+ ias.ApplyAttributeBuilder (this, cb);
+ }
+
//
// Applies the attributes to the `builder'.
//
} else if (a.Type != TypeManager.dllimport_type){
((MethodBuilder) builder).SetCustomAttribute (cb);
}
- } else if (kind is Constructor) {
- ((ConstructorBuilder) builder).SetCustomAttribute (cb);
- } else if (kind is Field) {
- ((FieldBuilder) builder).SetCustomAttribute (cb);
- } else if (kind is Property || kind is Indexer) {
- ((PropertyBuilder) builder).SetCustomAttribute (cb);
- } else if (kind is Event) {
- ((MyEventBuilder) builder).SetCustomAttribute (cb);
- } else if (kind is ParameterBuilder) {
- if (a.Type == TypeManager.marshal_as_attr_type) {
- UnmanagedMarshal marshal = UnmanagedMarshal.DefineUnmanagedMarshal (a.UnmanagedType);
- ((ParameterBuilder) builder).SetMarshal (marshal);
- } else
- ((ParameterBuilder) builder).SetCustomAttribute (cb);
- } else if (kind is Enum) {
- ((TypeBuilder) builder).SetCustomAttribute (cb);
- } else if (kind is TypeContainer) {
- TypeContainer tc = (TypeContainer) kind;
-
- if (a.UsageAttr) {
- tc.Targets = a.Targets;
- tc.AllowMultiple = a.AllowMultiple;
- tc.Inherited = a.Inherited;
-
- } else if (a.Type == TypeManager.default_member_type) {
- if (tc.Indexers != null) {
- Report.Error (646, loc, "Cannot specify the DefaultMember attribute on" + " a type containing an indexer");
- return;
- }
- } else {
- if (!CheckAttribute (a, kind)) {
- Error_AttributeNotValidForElement (a, loc);
- return;
- }
- }
-
- try {
- ((TypeBuilder) builder).SetCustomAttribute (cb);
- } catch (System.ArgumentException) {
- Report.Warning (-21, loc, "The CharSet named property on StructLayout\n"+"\tdoes not work correctly on Microsoft.NET\n"+"\tYou might want to remove the CharSet declaration\n"+"\tor compile using the Mono runtime instead of the\n"+"\tMicrosoft .NET runtime");
- }
- } else if (kind is Interface) {
- Interface iface = (Interface) kind;
- if (!CheckAttribute (a, kind)) {
- Error_AttributeNotValidForElement (a, loc);
- return;
- }
- ((TypeBuilder) builder).SetCustomAttribute (cb);
- } else if (kind is AssemblyBuilder){
- ((AssemblyBuilder) builder).SetCustomAttribute (cb);
- } else if (kind is ModuleBuilder) {
- ((ModuleBuilder) builder).SetCustomAttribute (cb);
- } else if (kind is FieldBuilder) {
- ((FieldBuilder) builder).SetCustomAttribute (cb);
- } else
+ } else
throw new Exception ("Unknown kind: " + kind);
}
}
CallingConvention cc = CallingConvention.Winapi;
CharSet charset = CharSet.Ansi;
bool preserve_sig = true;
- bool exact_spelling = false;
- bool set_last_err = false;
+ /*bool exact_spelling = false;
+ bool set_last_err = false;*/
string entry_point = null;
for (int i = 0; i < named_args.Count; i++) {
charset = (CharSet) c.GetValue ();
else if (member_name == "EntryPoint")
entry_point = (string) c.GetValue ();
- else if (member_name == "SetLastError")
+ /*else if (member_name == "SetLastError")
set_last_err = (bool) c.GetValue ();
else if (member_name == "ExactSpelling")
- exact_spelling = (bool) c.GetValue ();
+ exact_spelling = (bool) c.GetValue ();*/
else if (member_name == "PreserveSig")
preserve_sig = (bool) c.GetValue ();
} else {
mb.SetImplementationFlags (MethodImplAttributes.PreserveSig);
return mb;
- }
+ }
+
+ public bool IsAssemblyAttribute {
+ get {
+ return ExplicitTarget == "assembly";
+ }
+ }
+
+ public bool IsModuleAttribute {
+ get {
+ return ExplicitTarget == "module";
+ }
+ }
}
public class Attributes {
Attrs = attrs;
}
- public void AddAttributes (ArrayList attrs)
+ public void Add (Attribute attr)
{
- Attrs.AddRange (attrs);
+ Attrs.Add (attr);
}
- public bool Contains (Type t)
+ public void Add (ArrayList attrs)
{
- foreach (Attribute a in Attrs){
- if (a.Type == t)
- return true;
- }
- return false;
- }
+ Attrs.AddRange (attrs);
+ }
+
+ public void Emit (EmitContext ec, Attributable ias)
+ {
+ ListDictionary ld = new ListDictionary ();
+
+ foreach (Attribute a in Attrs)
+ a.Emit (ec, ias, ld);
+ }
}
}