Browse Source

Fix fixes an issue causing the type system to believe that accessors implement interface members even though there is an explicit implementation of the accessor owner.

Closes icsharpcode/NRefactory#170
pull/32/merge
Daniel Grunwald 13 years ago
parent
commit
5acf6aef0d
  1. 23
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.TestCase.cs
  2. 39
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  3. 5
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedMember.cs

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

@ -367,6 +367,27 @@ namespace ICSharpCode.NRefactory.TypeSystem.TestCase @@ -367,6 +367,27 @@ namespace ICSharpCode.NRefactory.TypeSystem.TestCase
public const int SOf = sizeof(float);
public const int SOd = sizeof(double);
public const int SObl = sizeof(bool);
public const int SOe = sizeof(MyEnum);
public const int SOe = sizeof(MyEnum);
}
public interface IExplicitImplementationTests
{
void M(int a);
int P { get; set; }
event Action E;
int this[int x] { get; set; }
}
public class ExplicitImplementationTests : IExplicitImplementationTests
{
public void M(int a) {}
public int P { get; set; }
public event Action E;
public int this[int x] { get { return 0; } set {} }
void IExplicitImplementationTests.M(int a) {}
int IExplicitImplementationTests.P { get; set; }
event Action IExplicitImplementationTests.E { add {} remove {} }
int IExplicitImplementationTests.this[int x] { get { return 0; } set {} }
}
}

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

@ -1285,5 +1285,44 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1285,5 +1285,44 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.IsTrue(field.IsConst);
Assert.AreEqual((int)StringComparison.OrdinalIgnoreCase, field.ConstantValue);
}
[Test]
public void ExplicitImplementation()
{
var type = GetTypeDefinition(typeof(ExplicitImplementationTests));
var itype = GetTypeDefinition(typeof(IExplicitImplementationTests));
var methods = type.GetMethods(m => m.Name == "M").ToList();
var imethod = itype.GetMethods(m => m.Name == "M").Single();
Assert.That(methods.Select(m => m.ImplementedInterfaceMembers.Count).ToList(), Is.EquivalentTo(new[] { 0, 1 }));
Assert.AreEqual(methods.SelectMany(m => m.ImplementedInterfaceMembers).Single(), imethod);
var properties = type.GetProperties(p => p.Name == "P").ToList();
var iproperty = itype.GetProperties(m => m.Name == "P").Single();
Assert.That(properties.Select(p => p.ImplementedInterfaceMembers.Count).ToList(), Is.EquivalentTo(new[] { 0, 1 }));
Assert.AreEqual(properties.SelectMany(p => p.ImplementedInterfaceMembers).Single(), iproperty);
Assert.That(properties.Select(p => p.Getter.ImplementedInterfaceMembers.Count).ToList(), Is.EquivalentTo(new[] { 0, 1 }));
Assert.AreEqual(properties.SelectMany(p => p.Getter.ImplementedInterfaceMembers).Single(), iproperty.Getter);
Assert.That(properties.Select(p => p.Setter.ImplementedInterfaceMembers.Count).ToList(), Is.EquivalentTo(new[] { 0, 1 }));
Assert.AreEqual(properties.SelectMany(p => p.Setter.ImplementedInterfaceMembers).Single(), iproperty.Setter);
var indexers = type.GetProperties(p => p.Name == "Item").ToList();
var iindexer = itype.GetProperties(m => m.Name == "Item").Single();
Assert.That(indexers.Select(p => p.ImplementedInterfaceMembers.Count).ToList(), Is.EquivalentTo(new[] { 0, 1 }));
Assert.AreEqual(indexers.SelectMany(p => p.ImplementedInterfaceMembers).Single(), iindexer);
Assert.That(indexers.Select(p => p.Getter.ImplementedInterfaceMembers.Count).ToList(), Is.EquivalentTo(new[] { 0, 1 }));
Assert.AreEqual(indexers.SelectMany(p => p.Getter.ImplementedInterfaceMembers).Single(), iindexer.Getter);
Assert.That(indexers.Select(p => p.Setter.ImplementedInterfaceMembers.Count).ToList(), Is.EquivalentTo(new[] { 0, 1 }));
Assert.AreEqual(indexers.SelectMany(p => p.Setter.ImplementedInterfaceMembers).Single(), iindexer.Setter);
var events = type.GetEvents(e => e.Name == "E").ToList();
var ievent = itype.GetEvents(m => m.Name == "E").Single();
Assert.That(events.Select(e => e.ImplementedInterfaceMembers.Count).ToList(), Is.EquivalentTo(new[] { 0, 1 }));
Assert.AreEqual(events.SelectMany(e => e.ImplementedInterfaceMembers).Single(), ievent);
Assert.That(events.Select(e => e.AddAccessor.ImplementedInterfaceMembers.Count).ToList(), Is.EquivalentTo(new[] { 0, 1 }));
Assert.AreEqual(events.SelectMany(e => e.AddAccessor.ImplementedInterfaceMembers).Single(), ievent.AddAccessor);
Assert.That(events.Select(e => e.RemoveAccessor.ImplementedInterfaceMembers.Count).ToList(), Is.EquivalentTo(new[] { 0, 1 }));
Assert.AreEqual(events.SelectMany(e => e.RemoveAccessor.ImplementedInterfaceMembers).Single(), ievent.RemoveAccessor);
}
}
}

5
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedMember.cs

@ -84,7 +84,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -84,7 +84,10 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
.Where(m => m.DeclaringTypeDefinition != null && m.DeclaringTypeDefinition.Kind == TypeKind.Interface)
.ToArray();
result = result.Where(item => !DeclaringTypeDefinition.Members.Any(m => m.IsExplicitInterfaceImplementation && m.ImplementedInterfaceMembers.Contains(item))).ToArray();
IEnumerable<IMember> otherMembers = DeclaringTypeDefinition.Members;
if (EntityType == EntityType.Accessor)
otherMembers = DeclaringTypeDefinition.GetAccessors(options: GetMemberOptions.IgnoreInheritedMembers);
result = result.Where(item => !otherMembers.Any(m => m.IsExplicitInterfaceImplementation && m.ImplementedInterfaceMembers.Contains(item))).ToArray();
return result;
}

Loading…
Cancel
Save