bool resolve_error;
+ readonly bool nameEscaped;
+
static AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All);
static Assembly orig_sec_assembly;
static PtrHashtable usage_attr_cache = new PtrHashtable ();
- public Attribute (string target, Expression left_expr, string identifier, ArrayList args, Location loc)
+ public Attribute (string target, Expression left_expr, string identifier, ArrayList args, Location loc, bool nameEscaped)
{
LeftExpr = left_expr;
Identifier = identifier;
Arguments = args;
Location = loc;
ExplicitTarget = target;
+ this.nameEscaped = nameEscaped;
}
void Error_InvalidNamedArgument (string name)
{
- Report.Error (617, Location, "`{0}' is not a valid named attribute argument. Named attribute arguments must be fields which are not readonly, static, const or read-write properties which are public and not static",
+ Report.Error (617, Location, "`{0}' is not a valid named attribute argument. Named attribute arguments " +
+ "must be fields which are not readonly, static, const or read-write properties which are " +
+ "public and not static",
name);
}
void Error_InvalidNamedAgrumentType (string name)
{
- Report.Error (655, Location, "`{0}' is not a valid named attribute argument because it is not a valid attribute parameter type", name);
+ Report.Error (655, Location, "`{0}' is not a valid named attribute argument because it is not a valid " +
+ "attribute parameter type", name);
}
static void Error_AttributeArgumentNotValid (string extra, Location loc)
/// </summary>
public void Error_AttributeEmitError (string inner)
{
- Report.Error (647, Location, "Error during emitting `{0}' attribute. The reason is `{1}'", TypeManager.CSharpName (Type), inner);
+ Report.Error (647, Location, "Error during emitting `{0}' attribute. The reason is `{1}'",
+ TypeManager.CSharpName (Type), inner);
}
public void Error_InvalidSecurityParent ()
{
bool t1_is_attr = false;
Type t1 = ResolvePossibleAttributeType (ec, Identifier, true, ref t1_is_attr);
- // FIXME: Shouldn't do this for quoted attributes: [@A]
bool t2_is_attr = false;
- Type t2 = ResolvePossibleAttributeType (ec, Identifier + "Attribute", true, ref t2_is_attr);
+ Type t2 = nameEscaped ? null :
+ ResolvePossibleAttributeType (ec, Identifier + "Attribute", true, ref t2_is_attr);
if (t1_is_attr && t2_is_attr) {
- Report.Error (1614, Location, "`{0}' is ambiguous between `{0}' and `{0}Attribute'. Use either `@{0}' or `{0}Attribute'", GetSignatureForError ());
+ Report.Error (1614, Location, "`{0}' is ambiguous between `{0}' and `{0}Attribute'. " +
+ "Use either `@{0}' or `{0}Attribute'", GetSignatureForError ());
resolve_error = true;
return;
}
//
public static bool GetAttributeArgumentExpression (Expression e, Location loc, Type arg_type, out object result)
{
- if (e is EnumConstant) {
- if (RootContext.StdLib)
- result = ((EnumConstant)e).GetValueAsEnumType ();
- else
- result = ((EnumConstant)e).GetValue ();
-
- return true;
- }
-
Constant constant = e as Constant;
if (constant != null) {
- if (e.Type != arg_type) {
- constant = Const.ChangeType (loc, constant, arg_type);
- if (constant == null) {
- result = null;
- Error_AttributeArgumentNotValid (loc);
- return false;
- }
+ constant = constant.ToType (arg_type, loc);
+ if (constant == null) {
+ result = null;
+ return false;
}
- result = constant.GetValue ();
+ result = constant.GetTypedValue ();
return true;
} else if (e is TypeOf) {
result = ((TypeOf) e).TypeArg;
} else if (e is EmptyCast) {
Expression child = ((EmptyCast)e).Child;
return GetAttributeArgumentExpression (child, loc, child.Type, out result);
+ } else if (e is As) {
+ As as_e = (As) e;
+ return GetAttributeArgumentExpression (as_e.Expr, loc, as_e.ProbeType.Type, out result);
}
result = null;
bool IsValidArgumentType (Type t)
{
+ if (t.IsArray)
+ t = t.GetElementType ();
+
return TypeManager.IsPrimitiveType (t) ||
- (t.IsArray && TypeManager.IsPrimitiveType (t.GetElementType ())) ||
TypeManager.IsEnumType (t) ||
t == TypeManager.string_type ||
t == TypeManager.object_type ||
return null;
}
+ ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (Type);
+ if (obsolete_attr != null) {
+ AttributeTester.Report_ObsoleteMessage (obsolete_attr, TypeManager.CSharpName (Type), Location);
+ }
+
if (Arguments == null) {
object o = att_cache [Type];
if (o != null) {
}
ConstructorInfo ctor = ResolveArguments (ec);
- if (ctor == null)
+ if (ctor == null) {
+ if (Type is TypeBuilder &&
+ TypeManager.LookupDeclSpace (Type).MemberCache == null)
+ // The attribute type has been DefineType'd, but not Defined. Let's not treat it as an error.
+ // It'll be resolved again when the attached-to entity is emitted.
+ resolve_error = false;
return null;
+ }
CustomAttributeBuilder cb;
BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
Location);
+ if (mg == null) {
+ // FIXME: Punt the issue for now.
+ if (Type is TypeBuilder)
+ return null;
+ throw new InternalErrorException ("Type " + Type + " doesn't have constructors");
+ }
+
MethodBase constructor = Invocation.OverloadResolve (
ec, (MethodGroupExpr) mg, pos_args, false, Location);
}
catch (Exception e) {
Error_AttributeEmitError (e.Message);
+ return null;
}
}
-// TODO: reenable
-// if (Type == TypeManager.methodimpl_attr_type &&
-// pos_values.Length == 1 && ((Argument)pos_args [0]).Type == TypeManager.short_type &&
-// !System.Enum.IsDefined (TypeManager.method_impl_options, pos_values [0])) {
-// Error_AttributeEmitError ("Incorrect argument value.");
-// }
+
+ if (Type == TypeManager.methodimpl_attr_type &&
+ pos_values.Length == 1 && ((Argument)pos_args [0]).Type == TypeManager.short_type &&
+ !System.Enum.IsDefined (typeof (MethodImplOptions), pos_values [0])) {
+ Error_AttributeEmitError ("Incorrect argument value.");
+ return null;
+ }
//
// Now we perform some checks on the positional args as they
orig_assembly_type = orig_sec_assembly.GetType (Type.FullName, true);
if (orig_assembly_type == null) {
- Report.Warning (-112, 1, Location, "Self-referenced security attribute `{0}' was not found in previous version of assembly");
+ Report.Warning (-112, 1, Location, "Self-referenced security attribute `{0}' " +
+ "was not found in previous version of assembly");
return;
}
}
return null;
}
+ //
+ // Theoretically, we can get rid of this, since FieldBuilder.SetCustomAttribute()
+ // and ParameterBuilder.SetCustomAttribute() are supposed to handle this attribute.
+ // However, we can't, since it appears that the .NET 1.1 SRE hangs when given a MarshalAsAttribute.
+ //
public UnmanagedMarshal GetMarshal (Attributable attr)
{
- UnmanagedType UnmanagedType = (UnmanagedType)System.Enum.Parse (typeof (UnmanagedType), pos_values [0].ToString ());
+ UnmanagedType UnmanagedType;
+ if (!RootContext.StdLib || pos_values [0].GetType () != typeof (UnmanagedType))
+ UnmanagedType = (UnmanagedType) System.Enum.ToObject (typeof (UnmanagedType), pos_values [0]);
+ else
+ UnmanagedType = (UnmanagedType) pos_values [0];
object value = GetFieldValue ("SizeParamIndex");
if (value != null && UnmanagedType != UnmanagedType.LPArray) {
}
object o = GetFieldValue ("ArraySubType");
- UnmanagedType array_sub_type = o == null ? UnmanagedType.I4 : (UnmanagedType) o;
-
+ UnmanagedType array_sub_type = o == null ? (UnmanagedType) 0x50 /* NATIVE_MAX */ : (UnmanagedType) o;
+
switch (UnmanagedType) {
case UnmanagedType.CustomMarshaler: {
MethodInfo define_custom = typeof (UnmanagedMarshal).GetMethod ("DefineCustom",
- BindingFlags.Static | BindingFlags.Public);
+ BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (define_custom == null) {
Report.RuntimeMissingSupport (Location, "set marshal info");
return null;
object size_param_index = GetFieldValue ("SizeParamIndex");
if ((size_const != null) || (size_param_index != null)) {
- MethodInfo define_array = typeof (UnmanagedMarshal).GetMethod ("DefineLPArrayInternal", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
+ MethodInfo define_array = typeof (UnmanagedMarshal).GetMethod ("DefineLPArrayInternal",
+ BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (define_array == null) {
Report.RuntimeMissingSupport (Location, "set marshal info");
return null;
}
case UnmanagedType.SafeArray:
return UnmanagedMarshal.DefineSafeArray (array_sub_type);
-
+
case UnmanagedType.ByValArray:
FieldMember fm = attr as FieldMember;
if (fm == null) {
return null;
}
return UnmanagedMarshal.DefineByValArray ((int) GetFieldValue ("SizeConst"));
-
+
case UnmanagedType.ByValTStr:
return UnmanagedMarshal.DefineByValTStr ((int) GetFieldValue ("SizeConst"));
-
+
default:
return UnmanagedMarshal.DefineUnmanagedMarshal (UnmanagedType);
}
public MethodImplOptions GetMethodImplOptions ()
{
- return (MethodImplOptions)System.Enum.Parse (typeof (MethodImplOptions), pos_values [0].ToString ());
+ if (pos_values [0].GetType () != typeof (MethodImplOptions))
+ return (MethodImplOptions)System.Enum.ToObject (typeof (MethodImplOptions), pos_values [0]);
+ return (MethodImplOptions)pos_values [0];
}
public LayoutKind GetLayoutKindValue ()
{
- return (LayoutKind)System.Enum.Parse (typeof (LayoutKind), pos_values [0].ToString ());
+ if (!RootContext.StdLib || pos_values [0].GetType () != typeof (LayoutKind))
+ return (LayoutKind)System.Enum.ToObject (typeof (LayoutKind), pos_values [0]);
+
+ return (LayoutKind)pos_values [0];
}
/// <summary>
AttributeUsageAttribute usage_attr = GetAttributeUsage (ec);
if ((usage_attr.ValidOn & Target) == 0) {
- Report.Error (592, Location, "Attribute `{0}' is not valid on this declaration type. It is valid on `{1}' declarations only",
+ Report.Error (592, Location, "Attribute `{0}' is not valid on this declaration type. " +
+ "It is valid on `{1}' declarations only",
GetSignatureForError (), GetValidTargets ());
return;
}
MethodInfo set_set_last_error = null;
if (field_info_arr != null) {
-
+
for (int i = 0; i < field_info_arr.Length; i++) {
switch (field_info_arr [i].Name) {
- case "BestFitMapping":
- best_fit_mapping = (bool) field_values_arr [i];
- best_fit_mapping_set = true;
- break;
- case "CallingConvention":
- cc = (CallingConvention) field_values_arr [i];
- break;
- case "CharSet":
- charset = (CharSet) field_values_arr [i];
- break;
- case "EntryPoint":
- entry_point = (string) field_values_arr [i];
- break;
- case "ExactSpelling":
- exact_spelling = (bool) field_values_arr [i];
- exact_spelling_set = true;
- break;
- case "PreserveSig":
- preserve_sig = (bool) field_values_arr [i];
- break;
- case "SetLastError":
- set_last_error = (bool) field_values_arr [i];
- set_last_error_set = true;
- break;
- case "ThrowOnUnmappableChar":
- throw_on_unmappable = (bool) field_values_arr [i];
- throw_on_unmappable_set = true;
- break;
- default:
- throw new InternalErrorException (field_info_arr [i].ToString ());
+ case "BestFitMapping":
+ best_fit_mapping = (bool) field_values_arr [i];
+ best_fit_mapping_set = true;
+ break;
+ case "CallingConvention":
+ cc = (CallingConvention) field_values_arr [i];
+ break;
+ case "CharSet":
+ charset = (CharSet) field_values_arr [i];
+ break;
+ case "EntryPoint":
+ entry_point = (string) field_values_arr [i];
+ break;
+ case "ExactSpelling":
+ exact_spelling = (bool) field_values_arr [i];
+ exact_spelling_set = true;
+ break;
+ case "PreserveSig":
+ preserve_sig = (bool) field_values_arr [i];
+ break;
+ case "SetLastError":
+ set_last_error = (bool) field_values_arr [i];
+ set_last_error_set = true;
+ break;
+ case "ThrowOnUnmappableChar":
+ throw_on_unmappable = (bool) field_values_arr [i];
+ throw_on_unmappable_set = true;
+ break;
+ default:
+ throw new InternalErrorException (field_info_arr [i].ToString ());
}
}
}
-
+
if (throw_on_unmappable_set || best_fit_mapping_set || exact_spelling_set || set_last_error_set) {
- set_best_fit = typeof (MethodBuilder).GetMethod ("set_BestFitMapping", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
- set_throw_on = typeof (MethodBuilder).GetMethod ("set_ThrowOnUnmappableChar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
- set_exact_spelling = typeof (MethodBuilder).GetMethod ("set_ExactSpelling", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
- set_set_last_error = typeof (MethodBuilder).GetMethod ("set_SetLastError", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
-
- if ((set_best_fit == null) || (set_throw_on == null) || (set_exact_spelling == null) || (set_set_last_error == null)) {
+ set_best_fit = typeof (MethodBuilder).
+ GetMethod ("set_BestFitMapping", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+ set_throw_on = typeof (MethodBuilder).
+ GetMethod ("set_ThrowOnUnmappableChar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+ set_exact_spelling = typeof (MethodBuilder).
+ GetMethod ("set_ExactSpelling", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+ set_set_last_error = typeof (MethodBuilder).
+ GetMethod ("set_SetLastError", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
+
+ if ((set_best_fit == null) || (set_throw_on == null) ||
+ (set_exact_spelling == null) || (set_set_last_error == null)) {
Report.Error (-1, Location,
- "The ThrowOnUnmappableChar, BestFitMapping, SetLastError, and ExactSpelling attributes can only be emitted when running on the mono runtime.");
+ "The ThrowOnUnmappableChar, BestFitMapping, SetLastError, " +
+ "and ExactSpelling attributes can only be emitted when running on the mono runtime.");
return null;
}
}
/// For global attributes (assembly, module) we need special handling.
/// Attributes can be located in the several files
/// </summary>
- public class GlobalAttribute: Attribute
+ public class GlobalAttribute : Attribute
{
public readonly NamespaceEntry ns;
public GlobalAttribute (TypeContainer container, string target,
- Expression left_expr, string identifier, ArrayList args, Location loc):
- base (target, left_expr, identifier, args, loc)
+ Expression left_expr, string identifier, ArrayList args, Location loc, bool nameEscaped):
+ base (target, left_expr, identifier, args, loc, nameEscaped)
{
ns = container.NamespaceEntry;
}
// TODO: we can skip the first item
if (((IList) valid_targets).Contains (a.ExplicitTarget)) {
switch (a.ExplicitTarget) {
- case "return": a.Target = AttributeTargets.ReturnValue; continue;
- case "param": a.Target = AttributeTargets.Parameter; continue;
- case "field": a.Target = AttributeTargets.Field; continue;
- case "method": a.Target = AttributeTargets.Method; continue;
- case "property": a.Target = AttributeTargets.Property; continue;
+ case "return": a.Target = AttributeTargets.ReturnValue; continue;
+ case "param": a.Target = AttributeTargets.Parameter; continue;
+ case "field": a.Target = AttributeTargets.Field; continue;
+ case "method": a.Target = AttributeTargets.Method; continue;
+ case "property": a.Target = AttributeTargets.Property; continue;
}
throw new InternalErrorException ("Unknown explicit target: " + a.ExplicitTarget);
}
-
+
StringBuilder sb = new StringBuilder ();
foreach (string s in valid_targets) {
sb.Append (s);
sb.Append (", ");
}
sb.Remove (sb.Length - 2, 2);
- Report.Error (657, a.Location, "`{0}' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are `{1}'", a.ExplicitTarget, sb.ToString ());
+ Report.Error (657, a.Location, "`{0}' is not a valid attribute location for this declaration. " +
+ "Valid attribute locations for this declaration are `{1}'", a.ExplicitTarget, sb.ToString ());
return false;
}
return true;
for (int i = 1; i < modules.Length; ++i) {
Module module = modules [i];
if (!IsClsCompliant (module)) {
- Report.Error (3013, "Added modules must be marked with the CLSCompliant attribute to match the assembly", module.Name);
+ Report.Error (3013, "Added modules must be marked with the CLSCompliant attribute " +
+ "to match the assembly", module.Name);
return;
}
}
}
- /// <summary>
- /// Tests container name for CLS-Compliant name (differing only in case)
- /// </summary>
- public static void VerifyTopLevelNameClsCompliance ()
+ public static Type GetImportedIgnoreCaseClsType (string name)
{
- Hashtable locase_table = new Hashtable ();
-
- // Convert imported type names to lower case and ignore not cls compliant
- foreach (DictionaryEntry de in TypeManager.all_imported_types) {
- Type t = (Type)de.Value;
- if (!AttributeTester.IsClsCompliant (t))
- continue;
-
- locase_table.Add (((string)de.Key).ToLower (System.Globalization.CultureInfo.InvariantCulture), t);
- }
-
- foreach (DictionaryEntry de in RootContext.Tree.AllDecls) {
- if (!(de.Key is MemberName))
- throw new InternalErrorException ("");
- DeclSpace decl = (DeclSpace) de.Value;
- if (!decl.IsClsComplianceRequired (decl))
- continue;
-
- string lcase = decl.Name.ToLower (System.Globalization.CultureInfo.InvariantCulture);
- if (!locase_table.Contains (lcase)) {
- locase_table.Add (lcase, decl);
+ foreach (Assembly a in TypeManager.GetAssemblies ()) {
+ Type t = a.GetType (name, false, true);
+ if (t == null)
continue;
- }
-
- object conflict = locase_table [lcase];
- if (conflict is Type)
- Report.SymbolRelatedToPreviousError ((Type)conflict);
- else
- Report.SymbolRelatedToPreviousError ((MemberCore)conflict);
- Report.Error (3005, decl.Location, "Identifier `{0}' differing only in case is not CLS-compliant", decl.GetSignatureForError ());
+ if (IsClsCompliant (t))
+ return t;
}
+ return null;
}
static bool IsClsCompliant (ICustomAttributeProvider attribute_provider)
type = type.GetGenericTypeDefinition ();
DeclSpace ds = TypeManager.LookupDeclSpace (type);
if (ds != null)
- return ds.IsClsComplianceRequired (ds.Parent);
+ return ds.IsClsComplianceRequired (ds);
if (type.IsGenericParameter)
return true;
if (attribute.Length == 1)
result = (ObsoleteAttribute)attribute [0];
} else {
- result = type_ds.GetObsoleteAttribute (type_ds);
+ result = type_ds.GetObsoleteAttribute ();
}
}
- analyzed_types_obsolete.Add (type, result == null ? FALSE : result);
+ // Cannot use .Add because of corlib bootstrap
+ analyzed_types_obsolete [type] = result == null ? FALSE : result;
return result;
}
if (mb.DeclaringType is TypeBuilder)
return null;
- PropertyInfo pi = PropertyExpr.AccessorTable [mb] as PropertyInfo;
- if (pi != null)
- return GetMemberObsoleteAttribute (pi);
+ if (mb.IsSpecialName) {
+ PropertyInfo pi = PropertyExpr.AccessorTable [mb] as PropertyInfo;
+ if (pi != null) {
+ // FIXME: This is buggy as properties from this assembly are included as well
+ return null;
+ //return GetMemberObsoleteAttribute (pi);
+ }
+ }
return GetMemberObsoleteAttribute (mb);
}
if ((mi.DeclaringType is TypeBuilder) || mi.DeclaringType.IsGenericInstance)
return null;
- ObsoleteAttribute oa = System.Attribute.GetCustomAttribute (mi, TypeManager.obsolete_attribute_type, false) as ObsoleteAttribute;
+ ObsoleteAttribute oa = System.Attribute.GetCustomAttribute (mi, TypeManager.obsolete_attribute_type, false)
+ as ObsoleteAttribute;
analyzed_member_obsolete.Add (mi, oa == null ? FALSE : oa);
return oa;
}
if (mb.Mono_IsInflatedMethod)
return false;
- ConditionalAttribute[] attrs = mb.GetCustomAttributes (TypeManager.conditional_attribute_type, true) as ConditionalAttribute[];
+ ConditionalAttribute[] attrs = mb.GetCustomAttributes (TypeManager.conditional_attribute_type, true)
+ as ConditionalAttribute[];
if (attrs.Length == 0) {
analyzed_method_excluded.Add (mb, FALSE);
return false;