[mcs] Avoid agressive generic members inflation from using static. Fixes #43400
authorMarek Safar <masafa@microsoft.com>
Tue, 16 Aug 2016 11:57:23 +0000 (13:57 +0200)
committerMarek Safar <marek.safar@gmail.com>
Tue, 16 Aug 2016 12:01:03 +0000 (14:01 +0200)
mcs/mcs/class.cs
mcs/mcs/doc.cs
mcs/mcs/ecore.cs
mcs/mcs/expression.cs
mcs/mcs/generic.cs
mcs/mcs/import.cs
mcs/mcs/membercache.cs
mcs/mcs/namespace.cs
mcs/tests/test-static-using-12.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml

index 96ac0c8db4c24aacc9f18f573adfff3d885d54da..37039f81ef460cb3d6cae1f631522ea664e5c1c8 100644 (file)
@@ -2500,7 +2500,7 @@ namespace Mono.CSharp
                        //      return null;
 
                        var container = PartialContainer.CurrentType;
-                       return MemberCache.FindNestedType (container, name, arity);
+                       return MemberCache.FindNestedType (container, name, arity, false);
                }
 
                public void Mark_HasEquals ()
index 296faded937ff51c83192f1636673fae75fa1d2e..0e5ec2265670238c72227b86387cc80a61613da6 100644 (file)
@@ -290,7 +290,7 @@ namespace Mono.CSharp
 
                        TypeExpr texpr = left as TypeExpr;
                        if (texpr != null) {
-                               var found = MemberCache.FindNestedType (texpr.Type, mn.Name, mn.Arity);
+                               var found = MemberCache.FindNestedType (texpr.Type, mn.Name, mn.Arity, false);
                                if (found != null)
                                        return new TypeExpression (found, Location.Null);
 
index fd5732f7598dd20feea9bb715a99f508dce247ab..42eba97ee475763eb15186ea8a25bbe36fc1fca9 100644 (file)
@@ -2929,15 +2929,6 @@ namespace Mono.CSharp {
                                        return me;
                                }
 
-                               //
-                               // Stage 3: Lookup nested types, namespaces and type parameters in the context
-                               //
-                               if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) {
-                                       if (IsPossibleTypeOrNamespace (rc)) {
-                                               return ResolveAsTypeOrNamespace (rc, false);
-                                       }
-                               }
-
                                var expr = NamespaceContainer.LookupStaticUsings (rc, Name, Arity, loc);
                                if (expr != null) {
                                        if (Arity > 0) {
@@ -2950,6 +2941,15 @@ namespace Mono.CSharp {
                                        return expr;
                                }
 
+                               //
+                               // Stage 3: Lookup nested types, namespaces and type parameters in the context
+                               //
+                               if ((restrictions & MemberLookupRestrictions.InvocableOnly) == 0 && !variable_found) {
+                                       if (IsPossibleTypeOrNamespace (rc)) {
+                                               return ResolveAsTypeOrNamespace (rc, false);
+                                       }
+                               }
+
                                if ((restrictions & MemberLookupRestrictions.NameOfExcluded) == 0 && Name == "nameof")
                                        return new NameOf (this);
 
index bc75f5388cd83848d520c9735078db8cda4a733c..02ae36b34c16802d921a2476f4a1ab3d750052c3 100644 (file)
@@ -9959,7 +9959,7 @@ namespace Mono.CSharp
 
                        TypeSpec nested = null;
                        while (expr_type != null) {
-                               nested = MemberCache.FindNestedType (expr_type, Name, Arity);
+                               nested = MemberCache.FindNestedType (expr_type, Name, Arity, false);
                                if (nested == null) {
                                        if (expr_type == tnew_expr) {
                                                Error_IdentifierNotFound (rc, expr_type);
@@ -9967,7 +9967,7 @@ namespace Mono.CSharp
                                        }
 
                                        expr_type = tnew_expr;
-                                       nested = MemberCache.FindNestedType (expr_type, Name, Arity);
+                                       nested = MemberCache.FindNestedType (expr_type, Name, Arity, false);
                                        ErrorIsInaccesible (rc, nested.GetSignatureForError (), loc);
                                        break;
                                }
@@ -10008,7 +10008,7 @@ namespace Mono.CSharp
 
                public void Error_IdentifierNotFound (IMemberContext rc, TypeSpec expr_type)
                {
-                       var nested = MemberCache.FindNestedType (expr_type, Name, -System.Math.Max (1, Arity));
+                       var nested = MemberCache.FindNestedType (expr_type, Name, -System.Math.Max (1, Arity), false);
 
                        if (nested != null) {
                                Error_TypeArgumentsCannotBeUsed (rc, nested, expr.Location);
index 556a08b85241204a64a96bc55d4a65460576f6c9..b34f2dc1ec56dfbadb8ff468da7940d1f49b3ca4 100644 (file)
@@ -1551,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
index d302724c386d84cf5998ceaec7fd542b43e47b2e..60073b9f4c1338929c6098c9a28f861d36534132 100644 (file)
@@ -814,7 +814,7 @@ namespace Mono.CSharp
                                                if (t.Kind == MemberKind.MissingType)
                                                        spec = t;
                                                else
-                                                       spec = MemberCache.FindNestedType (spec, t.Name, t.Arity);
+                                                       spec = MemberCache.FindNestedType (spec, t.Name, t.Arity, false);
 
                                                if (t.Arity > 0) {
                                                        spec = spec.MakeGenericType (module, targs.Skip (targs_pos).Take (spec.Arity).ToArray ());
@@ -834,7 +834,7 @@ namespace Mono.CSharp
                                                if (index > 0)
                                                        name = name.Substring (0, index);
 
-                                               spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos);
+                                               spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos, false);
 
                                                if (spec.Arity > 0) {
                                                        spec = spec.MakeGenericType (module, targs.Skip (targs_pos).ToArray ());
index 6a555cf325c01a82086f67180543cc92657b9aa1..8ada0a97071a327cd2c8433a09eb654d904633bd 100644 (file)
@@ -465,7 +465,7 @@ namespace Mono.CSharp {
                //
                // Finds the nested type in container
                //
-               public static TypeSpec FindNestedType (TypeSpec container, string name, int arity)
+               public static TypeSpec FindNestedType (TypeSpec container, string name, int arity, bool declaredOnlyClass)
                {
                        IList<MemberSpec> applicable;
                        TypeSpec best_match = null;
@@ -494,7 +494,7 @@ namespace Mono.CSharp {
                                                if (arity < 0) {
                                                        if (best_match == null) {
                                                                best_match = ts;
-                                                       } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (ts.Arity + arity)) {
+                                                       } else if (System.Math.Abs (ts.Arity + arity) < System.Math.Abs (best_match.Arity + arity)) {
                                                                best_match = ts;
                                                        }
                                                }
@@ -502,7 +502,7 @@ namespace Mono.CSharp {
                                }
 
                                container = container.BaseType;
-                       } while (container != null);
+                       } while (container != null && !declaredOnlyClass);
 
                        return best_match;
                }
index d81c307ae085acd14d48606b1af9d068b0c4ee25..b5379056ee7f9ae38bc0166c9c8f191465762f2f 100644 (file)
@@ -1159,38 +1159,18 @@ namespace Mono.CSharp {
 
                        if (types_using_table != null) {
                                foreach (var using_type in types_using_table) {
-                                       var members = MemberCache.FindMembers (using_type, name, true);
-                                       if (members == null)
+                                       var type = MemberCache.FindNestedType (using_type, name, arity, true);
+                                       if (type == null)
                                                continue;
+                                       
+                                       fne = new TypeExpression (type, loc);
+                                       if (match == null) {
+                                               match = fne;
+                                               continue;
+                                       }
 
-                                       foreach (var member in members) {
-                                               if (arity > 0 && member.Arity != arity)
-                                                       continue;
-                                               
-                                               if ((member.Kind & MemberKind.NestedMask) != 0) {
-                                                       // non-static nested type is included with using static
-                                               } else {
-                                                       if ((member.Modifiers & Modifiers.STATIC) == 0)
-                                                               continue;
-
-                                                       if ((member.Modifiers & Modifiers.METHOD_EXTENSION) != 0)
-                                                               continue;
-
-                                                       if (mode == LookupMode.Normal)
-                                                               continue;
-                                                       
-                                                       return null;
-                                               }
-
-                                               fne = new TypeExpression ((TypeSpec) member, loc);
-                                               if (match == null) {
-                                                       match = fne;
-                                                       continue;
-                                               }
-
-                                               if (mode == LookupMode.Normal) {
-                                                       Error_AmbiguousReference (name, match, fne, loc);
-                                               }
+                                       if (mode == LookupMode.Normal) {
+                                               Error_AmbiguousReference (name, match, fne, loc);
                                        }
                                }
                        }
diff --git a/mcs/tests/test-static-using-12.cs b/mcs/tests/test-static-using-12.cs
new file mode 100644 (file)
index 0000000..8d17085
--- /dev/null
@@ -0,0 +1,24 @@
+namespace A.B
+{
+       public static class G<T>
+       {
+               public class DD
+               {
+               }
+
+               public static object Dock () => null;
+       }
+}
+
+namespace N2
+{
+       using static A.B.G<int>;
+
+       class M : DD
+       {
+               public static void Main ()
+               {
+                       Dock ();
+               }
+       }
+}
index 3f25baf1abb1860e74023b10fe3e421fcd54da8c..0964285cc654069417501810315bf9f5012be27d 100644 (file)
       </method>
     </type>
   </test>
+  <test name="test-static-using-12.cs">
+    <type name="A.B.G`1[T]">
+      <method name="System.Object Dock()" attrs="150">
+        <size>9</size>
+      </method>
+    </type>
+    <type name="A.B.G`1+DD[T]">
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="N2.M">
+      <method name="Void Main()" attrs="150">
+        <size>8</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-var-01.cs">
     <type name="Test">
       <method name="Int32 Main()" attrs="150">