X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fattribute.cs;h=64ca04c520fba7cfeca088138ba694c1b1587b05;hb=f131b2a601976ad30bb0633b57cf33ab92aa2ec7;hp=d92bcad184a9d312243555d234ef3ced278dbb71;hpb=cffdf4d1ac645f8eb395036e8f044d6a89fba442;p=mono.git diff --git a/mcs/mcs/attribute.cs b/mcs/mcs/attribute.cs index d92bcad184a..64ca04c520f 100644 --- a/mcs/mcs/attribute.cs +++ b/mcs/mcs/attribute.cs @@ -75,7 +75,8 @@ namespace Mono.CSharp { public abstract string[] ValidAttributeTargets { get; } }; - public class Attribute { + public class Attribute : Expression + { public readonly string ExplicitTarget; public AttributeTargets Target; @@ -85,17 +86,13 @@ namespace Mono.CSharp { public readonly string Identifier; readonly ArrayList PosArguments; - readonly ArrayList NamedArguments; - - public readonly Location Location; - - public Type Type; + 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,7 +118,7 @@ namespace Mono.CSharp { PosArguments = (ArrayList)args [0]; NamedArguments = (ArrayList)args [1]; } - Location = loc; + this.loc = loc; ExplicitTarget = target; this.nameEscaped = nameEscaped; } @@ -137,7 +134,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 +184,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. @@ -283,7 +285,7 @@ namespace Mono.CSharp { return Type; } - public string GetSignatureForError () + public override string GetSignatureForError () { if (Type != null) return TypeManager.CSharpName (Type); @@ -303,6 +305,29 @@ namespace Mono.CSharp { t == TypeManager.type_type; } + [Conditional ("GMCS_SOURCE")] + void ApplyModuleCharSet () + { + if (Type != TypeManager.dllimport_type) + return; + + if (!CodeGen.Module.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), CodeGen.Module.DefaultCharSet, Location)))); + } + public CustomAttributeBuilder Resolve () { if (resolve_error) @@ -335,8 +360,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, owner.ResolveContext.DeclContainer, + Location, null, typeof (Attribute), owner.ResolveContext.DeclContainer.ModFlags, false); ec.IsAnonymousMethodAllowed = false; ConstructorInfo ctor = ResolveConstructor (ec); @@ -349,9 +378,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,21 +423,22 @@ namespace Mono.CSharp { return null; } } - - Expression mg = Expression.MemberLookup (ec.ContainerType, + + MethodGroupExpr mg = MemberLookupFinal (ec, ec.ContainerType, Type, ".ctor", MemberTypes.Constructor, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, - Location); + Location) as MethodGroupExpr; if (mg == null) return null; - MethodBase constructor = Invocation.OverloadResolve ( - ec, (MethodGroupExpr) mg, PosArguments, false, Location); - - if (constructor == null) + mg = mg.OverloadResolve (ec, PosArguments, false, Location); + if (mg == null) return null; + + ConstructorInfo constructor = (ConstructorInfo)mg; + // TODO: move to OverloadResolve ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (constructor); if (oa != null && !Owner.ResolveContext.IsInObsoleteScope) { AttributeTester.Report_ObsoleteMessage (oa, mg.GetSignatureForError (), mg.Location); @@ -411,7 +446,7 @@ namespace Mono.CSharp { if (PosArguments == null) { pos_values = EmptyObject; - return (ConstructorInfo)constructor; + return constructor; } ParameterData pd = TypeManager.GetParameterData (constructor); @@ -634,7 +669,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, "); @@ -686,32 +721,37 @@ 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); if (attr_class == null) { - object[] usage_attr = Type.GetCustomAttributes (TypeManager.attribute_usage_type, true); + object[] usage_attr = type.GetCustomAttributes (TypeManager.attribute_usage_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 (TypeManager.attribute_usage_type); - 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; } @@ -1105,11 +1145,19 @@ namespace Mono.CSharp { return (CharSet)System.Enum.Parse (typeof (CharSet), pos_values [0].ToString ()); } - public MethodImplOptions GetMethodImplOptions () - { - if (pos_values [0].GetType () != typeof (MethodImplOptions)) - return (MethodImplOptions)System.Enum.ToObject (typeof (MethodImplOptions), pos_values [0]); - return (MethodImplOptions)pos_values [0]; + public bool IsInternalMethodImplAttribute { + get { + if (Type != TypeManager.methodimpl_attr_type) + 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 () @@ -1148,7 +1196,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", @@ -1213,121 +1261,6 @@ namespace Mono.CSharp { } } } - - public MethodBuilder DefinePInvokeMethod (TypeBuilder builder, string name, - MethodAttributes flags, IMethodData method, 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, - method.ParameterInfo.CallingConvention, method.ReturnType, 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 () { @@ -1340,16 +1273,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; } @@ -1360,6 +1293,16 @@ namespace Mono.CSharp { return null; return e.TypeArgument; } + + public override Expression DoResolve (EmitContext ec) + { + throw new NotImplementedException (); + } + + public override void Emit (EmitContext ec) + { + throw new NotImplementedException (); + } } @@ -1376,6 +1319,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] = CodeGen.Module; + return; + } + throw new NotImplementedException ("Unknown global explicit target " + ExplicitTarget); } void Enter () @@ -1516,7 +1473,8 @@ 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 ()); } } @@ -1642,8 +1600,10 @@ namespace Mono.CSharp { } bool result; - if (type.IsArray || type.IsByRef) { + if (type.IsArray || type.IsByRef) { result = IsClsCompliant (TypeManager.GetElementType (type)); + } else if (TypeManager.IsNullableType (type)) { + result = IsClsCompliant (TypeManager.GetTypeArguments (type) [0]); } else { result = AnalyzeTypeCompliance (type); } @@ -1664,11 +1624,14 @@ namespace Mono.CSharp { 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) { + if (!fi.IsDefined (TypeManager.fixed_buffer_attr_type, false)) { fixed_buffer_cache.Add (fi, FALSE); return null; } @@ -1841,7 +1804,7 @@ 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; } @@ -1850,10 +1813,6 @@ namespace Mono.CSharp { public static bool IsConditionalMethodExcluded (MethodBase mb) { - 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;