X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=mcs%2Fmcs%2Fattribute.cs;h=cedc83550dfad99b00c4c2214bb68f669d89d689;hb=9d23552efbb02fb4d6410db9fd1ce0a9ca9d08a8;hp=8377e0ccd0f820b485fd7c88def06e62574cb227;hpb=987f8c63e214937c50dcb308149f7558a2cbba41;p=mono.git diff --git a/mcs/mcs/attribute.cs b/mcs/mcs/attribute.cs index 8377e0ccd0f..cedc83550df 100644 --- a/mcs/mcs/attribute.cs +++ b/mcs/mcs/attribute.cs @@ -4,10 +4,10 @@ // Author: Ravi Pratap (ravi@ximian.com) // Marek Safar (marek.safar@seznam.cz) // -// Licensed under the terms of the GNU GPL -// -// (C) 2001 Ximian, Inc (http://www.ximian.com) +// Dual licensed under the terms of the MIT X11 or GNU GPL // +// Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) +// Copyright 2003-2008 Novell, Inc. // using System; @@ -57,7 +57,7 @@ namespace Mono.CSharp { /// /// Use member-specific procedure to apply attribute @a in @cb to the entity being built in @builder /// - public abstract void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb); + public abstract void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa); /// /// Returns one AttributeTarget for this element. @@ -75,7 +75,48 @@ namespace Mono.CSharp { public abstract string[] ValidAttributeTargets { get; } }; - public class Attribute { + public class Attribute : Expression + { + // + // Wraps owner resolve context, the owner is an attribute + // parent and the rest is exactly same + // + struct AttributeResolveContext : IResolveContext + { + readonly IResolveContext rc; + + public AttributeResolveContext (IResolveContext rc) + { + this.rc = rc; + } + + #region IResolveContext Members + + public DeclSpace DeclContainer { + get { + DeclSpace ds = rc as DeclSpace; + if (ds == null) + return rc.DeclContainer; + + return ds; + } + } + + public bool IsInObsoleteScope { + get { return rc.IsInObsoleteScope; } + } + + public bool IsInUnsafeScope { + get { return rc.IsInUnsafeScope; } + } + + public DeclSpace GenericDeclContainer { + get { return rc.GenericDeclContainer; } + } + + #endregion + } + public readonly string ExplicitTarget; public AttributeTargets Target; @@ -84,18 +125,14 @@ namespace Mono.CSharp { public readonly Expression LeftExpr; public readonly string Identifier; - readonly ArrayList PosArguments; - readonly ArrayList NamedArguments; - - public readonly Location Location; - - public Type Type; + ArrayList PosArguments; + ArrayList NamedArguments; bool resolve_error; readonly bool nameEscaped; // It can contain more onwers when the attribute is applied to multiple fiels. - Attributable[] owners; + protected Attributable[] owners; static readonly AttributeUsageAttribute DefaultUsageAttribute = new AttributeUsageAttribute (AttributeTargets.All); static Assembly orig_sec_assembly; @@ -121,11 +158,19 @@ namespace Mono.CSharp { PosArguments = (ArrayList)args [0]; NamedArguments = (ArrayList)args [1]; } - Location = loc; + this.loc = loc; ExplicitTarget = target; this.nameEscaped = nameEscaped; } + public Attribute Clone () + { + Attribute a = new Attribute (ExplicitTarget, LeftExpr, Identifier, null, loc, nameEscaped); + a.PosArguments = PosArguments; + a.NamedArguments = NamedArguments; + return a; + } + static Attribute () { Reset (); @@ -137,7 +182,7 @@ namespace Mono.CSharp { att_cache = new PtrHashtable (); } - public void AttachTo (Attributable owner) + public virtual void AttachTo (Attributable owner) { if (this.owners == null) { this.owners = new Attributable[1] { owner }; @@ -187,6 +232,11 @@ namespace Mono.CSharp { Report.Error (596, Location, "The Guid attribute must be specified with the ComImport attribute"); } + public void Error_MisusedExtensionAttribute () + { + Report.Error (1112, Location, "Do not use `{0}' directly. Use parameter modifier `this' instead", GetSignatureForError ()); + } + /// /// 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. @@ -215,7 +265,7 @@ namespace Mono.CSharp { Type ResolvePossibleAttributeType (string name, bool silent, ref bool is_attr) { - IResolveContext rc = Owner.ResolveContext; + IResolveContext rc = new AttributeResolveContext (Owner.ResolveContext); TypeExpr te; if (LeftExpr == null) { @@ -283,7 +333,7 @@ namespace Mono.CSharp { return Type; } - public string GetSignatureForError () + public override string GetSignatureForError () { if (Type != null) return TypeManager.CSharpName (Type); @@ -291,18 +341,53 @@ namespace Mono.CSharp { return LeftExpr == null ? Identifier : LeftExpr.GetSignatureForError () + "." + Identifier; } - bool IsValidArgumentType (Type t) + public bool HasSecurityAttribute { + get { + PredefinedAttribute pa = PredefinedAttributes.Get.Security; + return pa.IsDefined && TypeManager.IsSubclassOf (type, pa.Type); + } + } + + public bool IsValidSecurityAttribute () + { + return HasSecurityAttribute && IsSecurityActionValid (false); + } + + static bool IsValidArgumentType (Type t) { if (t.IsArray) - t = t.GetElementType (); + t = TypeManager.GetElementType (t); - return TypeManager.IsPrimitiveType (t) || + return t == TypeManager.string_type || + TypeManager.IsPrimitiveType (t) || TypeManager.IsEnumType (t) || - t == TypeManager.string_type || t == TypeManager.object_type || t == TypeManager.type_type; } + [Conditional ("GMCS_SOURCE")] + void ApplyModuleCharSet () + { + if (Type != PredefinedAttributes.Get.DllImport) + return; + + if (!RootContext.ToplevelTypes.HasDefaultCharSet) + return; + + const string CharSetEnumMember = "CharSet"; + if (NamedArguments == null) { + NamedArguments = new ArrayList (1); + } else { + foreach (DictionaryEntry de in NamedArguments) { + if ((string)de.Key == CharSetEnumMember) + return; + } + } + + NamedArguments.Add (new DictionaryEntry (CharSetEnumMember, + new Argument (Constant.CreateConstant (typeof (CharSet), RootContext.ToplevelTypes.DefaultCharSet, Location)))); + } + public CustomAttributeBuilder Resolve () { if (resolve_error) @@ -335,8 +420,12 @@ namespace Mono.CSharp { } Attributable owner = Owner; - EmitContext ec = new EmitContext (owner.ResolveContext, owner.ResolveContext.DeclContainer, owner.ResolveContext.DeclContainer, - Location, null, null, owner.ResolveContext.DeclContainer.ModFlags, false); + DeclSpace ds = owner.ResolveContext as DeclSpace; + if (ds == null) + ds = owner.ResolveContext.DeclContainer; + + EmitContext ec = new EmitContext (owner.ResolveContext, ds, ds, + Location, null, typeof (Attribute), ds.ModFlags, false); ec.IsAnonymousMethodAllowed = false; ConstructorInfo ctor = ResolveConstructor (ec); @@ -349,9 +438,14 @@ namespace Mono.CSharp { return null; } - CustomAttributeBuilder cb; + ApplyModuleCharSet (); + CustomAttributeBuilder cb; try { + // SRE does not allow private ctor but we want to report all source code errors + if (ctor.IsPrivate) + return null; + if (NamedArguments == null) { cb = new CustomAttributeBuilder (ctor, pos_values); @@ -389,80 +483,40 @@ namespace Mono.CSharp { return null; } } - - Expression mg = Expression.MemberLookup (ec.ContainerType, - Type, ".ctor", MemberTypes.Constructor, + + MethodGroupExpr mg = MemberLookupFinal (ec, ec.ContainerType, + Type, ConstructorInfo.ConstructorName, MemberTypes.Constructor, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, - Location); + Location) as MethodGroupExpr; if (mg == null) - return null; + throw new NotImplementedException (); - MethodBase constructor = Invocation.OverloadResolve ( - ec, (MethodGroupExpr) mg, PosArguments, false, Location); - - if (constructor == null) + mg = mg.OverloadResolve (ec, ref PosArguments, false, Location); + if (mg == null) return null; - - ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (constructor); - if (oa != null && !Owner.ResolveContext.IsInObsoleteScope) { - AttributeTester.Report_ObsoleteMessage (oa, mg.GetSignatureForError (), mg.Location); - } - + + ConstructorInfo constructor = (ConstructorInfo)mg; if (PosArguments == null) { pos_values = EmptyObject; - return (ConstructorInfo)constructor; + return constructor; } - ParameterData pd = TypeManager.GetParameterData (constructor); + AParametersCollection pd = TypeManager.GetParameterData (constructor); int pos_arg_count = PosArguments.Count; - int last_real_param = pd.Count; - pos_values = new object [pos_arg_count]; - - if (pd.HasParams) { - // When the params is not filled we need to put one - if (last_real_param > pos_arg_count) { - object [] new_pos_values = new object [pos_arg_count + 1]; - pos_values.CopyTo (new_pos_values, 0); - new_pos_values [pos_arg_count] = new object [] {} ; - pos_values = new_pos_values; - } - last_real_param--; - } - for (int j = 0; j < pos_arg_count; ++j) { Argument a = (Argument) PosArguments [j]; - if (!a.Expr.GetAttributableValue (a.Type, out pos_values [j])) + if (!a.Expr.GetAttributableValue (ec, a.Type, out pos_values [j])) return null; - - if (j < last_real_param) - continue; - - if (j == last_real_param) { - object [] array = new object [pos_arg_count - last_real_param]; - array [0] = pos_values [j]; - pos_values [j] = array; - continue; - } - - object [] params_array = (object []) pos_values [last_real_param]; - params_array [j - last_real_param] = pos_values [j]; - } - - // Adjust the size of the pos_values if it had params - if (last_real_param != pos_arg_count) { - object [] new_pos_values = new object [last_real_param + 1]; - Array.Copy (pos_values, new_pos_values, last_real_param + 1); - pos_values = new_pos_values; } // Here we do the checks which should be done by corlib or by runtime. // However Zoltan doesn't like it and every Mono compiler has to do it again. - - if (Type == TypeManager.guid_attr_type) { + PredefinedAttributes pa = PredefinedAttributes.Get; + if (Type == pa.Guid) { try { new Guid ((string)pos_values [0]); } @@ -472,27 +526,28 @@ namespace Mono.CSharp { } } - if (Type == TypeManager.attribute_usage_type && (int)pos_values [0] == 0) { + if (Type == pa.AttributeUsage && (int)pos_values [0] == 0) { 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])) { + if (Type == pa.IndexerName || Type == pa.Conditional) { + string v = pos_values [0] as string; + if (!Tokenizer.IsValidIdentifier (v) || Tokenizer.IsKeyword (v)) { 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 && + if (Type == pa.MethodImpl && pos_values.Length == 1 && + pd.Types [0] == TypeManager.short_type && !System.Enum.IsDefined (typeof (MethodImplOptions), pos_values [0].ToString ())) { Error_AttributeEmitError ("Incorrect argument value."); return null; } - return (ConstructorInfo)constructor; + return constructor; } protected virtual bool ResolveNamedArguments (EmitContext ec) @@ -510,7 +565,7 @@ namespace Mono.CSharp { string member_name = (string) de.Key; if (seen_names.Contains(member_name)) { - Report.Error(643, Location, "'" + member_name + "' duplicate named attribute argument"); + Report.Error(643, Location, "'{0}' duplicate named attribute argument", member_name); return false; } seen_names.Add(member_name); @@ -538,8 +593,7 @@ namespace Mono.CSharp { } if (member == null){ - Report.Error (117, Location, "`{0}' does not contain a definition for `{1}'", - TypeManager.CSharpName (Type), member_name); + Expression.Error_TypeDoesNotContainDefinition (Location, Type, member_name); return false; } @@ -564,14 +618,14 @@ namespace Mono.CSharp { return false; } - if (!IsValidArgumentType (pi.PropertyType)) { + if (!IsValidArgumentType (member.Type)) { Report.SymbolRelatedToPreviousError (pi); Error_InvalidNamedAgrumentType (member_name); return false; } object value; - if (!a.Expr.GetAttributableValue (pi.PropertyType, out value)) + if (!a.Expr.GetAttributableValue (ec, member.Type, out value)) return false; PropertyBase pb = TypeManager.GetProperty (pi); @@ -591,14 +645,14 @@ namespace Mono.CSharp { return false; } - if (!IsValidArgumentType (fi.FieldType)) { + if (!IsValidArgumentType (member.Type)) { Report.SymbolRelatedToPreviousError (fi); Error_InvalidNamedAgrumentType (member_name); return false; } object value; - if (!a.Expr.GetAttributableValue (fi.FieldType, out value)) + if (!a.Expr.GetAttributableValue (ec, member.Type, out value)) return false; FieldBase fb = TypeManager.GetField (fi); @@ -635,7 +689,7 @@ namespace Mono.CSharp { public string GetValidTargets () { StringBuilder sb = new StringBuilder (); - AttributeTargets targets = GetAttributeUsage ().ValidOn; + AttributeTargets targets = GetAttributeUsage (Type).ValidOn; if ((targets & AttributeTargets.Assembly) != 0) sb.Append ("assembly, "); @@ -687,32 +741,41 @@ namespace Mono.CSharp { } /// - /// Returns AttributeUsage attribute for this type + /// Returns AttributeUsage attribute based on types hierarchy /// - AttributeUsageAttribute GetAttributeUsage () + static AttributeUsageAttribute GetAttributeUsage (Type type) { - AttributeUsageAttribute ua = usage_attr_cache [Type] as AttributeUsageAttribute; + AttributeUsageAttribute ua = usage_attr_cache [type] as AttributeUsageAttribute; if (ua != null) return ua; - Class attr_class = TypeManager.LookupClass (Type); + Class attr_class = TypeManager.LookupClass (type); + PredefinedAttribute pa = PredefinedAttributes.Get.AttributeUsage; if (attr_class == null) { - object[] usage_attr = Type.GetCustomAttributes (TypeManager.attribute_usage_type, true); + if (!pa.IsDefined) + return new AttributeUsageAttribute (0); + + object[] usage_attr = type.GetCustomAttributes (pa.Type, true); ua = (AttributeUsageAttribute)usage_attr [0]; - usage_attr_cache.Add (Type, ua); + usage_attr_cache.Add (type, ua); return ua; } - Attribute a = attr_class.OptAttributes == null - ? null - : attr_class.OptAttributes.Search (TypeManager.attribute_usage_type); + Attribute a = null; + if (attr_class.OptAttributes != null) + a = attr_class.OptAttributes.Search (pa); - ua = a == null - ? DefaultUsageAttribute - : a.GetAttributeUsageAttribute (); + if (a == null) { + if (attr_class.TypeBuilder.BaseType != TypeManager.attribute_type) + ua = GetAttributeUsage (attr_class.TypeBuilder.BaseType); + else + ua = DefaultUsageAttribute; + } else { + ua = a.GetAttributeUsageAttribute (); + } - usage_attr_cache.Add (Type, ua); + usage_attr_cache.Add (type, ua); return ua; } @@ -833,11 +896,11 @@ namespace Mono.CSharp { // TODO: we can skip the first item if (((IList) valid_targets).Contains (ExplicitTarget)) { switch (ExplicitTarget) { - case "return": Target = AttributeTargets.ReturnValue; return true; - case "param": Target = AttributeTargets.Parameter; return true; - case "field": Target = AttributeTargets.Field; return true; - case "method": Target = AttributeTargets.Method; return true; - case "property": Target = AttributeTargets.Property; return true; + case "return": Target = AttributeTargets.ReturnValue; return true; + case "param": Target = AttributeTargets.Parameter; return true; + case "field": Target = AttributeTargets.Field; return true; + case "method": Target = AttributeTargets.Method; return true; + case "property": Target = AttributeTargets.Property; return true; } throw new InternalErrorException ("Unknown explicit target: " + ExplicitTarget); } @@ -856,7 +919,7 @@ namespace Mono.CSharp { /// /// Tests permitted SecurityAction for assembly or other types /// - public bool CheckSecurityActionValidity (bool for_assembly) + protected virtual bool IsSecurityActionValid (bool for_assembly) { SecurityAction action = GetSecurityActionValue (); @@ -943,9 +1006,11 @@ namespace Mono.CSharp { if (prop_info_arr != null) { for (int i = 0; i < prop_info_arr.Length; ++i) { PropertyInfo emited_pi = prop_info_arr [i]; - PropertyInfo pi = orig_assembly_type.GetProperty (emited_pi.Name, emited_pi.PropertyType); + // FIXME: We are missing return type filter + // TODO: pi can be null + PropertyInfo pi = orig_assembly_type.GetProperty (emited_pi.Name); - object old_instance = pi.PropertyType.IsEnum ? + object old_instance = TypeManager.IsEnumType (pi.PropertyType) ? System.Enum.ToObject (pi.PropertyType, prop_values_arr [i]) : prop_values_arr [i]; @@ -961,15 +1026,15 @@ namespace Mono.CSharp { // IS is correct because for corlib we are using an instance from old corlib if (!(perm is System.Security.CodeAccessPermission)) { switch (action) { - case SecurityAction.Demand: - action = (SecurityAction)13; - break; - case SecurityAction.LinkDemand: - action = (SecurityAction)14; - break; - case SecurityAction.InheritanceDemand: - action = (SecurityAction)15; - break; + case SecurityAction.Demand: + action = (SecurityAction)13; + break; + case SecurityAction.LinkDemand: + action = (SecurityAction)14; + break; + case SecurityAction.InheritanceDemand: + action = (SecurityAction)15; + break; } } @@ -988,14 +1053,6 @@ namespace Mono.CSharp { ps.AddPermission (perm); } - static object GetValue (object value) - { - if (value is EnumConstant) - return ((EnumConstant) value).GetValue (); - else - return value; - } - public object GetPropertyValue (string name) { if (prop_info_arr == null) @@ -1009,25 +1066,12 @@ namespace Mono.CSharp { return null; } - object GetFieldValue (string name) - { - int i; - if (field_info_arr == null) - return null; - i = 0; - foreach (FieldInfo fi in field_info_arr) { - if (fi.Name == name) - return GetValue (field_values_arr [i]); - i++; - } - 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. // +#if !NET_2_0 public UnmanagedMarshal GetMarshal (Attributable attr) { UnmanagedType UnmanagedType; @@ -1086,7 +1130,7 @@ namespace Mono.CSharp { return UnmanagedMarshal.DefineSafeArray (array_sub_type); case UnmanagedType.ByValArray: - FieldMember fm = attr as FieldMember; + FieldBase fm = attr as FieldBase; if (fm == null) { Error_AttributeEmitError ("Specified unmanaged type is only valid on fields"); return null; @@ -1101,16 +1145,61 @@ namespace Mono.CSharp { } } + object GetFieldValue (string name) + { + int i; + if (field_info_arr == null) + return null; + i = 0; + foreach (FieldInfo fi in field_info_arr) { + if (fi.Name == name) + return GetValue (field_values_arr [i]); + i++; + } + return null; + } + + static object GetValue (object value) + { + if (value is EnumConstant) + return ((EnumConstant) value).GetValue (); + else + return value; + } + +#endif + public CharSet GetCharSetValue () { return (CharSet)System.Enum.Parse (typeof (CharSet), pos_values [0].ToString ()); } - public MethodImplOptions GetMethodImplOptions () + public bool HasField (string fieldName) { - if (pos_values [0].GetType () != typeof (MethodImplOptions)) - return (MethodImplOptions)System.Enum.ToObject (typeof (MethodImplOptions), pos_values [0]); - return (MethodImplOptions)pos_values [0]; + if (field_info_arr == null) + return false; + + foreach (FieldInfo fi in field_info_arr) { + if (fi.Name == fieldName) + return true; + } + + return false; + } + + public bool IsInternalMethodImplAttribute { + get { + if (Type != PredefinedAttributes.Get.MethodImpl) + return false; + + MethodImplOptions options; + if (pos_values[0].GetType () != typeof (MethodImplOptions)) + options = (MethodImplOptions)System.Enum.ToObject (typeof (MethodImplOptions), pos_values[0]); + else + options = (MethodImplOptions)pos_values[0]; + + return (options & MethodImplOptions.InternalCall) != 0; + } } public LayoutKind GetLayoutKindValue () @@ -1149,7 +1238,7 @@ namespace Mono.CSharp { if (cb == null) return; - AttributeUsageAttribute usage_attr = GetAttributeUsage (); + AttributeUsageAttribute usage_attr = GetAttributeUsage (Type); if ((usage_attr.ValidOn & Target) == 0) { Report.Error (592, Location, "The attribute `{0}' is not valid on this declaration type. " + "It is valid on `{1}' declarations only", @@ -1159,7 +1248,7 @@ namespace Mono.CSharp { try { foreach (Attributable owner in owners) - owner.ApplyAttributeBuilder (this, cb); + owner.ApplyAttributeBuilder (this, cb, PredefinedAttributes.Get); } catch (Exception e) { Error_AttributeEmitError (e.Message); @@ -1191,7 +1280,7 @@ namespace Mono.CSharp { return; if (arg.Type.IsArray) { - Report.Error (3016, Location, "Arrays as attribute arguments are not CLS-compliant"); + Report.Warning (3016, 1, Location, "Arrays as attribute arguments are not CLS-compliant"); return; } } @@ -1208,127 +1297,12 @@ namespace Mono.CSharp { return; if (arg.Type.IsArray) { - Report.Error (3016, Location, "Arrays as attribute arguments are not CLS-compliant"); + Report.Warning (3016, 1, Location, "Arrays as attribute arguments are not CLS-compliant"); return; } } } } - - public MethodBuilder DefinePInvokeMethod (TypeBuilder builder, string name, - MethodAttributes flags, Type ret_type, Type [] param_types) - { - if (pos_values == null) - // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args. - // But because a lot of attribute class code must be rewritten will be better to wait... - Resolve (); - - if (resolve_error) - return null; - - string dll_name = (string)pos_values [0]; - - // Default settings - CallingConvention cc = CallingConvention.Winapi; - CharSet charset = CodeGen.Module.DefaultCharSet; - bool preserve_sig = true; - 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) { - - 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 ()); - } - } - } - - 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, BestFitMapping, SetLastError, " + - "and ExactSpelling attributes can only be emitted when running on the mono runtime."); - return null; - } - } - - try { - MethodBuilder mb = builder.DefinePInvokeMethod ( - name, dll_name, entry_point, flags | MethodAttributes.HideBySig | MethodAttributes.PinvokeImpl, - CallingConventions.Standard, ret_type, param_types, cc, charset); - - if (preserve_sig) - mb.SetImplementationFlags (MethodImplAttributes.PreserveSig); - - if (throw_on_unmappable_set) - 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; - } - catch (ArgumentException e) { - Error_AttributeEmitError (e.Message); - return null; - } - } private Expression GetValue () { @@ -1341,16 +1315,16 @@ namespace Mono.CSharp { public string GetString () { Expression e = GetValue (); - if (e is StringLiteral) - return (e as StringLiteral).Value; + if (e is StringConstant) + return ((StringConstant)e).Value; return null; } public bool GetBoolean () { Expression e = GetValue (); - if (e is BoolLiteral) - return (e as BoolLiteral).Value; + if (e is BoolConstant) + return ((BoolConstant)e).Value; return false; } @@ -1361,6 +1335,21 @@ namespace Mono.CSharp { return null; return e.TypeArgument; } + + public override Expression CreateExpressionTree (EmitContext ec) + { + throw new NotSupportedException ("ET"); + } + + public override Expression DoResolve (EmitContext ec) + { + throw new NotImplementedException (); + } + + public override void Emit (EmitContext ec) + { + throw new NotImplementedException (); + } } @@ -1377,6 +1366,20 @@ namespace Mono.CSharp { base (target, left_expr, identifier, args, loc, nameEscaped) { this.ns = ns; + this.owners = new Attributable[1]; + } + + public override void AttachTo (Attributable owner) + { + if (ExplicitTarget == "assembly") { + owners [0] = CodeGen.Assembly; + return; + } + if (ExplicitTarget == "module") { + owners [0] = RootContext.ToplevelTypes; + return; + } + throw new NotImplementedException ("Unknown global explicit target " + ExplicitTarget); } void Enter () @@ -1394,6 +1397,11 @@ namespace Mono.CSharp { RootContext.ToplevelTypes.NamespaceEntry = ns; } + protected override bool IsSecurityActionValid (bool for_assembly) + { + return base.IsSecurityActionValid (true); + } + void Leave () { RootContext.ToplevelTypes.NamespaceEntry = null; @@ -1458,6 +1466,15 @@ namespace Mono.CSharp { a.AttachTo (attributable); } + public Attributes Clone () + { + ArrayList al = new ArrayList (Attrs.Count); + foreach (Attribute a in Attrs) + al.Add (a.Clone ()); + + return new Attributes (al); + } + /// /// Checks whether attribute target is valid for the current element /// @@ -1470,7 +1487,7 @@ namespace Mono.CSharp { return true; } - public Attribute Search (Type t) + public Attribute Search (PredefinedAttribute t) { foreach (Attribute a in Attrs) { if (a.ResolveType () == t) @@ -1482,7 +1499,7 @@ namespace Mono.CSharp { /// /// Returns all attributes of type 't'. Use it when attribute is AllowMultiple = true /// - public Attribute[] SearchMulti (Type t) + public Attribute[] SearchMulti (PredefinedAttribute t) { ArrayList ar = null; @@ -1517,11 +1534,12 @@ namespace Mono.CSharp { Report.SymbolRelatedToPreviousError (collision.Location, ""); Attribute a = (Attribute)d.Key; - Report.Error (579, a.Location, "The attribute `{0}' cannot be applied multiple times", a.GetSignatureForError ()); + Report.Error (579, a.Location, "The attribute `{0}' cannot be applied multiple times", + a.GetSignatureForError ()); } } - public bool Contains (Type t) + public bool Contains (PredefinedAttribute t) { return Search (t) != null; } @@ -1536,10 +1554,7 @@ namespace Mono.CSharp { static PtrHashtable analyzed_types_obsolete; static PtrHashtable analyzed_member_obsolete; static PtrHashtable analyzed_method_excluded; - -#if NET_2_0 static PtrHashtable fixed_buffer_cache; -#endif static object TRUE = new object (); static object FALSE = new object (); @@ -1559,9 +1574,7 @@ namespace Mono.CSharp { 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 { @@ -1574,8 +1587,10 @@ namespace Mono.CSharp { /// Returns true if parameters of two compared methods are CLS-Compliant. /// It tests differing only in ref or out, or in array rank. /// - public static Result AreOverloadedMethodParamsClsCompliant (Type[] types_a, Type[] types_b) + public static Result AreOverloadedMethodParamsClsCompliant (AParametersCollection pa, AParametersCollection pb) { + Type [] types_a = pa.Types; + Type [] types_b = pb.Types; if (types_a == null || types_b == null) return Result.Ok; @@ -1588,8 +1603,8 @@ namespace Mono.CSharp { Type bType = types_b [i]; if (aType.IsArray && bType.IsArray) { - Type a_el_type = aType.GetElementType (); - Type b_el_type = bType.GetElementType (); + Type a_el_type = TypeManager.GetElementType (aType); + Type b_el_type = TypeManager.GetElementType (bType); if (aType.GetArrayRank () != bType.GetArrayRank () && a_el_type == b_el_type) { result = Result.RefOutArrayError; continue; @@ -1601,25 +1616,11 @@ namespace Mono.CSharp { } } - Type aBaseType = aType; - bool is_either_ref_or_out = false; - - if (aType.IsByRef || aType.IsPointer) { - aBaseType = aType.GetElementType (); - is_either_ref_or_out = true; - } - - Type bBaseType = bType; - if (bType.IsByRef || bType.IsPointer) - { - bBaseType = bType.GetElementType (); - is_either_ref_or_out = !is_either_ref_or_out; - } - - if (aBaseType != bBaseType) + if (aType != bType) return Result.Ok; - if (is_either_ref_or_out) + const Parameter.Modifier out_ref_mod = (Parameter.Modifier.OUTMASK | Parameter.Modifier.REFMASK); + if ((pa.FixedParameters[i].ModFlags & out_ref_mod) != (pb.FixedParameters[i].ModFlags & out_ref_mod)) result = Result.RefOutArrayError; } return result; @@ -1638,13 +1639,15 @@ namespace Mono.CSharp { return type_compliance == TRUE; if (type.IsPointer) { - analyzed_types.Add (type, null); + analyzed_types.Add (type, FALSE); return false; } bool result; - if (type.IsArray || type.IsByRef) { + if (type.IsArray) { result = IsClsCompliant (TypeManager.GetElementType (type)); + } else if (TypeManager.IsNullableType (type)) { + result = IsClsCompliant (TypeManager.GetTypeArguments (type) [0]); } else { result = AnalyzeTypeCompliance (type); } @@ -1657,15 +1660,25 @@ namespace Mono.CSharp { /// public static IFixedBuffer GetFixedBuffer (FieldInfo fi) { + // Fixed buffer helper type is generated as value type + if (TypeManager.IsReferenceType (fi.FieldType)) + return null; + FieldBase fb = TypeManager.GetField (fi); if (fb != null) { return fb as IFixedBuffer; } + + if (TypeManager.GetConstant (fi) != null) + return null; -#if NET_2_0 object o = fixed_buffer_cache [fi]; if (o == null) { - if (System.Attribute.GetCustomAttribute (fi, TypeManager.fixed_buffer_attr_type) == null) { + PredefinedAttribute pa = PredefinedAttributes.Get.FixedBuffer; + if (!pa.IsDefined) + return null; + + if (!fi.IsDefined (pa.Type, false)) { fixed_buffer_cache.Add (fi, FALSE); return null; } @@ -1679,21 +1692,18 @@ namespace Mono.CSharp { return null; return (IFixedBuffer)o; -#else - return null; -#endif } public static void VerifyModulesClsCompliance () { - Module[] modules = RootNamespace.Global.Modules; + Module[] modules = GlobalRootNamespace.Instance.Modules; if (modules == null) return; // The first module is generated assembly for (int i = 1; i < modules.Length; ++i) { Module module = modules [i]; - if (!IsClsCompliant (module)) { + if (!GetClsCompliantAttributeValue (module, null)) { Report.Error (3013, "Added modules must be marked with the CLSCompliant attribute " + "to match the assembly", module.Name); return; @@ -1703,7 +1713,7 @@ namespace Mono.CSharp { public static Type GetImportedIgnoreCaseClsType (string name) { - foreach (Assembly a in RootNamespace.Global.Assemblies) { + foreach (Assembly a in GlobalRootNamespace.Instance.Assemblies) { Type t = a.GetType (name, false, true); if (t == null) continue; @@ -1714,13 +1724,21 @@ namespace Mono.CSharp { return null; } - static bool IsClsCompliant (ICustomAttributeProvider attribute_provider) + static bool GetClsCompliantAttributeValue (ICustomAttributeProvider attribute_provider, Assembly a) { - object[] CompliantAttribute = attribute_provider.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false); - if (CompliantAttribute.Length == 0) + PredefinedAttribute pa = PredefinedAttributes.Get.CLSCompliant; + if (!pa.IsDefined) return false; - return ((CLSCompliantAttribute)CompliantAttribute[0]).IsCompliant; + object[] cls_attr = attribute_provider.GetCustomAttributes (pa.Type, false); + if (cls_attr.Length == 0) { + if (a == null) + return false; + + return GetClsCompliantAttributeValue (a, null); + } + + return ((CLSCompliantAttribute)cls_attr [0]).IsCompliant; } static bool AnalyzeTypeCompliance (Type type) @@ -1734,11 +1752,7 @@ namespace Mono.CSharp { if (TypeManager.IsGenericParameter (type)) return true; - object[] CompliantAttribute = type.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false); - if (CompliantAttribute.Length == 0) - return IsClsCompliant (type.Assembly); - - return ((CLSCompliantAttribute)CompliantAttribute[0]).IsCompliant; + return GetClsCompliantAttributeValue (type, type.Assembly); } /// @@ -1754,22 +1768,25 @@ namespace Mono.CSharp { return (ObsoleteAttribute)type_obsolete; ObsoleteAttribute result = null; - if (type.IsByRef || type.IsArray || type.IsPointer) { + if (TypeManager.HasElementType (type)) { result = GetObsoleteAttribute (TypeManager.GetElementType (type)); - } else if (TypeManager.IsGenericParameter (type) || TypeManager.IsGenericType (type)) - return null; - else { + } else if (TypeManager.IsGenericParameter (type)) + result = null; // TODO: throw new NotSupportedException () + else if (TypeManager.IsGenericType (type) && !TypeManager.IsGenericTypeDefinition (type)) { + return GetObsoleteAttribute (TypeManager.DropGenericTypeArguments (type)); + } else { DeclSpace type_ds = TypeManager.LookupDeclSpace (type); // Type is external, we can get attribute directly if (type_ds == null) { - object[] attribute = type.GetCustomAttributes (TypeManager.obsolete_attribute_type, false); - if (attribute.Length == 1) - result = (ObsoleteAttribute)attribute [0]; + PredefinedAttribute pa = PredefinedAttributes.Get.Obsolete; + if (pa.IsDefined) { + object[] attribute = type.GetCustomAttributes (pa.Type, false); + if (attribute.Length == 1) + result = (ObsoleteAttribute) attribute[0]; + } } else { - // Is null during corlib bootstrap - if (TypeManager.obsolete_attribute_type != null) - result = type_ds.GetObsoleteAttribute (); + result = type_ds.GetObsoleteAttribute (); } } @@ -1791,23 +1808,13 @@ namespace Mono.CSharp { if (mb.DeclaringType is TypeBuilder) return null; - if (mb.IsSpecialName) { - PropertyInfo pi = PropertyExpr.AccessorTable [mb] as PropertyInfo; - if (pi != null) { - if (TypeManager.LookupDeclSpace (pi.DeclaringType) == null) - return GetMemberObsoleteAttribute (pi); + MemberInfo mi = TypeManager.GetPropertyFromAccessor (mb); + if (mi != null) + return GetMemberObsoleteAttribute (mi); - return null; - } - - EventInfo ei = EventExpr.AccessorTable [mb] as EventInfo; - if (ei != null) { - if (TypeManager.LookupDeclSpace (ei.DeclaringType) == null) - return GetMemberObsoleteAttribute (ei); - - return null; - } - } + mi = TypeManager.GetEventFromAccessor (mb); + if (mi != null) + return GetMemberObsoleteAttribute (mi); return GetMemberObsoleteAttribute (mb); } @@ -1827,7 +1834,11 @@ namespace Mono.CSharp { if ((mi.DeclaringType is TypeBuilder) || TypeManager.IsGenericType (mi.DeclaringType)) return null; - ObsoleteAttribute oa = System.Attribute.GetCustomAttribute (mi, TypeManager.obsolete_attribute_type, false) + PredefinedAttribute pa = PredefinedAttributes.Get.Obsolete; + if (!pa.IsDefined) + return null; + + ObsoleteAttribute oa = System.Attribute.GetCustomAttribute (mi, pa.Type, false) as ObsoleteAttribute; analyzed_member_obsolete.Add (mi, oa == null ? FALSE : oa); return oa; @@ -1843,24 +1854,24 @@ namespace Mono.CSharp { return; } - if (oa.Message == null) { + if (oa.Message == null || oa.Message.Length == 0) { Report.Warning (612, 1, loc, "`{0}' is obsolete", member); return; } Report.Warning (618, 2, loc, "`{0}' is obsolete: `{1}'", member, oa.Message); } - public static bool IsConditionalMethodExcluded (MethodBase mb) + public static bool IsConditionalMethodExcluded (MethodBase mb, Location loc) { - mb = TypeManager.DropGenericMethodArguments (mb); - if ((mb is MethodBuilder) || (mb is ConstructorBuilder)) - return false; - object excluded = analyzed_method_excluded [mb]; if (excluded != null) return excluded == TRUE ? true : false; - ConditionalAttribute[] attrs = mb.GetCustomAttributes (TypeManager.conditional_attribute_type, true) + PredefinedAttribute pa = PredefinedAttributes.Get.Conditional; + if (!pa.IsDefined) + return false; + + ConditionalAttribute[] attrs = mb.GetCustomAttributes (pa.Type, true) as ConditionalAttribute[]; if (attrs.Length == 0) { analyzed_method_excluded.Add (mb, FALSE); @@ -1868,11 +1879,12 @@ namespace Mono.CSharp { } foreach (ConditionalAttribute a in attrs) { - if (RootContext.AllDefines.Contains (a.ConditionString)) { + if (loc.CompilationUnit.IsConditionalDefined (a.ConditionString)) { analyzed_method_excluded.Add (mb, FALSE); return false; } } + analyzed_method_excluded.Add (mb, TRUE); return true; } @@ -1881,7 +1893,7 @@ namespace Mono.CSharp { /// Analyzes class whether it has attribute which has ConditionalAttribute /// and its condition is not defined. /// - public static bool IsAttributeExcluded (Type type) + public static bool IsAttributeExcluded (Type type, Location loc) { if (!type.IsClass) return false; @@ -1890,10 +1902,11 @@ namespace Mono.CSharp { // TODO: add caching // TODO: merge all Type bases attribute caching to one cache to save memory - if (class_decl == null) { - object[] attributes = type.GetCustomAttributes (TypeManager.conditional_attribute_type, false); + PredefinedAttribute pa = PredefinedAttributes.Get.Conditional; + if (class_decl == null && pa.IsDefined) { + object[] attributes = type.GetCustomAttributes (pa.Type, false); foreach (ConditionalAttribute ca in attributes) { - if (RootContext.AllDefines.Contains (ca.ConditionString)) + if (loc.CompilationUnit.IsConditionalDefined (ca.ConditionString)) return false; } return attributes.Length > 0; @@ -1905,8 +1918,12 @@ namespace Mono.CSharp { public static Type GetCoClassAttribute (Type type) { TypeContainer tc = TypeManager.LookupInterface (type); + PredefinedAttribute pa = PredefinedAttributes.Get.CoClass; if (tc == null) { - object[] o = type.GetCustomAttributes (TypeManager.coclass_attr_type, false); + if (!pa.IsDefined) + return null; + + object[] o = type.GetCustomAttributes (pa.Type, false); if (o.Length < 1) return null; return ((System.Runtime.InteropServices.CoClassAttribute)o[0]).CoClass; @@ -1915,11 +1932,243 @@ namespace Mono.CSharp { if (tc.OptAttributes == null) return null; - Attribute a = tc.OptAttributes.Search (TypeManager.coclass_attr_type); + Attribute a = tc.OptAttributes.Search (pa); if (a == null) return null; return a.GetCoClassAttributeValue (); } } + + public class PredefinedAttributes + { + // Core types + public readonly PredefinedAttribute ParamArray; + public readonly PredefinedAttribute Out; + + // Optional types + public readonly PredefinedAttribute Obsolete; + public readonly PredefinedAttribute DllImport; + public readonly PredefinedAttribute MethodImpl; + public readonly PredefinedAttribute MarshalAs; + public readonly PredefinedAttribute In; + public readonly PredefinedAttribute IndexerName; + public readonly PredefinedAttribute Conditional; + public readonly PredefinedAttribute CLSCompliant; + public readonly PredefinedAttribute Security; + public readonly PredefinedAttribute Required; + public readonly PredefinedAttribute Guid; + public readonly PredefinedAttribute AssemblyCulture; + public readonly PredefinedAttribute AssemblyVersion; + public readonly PredefinedAttribute ComImport; + public readonly PredefinedAttribute CoClass; + public readonly PredefinedAttribute AttributeUsage; + public readonly PredefinedAttribute DefaultParameterValue; + + // New in .NET 2.0 + public readonly PredefinedAttribute DefaultCharset; + public readonly PredefinedAttribute TypeForwarder; + public readonly PredefinedAttribute FixedBuffer; + public readonly PredefinedAttribute CompilerGenerated; + public readonly PredefinedAttribute InternalsVisibleTo; + public readonly PredefinedAttribute RuntimeCompatibility; + public readonly PredefinedAttribute DebuggerHidden; + public readonly PredefinedAttribute UnsafeValueType; + + // New in .NET 3.5 + public readonly PredefinedAttribute Extension; + + // + // Optional types which are used as types and for member lookup + // + public readonly PredefinedAttribute DefaultMember; + public readonly PredefinedAttribute DecimalConstant; + public readonly PredefinedAttribute StructLayout; + public readonly PredefinedAttribute FieldOffset; + + public static PredefinedAttributes Get = new PredefinedAttributes (); + + private PredefinedAttributes () + { + ParamArray = new PredefinedAttribute ("System", "ParamArrayAttribute"); + Out = new PredefinedAttribute ("System.Runtime.InteropServices", "OutAttribute"); + + Obsolete = new PredefinedAttribute ("System", "ObsoleteAttribute"); + DllImport = new PredefinedAttribute ("System.Runtime.InteropServices", "DllImportAttribute"); + MethodImpl = new PredefinedAttribute ("System.Runtime.CompilerServices", "MethodImplAttribute"); + MarshalAs = new PredefinedAttribute ("System.Runtime.InteropServices", "MarshalAsAttribute"); + In = new PredefinedAttribute ("System.Runtime.InteropServices", "InAttribute"); + IndexerName = new PredefinedAttribute ("System.Runtime.CompilerServices", "IndexerNameAttribute"); + Conditional = new PredefinedAttribute ("System.Diagnostics", "ConditionalAttribute"); + CLSCompliant = new PredefinedAttribute ("System", "CLSCompliantAttribute"); + Security = new PredefinedAttribute ("System.Security.Permissions", "SecurityAttribute"); + Required = new PredefinedAttribute ("System.Runtime.CompilerServices", "RequiredAttributeAttribute"); + Guid = new PredefinedAttribute ("System.Runtime.InteropServices", "GuidAttribute"); + AssemblyCulture = new PredefinedAttribute ("System.Reflection", "AssemblyCultureAttribute"); + AssemblyVersion = new PredefinedAttribute ("System.Reflection", "AssemblyVersionAttribute"); + ComImport = new PredefinedAttribute ("System.Runtime.InteropServices", "ComImportAttribute"); + CoClass = new PredefinedAttribute ("System.Runtime.InteropServices", "CoClassAttribute"); + AttributeUsage = new PredefinedAttribute ("System", "AttributeUsageAttribute"); + DefaultParameterValue = new PredefinedAttribute ("System.Runtime.InteropServices", "DefaultParameterValueAttribute"); + + DefaultCharset = new PredefinedAttribute ("System.Runtime.InteropServices", "DefaultCharSetAttribute"); + TypeForwarder = new PredefinedAttribute ("System.Runtime.CompilerServices", "TypeForwardedToAttribute"); + FixedBuffer = new PredefinedAttribute ("System.Runtime.CompilerServices", "FixedBufferAttribute"); + CompilerGenerated = new PredefinedAttribute ("System.Runtime.CompilerServices", "CompilerGeneratedAttribute"); + InternalsVisibleTo = new PredefinedAttribute ("System.Runtime.CompilerServices", "InternalsVisibleToAttribute"); + RuntimeCompatibility = new PredefinedAttribute ("System.Runtime.CompilerServices", "RuntimeCompatibilityAttribute"); + DebuggerHidden = new PredefinedAttribute ("System.Diagnostics", "DebuggerHiddenAttribute"); + UnsafeValueType = new PredefinedAttribute ("System.Runtime.CompilerServices", "UnsafeValueTypeAttribute"); + + Extension = new PredefinedAttribute ("System.Runtime.CompilerServices", "ExtensionAttribute"); + + DefaultMember = new PredefinedAttribute ("System.Reflection", "DefaultMemberAttribute"); + DecimalConstant = new PredefinedAttribute ("System.Runtime.CompilerServices", "DecimalConstantAttribute"); + StructLayout = new PredefinedAttribute ("System.Runtime.InteropServices", "StructLayoutAttribute"); + FieldOffset = new PredefinedAttribute ("System.Runtime.InteropServices", "FieldOffsetAttribute"); + } + + public void Initialize () + { + foreach (FieldInfo fi in GetType ().GetFields (BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { + ((PredefinedAttribute) fi.GetValue (this)).Resolve (true); + } + } + + public static void Reset () + { + Get = new PredefinedAttributes (); + } + } + + public class PredefinedAttribute + { + Type type; + CustomAttributeBuilder cab; + ConstructorInfo ctor; + readonly string ns, name; + + public PredefinedAttribute (string ns, string name) + { + this.ns = ns; + this.name = name; + } + + public static bool operator == (Type type, PredefinedAttribute pa) + { + return type == pa.type; + } + + public static bool operator != (Type type, PredefinedAttribute pa) + { + return type != pa.type; + } + + public ConstructorInfo Constructor { + get { return ctor; } + } + + public override int GetHashCode () + { + return base.GetHashCode (); + } + + public override bool Equals (object obj) + { + throw new NotSupportedException (); + } + + public void EmitAttribute (ConstructorBuilder builder) + { + if (ResolveBuilder ()) + builder.SetCustomAttribute (cab); + } + + public void EmitAttribute (MethodBuilder builder) + { + if (ResolveBuilder ()) + builder.SetCustomAttribute (cab); + } + + public void EmitAttribute (FieldBuilder builder) + { + if (ResolveBuilder ()) + builder.SetCustomAttribute (cab); + } + + public void EmitAttribute (TypeBuilder builder) + { + if (ResolveBuilder ()) + builder.SetCustomAttribute (cab); + } + + public void EmitAttribute (AssemblyBuilder builder) + { + if (ResolveBuilder ()) + builder.SetCustomAttribute (cab); + } + + public void EmitAttribute (ParameterBuilder builder, Location loc) + { + if (ResolveBuilder ()) + builder.SetCustomAttribute (cab); + } + + public bool IsDefined { + get { return type != null && type != typeof (PredefinedAttribute); } + } + + public bool Resolve (bool canFail) + { + if (type != null) { + if (IsDefined) + return true; + if (canFail) + return false; + } + + type = TypeManager.CoreLookupType (ns, name, Kind.Class, !canFail); + if (type == null) { + type = typeof (PredefinedAttribute); + return false; + } + + return true; + } + + bool ResolveBuilder () + { + if (cab != null) + return true; + + // + // Handle all parameter-less attributes as optional + // + if (!Resolve (true)) + return false; + + ConstructorInfo ci = TypeManager.GetPredefinedConstructor (type, Location.Null, Type.EmptyTypes); + if (ci == null) + return false; + + cab = new CustomAttributeBuilder (ci, new object[0]); + return true; + } + + public bool ResolveConstructor (Location loc, params Type[] argType) + { + if (ctor != null) + throw new InternalErrorException ("Predefined ctor redefined"); + + if (!Resolve (false)) + return false; + + ctor = TypeManager.GetPredefinedConstructor (type, loc, argType); + return ctor != null; + } + + public Type Type { + get { return type; } + } + } }