Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / mcs / attribute.cs
index 47996afaaaa961b0a6089f3f86153edfc9c2c3b5..4fbc993a55a882591eb2192cfbe79fa163027afe 100644 (file)
@@ -144,6 +144,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool ResolveError {
+                       get {
+                               return resolve_error;
+                       }
+               }
+
                public ATypeNameExpression TypeExpression {
                        get {
                                return expression;
@@ -276,10 +282,10 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
                /// </summary>
-               void ResolveAttributeType ()
+               void ResolveAttributeType (bool comparisonOnly)
                {
                        SessionReportPrinter resolve_printer = new SessionReportPrinter ();
-                       ReportPrinter prev_recorder = context.Module.Compiler.Report.SetPrinter (resolve_printer);
+                       ReportPrinter prev_recorder = Report.SetPrinter (resolve_printer);
 
                        bool t1_is_attr = false;
                        bool t2_is_attr = false;
@@ -311,9 +317,12 @@ namespace Mono.CSharp {
                        }
 
                        if (t1_is_attr && t2_is_attr && t1 != t2) {
-                               Report.Error (1614, Location, "`{0}' is ambiguous between `{1}' and `{2}'. Use either `@{0}' or `{0}Attribute'",
-                                       GetSignatureForError (), expression.GetSignatureForError (), expanded.GetSignatureForError ());
-                               resolve_error = true;
+                               if (!comparisonOnly) {
+                                       Report.Error (1614, Location, "`{0}' is ambiguous between `{1}' and `{2}'. Use either `@{0}' or `{0}Attribute'",
+                                               GetSignatureForError (), expression.GetSignatureForError (), expanded.GetSignatureForError ());
+                                       resolve_error = true;
+                               }
+
                                return;
                        }
 
@@ -327,6 +336,9 @@ namespace Mono.CSharp {
                                return;
                        }
 
+                       if (comparisonOnly)
+                               return;
+
                        resolve_error = true;
 
                        if (t1 != null) {
@@ -346,10 +358,10 @@ namespace Mono.CSharp {
                        resolve_printer.Merge (prev_recorder);
                }
 
-               public TypeSpec ResolveType ()
+               public TypeSpec ResolveTypeForComparison ()
                {
                        if (Type == null && !resolve_error)
-                               ResolveAttributeType ();
+                               ResolveAttributeType (true);
                        return Type;
                }
 
@@ -425,7 +437,7 @@ namespace Mono.CSharp {
                        arg_resolved = true;
 
                        if (Type == null) {
-                               ResolveAttributeType ();
+                               ResolveAttributeType (false);
                                if (Type == null)
                                        return null;
                        }
@@ -897,6 +909,11 @@ namespace Mono.CSharp {
                // Returns true for MethodImplAttribute with MethodImplOptions.InternalCall value
                // 
                public bool IsInternalCall ()
+               {
+                       return (GetMethodImplOptions () & MethodImplOptions.InternalCall) != 0;
+               }
+
+               public MethodImplOptions GetMethodImplOptions ()
                {
                        MethodImplOptions options = 0;
                        if (pos_args.Count == 1) {
@@ -906,7 +923,7 @@ namespace Mono.CSharp {
                                options = (MethodImplOptions) System.Enum.Parse (typeof (MethodImplOptions), named.GetValue ().ToString ());
                        }
 
-                       return (options & MethodImplOptions.InternalCall) != 0;
+                       return options;
                }
 
                //
@@ -1006,7 +1023,7 @@ namespace Mono.CSharp {
                                                                if (pos_args.Count == 1 && pos_args[0].Expr is Constant) {
                                                                        var value = ((Constant) pos_args[0].Expr).GetValue () as string;
                                                                        if (string.IsNullOrEmpty (value))
-                                                                               Error_AttributeEmitError ("DllName cannot be empty");
+                                                                               Error_AttributeEmitError ("DllName cannot be empty or null");
                                                                }
                                                        } else if (Type == predefined.MethodImpl && pt.BuiltinType == BuiltinTypeSpec.Type.Short &&
                                                                !System.Enum.IsDefined (typeof (MethodImplOptions), ((Constant) arg_expr).GetValue ().ToString ())) {
@@ -1188,6 +1205,16 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool HasResolveError()
+               {
+                       foreach (var a in Attrs) {
+                               if (a.ResolveError)
+                                       return true;
+                       }
+
+                       return false;
+               }
+
                public Attribute Search (PredefinedAttribute t)
                {
                        return Search (null, t);
@@ -1199,7 +1226,7 @@ namespace Mono.CSharp {
                                if (explicitTarget != null && a.ExplicitTarget != explicitTarget)
                                        continue;
 
-                               if (a.ResolveType () == t)
+                               if (a.ResolveTypeForComparison () == t)
                                        return a;
                        }
                        return null;
@@ -1213,7 +1240,7 @@ namespace Mono.CSharp {
                        List<Attribute> ar = null;
 
                        foreach (Attribute a in Attrs) {
-                               if (a.ResolveType () == t) {
+                               if (a.ResolveTypeForComparison () == t) {
                                        if (ar == null)
                                                ar = new List<Attribute> (Attrs.Count);
                                        ar.Add (a);
@@ -1452,6 +1479,12 @@ namespace Mono.CSharp {
                        Encode (type.MemberDefinition.IsImported ? old_type.AssemblyQualifiedName : old_type.FullName);
                }
 
+               public void EncodeTypeName (TypeContainer type)
+               {
+                       Encode (type.GetSignatureForMetadata ());
+               }
+
+
                //
                // Encodes single property named argument per call
                //
@@ -1538,56 +1571,6 @@ namespace Mono.CSharp {
        /// </summary>
        static class AttributeTester
        {
-               public enum Result {
-                       Ok,
-                       RefOutArrayError,
-                       ArrayArrayError
-               }
-
-               /// <summary>
-               /// Returns true if parameters of two compared methods are CLS-Compliant.
-               /// It tests differing only in ref or out, or in array rank.
-               /// </summary>
-               public static Result AreOverloadedMethodParamsClsCompliant (AParametersCollection pa, AParametersCollection pb) 
-               {
-                       TypeSpec [] types_a = pa.Types;
-                       TypeSpec [] types_b = pb.Types;
-                       if (types_a == null || types_b == null)
-                               return Result.Ok;
-
-                       if (types_a.Length != types_b.Length)
-                               return Result.Ok;
-
-                       Result result = Result.Ok;
-                       for (int i = 0; i < types_b.Length; ++i) {
-                               TypeSpec aType = types_a [i];
-                               TypeSpec bType = types_b [i];
-
-                               var ac_a = aType as ArrayContainer;
-                               var ac_b = aType as ArrayContainer;
-
-                               if (ac_a != null && ac_b != null) {
-                                       if (ac_a.Rank != ac_b.Rank && ac_a.Element == ac_b.Element) {
-                                               result = Result.RefOutArrayError;
-                                               continue;
-                                       }
-
-                                       if (ac_a.Element.IsArray || ac_b.Element.IsArray) {
-                                               result = Result.ArrayArrayError;
-                                               continue;
-                                       }
-                               }
-
-                               if (aType != bType)
-                                       return Result.Ok;
-
-                               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;
-               }
-
                /// <summary>
                /// Common method for Obsolete error/warning reporting.
                /// </summary>
@@ -1647,6 +1630,7 @@ namespace Mono.CSharp {
                public readonly PredefinedAttribute DebuggerHidden;
                public readonly PredefinedAttribute UnsafeValueType;
                public readonly PredefinedAttribute UnmanagedFunctionPointer;
+               public readonly PredefinedDebuggerBrowsableAttribute DebuggerBrowsable;
 
                // New in .NET 3.5
                public readonly PredefinedAttribute Extension;
@@ -1654,6 +1638,10 @@ namespace Mono.CSharp {
                // New in .NET 4.0
                public readonly PredefinedDynamicAttribute Dynamic;
 
+               // New in .NET 4.5
+               public readonly PredefinedStateMachineAttribute AsyncStateMachine;
+               public readonly PredefinedStateMachineAttribute IteratorStateMachine;
+
                //
                // Optional types which are used as types and for member lookup
                //
@@ -1661,6 +1649,9 @@ namespace Mono.CSharp {
                public readonly PredefinedDecimalAttribute DecimalConstant;
                public readonly PredefinedAttribute StructLayout;
                public readonly PredefinedAttribute FieldOffset;
+               public readonly PredefinedAttribute CallerMemberNameAttribute;
+               public readonly PredefinedAttribute CallerLineNumberAttribute;
+               public readonly PredefinedAttribute CallerFilePathAttribute;
 
                public PredefinedAttributes (ModuleContainer module)
                {
@@ -1701,6 +1692,7 @@ namespace Mono.CSharp {
                        DebuggerHidden = new PredefinedAttribute (module, "System.Diagnostics", "DebuggerHiddenAttribute");
                        UnsafeValueType = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "UnsafeValueTypeAttribute");
                        UnmanagedFunctionPointer = new PredefinedAttribute (module, "System.Runtime.InteropServices", "UnmanagedFunctionPointerAttribute");
+                       DebuggerBrowsable = new PredefinedDebuggerBrowsableAttribute (module, "System.Diagnostics", "DebuggerBrowsableAttribute");
 
                        Extension = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "ExtensionAttribute");
 
@@ -1711,6 +1703,15 @@ namespace Mono.CSharp {
                        StructLayout = new PredefinedAttribute (module, "System.Runtime.InteropServices", "StructLayoutAttribute");
                        FieldOffset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "FieldOffsetAttribute");
 
+                       AsyncStateMachine = new PredefinedStateMachineAttribute (module, "System.Runtime.CompilerServices", "AsyncStateMachineAttribute");
+                       IteratorStateMachine = new PredefinedStateMachineAttribute (module, "System.Runtime.CompilerServices", "IteratorStateMachineAttribute") {
+                               IsIterator = true
+                       };
+
+                       CallerMemberNameAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerMemberNameAttribute");
+                       CallerLineNumberAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerLineNumberAttribute");
+                       CallerFilePathAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerFilePathAttribute");
+
                        // TODO: Should define only attributes which are used for comparison
                        const System.Reflection.BindingFlags all_fields = System.Reflection.BindingFlags.Public |
                                System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly;
@@ -1784,22 +1785,12 @@ namespace Mono.CSharp {
                                builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
                }
 
-               public void EmitAttribute (FieldBuilder builder, AttributeEncoder argsEncoded)
-               {
-                       builder.SetCustomAttribute (GetCtorMetaInfo (), argsEncoded.ToArray ());
-               }
-
                public void EmitAttribute (TypeBuilder builder)
                {
                        if (ResolveBuilder ())
                                builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
                }
 
-               public void EmitAttribute (TypeBuilder builder, AttributeEncoder argsEncoded)
-               {
-                       builder.SetCustomAttribute (GetCtorMetaInfo (), argsEncoded.ToArray ());
-               }
-
                public void EmitAttribute (AssemblyBuilder builder)
                {
                        if (ResolveBuilder ())
@@ -1818,11 +1809,6 @@ namespace Mono.CSharp {
                                builder.SetCustomAttribute (GetCtorMetaInfo (), AttributeEncoder.Empty);
                }
 
-               public void EmitAttribute (ParameterBuilder builder, AttributeEncoder argsEncoded)
-               {
-                       builder.SetCustomAttribute (GetCtorMetaInfo (), argsEncoded.ToArray ());
-               }
-
                ConstructorInfo GetCtorMetaInfo ()
                {
                        return (ConstructorInfo) ctor.GetMetaInfo ();
@@ -1844,6 +1830,27 @@ namespace Mono.CSharp {
                }
        }
 
+       public class PredefinedDebuggerBrowsableAttribute : PredefinedAttribute
+       {
+               public PredefinedDebuggerBrowsableAttribute (ModuleContainer module, string ns, string name)
+                       : base (module, ns, name)
+               {
+               }
+
+               public void EmitAttribute (FieldBuilder builder, System.Diagnostics.DebuggerBrowsableState state)
+               {
+                       var ctor = module.PredefinedMembers.DebuggerBrowsableAttributeCtor.Get ();
+                       if (ctor == null)
+                               return;
+
+                       AttributeEncoder encoder = new AttributeEncoder ();
+                       encoder.Encode ((int) state);
+                       encoder.EncodeEmptyNamedArguments ();
+
+                       builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
+               }
+       }
+
        public class PredefinedDecimalAttribute : PredefinedAttribute
        {
                public PredefinedDecimalAttribute (ModuleContainer module, string ns, string name)
@@ -1888,6 +1895,34 @@ namespace Mono.CSharp {
                }
        }
 
+       public class PredefinedStateMachineAttribute : PredefinedAttribute
+       {
+               public PredefinedStateMachineAttribute (ModuleContainer module, string ns, string name)
+                       : base (module, ns, name)
+               {
+               }
+
+               public bool IsIterator { get; set; }
+
+               public void EmitAttribute (MethodBuilder builder, StateMachine type)
+               {
+                       var predefined_ctor = IsIterator ?
+                               module.PredefinedMembers.IteratorStateMachineAttributeCtor :
+                               module.PredefinedMembers.AsyncStateMachineAttributeCtor;
+
+                       var ctor = predefined_ctor.Get ();
+
+                       if (ctor == null)
+                               return;
+
+                       AttributeEncoder encoder = new AttributeEncoder ();
+                       encoder.EncodeTypeName (type);
+                       encoder.EncodeEmptyNamedArguments ();
+
+                       builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
+               }
+       }
+
        public class PredefinedDynamicAttribute : PredefinedAttribute
        {
                MethodSpec tctor;