public Attributable (Attributes attrs)
{
- OptAttributes = attrs;
+ if (attrs != null)
+ OptAttributes = attrs;
}
public Attributes OptAttributes
bool resolve_error;
readonly bool nameEscaped;
- Attributable owner;
+
+ // It can contain more onwers when the attribute is applied to multiple fiels.
+ Attributable[] owners;
static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
static Assembly orig_sec_assembly;
object [] prop_values_arr;
object [] pos_values;
- static PtrHashtable usage_attr_cache = new PtrHashtable ();
-
+ static PtrHashtable usage_attr_cache;
// Cache for parameter-less attributes
- static PtrHashtable att_cache = new PtrHashtable ();
+ static PtrHashtable att_cache;
public Attribute (string target, Expression left_expr, string identifier, object[] args, Location loc, bool nameEscaped)
{
this.nameEscaped = nameEscaped;
}
+ static Attribute ()
+ {
+ Reset ();
+ }
+
+ public static void Reset ()
+ {
+ usage_attr_cache = new PtrHashtable ();
+ att_cache = new PtrHashtable ();
+ }
+
public void AttachTo (Attributable owner)
{
- this.owner = owner;
+ if (this.owners == null) {
+ this.owners = new Attributable[1] { owner };
+ return;
+ }
+
+ // When the same attribute is attached to multiple fiels
+ // we use this extra_owners as a list of owners. The attribute
+ // then can be removed because will be emitted when first owner
+ // is served
+ Attributable[] new_array = new Attributable [this.owners.Length + 1];
+ owners.CopyTo (new_array, 0);
+ new_array [owners.Length] = owner;
+ this.owners = new_array;
+ owner.OptAttributes = null;
}
void Error_InvalidNamedArgument (string name)
"expression or array creation expression");
}
+ public void Error_MissingGuidAttribute ()
+ {
+ Report.Error (596, Location, "The Guid attribute must be specified with the ComImport attribute");
+ }
+
/// <summary>
/// This is rather hack. We report many emit attribute error with same error to be compatible with
/// csc. But because csc has to report them this way because error came from ilasm we needn't.
Error_AttributeEmitError ("it is attached to invalid parent");
}
+ Attributable Owner {
+ get {
+ return owners [0];
+ }
+ }
+
protected virtual TypeExpr ResolveAsTypeTerminal (Expression expr, IResolveContext ec, bool silent)
{
return expr.ResolveAsTypeTerminal (ec, silent);
Type ResolvePossibleAttributeType (string name, bool silent, ref bool is_attr)
{
- IResolveContext rc = owner.ResolveContext;
+ IResolveContext rc = Owner.ResolveContext;
TypeExpr te;
if (LeftExpr == null) {
te = ResolveAsTypeTerminal (new SimpleName (name, Location), rc, silent);
} else {
- te = ResolveAsTypeTerminal (new MemberAccess (LeftExpr, name, Location), rc, silent);
+ te = ResolveAsTypeTerminal (new MemberAccess (LeftExpr, name), rc, silent);
}
if (te == null)
}
}
+ Attributable owner = Owner;
EmitContext ec = new EmitContext (owner.ResolveContext, owner.ResolveContext.DeclContainer, owner.ResolveContext.DeclContainer,
Location, null, null, owner.ResolveContext.DeclContainer.ModFlags, false);
+ ec.IsAnonymousMethodAllowed = false;
ConstructorInfo ctor = ResolveConstructor (ec);
if (ctor == null)
BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
Location);
+ if (mg == null)
+ return null;
+
MethodBase constructor = Invocation.OverloadResolve (
ec, (MethodGroupExpr) mg, PosArguments, false, Location);
return null;
ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (constructor);
- if (oa != null && !owner.ResolveContext.IsInObsoleteScope) {
+ if (oa != null && !Owner.ResolveContext.IsInObsoleteScope) {
AttributeTester.Report_ObsoleteMessage (oa, mg.GetSignatureForError (), mg.Location);
}
for (int j = 0; j < pos_arg_count; ++j) {
Argument a = (Argument) PosArguments [j];
- if (!a.Expr.GetAttributableValue (out pos_values [j]))
+ if (!a.Expr.GetAttributableValue (a.Type, out pos_values [j]))
return null;
- if (TypeManager.IsPrimitiveType (a.Type) && a.Type != pos_values [j].GetType ()) {
- bool fail;
- // This can happen only for constants in same range
- pos_values [j] = TypeManager.ChangeType (pos_values [j], a.Type, out fail);
- }
-
if (j < last_real_param)
continue;
}
if (Type == TypeManager.attribute_usage_type && (int)pos_values [0] == 0) {
- Report.Error (591, Location, "Invalid value for argument to 'System.AttributeUsage' attribute");
+ Report.Error (591, Location, "Invalid value for argument to `System.AttributeUsage' attribute");
return null;
}
+ if (Type == TypeManager.indexer_name_type || Type == TypeManager.conditional_attribute_type) {
+ if (!Tokenizer.IsValidIdentifier ((string)pos_values [0])) {
+ Report.Error (633, ((Argument)PosArguments[0]).Expr.Location,
+ "The argument to the `{0}' attribute must be a valid identifier", GetSignatureForError ());
+ return null;
+ }
+ }
+
if (Type == TypeManager.methodimpl_attr_type && pos_values.Length == 1 &&
pd.ParameterType (0) == TypeManager.short_type &&
!System.Enum.IsDefined (typeof (MethodImplOptions), pos_values [0].ToString ())) {
return false;
}
- Expression e = Convert.ImplicitConversionRequired (ec, a.Expr, pi.PropertyType, a.Expr.Location);
- if (e == null)
- return false;
-
object value;
- if (!e.GetAttributableValue (out value))
+ if (!a.Expr.GetAttributableValue (pi.PropertyType, out value))
return false;
PropertyBase pb = TypeManager.GetProperty (pi);
return false;
}
- Expression e = Convert.ImplicitConversionRequired (ec, a.Expr, fi.FieldType, a.Expr.Location);
- if (e == null)
- return false;
-
object value;
- if (!e.GetAttributableValue (out value))
+ if (!a.Expr.GetAttributableValue (fi.FieldType, out value))
return false;
FieldBase fb = TypeManager.GetField (fi);
field_infos.Add (fi);
}
- if (obsolete_attr != null && !owner.ResolveContext.IsInObsoleteScope)
+ if (obsolete_attr != null && !Owner.ResolveContext.IsInObsoleteScope)
AttributeTester.Report_ObsoleteMessage (obsolete_attr, member.GetSignatureForError (), member.Location);
}
public bool CheckTarget ()
{
- string[] valid_targets = owner.ValidAttributeTargets;
+ string[] valid_targets = Owner.ValidAttributeTargets;
if (ExplicitTarget == null || ExplicitTarget == valid_targets [0]) {
- Target = owner.AttributeTargets;
+ Target = Owner.AttributeTargets;
return true;
}
ps.AddPermission (perm);
}
- object GetValue (object value)
+ static object GetValue (object value)
{
if (value is EnumConstant)
return ((EnumConstant) value).GetValue ();
return base.GetHashCode ();
}
+ public object GetParameterDefaultValue ()
+ {
+ return pos_values [0];
+ }
+
/// <summary>
/// Emit attribute for Attributable symbol
/// </summary>
}
try {
- owner.ApplyAttributeBuilder (this, cb);
+ foreach (Attributable owner in owners)
+ owner.ApplyAttributeBuilder (this, cb);
}
catch (Exception e) {
Error_AttributeEmitError (e.Message);
return;
// Here we are testing attribute arguments for array usage (error 3016)
- if (owner.IsClsComplianceRequired ()) {
+ if (Owner.IsClsComplianceRequired ()) {
if (PosArguments != null) {
foreach (Argument arg in PosArguments) {
// Type is undefined (was error 246)
/// </summary>
sealed class AttributeTester
{
- static PtrHashtable analyzed_types = new PtrHashtable ();
- static PtrHashtable analyzed_types_obsolete = new PtrHashtable ();
- static PtrHashtable analyzed_member_obsolete = new PtrHashtable ();
- static PtrHashtable analyzed_method_excluded = new PtrHashtable ();
+ static PtrHashtable analyzed_types;
+ static PtrHashtable analyzed_types_obsolete;
+ static PtrHashtable analyzed_member_obsolete;
+ static PtrHashtable analyzed_method_excluded;
#if NET_2_0
- static PtrHashtable fixed_buffer_cache = new PtrHashtable ();
+ static PtrHashtable fixed_buffer_cache;
#endif
static object TRUE = new object ();
static object FALSE = new object ();
+ static AttributeTester ()
+ {
+ Reset ();
+ }
+
private AttributeTester ()
{
}
+ public static void Reset ()
+ {
+ analyzed_types = new PtrHashtable ();
+ analyzed_types_obsolete = new PtrHashtable ();
+ analyzed_member_obsolete = new PtrHashtable ();
+ analyzed_method_excluded = new PtrHashtable ();
+#if NET_2_0
+ fixed_buffer_cache = new PtrHashtable ();
+#endif
+ }
+
public enum Result {
Ok,
RefOutArrayError,