Browse Source

Fixed resolving simple names within a generic class that refer to a non-generic inner class.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
57d55c651d
  1. 16
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs
  2. 2
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs
  3. 5
      ICSharpCode.NRefactory.Tests/TypeSystem/GetMembersTests.cs
  4. 9
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs
  5. 14
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  6. 3
      ICSharpCode.NRefactory/TypeSystem/IType.cs
  7. 7
      ICSharpCode.NRefactory/TypeSystem/Implementation/GetMembersHelper.cs

16
ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs

@ -188,5 +188,21 @@ public class Foo : A<int>
var lrr = Resolve<MemberResolveResult>(program); var lrr = Resolve<MemberResolveResult>(program);
Assert.AreEqual("System.Int32", lrr.Type.FullName); Assert.AreEqual("System.Int32", lrr.Type.FullName);
} }
[Test]
public void MemberInGenericClassReferringToInnerClass()
{
string program = @"public class Foo<T> {
public class TestFoo { }
public TestFoo Bar = new TestFoo ();
}
public class Test {
public void SomeMethod (Foo<Test> foo) {
var f = $foo.Bar$;
}
}";
var mrr = Resolve<MemberResolveResult>(program);
Assert.AreEqual("Foo`1+TestFoo[[Test]]", mrr.Type.ReflectionName);
}
} }
} }

2
ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs

@ -862,7 +862,7 @@ class B
} }
[Test] [Test]
public void InheritingInnerClassShouldNotCauseStackOverflow() public void InheritingInnerClassShouldNotCauseStackOverflow()
{ {
string program = @"class Test : $Test.Base$, Test.ITest { public class Base {} interface ITest {} }"; string program = @"class Test : $Test.Base$, Test.ITest { public class Base {} interface ITest {} }";
var result = Resolve<TypeResolveResult>(program); var result = Resolve<TypeResolveResult>(program);

5
ICSharpCode.NRefactory.Tests/TypeSystem/GetMembersTests.cs

@ -43,7 +43,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
b1.Kind = TypeKind.Interface; b1.Kind = TypeKind.Interface;
b1.Properties.Add(new DefaultProperty(b1, "P1")); b1.Properties.Add(new DefaultProperty(b1, "P1"));
DefaultTypeDefinition b2 = new DefaultTypeDefinition(mscorlib, string.Empty, "B1"); DefaultTypeDefinition b2 = new DefaultTypeDefinition(mscorlib, string.Empty, "B2");
b2.Kind = TypeKind.Interface; b2.Kind = TypeKind.Interface;
b2.Properties.Add(new DefaultProperty(b1, "P2")); b2.Properties.Add(new DefaultProperty(b1, "P2"));
@ -93,7 +93,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
{ {
ITypeDefinition dictionary = mscorlib.GetTypeDefinition(typeof(Dictionary<,>)); ITypeDefinition dictionary = mscorlib.GetTypeDefinition(typeof(Dictionary<,>));
IType keyCollection = dictionary.GetNestedTypes(mscorlib).Single(t => t.Name == "KeyCollection"); IType keyCollection = dictionary.GetNestedTypes(mscorlib).Single(t => t.Name == "KeyCollection");
Assert.IsTrue(keyCollection is ITypeDefinition); // the type should be parameterized
Assert.AreEqual("System.Collections.Generic.Dictionary`2+KeyCollection[[`0],[`1]]", keyCollection.ReflectionName);
} }
[Test] [Test]

9
ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs

@ -127,4 +127,13 @@ namespace ICSharpCode.NRefactory.TypeSystem.TestCase
public const string NullString = null; public const string NullString = null;
} }
public class OuterGeneric<X>
{
public class Inner {}
public OuterGeneric<X>.Inner Field1;
public Inner Field2;
public OuterGeneric<OuterGeneric<X>.Inner>.Inner Field3;
}
} }

14
ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs

@ -476,5 +476,19 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.IsTrue(answer.IsConst); Assert.IsTrue(answer.IsConst);
Assert.IsNull(answer.ConstantValue.Resolve(ctx).ConstantValue); Assert.IsNull(answer.ConstantValue.Resolve(ctx).ConstantValue);
} }
[Test]
public void InnerClassInGenericClassIsReferencedUsingParameterizedType()
{
ITypeDefinition type = ctx.GetTypeDefinition(typeof(OuterGeneric<>));
IField field1 = type.Fields.Single(f => f.Name == "Field1");
IField field2 = type.Fields.Single(f => f.Name == "Field2");
IField field3 = type.Fields.Single(f => f.Name == "Field3");
// types must be self-parameterized
Assert.AreEqual("ICSharpCode.NRefactory.TypeSystem.TestCase.OuterGeneric`1+Inner[[`0]]", field1.Type.Resolve(ctx).ReflectionName);
Assert.AreEqual("ICSharpCode.NRefactory.TypeSystem.TestCase.OuterGeneric`1+Inner[[`0]]", field2.Type.Resolve(ctx).ReflectionName);
Assert.AreEqual("ICSharpCode.NRefactory.TypeSystem.TestCase.OuterGeneric`1+Inner[[ICSharpCode.NRefactory.TypeSystem.TestCase.OuterGeneric`1+Inner[[`0]]]]", field3.Type.Resolve(ctx).ReflectionName);
}
} }
} }

3
ICSharpCode.NRefactory/TypeSystem/IType.cs

@ -121,8 +121,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// The filter is tested on the original type definitions (before parameterization).</param> /// The filter is tested on the original type definitions (before parameterization).</param>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// If the nested type is generic (and has more type parameters than the outer class), /// If the nested type is generic, this method will return a parameterized type,
/// this method will return a parameterized type,
/// where the additional type parameters are set to <see cref="SharedType.UnboundTypeArgument"/>. /// where the additional type parameters are set to <see cref="SharedType.UnboundTypeArgument"/>.
/// </para> /// </para>
/// <para> /// <para>

7
ICSharpCode.NRefactory/TypeSystem/Implementation/GetMembersHelper.cs

@ -66,12 +66,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
if (!(filter == null || filter(nestedType))) if (!(filter == null || filter(nestedType)))
continue; continue;
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) { if (totalTypeParameterCount == 0 || (options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) {
yield return nestedType;
} else if (totalTypeParameterCount == 0 || (pt == null && totalTypeParameterCount == outerTypeParameterCount)) {
// The nested type has no new type parameters, and there are no type arguments
// to copy from the outer type
// -> we can directly return the nested type definition
yield return nestedType; yield return nestedType;
} else { } else {
// We need to parameterize the nested type // We need to parameterize the nested type

Loading…
Cancel
Save