Merge pull request #3499 from kumpera/fix_logging
[mono.git] / mcs / mcs / generic.cs
index f549432b29ab1330142ff0291f4bf4b8eacda448..b34f2dc1ec56dfbadb8ff468da7940d1f49b3ca4 100644 (file)
@@ -195,9 +195,7 @@ namespace Mono.CSharp {
                                        continue;
 
                                if (obsoleteCheck) {
-                                       ObsoleteAttribute obsolete_attr = t.GetAttributeObsolete ();
-                                       if (obsolete_attr != null)
-                                               AttributeTester.Report_ObsoleteMessage (obsolete_attr, t.GetSignatureForError (), c.Location, context.Module.Compiler.Report);
+                                       t.CheckObsoleteness (context, c.Location);
                                }
 
                                ConstraintChecker.Check (context, t, c.Location);
@@ -651,10 +649,10 @@ namespace Mono.CSharp {
                                var meta_constraints = new List<MetaType> (spec.TypeArguments.Length);
                                foreach (var c in spec.TypeArguments) {
                                        //
-                                       // Inflated type parameters can collide with special constraint types, don't
+                                       // Inflated type parameters can collide with base type constraint, don't
                                        // emit any such type parameter.
                                        //
-                                       if (c.BuiltinType == BuiltinTypeSpec.Type.Object || c.BuiltinType == BuiltinTypeSpec.Type.ValueType)
+                                       if (c.IsClass && spec.BaseType.BuiltinType != BuiltinTypeSpec.Type.Object)
                                                continue;
 
                                        meta_constraints.Add (c.GetMetaInfo ());
@@ -1062,8 +1060,11 @@ namespace Mono.CSharp {
                        return effective_base = Convert.FindMostEncompassedType (types);
                }
 
-               public override string GetSignatureForDocumentation ()
+               public override string GetSignatureForDocumentation (bool explicitName)
                {
+                       if (explicitName)
+                               return Name;
+
                        var prefix = IsMethodOwned ? "``" : "`";
                        return prefix + DeclaredPosition;
                }
@@ -1111,14 +1112,20 @@ namespace Mono.CSharp {
                        //
                        bool found;
                        if (!TypeSpecComparer.Override.IsEqual (BaseType, other.BaseType)) {
-                               if (other.targs == null)
-                                       return false;
-
                                found = false;
-                               foreach (var otarg in other.targs) {
-                                       if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
-                                               found = true;
-                                               break;
+                               if (other.targs != null) {
+                                       foreach (var otarg in other.targs) {
+                                               if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
+                                                       found = true;
+                                                       break;
+                                               }
+                                       }
+                               } else if (targs != null) {
+                                       foreach (var targ in targs) {
+                                               if (TypeSpecComparer.Override.IsEqual (targ, other.BaseType)) {
+                                                       found = true;
+                                                       break;
+                                               }
                                        }
                                }
 
@@ -1131,7 +1138,7 @@ namespace Mono.CSharp {
                                //
                                // Iterate over inflated interfaces
                                //
-                               foreach (var iface in Interfaces) {
+                               foreach (var iface in InterfacesDefined) {
                                        found = false;
                                        if (other.InterfacesDefined != null) {
                                                foreach (var oiface in other.Interfaces) {
@@ -1161,18 +1168,25 @@ namespace Mono.CSharp {
 
                        // Check interfaces implementation <- definition
                        if (other.InterfacesDefined != null) {
-                               if (InterfacesDefined == null)
-                                       return false;
-
                                //
                                // Iterate over inflated interfaces
                                //
-                               foreach (var oiface in other.Interfaces) {
+                               foreach (var oiface in other.InterfacesDefined) {
                                        found = false;
-                                       foreach (var iface in Interfaces) {
-                                               if (TypeSpecComparer.Override.IsEqual (iface, oiface)) {
-                                                       found = true;
-                                                       break;
+
+                                       if (InterfacesDefined != null) {
+                                               foreach (var iface in Interfaces) {
+                                                       if (TypeSpecComparer.Override.IsEqual (iface, oiface)) {
+                                                               found = true;
+                                                               break;
+                                                       }
+                                               }
+                                       } else if (targs != null) {
+                                               foreach (var targ in targs) {
+                                                       if (TypeSpecComparer.Override.IsEqual (targ, oiface)) {
+                                                               found = true;
+                                                               break;
+                                                       }
                                                }
                                        }
 
@@ -1183,18 +1197,30 @@ namespace Mono.CSharp {
 
                        // Check type parameters implementation -> definition
                        if (targs != null) {
-                               if (other.targs == null)
-                                       return false;
-
                                foreach (var targ in targs) {
                                        found = false;
-                                       foreach (var otarg in other.targs) {
-                                               if (TypeSpecComparer.Override.IsEqual (targ, otarg)) {
-                                                       found = true;
-                                                       break;
+
+                                       if (other.targs != null) {
+                                               foreach (var otarg in other.targs) {
+                                                       if (TypeSpecComparer.Override.IsEqual (targ, otarg)) {
+                                                               found = true;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+
+                                       if (other.InterfacesDefined != null && !found) {
+                                               foreach (var iface in other.Interfaces) {
+                                                       if (TypeSpecComparer.Override.IsEqual (iface, targ)) {
+                                                               found = true;
+                                                               break;
+                                                       }
                                                }
                                        }
 
+                                       if (!found)
+                                               found = TypeSpecComparer.Override.IsEqual (targ, other.BaseType);
+
                                        if (!found)
                                                return false;
                                }
@@ -1308,12 +1334,26 @@ namespace Mono.CSharp {
                {
                        cache = new MemberCache ();
 
+                       if (targs != null) {
+                               foreach (var ta in targs) {
+                                       var tps = ta as TypeParameterSpec;
+                                       var b_type = tps == null ? ta : tps.GetEffectiveBase ();
+
+                                       //
+                                       // Find the most specific type when base type was inflated from base constraints
+                                       //
+                                       if (b_type != null && !b_type.IsStructOrEnum && TypeSpec.IsBaseClass (b_type, BaseType, false))
+                                               BaseType = b_type;
+                               }
+                       }
+
                        //
                        // For a type parameter the membercache is the union of the sets of members of the types
                        // specified as a primary constraint or secondary constraint
                        //
-                       if (BaseType.BuiltinType != BuiltinTypeSpec.Type.Object && BaseType.BuiltinType != BuiltinTypeSpec.Type.ValueType)
+                       if (BaseType.BuiltinType != BuiltinTypeSpec.Type.Object && BaseType.BuiltinType != BuiltinTypeSpec.Type.ValueType) {
                                cache.AddBaseType (BaseType);
+                       }
 
                        if (InterfacesDefined != null) {
                                foreach (var iface_type in InterfacesDefined) {
@@ -1321,25 +1361,13 @@ namespace Mono.CSharp {
                                }
                        }
 
+                       //
+                       // Import interfaces after base type to match behavior from ordinary classes
+                       //
                        if (targs != null) {
                                foreach (var ta in targs) {
                                        var tps = ta as TypeParameterSpec;
-                                       IList<TypeSpec> ifaces;
-                                       TypeSpec b_type;
-                                       if (tps != null) {
-                                               b_type = tps.GetEffectiveBase ();
-                                               ifaces = tps.InterfacesDefined;
-                                       } else {
-                                               b_type = ta;
-                                               ifaces = ta.Interfaces;
-                                       }
-
-                                       //
-                                       // Don't add base type which was inflated from base constraints but it's not valid
-                                       // in C# context
-                                       //
-                                       if (b_type != null && b_type.BuiltinType != BuiltinTypeSpec.Type.Object && b_type.BuiltinType != BuiltinTypeSpec.Type.ValueType && !b_type.IsStructOrEnum)
-                                               cache.AddBaseType (b_type);
+                                       var ifaces = tps == null ? ta.Interfaces : tps.InterfacesDefined;
 
                                        if (ifaces != null) {
                                                foreach (var iface_type in ifaces) {
@@ -1523,7 +1551,7 @@ namespace Mono.CSharp {
                                // Parent was inflated, find the same type on inflated type
                                // to use same cache for nested types on same generic parent
                                //
-                               type = MemberCache.FindNestedType (parent, type.Name, type.Arity);
+                               type = MemberCache.FindNestedType (parent, type.Name, type.Arity, false);
 
                                //
                                // Handle the tricky case where parent shares local type arguments
@@ -1912,6 +1940,14 @@ namespace Mono.CSharp {
                        return definition.GetMetaInfo ().MakeGenericType (all.ToArray ());
                }
 
+               public override void CheckObsoleteness (IMemberContext mc, Location loc)
+               {
+                       base.CheckObsoleteness (mc, loc);
+
+                       foreach (var ta in TypeArguments)
+                               ta.CheckObsoleteness (mc, loc);
+               }
+
                public override ObsoleteAttribute GetAttributeObsolete ()
                {
                        return open_type.GetAttributeObsolete ();
@@ -2186,7 +2222,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Resolve the type arguments.
                /// </summary>
-               public virtual bool Resolve (IMemberContext ec)
+               public virtual bool Resolve (IMemberContext ec, bool allowUnbound)
                {
                        if (atypes != null)
                            return true;
@@ -2239,9 +2275,12 @@ namespace Mono.CSharp {
 
        public class UnboundTypeArguments : TypeArguments
        {
-               public UnboundTypeArguments (int arity)
+               Location loc;
+
+               public UnboundTypeArguments (int arity, Location loc)
                        : base (new FullNamedExpression[arity])
                {
+                       this.loc = loc;
                }
 
                public override bool IsEmpty {
@@ -2250,8 +2289,12 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override bool Resolve (IMemberContext ec)
+               public override bool Resolve (IMemberContext mc, bool allowUnbound)
                {
+                       if (!allowUnbound) {
+                               mc.Module.Compiler.Report.Error (7003, loc, "Unbound generic name is not valid in this context");
+                       }
+
                        // Nothing to be resolved
                        return true;
                }
@@ -2437,7 +2480,7 @@ namespace Mono.CSharp {
                        if (eclass != ExprClass.Unresolved)
                                return type;
 
-                       if (!args.Resolve (mc))
+                       if (!args.Resolve (mc, allowUnboundTypeArguments))
                                return null;
 
                        TypeSpec[] atypes = args.Arguments;
@@ -2555,6 +2598,9 @@ namespace Mono.CSharp {
                //
                public bool CheckAll (MemberSpec context, TypeSpec[] targs, TypeParameterSpec[] tparams, Location loc)
                {
+                       if (targs == null)
+                               return true;
+
                        for (int i = 0; i < tparams.Length; i++) {
                                var targ = targs[i];
                                if (!CheckConstraint (context, targ, tparams [i], loc))
@@ -3065,21 +3111,36 @@ namespace Mono.CSharp {
                                return ExactInference (ac_u.Element, ac_v.Element);
                        }
 
-                       // If V is constructed type and U is constructed type
+                       //
+                       // If V is constructed type and U is constructed type or dynamic
+                       //
                        if (TypeManager.IsGenericType (v)) {
-                               if (!TypeManager.IsGenericType (u) || v.MemberDefinition != u.MemberDefinition)
-                                       return 0;
+                               if (u.BuiltinType == BuiltinTypeSpec.Type.Dynamic) {
 
-                               TypeSpec [] ga_u = TypeManager.GetTypeArguments (u);
-                               TypeSpec [] ga_v = TypeManager.GetTypeArguments (v);
-                               if (ga_u.Length != ga_v.Length)
-                                       return 0;
+                                       var ga_v = v.TypeArguments;
+
+                                       int score = 0;
+                                       for (int i = 0; i < ga_v.Length; ++i)
+                                               score += ExactInference (u, ga_v [i]);
+
+                                       return System.Math.Min (1, score);
+
+                               } else {
+                                       if (!TypeManager.IsGenericType (u) || v.MemberDefinition != u.MemberDefinition)
+                                               return 0;
+
+                                       var ga_u = u.TypeArguments;
+                                       var ga_v = v.TypeArguments;
+
+                                       if (u.TypeArguments.Length != u.TypeArguments.Length)
+                                               return 0;
 
-                               int score = 0;
-                               for (int i = 0; i < ga_u.Length; ++i)
-                                       score += ExactInference (ga_u [i], ga_v [i]);
+                                       int score = 0;
+                                       for (int i = 0; i < ga_v.Length; ++i)
+                                               score += ExactInference (ga_u [i], ga_v [i]);
 
-                               return System.Math.Min (1, score);
+                                       return System.Math.Min (1, score);
+                               }
                        }
 
                        // If V is one of the unfixed type arguments
@@ -3209,7 +3270,7 @@ namespace Mono.CSharp {
                                                        continue;
 
                                                if (!applicable[cii])
-                                                       break;
+                                                       continue;
 
                                                //
                                                // For each exact bound U of Xi all types Uj which are not identical
@@ -3226,7 +3287,7 @@ namespace Mono.CSharp {
                                                        continue;
 
                                                if (!applicable[cii])
-                                                       break;
+                                                       continue;
 
                                                //
                                                // For each lower bound U of Xi all types Uj to which there is not an implicit conversion
@@ -3245,7 +3306,7 @@ namespace Mono.CSharp {
                                                        continue;
 
                                                if (!applicable[cii])
-                                                       break;
+                                                       continue;
 
                                                //
                                                // For each upper bound U of Xi all types Uj from which there is not an implicit conversion