X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fgmcs%2Fattribute.cs;h=edf65832d5f20be31c5379b2c95ac15756e701fe;hb=4a9ecda075e6914d55f4621a87073299b3baa1e3;hp=674cecd13e21db9c100f510b133463aac63fffc0;hpb=690caa82d2e3f2e20bbca4e5cdf170a64173b500;p=mono.git diff --git a/mcs/gmcs/attribute.cs b/mcs/gmcs/attribute.cs index 674cecd13e2..edf65832d5f 100644 --- a/mcs/gmcs/attribute.cs +++ b/mcs/gmcs/attribute.cs @@ -21,6 +21,7 @@ using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using System.Text; +using System.IO; namespace Mono.CSharp { @@ -71,6 +72,7 @@ namespace Mono.CSharp { public readonly string ExplicitTarget; public AttributeTargets Target; + // TODO: remove this member public readonly string Name; public readonly Expression LeftExpr; public readonly string Identifier; @@ -83,7 +85,10 @@ namespace Mono.CSharp { bool resolve_error; + readonly bool nameEscaped; + static AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All); + static Assembly orig_sec_assembly; // non-null if named args present after Resolve () is called PropertyInfo [] prop_info_arr; @@ -94,7 +99,7 @@ namespace Mono.CSharp { 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; @@ -102,18 +107,21 @@ namespace Mono.CSharp { Arguments = args; Location = loc; ExplicitTarget = target; + this.nameEscaped = nameEscaped; } void Error_InvalidNamedArgument (string name) { - Report.Error (617, Location, "Invalid attribute argument: '{0}'. Argument must be fields " + - "fields which are not readonly, static or const; or read-write instance properties.", - 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", + name); } void Error_InvalidNamedAgrumentType (string name) { - Report.Error (655, Location, "'{0}' is not a valid named attribute argument because its type is not valid attribute 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) @@ -140,7 +148,8 @@ namespace Mono.CSharp { /// public void Error_AttributeEmitError (string inner) { - Report.Error (647, Location, "Error emitting '{0}' attribute because '{1}'", Name, inner); + Report.Error (647, Location, "Error during emitting `{0}' attribute. The reason is `{1}'", + TypeManager.CSharpName (Type), inner); } public void Error_InvalidSecurityParent () @@ -148,103 +157,88 @@ namespace Mono.CSharp { Error_AttributeEmitError ("it is attached to invalid parent"); } - void Error_AttributeConstructorMismatch () + protected virtual FullNamedExpression ResolveAsTypeTerminal (Expression expr, EmitContext ec, bool silent) { - Report.Error (-6, Location, - "Could not find a constructor for this argument list."); + return expr.ResolveAsTypeTerminal (ec, silent); } - - protected virtual FullNamedExpression ResolveAsTypeStep (Expression expr, EmitContext ec) + protected virtual FullNamedExpression ResolveAsTypeStep (Expression expr, EmitContext ec, bool silent) { - return expr.ResolveAsTypeStep (ec); + return expr.ResolveAsTypeStep (ec, silent); } - void ResolvePossibleAttributeTypes (EmitContext ec, out Type t1, out Type t2) + Type ResolvePossibleAttributeType (EmitContext ec, string name, bool silent, ref bool is_attr) { - t1 = null; - t2 = null; - - FullNamedExpression n1 = null; - FullNamedExpression n2 = null; - string IdentifierAttribute = Identifier + "Attribute"; + FullNamedExpression fn; if (LeftExpr == null) { - n1 = ResolveAsTypeStep (new SimpleName (Identifier, Location), ec); - - // FIXME: Shouldn't do this for quoted attributes: [@A] - n2 = ResolveAsTypeStep (new SimpleName (IdentifierAttribute, Location), ec); + fn = ResolveAsTypeTerminal (new SimpleName (name, Location), ec, silent); } else { - FullNamedExpression l = ResolveAsTypeStep (LeftExpr, ec); - if (l == null) { - Report.Error (246, Location, "Couldn't find namespace or type '{0}'", LeftExpr); - return; - } - n1 = new MemberAccess (l, Identifier, Location).ResolveNamespaceOrType (ec, true); - - // FIXME: Shouldn't do this for quoted attributes: [X.@A] - n2 = new MemberAccess (l, IdentifierAttribute, Location).ResolveNamespaceOrType (ec, true); + fn = ResolveAsTypeStep (LeftExpr, ec, silent); + if (fn == null) + return null; + fn = new MemberAccess (fn, name, Location).ResolveAsTypeTerminal (ec, silent); } - TypeExpr te1 = n1 == null ? null : n1 as TypeExpr; - TypeExpr te2 = n2 == null ? null : n2 as TypeExpr; + TypeExpr te = fn as TypeExpr; + if (te == null) + return null; - if (te1 != null) - t1 = te1.ResolveType (ec); - if (te2 != null) - t2 = te2.ResolveType (ec); + Type t = te.Type; + if (t.IsSubclassOf (TypeManager.attribute_type)) { + is_attr = true; + } else if (!silent) { + Report.SymbolRelatedToPreviousError (t); + Report.Error (616, Location, "`{0}': is not an attribute class", TypeManager.CSharpName (t)); + } + return t; } /// - /// Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true. - /// - Type CheckAttributeType (EmitContext ec) - { - Type t1, t2; - ResolvePossibleAttributeTypes (ec, out t1, out t2); - - String err0616 = null; - if (t1 != null && ! t1.IsSubclassOf (TypeManager.attribute_type)) { - t1 = null; - err0616 = "'{0}' is not an attribute class"; + /// Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true. + /// + void ResolveAttributeType (EmitContext ec) + { + bool t1_is_attr = false; + Type t1 = ResolvePossibleAttributeType (ec, Identifier, true, ref t1_is_attr); + bool t2_is_attr = false; + 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 ()); + resolve_error = true; + return; } - if (t2 != null && ! t2.IsSubclassOf (TypeManager.attribute_type)) { - t2 = null; - err0616 = (err0616 != null) - ? "Neither '{0}' nor '{0}Attribute' is an attribute class" - : "'{0}Attribute': is not an attribute class"; + if (t1_is_attr) { + Type = t1; + return; } - if (t1 != null && t2 != null) { - Report.Error (1614, Location, "'{0}' is ambiguous; use either '@{0}' or '{0}Attribute'", Name); - return null; + if (t2_is_attr) { + Type = t2; + return; } + + if (t1 == null && t2 == null) + ResolvePossibleAttributeType (ec, Identifier, false, ref t1_is_attr); if (t1 != null) - return t1; + ResolvePossibleAttributeType (ec, Identifier, false, ref t1_is_attr); if (t2 != null) - return t2; - if (err0616 != null) { - Report.Error (616, Location, err0616, Name); - return null; - } - - Report.Error (246, Location, - "Could not find attribute '{0}' (are you missing a using directive or an assembly reference ?)", - Name); - + ResolvePossibleAttributeType (ec, Identifier + "Attribute", false, ref t2_is_attr); resolve_error = true; - return null; } public virtual Type ResolveType (EmitContext ec) { if (Type == null && !resolve_error) - Type = CheckAttributeType (ec); + ResolveAttributeType (ec); return Type; } - string GetFullMemberName (string member) + public string GetSignatureForError () { - return Type.FullName + '.' + member; + return LeftExpr == null ? Identifier : LeftExpr.GetSignatureForError () + "." + Identifier; } // @@ -253,26 +247,14 @@ namespace Mono.CSharp { // 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; @@ -284,6 +266,9 @@ namespace Mono.CSharp { } 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; @@ -293,8 +278,10 @@ namespace Mono.CSharp { 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 || @@ -312,17 +299,21 @@ namespace Mono.CSharp { resolve_error = true; if (Type == null) { - Type = CheckAttributeType (ec); - + ResolveAttributeType (ec); if (Type == null) return null; } if (Type.IsAbstract) { - Report.Error (653, Location, "Cannot apply attribute class '{0}' because it is abstract", Name); + Report.Error (653, Location, "Cannot apply attribute class `{0}' because it is abstract", GetSignatureForError ()); 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) { @@ -332,6 +323,15 @@ namespace Mono.CSharp { } ConstructorInfo ctor = ResolveArguments (ec); + 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; try { @@ -450,13 +450,13 @@ namespace Mono.CSharp { Location); if (member != null) { - Report.Error (122, Location, "'{0}' is inaccessible due to its protection level", GetFullMemberName (member_name)); + Expression.ErrorIsInaccesible (Location, member.GetSignatureForError ()); return null; } } if (member == null){ - Report.Error (117, Location, "Attribute `{0}' does not contain a definition for `{1}'", + Report.Error (117, Location, "`{0}' does not contain a definition for `{1}'", Type, member_name); return null; } @@ -526,8 +526,10 @@ namespace Mono.CSharp { Location); if (mg == null) { - Error_AttributeConstructorMismatch (); - return 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 ( @@ -547,14 +549,16 @@ namespace Mono.CSharp { } 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 @@ -640,49 +644,50 @@ namespace Mono.CSharp { AttributeTargets targets = GetAttributeUsage (null).ValidOn; if ((targets & AttributeTargets.Assembly) != 0) - sb.Append ("'assembly' "); + sb.Append ("assembly, "); - if ((targets & AttributeTargets.Class) != 0) - sb.Append ("'class' "); + if ((targets & AttributeTargets.Module) != 0) + sb.Append ("module, "); - if ((targets & AttributeTargets.Constructor) != 0) - sb.Append ("'constructor' "); + if ((targets & AttributeTargets.Class) != 0) + sb.Append ("class, "); - if ((targets & AttributeTargets.Delegate) != 0) - sb.Append ("'delegate' "); + if ((targets & AttributeTargets.Struct) != 0) + sb.Append ("struct, "); if ((targets & AttributeTargets.Enum) != 0) - sb.Append ("'enum' "); + sb.Append ("enum, "); - if ((targets & AttributeTargets.Event) != 0) - sb.Append ("'event' "); + if ((targets & AttributeTargets.Constructor) != 0) + sb.Append ("constructor, "); - if ((targets & AttributeTargets.Field) != 0) - sb.Append ("'field' "); + if ((targets & AttributeTargets.Method) != 0) + sb.Append ("method, "); - if ((targets & AttributeTargets.Interface) != 0) - sb.Append ("'interface' "); + if ((targets & AttributeTargets.Property) != 0) + sb.Append ("property, indexer, "); - if ((targets & AttributeTargets.Method) != 0) - sb.Append ("'method' "); + if ((targets & AttributeTargets.Field) != 0) + sb.Append ("field, "); - if ((targets & AttributeTargets.Module) != 0) - sb.Append ("'module' "); + if ((targets & AttributeTargets.Event) != 0) + sb.Append ("event, "); + + if ((targets & AttributeTargets.Interface) != 0) + sb.Append ("interface, "); if ((targets & AttributeTargets.Parameter) != 0) - sb.Append ("'parameter' "); + sb.Append ("parameter, "); - if ((targets & AttributeTargets.Property) != 0) - sb.Append ("'property' "); + if ((targets & AttributeTargets.Delegate) != 0) + sb.Append ("delegate, "); if ((targets & AttributeTargets.ReturnValue) != 0) - sb.Append ("'return' "); - - if ((targets & AttributeTargets.Struct) != 0) - sb.Append ("'struct' "); - - return sb.ToString (); + sb.Append ("return, "); + if ((targets & AttributeTargets.GenericParameter) != 0) + sb.Append ("type parameter, "); + return sb.Remove (sb.Length - 2, 2).ToString (); } /// @@ -855,14 +860,35 @@ namespace Mono.CSharp { /// public void ExtractSecurityPermissionSet (ListDictionary permissions) { - if (TypeManager.LookupDeclSpace (Type) != null && RootContext.StdLib) { - Error_AttributeEmitError ("security custom attributes can not be referenced from defining assembly"); - return; + Type orig_assembly_type = null; + + if (TypeManager.LookupDeclSpace (Type) != null) { + if (!RootContext.StdLib) { + orig_assembly_type = Type.GetType (Type.FullName); + } else { + string orig_version_path = Environment.GetEnvironmentVariable ("__SECURITY_BOOTSTRAP_DB"); + if (orig_version_path == null) { + Error_AttributeEmitError ("security custom attributes can not be referenced from defining assembly"); + return; + } + + if (orig_sec_assembly == null) { + string file = Path.Combine (orig_version_path, Driver.OutputFile); + orig_sec_assembly = Assembly.LoadFile (file); + } + + 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"); + return; + } + } } SecurityAttribute sa; - // For all assemblies except corlib we can avoid all hacks - if (RootContext.StdLib) { + // For all non-selfreferencing security attributes we can avoid all hacks + if (orig_assembly_type == null) { sa = (SecurityAttribute) Activator.CreateInstance (Type, pos_values); if (prop_info_arr != null) { @@ -872,15 +898,14 @@ namespace Mono.CSharp { } } } else { - Type temp_type = Type.GetType (Type.FullName); - // HACK: All mscorlib attributes have same ctor syntax - sa = (SecurityAttribute) Activator.CreateInstance (temp_type, new object[] { GetSecurityActionValue () } ); + // HACK: All security attributes have same ctor syntax + sa = (SecurityAttribute) Activator.CreateInstance (orig_assembly_type, new object[] { GetSecurityActionValue () } ); - // All types are from newly created corlib but for invocation with old we need to convert them + // All types are from newly created assembly but for invocation with old one we need to convert them if (prop_info_arr != null) { for (int i = 0; i < prop_info_arr.Length; ++i) { PropertyInfo emited_pi = prop_info_arr [i]; - PropertyInfo pi = temp_type.GetProperty (emited_pi.Name, emited_pi.PropertyType); + PropertyInfo pi = orig_assembly_type.GetProperty (emited_pi.Name, emited_pi.PropertyType); object old_instance = pi.PropertyType.IsEnum ? System.Enum.ToObject (pi.PropertyType, prop_values_arr [i]) : @@ -960,9 +985,18 @@ namespace Mono.CSharp { 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) { @@ -971,12 +1005,12 @@ namespace Mono.CSharp { } 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; @@ -994,7 +1028,8 @@ namespace Mono.CSharp { 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; @@ -1011,7 +1046,7 @@ namespace Mono.CSharp { } case UnmanagedType.SafeArray: return UnmanagedMarshal.DefineSafeArray (array_sub_type); - + case UnmanagedType.ByValArray: FieldMember fm = attr as FieldMember; if (fm == null) { @@ -1019,10 +1054,10 @@ namespace Mono.CSharp { return null; } return UnmanagedMarshal.DefineByValArray ((int) GetFieldValue ("SizeConst")); - + case UnmanagedType.ByValTStr: return UnmanagedMarshal.DefineByValTStr ((int) GetFieldValue ("SizeConst")); - + default: return UnmanagedMarshal.DefineUnmanagedMarshal (UnmanagedType); } @@ -1035,12 +1070,17 @@ namespace Mono.CSharp { 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]; } /// @@ -1054,7 +1094,9 @@ namespace Mono.CSharp { 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.", Name, GetValidTargets ()); + Report.Error (592, Location, "Attribute `{0}' is not valid on this declaration type. " + + "It is valid on `{1}' declarations only", + GetSignatureForError (), GetValidTargets ()); return; } @@ -1072,7 +1114,7 @@ namespace Mono.CSharp { emitted_targets = new ArrayList (); emitted_attr.Add (Type, emitted_targets); } else if (emitted_targets.Contains (Target)) { - Report.Error (579, Location, "Duplicate '" + Name + "' attribute"); + Report.Error (579, Location, "Duplicate `{0}' attribute", GetSignatureForError ()); return; } emitted_targets.Add (Target); @@ -1139,58 +1181,72 @@ namespace Mono.CSharp { string entry_point = name; bool best_fit_mapping = false; bool throw_on_unmappable = false; + bool exact_spelling = false; + bool set_last_error = false; bool best_fit_mapping_set = false; bool throw_on_unmappable_set = false; + bool exact_spelling_set = false; + bool set_last_error_set = false; MethodInfo set_best_fit = null; MethodInfo set_throw_on = null; + MethodInfo set_exact_spelling = null; + MethodInfo set_set_last_error = null; if (field_info_arr != null) { - int char_set_extra = 0; - + 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": - char_set_extra |= 0x01; - break; - case "PreserveSig": - preserve_sig = (bool) field_values_arr [i]; - break; - case "SetLastError": - char_set_extra |= 0x40; - 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 ()); } } - charset |= (CharSet)char_set_extra; } - - if (throw_on_unmappable_set || best_fit_mapping_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); - - if ((set_best_fit == null) || (set_throw_on == null)) { + + 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)) { Report.Error (-1, Location, - "The ThrowOnUnmappableChar and BestFitMapping 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; } } @@ -1207,6 +1263,10 @@ namespace Mono.CSharp { set_throw_on.Invoke (mb, 0, null, new object [] { throw_on_unmappable }, null); if (best_fit_mapping_set) set_best_fit.Invoke (mb, 0, null, new object [] { best_fit_mapping }, null); + if (exact_spelling_set) + set_exact_spelling.Invoke (mb, 0, null, new object [] { exact_spelling }, null); + if (set_last_error_set) + set_set_last_error.Invoke (mb, 0, null, new object [] { set_last_error }, null); return mb; } @@ -1251,13 +1311,13 @@ namespace Mono.CSharp { /// For global attributes (assembly, module) we need special handling. /// Attributes can be located in the several files /// - 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; } @@ -1282,11 +1342,23 @@ namespace Mono.CSharp { RootContext.Tree.Types.NamespaceEntry = null; } - protected override FullNamedExpression ResolveAsTypeStep (Expression expr, EmitContext ec) + protected override FullNamedExpression ResolveAsTypeStep (Expression expr, EmitContext ec, bool silent) { try { Enter (); - return base.ResolveAsTypeStep (expr, ec); + return base.ResolveAsTypeStep (expr, ec, silent); + } + finally { + Leave (); + } + } + + + protected override FullNamedExpression ResolveAsTypeTerminal (Expression expr, EmitContext ec, bool silent) + { + try { + Enter (); + return base.ResolveAsTypeTerminal (expr, ec, silent); } finally { Leave (); @@ -1339,22 +1411,23 @@ namespace Mono.CSharp { // 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; @@ -1493,7 +1566,7 @@ namespace Mono.CSharp { foreach (Parameter arg in fixedParameters) { if (!AttributeTester.IsClsCompliant (arg.ParameterType)) { - Report.Error (3001, loc, "Argument type '{0}' is not CLS-compliant", arg.GetSignatureForError ()); + Report.Error (3001, loc, "Argument type `{0}' is not CLS-compliant", arg.GetSignatureForError ()); return false; } } @@ -1566,49 +1639,24 @@ namespace Mono.CSharp { 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; } } } - /// - /// Tests container name for CLS-Compliant name (differing only in case) - /// - 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) @@ -1626,7 +1674,7 @@ namespace Mono.CSharp { 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; @@ -1664,11 +1712,12 @@ namespace Mono.CSharp { 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; } @@ -1685,9 +1734,14 @@ namespace Mono.CSharp { 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); } @@ -1707,7 +1761,8 @@ namespace Mono.CSharp { 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; } @@ -1718,16 +1773,16 @@ namespace Mono.CSharp { public static void Report_ObsoleteMessage (ObsoleteAttribute oa, string member, Location loc) { if (oa.IsError) { - Report.Error (619, loc, "'{0}' is obsolete: '{1}'", member, oa.Message); + Report.Error (619, loc, "`{0}' is obsolete: `{1}'", member, oa.Message); return; } if (oa.Message == null) { - Report.Warning (612, loc, "'{0}' is obsolete", member); + Report.Warning (612, loc, "`{0}' is obsolete", member); return; } if (RootContext.WarningLevel >= 2) - Report.Warning (618, loc, "'{0}' is obsolete: '{1}'", member, oa.Message); + Report.Warning (618, loc, "`{0}' is obsolete: `{1}'", member, oa.Message); } public static bool IsConditionalMethodExcluded (MethodBase mb) @@ -1739,7 +1794,8 @@ namespace Mono.CSharp { 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;