diff options
author | Daniel Grunwald <daniel@danielgrunwald.de> | 2012-05-18 20:23:19 +0400 |
---|---|---|
committer | Daniel Grunwald <daniel@danielgrunwald.de> | 2012-05-18 20:23:33 +0400 |
commit | cbb1fe5008dfcd7144c29d65ff4f6bbfbb65d660 (patch) | |
tree | b7b74c091968c647fb4565b5274bb4a0bfafe1e3 | |
parent | c93aca4b914b8f2cb3e6f0daf22daf32085f5d39 (diff) |
Fixed some issues resolving members.
6 files changed, 37 insertions, 10 deletions
diff --git a/ICSharpCode.NRefactory.ConsistencyCheck/TypeSystemTests.cs b/ICSharpCode.NRefactory.ConsistencyCheck/TypeSystemTests.cs index 5c8b6a3a..381a4c7a 100644 --- a/ICSharpCode.NRefactory.ConsistencyCheck/TypeSystemTests.cs +++ b/ICSharpCode.NRefactory.ConsistencyCheck/TypeSystemTests.cs @@ -56,17 +56,24 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck { foreach (var project in solution.Projects) { var compilation = project.Compilation; - var context = new SimpleTypeResolveContext(compilation.MainAssembly); + var assemblyContext = new SimpleTypeResolveContext(compilation.MainAssembly); foreach (var typeDef in compilation.MainAssembly.GetAllTypeDefinitions()) { foreach (var part in typeDef.Parts) { - if (!typeDef.Equals(part.Resolve(context))) + if (!typeDef.Equals(part.Resolve(assemblyContext))) throw new InvalidOperationException(); } foreach (var member in typeDef.Members) { - var resolvedMember = member.UnresolvedMember.Resolve(context); + var resolvedMember = member.UnresolvedMember.Resolve(assemblyContext); if (!member.Equals(resolvedMember)) throw new InvalidOperationException(); } + // ToMemberReference() requires an appropriate generic context if the member + // contains open generics; otherwise the main context of the compilation is sufficient. + ITypeResolveContext context; + if (typeDef.TypeParameterCount > 0) + context = new SimpleTypeResolveContext(typeDef); + else + context = compilation.TypeResolveContext; // Include (potentially specialized) inherited members when testing ToMemberReference() foreach (var member in typeDef.GetMembers()) { var resolvedMember = member.ToMemberReference().Resolve(context); diff --git a/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs index 1c6a1c2c..7f5922f1 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/Parser/TypeSystemConvertVisitorTests.cs @@ -108,6 +108,17 @@ namespace ICSharpCode.NRefactory.CSharp.Parser } [Test] + public void ExplicitImplementationOfUnifiedMethods_ToMemberReference() + { + IType type = compilation.FindType(typeof(ExplicitGenericInterfaceImplementationWithUnifiableMethods<int, int>)); + Assert.AreEqual(2, type.GetMethods(m => m.IsExplicitInterfaceImplementation).Count()); + foreach (IMethod method in type.GetMethods(m => m.IsExplicitInterfaceImplementation)) { + IMethod resolvedMethod = (IMethod)method.ToMemberReference().Resolve(compilation.TypeResolveContext); + Assert.AreEqual(method, resolvedMethod); + } + } + + [Test] public void PartialMethodWithImplementation() { var t = compilation.FindType(typeof(PartialClass)); diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedMember.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedMember.cs index c41290ce..c7469621 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedMember.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractUnresolvedMember.cs @@ -213,7 +213,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation return method; } else if (method.IsExplicitInterfaceImplementation && method.ImplementedInterfaceMembers.Count == 1) { IType explicitInterfaceType = explicitInterfaceTypeReference.Resolve(contextForMethod); - if (explicitInterfaceTypeReference.Equals(method.ImplementedInterfaceMembers[0].DeclaringType)) + if (explicitInterfaceType.Equals(method.ImplementedInterfaceMembers[0].DeclaringType)) return method; } } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMemberReference.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMemberReference.cs index 6e26291f..632207e6 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMemberReference.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMemberReference.cs @@ -24,7 +24,7 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation { /// <summary> /// References an entity by its type and name. - /// This class can be used to refer to fields, events, and parameterless properties. + /// This class can be used to refer to all members except for constructors and explicit interface implementations. /// </summary> /// <remarks> /// Resolving a DefaultMemberReference requires a context that provides enough information for resolving the declaring type reference @@ -64,11 +64,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation IEnumerable<IMember> members; if (entityType == EntityType.Method) { members = type.GetMethods( - m => m.Name == name && m.EntityType == EntityType.Method && m.TypeParameters.Count == typeParameterCount, + m => m.Name == name && m.EntityType == EntityType.Method + && m.TypeParameters.Count == typeParameterCount && !m.IsExplicitInterfaceImplementation, GetMemberOptions.IgnoreInheritedMembers); } else { members = type.GetMembers( - m => m.Name == name && m.EntityType == entityType, + m => m.Name == name && m.EntityType == entityType && !m.IsExplicitInterfaceImplementation, GetMemberOptions.IgnoreInheritedMembers); } var resolvedParameterTypes = parameterTypes.Resolve(context); diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DummyTypeParameter.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DummyTypeParameter.cs index d6658dfe..b95b9d66 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DummyTypeParameter.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DummyTypeParameter.cs @@ -138,6 +138,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation } } + public override string ToString() + { + return ReflectionName + " (dummy)"; + } + public override bool? IsReferenceType { get { return null; } } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/ExplicitInterfaceImplementationMemberReference.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/ExplicitInterfaceImplementationMemberReference.cs index 2da8ffe8..89377284 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/ExplicitInterfaceImplementationMemberReference.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/ExplicitInterfaceImplementationMemberReference.cs @@ -28,6 +28,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation /// Resolving an ExplicitInterfaceImplementationMemberReference requires a context /// that provides enough information for resolving the declaring type reference /// and the interface member reference. + /// Note that the interface member reference is resolved in '<c>context.WithCurrentTypeDefinition(declaringType.GetDefinition())</c>' + /// - this is done to ensure that open generics in the interface member reference resolve to the type parameters of the + /// declaring type. /// </remarks> [Serializable] public sealed class ExplicitInterfaceImplementationMemberReference : IMemberReference @@ -51,11 +54,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation public IMember Resolve(ITypeResolveContext context) { - IMember interfaceMember = interfaceMemberReference.Resolve(context); + IType declaringType = typeReference.Resolve(context); + IMember interfaceMember = interfaceMemberReference.Resolve(context.WithCurrentTypeDefinition(declaringType.GetDefinition())); if (interfaceMember == null) return null; - IType type = typeReference.Resolve(context); - var members = type.GetMembers( + var members = declaringType.GetMembers( m => m.EntityType == interfaceMember.EntityType && m.IsExplicitInterfaceImplementation, GetMemberOptions.IgnoreInheritedMembers); return members.FirstOrDefault(m => m.ImplementedInterfaceMembers.Count == 1 && interfaceMember.Equals(m.ImplementedInterfaceMembers[0])); |