Skip to content

Commit

Permalink
[mcs] Consider nested types when looking for potential types via usin…
Browse files Browse the repository at this point in the history
…g static. Fixes #29044
  • Loading branch information
marek-safar committed Apr 14, 2015
1 parent 8fad4b7 commit 322af7e
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 21 deletions.
35 changes: 35 additions & 0 deletions mcs/errors/cs0104-5.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// CS0104: `N' is an ambiguous reference between `C.N' and `A.T.N'
// Line: 32

namespace A
{
public class T
{
public class N
{

}
}
}

namespace C
{
struct N
{

}
}

namespace B
{
using static A.T;
using C;

static class Program
{
static void Main ()
{
var u = new N ();
}
}
}
23 changes: 23 additions & 0 deletions mcs/errors/cs0246-35.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// CS0246: The type or namespace name `B' could not be found. Are you missing an assembly reference?
// Line: 21

using static A;

class A : B
{
}

class P
{
public class N<T>
{
}
}

class Test
{
public static void Main ()
{
var n = default (N<int>);
}
}
87 changes: 66 additions & 21 deletions mcs/mcs/namespace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1147,10 +1147,7 @@ FullNamedExpression Lookup (string name, int arity, LookupMode mode, Location lo
var better = Namespace.IsImportedTypeOverride (Module, texpr_match.Type, texpr_fne.Type);
if (better == null) {
if (mode == LookupMode.Normal) {
Compiler.Report.SymbolRelatedToPreviousError (texpr_match.Type);
Compiler.Report.SymbolRelatedToPreviousError (texpr_fne.Type);
Compiler.Report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
name, texpr_match.GetSignatureForError (), texpr_fne.GetSignatureForError ());
Error_AmbiguousReference (name, texpr_match, texpr_fne, loc);
}

return match;
Expand All @@ -1160,9 +1157,56 @@ FullNamedExpression Lookup (string name, int arity, LookupMode mode, Location lo
match = texpr_fne;
}

if (types_using_table != null) {
foreach (var using_type in types_using_table) {
var members = MemberCache.FindMembers (using_type, name, true);
if (members == null)
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)
throw new NotImplementedException ();

return null;
}

fne = new TypeExpression ((TypeSpec) member, loc);
if (match == null) {
match = fne;
continue;
}

if (mode == LookupMode.Normal) {
Error_AmbiguousReference (name, match, fne, loc);
}
}
}
}

return match;
}

void Error_AmbiguousReference (string name, FullNamedExpression a, FullNamedExpression b, Location loc)
{
var report = Compiler.Report;
report.SymbolRelatedToPreviousError (a.Type);
report.SymbolRelatedToPreviousError (b.Type);
report.Error (104, loc, "`{0}' is an ambiguous reference between `{1}' and `{2}'",
name, a.GetSignatureForError (), b.GetSignatureForError ());
}

public static Expression LookupStaticUsings (IMemberContext mc, string name, int arity, Location loc)
{
for (var m = mc.CurrentMemberDefinition; m != null; m = m.Parent) {
Expand All @@ -1175,26 +1219,27 @@ public static Expression LookupStaticUsings (IMemberContext mc, string name, int
if (nc.types_using_table != null) {
foreach (var using_type in nc.types_using_table) {
var members = MemberCache.FindMembers (using_type, name, true);
if (members != null) {
foreach (var member in members) {
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 (arity > 0 && member.Arity != arity)
if (members == null)
continue;

foreach (var member in members) {
if ((member.Kind & MemberKind.NestedMask) != 0) {
// non-static nested type is included with using static
} else {
if ((member.Modifiers & Modifiers.STATIC) == 0)
continue;

if (candidates == null)
candidates = new List<MemberSpec> ();

candidates.Add (member);
if ((member.Modifiers & Modifiers.METHOD_EXTENSION) != 0)
continue;
}

if (arity > 0 && member.Arity != arity)
continue;

if (candidates == null)
candidates = new List<MemberSpec> ();

candidates.Add (member);
}
}
}
Expand Down
17 changes: 17 additions & 0 deletions mcs/tests/test-static-using-08.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using static A;
//using N = System.Int32;

class A
{
public class N
{
}
}

class Test
{
public static void Main ()
{
N n = default (N); // Am I Int32 or A.N
}
}
24 changes: 24 additions & 0 deletions mcs/tests/test-static-using-10.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace A
{
public class T
{
public class N
{

}
}
}

namespace B
{
using static A.T;

static class Program
{
static void Main ()
{
var t = typeof (N);
var u = new N ();
}
}
}
37 changes: 37 additions & 0 deletions mcs/tests/ver-il-net_4_5.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70158,13 +70158,50 @@
</method>
</type>
</test>
<test name="test-static-using-08.cs">
<type name="A">
<method name="Void .ctor()" attrs="6278">
<size>7</size>
</method>
</type>
<type name="A+N">
<method name="Void .ctor()" attrs="6278">
<size>7</size>
</method>
</type>
<type name="Test">
<method name="Void Main()" attrs="150">
<size>4</size>
</method>
<method name="Void .ctor()" attrs="6278">
<size>7</size>
</method>
</type>
</test>
<test name="test-static-using-09.cs">
<type name="Program">
<method name="Void Main()" attrs="145">
<size>9</size>
</method>
</type>
</test>
<test name="test-static-using-10.cs">
<type name="A.T">
<method name="Void .ctor()" attrs="6278">
<size>7</size>
</method>
</type>
<type name="A.T+N">
<method name="Void .ctor()" attrs="6278">
<size>7</size>
</method>
</type>
<type name="B.Program">
<method name="Void Main()" attrs="145">
<size>19</size>
</method>
</type>
</test>
<test name="test-var-01.cs">
<type name="Test">
<method name="Int32 Main()" attrs="150">
Expand Down

0 comments on commit 322af7e

Please sign in to comment.