From aa2e97f564243b53c3707b455b3799f1ccb0ddc1 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Tue, 14 Feb 2012 10:29:09 +0100 Subject: [PATCH] When copying type parameters into inner classes, re-use the same ITypeParameter instance. --- ICSharpCode.NRefactory.CSharp/Ast/AstType.cs | 4 +++- .../Program.cs | 16 +++++----------- .../TypeSystem/TypeSystemTests.cs | 5 ++--- .../TypeSystem/ITypeParameter.cs | 5 +++++ .../DefaultResolvedTypeDefinition.cs | 16 +++++++++++++++- 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs b/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs index 218bd312a8..be1b830e1f 100644 --- a/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs +++ b/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs @@ -110,7 +110,9 @@ namespace ICSharpCode.NRefactory.CSharp /// Create an ITypeReference for this AstType. /// /// - /// The resulting type reference requires a to be resolved. + /// The resulting type reference requires a + /// + /// to be resolved. /// public abstract ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type); diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/Program.cs b/ICSharpCode.NRefactory.ConsistencyCheck/Program.cs index 1f4f121894..d463923c9f 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/Program.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/Program.cs @@ -28,22 +28,16 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck { class Program { - /* public static readonly string[] AssemblySearchPaths = { @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0", + @"C:\Windows\Microsoft.NET\Framework\v2.0.50727", @"C:\Program Files (x86)\GtkSharp\2.12\lib\gtk-sharp-2.0", @"C:\Program Files (x86)\GtkSharp\2.12\lib\Mono.Posix", @"C:\work\SD\src\Tools\NUnit" }; - public const string SolutionFile = @"C:\work\NRefactory\NRefactory.sln"; - /*/ - public static readonly string[] AssemblySearchPaths = { - @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0", - @"C:\Windows\Microsoft.NET\Framework\v2.0.50727", - - }; - public const string SolutionFile = @"C:\work\SD\SharpDevelop.sln"; - //*/ + //public const string SolutionFile = @"C:\work\NRefactory\NRefactory.sln"; + //public const string SolutionFile = @"C:\work\SD\SharpDevelop.sln"; + public const string SolutionFile = @"C:\work\ILSpy\ILSpy.sln"; public const string TempPath = @"C:\temp"; @@ -63,7 +57,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck //RunTestOnAllFiles("Roundtripping test", RoundtripTest.RunTest); RunTestOnAllFiles("Resolver test", ResolverTest.RunTest); - //RunTestOnAllFiles("Resolver test (randomized order)", RandomizedOrderResolverTest.RunTest); + RunTestOnAllFiles("Resolver test (randomized order)", RandomizedOrderResolverTest.RunTest); Console.Write("Press any key to continue . . . "); Console.ReadKey(true); diff --git a/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs b/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs index 785fa09cc5..6ed5093a45 100644 --- a/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs +++ b/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs @@ -565,7 +565,8 @@ namespace ICSharpCode.NRefactory.TypeSystem public void InnerClassInGenericClass_TypeParameterOwner() { ITypeDefinition type = GetTypeDefinition(typeof(OuterGeneric<>.Inner)); - Assert.AreSame(type, type.TypeParameters[0].Owner); + Assert.AreSame(type.DeclaringTypeDefinition.TypeParameters[0], type.TypeParameters[0]); + Assert.AreSame(type.DeclaringTypeDefinition, type.TypeParameters[0].Owner); } [Test] @@ -574,7 +575,6 @@ namespace ICSharpCode.NRefactory.TypeSystem ITypeDefinition type = GetTypeDefinition(typeof(OuterGeneric<>.Inner)); IField f = type.Fields.Single(); Assert.AreEqual("ICSharpCode.NRefactory.TypeSystem.TestCase.OuterGeneric`1[[`0]]", f.Type.ReflectionName); - Assert.AreSame(type, ((f.Type as ParameterizedType).TypeArguments[0] as ITypeParameter).Owner); } [Test] @@ -583,7 +583,6 @@ namespace ICSharpCode.NRefactory.TypeSystem ITypeDefinition type = GetTypeDefinition(typeof(OuterGeneric<>.Inner)); IParameter p = type.Methods.Single(m => m.IsConstructor).Parameters.Single(); Assert.AreEqual("ICSharpCode.NRefactory.TypeSystem.TestCase.OuterGeneric`1[[`0]]", p.Type.ReflectionName); - Assert.AreSame(type, ((p.Type as ParameterizedType).TypeArguments[0] as ITypeParameter).Owner); } ResolveResult GetParamsAttributeArgument(int index) diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs index d3dd8ee4f4..9d4b360635 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs @@ -72,6 +72,11 @@ namespace ICSharpCode.NRefactory.TypeSystem /// Gets the owning method/class. /// This property may return null (for example for the dummy type parameters used by ). /// + /// + /// For "class Outer<T> { class Inner {} }", + /// inner.TypeParameters[0].Owner will be the outer class, because the same + /// ITypeParameter instance is used both on Outer`1 and Outer`1+Inner. + /// IEntity Owner { get; } /// diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs index 1369688e2e..b2f2a48d18 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs @@ -47,7 +47,21 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation this.parts = parts; ITypeResolveContext contextForTypeParameters = parts[0].CreateResolveContext(parentContext); contextForTypeParameters = contextForTypeParameters.WithCurrentTypeDefinition(this); - this.TypeParameters = parts[0].TypeParameters.CreateResolvedTypeParameters(contextForTypeParameters); + if (parentContext.CurrentTypeDefinition == null || parentContext.CurrentTypeDefinition.TypeParameterCount == 0) { + this.TypeParameters = parts[0].TypeParameters.CreateResolvedTypeParameters(contextForTypeParameters); + } else { + // This is a nested class inside a generic class; copy type parameters from outer class if we can: + var outerClass = parentContext.CurrentTypeDefinition; + ITypeParameter[] typeParameters = new ITypeParameter[parts[0].TypeParameters.Count]; + for (int i = 0; i < typeParameters.Length; i++) { + var unresolvedTP = parts[0].TypeParameters[i]; + if (i < outerClass.TypeParameterCount && outerClass.TypeParameters[i].Name == unresolvedTP.Name) + typeParameters[i] = outerClass.TypeParameters[i]; + else + typeParameters[i] = unresolvedTP.CreateResolvedTypeParameter(contextForTypeParameters); + } + this.TypeParameters = Array.AsReadOnly(typeParameters); + } List unresolvedAttributes = new List(); List contextPerAttribute = new List(); List contextPerMember = new List();