From c43a501ec4b1684751248b55a057933cf2159abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Kr=C3=BCger?= Date: Tue, 12 Feb 2013 13:24:36 +0100 Subject: [PATCH] Fixed type parameter substitution bug. --- .../CSharp/Resolver/MemberLookupTests.cs | 21 +++++++++++++++++++ .../TypeParameterSubstitution.cs | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs index 07050b6507..07b1e9ac28 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Resolver/MemberLookupTests.cs @@ -542,5 +542,26 @@ class C : B { var result = Resolve(program); Assert.AreEqual("op_Addition.Foo", result.Member.FullName); } + + /// + /// Bug 10201 - Wrong generics expansion for base recursive types + /// + [Test] + public void TestBug10201() + { + string program = @"public interface IA +{ +} +public class G : IA<$G$> +{} +"; + var rr = Resolve(program); + var baseType = rr.Type.DirectBaseTypes.First().TypeArguments.First () as ParameterizedType; + Assert.AreEqual("G", baseType.Name); + + Assert.AreEqual(2, baseType.TypeParameterCount); + Assert.AreEqual(TypeKind.TypeParameter, baseType.TypeArguments [0].Kind); + Assert.AreEqual("System.String", baseType.TypeArguments [1].FullName); + } } } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/TypeParameterSubstitution.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/TypeParameterSubstitution.cs index 2a56544147..b233002949 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/TypeParameterSubstitution.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/TypeParameterSubstitution.cs @@ -148,7 +148,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation public override IType VisitTypeParameter(ITypeParameter type) { int index = type.Index; + if (classTypeArguments != null && type.OwnerType == EntityType.TypeDefinition) { + // Don't substitute type parameters that are part of the type arguments. + if (classTypeArguments.Contains (type)) + return type; if (index >= 0 && index < classTypeArguments.Count) return classTypeArguments[index]; else