Browse Source

Add IType.GetAccessors().

Accessors now use EntityType.Accessor instead of EntityType.Method.
Added accessors support to DefaultMemberReference and ExplicitInterfaceImplementationMemberReference.
Removed hacky code from CecilLoader - we now allow IsExplicitInterfaceImplementation=true on accessors.
newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
806869e563
  1. 15
      ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs
  2. 23
      ICSharpCode.NRefactory.ConsistencyCheck/TypeSystemTests.cs
  3. 34
      ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  4. 1
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  5. 14
      ICSharpCode.NRefactory/TypeSystem/AnonymousType.cs
  6. 48
      ICSharpCode.NRefactory/TypeSystem/ArrayType.cs
  7. 98
      ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
  8. 3
      ICSharpCode.NRefactory/TypeSystem/EntityType.cs
  9. 15
      ICSharpCode.NRefactory/TypeSystem/IType.cs
  10. 8
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs
  11. 5
      ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs
  12. 51
      ICSharpCode.NRefactory/TypeSystem/Implementation/AccessorOwnerMemberReference.cs
  13. 12
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMemberReference.cs
  14. 32
      ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs
  15. 14
      ICSharpCode.NRefactory/TypeSystem/Implementation/ExplicitInterfaceImplementationMemberReference.cs
  16. 28
      ICSharpCode.NRefactory/TypeSystem/Implementation/GetMembersHelper.cs
  17. 54
      ICSharpCode.NRefactory/TypeSystem/InheritanceHelper.cs
  18. 5
      ICSharpCode.NRefactory/TypeSystem/IntersectionType.cs
  19. 8
      ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

15
ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs

@ -655,8 +655,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -655,8 +655,6 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
AddXmlDocumentation(p, indexerDeclaration);
ConvertParameters(p.Parameters, indexerDeclaration.Parameters);
p.Getter = ConvertAccessor(indexerDeclaration.Getter, p, "get_");
p.Setter = ConvertAccessor(indexerDeclaration.Setter, p, "set_");
if (!indexerDeclaration.PrivateImplementationType.IsNull) {
p.Accessibility = Accessibility.None;
@ -664,6 +662,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -664,6 +662,8 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
p.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
p.EntityType, indexerDeclaration.PrivateImplementationType.ToTypeReference(), p.Name, 0, GetParameterTypes(p.Parameters)));
}
p.Getter = ConvertAccessor(indexerDeclaration.Getter, p, "get_");
p.Setter = ConvertAccessor(indexerDeclaration.Setter, p, "set_");
currentTypeDefinition.Members.Add(p);
if (interningProvider != null) {
@ -677,6 +677,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -677,6 +677,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
if (accessor.IsNull)
return null;
var a = new DefaultUnresolvedMethod(currentTypeDefinition, prefix + p.Name);
a.EntityType = EntityType.Accessor;
a.AccessorOwner = p;
a.Accessibility = GetAccessibility(accessor.Modifiers) ?? p.Accessibility;
a.IsAbstract = p.IsAbstract;
@ -708,6 +709,15 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -708,6 +709,15 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
ConvertAttributes(a.Attributes, section);
}
}
if (p.IsExplicitInterfaceImplementation) {
a.IsExplicitInterfaceImplementation = true;
Debug.Assert(p.ExplicitInterfaceImplementations.Count == 1);
a.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
EntityType.Accessor,
p.ExplicitInterfaceImplementations[0].DeclaringTypeReference,
a.Name, 0, GetParameterTypes(a.Parameters)
));
}
return a;
}
#endregion
@ -756,6 +766,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -756,6 +766,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
DefaultUnresolvedMethod CreateDefaultEventAccessor(IUnresolvedEvent ev, string name, IUnresolvedParameter valueParameter)
{
var a = new DefaultUnresolvedMethod(currentTypeDefinition, name);
a.EntityType = EntityType.Accessor;
a.AccessorOwner = ev;
a.Region = ev.BodyRegion;
a.BodyRegion = ev.BodyRegion;

23
ICSharpCode.NRefactory.ConsistencyCheck/TypeSystemTests.cs

@ -62,7 +62,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -62,7 +62,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
if (!typeDef.Equals(part.Resolve(assemblyContext)))
throw new InvalidOperationException();
}
foreach (var member in typeDef.Members) {
foreach (var member in IncludeAccessors(typeDef.Members)) {
var resolvedMember = member.UnresolvedMember.Resolve(assemblyContext);
if (!member.Equals(resolvedMember))
throw new InvalidOperationException();
@ -75,7 +75,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -75,7 +75,7 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
else
context = compilation.TypeResolveContext;
// Include (potentially specialized) inherited members when testing ToMemberReference()
foreach (var member in typeDef.GetMembers()) {
foreach (var member in IncludeAccessors(typeDef.GetMembers())) {
var resolvedMember = member.ToMemberReference().Resolve(context);
if (!member.Equals(resolvedMember))
throw new InvalidOperationException();
@ -83,5 +83,24 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck @@ -83,5 +83,24 @@ namespace ICSharpCode.NRefactory.ConsistencyCheck
}
}
}
static IEnumerable<IMember> IncludeAccessors(IEnumerable<IMember> members)
{
foreach (var member in members) {
yield return member;
IProperty p = member as IProperty;
if (p != null && p.CanGet)
yield return p.Getter;
if (p != null && p.CanSet)
yield return p.Setter;
IEvent e = member as IEvent;
if (e != null && e.CanAdd)
yield return e.AddAccessor;
if (e != null && e.CanRemove)
yield return e.RemoveAccessor;
if (e != null && e.CanInvoke)
yield return e.InvokeAccessor;
}
}
}
}

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

@ -241,7 +241,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -241,7 +241,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
[Test]
public void Specialized_GetIndex_ToTypeReference()
public void Specialized_GetIndex_ToMemberReference()
{
var method = compilation.FindType(typeof(GenericClass<string, object>)).GetMethods(m => m.Name == "GetIndex").Single();
Assert.AreSame(method.TypeParameters[0], method.Parameters[0].Type);
@ -347,6 +347,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -347,6 +347,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
var testClass = GetTypeDefinition(typeof(PropertyTest));
IProperty p = testClass.Properties.Single(pr => pr.IsIndexer);
Assert.IsTrue(p.CanGet);
Assert.AreEqual(EntityType.Accessor, p.Getter.EntityType);
Assert.AreEqual("get_Item", p.Getter.Name);
Assert.AreEqual(Accessibility.Public, p.Getter.Accessibility);
Assert.AreEqual(new[] { "index" }, p.Getter.Parameters.Select(x => x.Name).ToArray());
@ -360,6 +361,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -360,6 +361,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
var testClass = GetTypeDefinition(typeof(PropertyTest));
IProperty p = testClass.Properties.Single(pr => pr.IsIndexer);
Assert.IsTrue(p.CanSet);
Assert.AreEqual(EntityType.Accessor, p.Setter.EntityType);
Assert.AreEqual("set_Item", p.Setter.Name);
Assert.AreEqual(Accessibility.Public, p.Setter.Accessibility);
Assert.AreEqual(new[] { "index", "value" }, p.Setter.Parameters.Select(x => x.Name).ToArray());
@ -934,6 +936,15 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -934,6 +936,15 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.That(prop.Setter.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { "ICSharpCode.NRefactory.TypeSystem.TestCase.IInterfaceWithProperty.set_Prop" }));
}
[Test]
public void PropertyAccessorsShouldSupportToMemberReference()
{
ITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsProperty));
var prop = type.Properties.Single(p => p.Name == "Prop");
var mr = prop.Getter.ToMemberReference();
Assert.AreEqual(prop.Getter, mr.Resolve(compilation.TypeResolveContext));
}
[Test]
public void IndexerAccessorsShouldBeReportedAsImplementingTheCorrectInterfaceAccessors() {
ITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsIndexers));
@ -972,6 +983,15 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -972,6 +983,15 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.That(type.Properties.All(p => p.Setter.ImplementedInterfaceMembers.Count == 1));
}
[Test]
public void ExplicitlyImplementedPropertyAccessorsShouldSupportToMemberReference()
{
ITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsPropertyExplicitly));
var prop = type.Properties.Single();
var mr = prop.Getter.ToMemberReference();
Assert.AreEqual(prop.Getter, mr.Resolve(compilation.TypeResolveContext));
}
[Test]
public void ExplicitDisposableImplementation()
{
@ -1037,6 +1057,15 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1037,6 +1057,15 @@ namespace ICSharpCode.NRefactory.TypeSystem
Assert.That(prop.Getter.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { "ICSharpCode.NRefactory.TypeSystem.TestCase.IInterfaceWithProperty.get_Prop" }));
Assert.That(prop.Setter.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { "ICSharpCode.NRefactory.TypeSystem.TestCase.IInterfaceWithProperty.set_Prop" }));
}
[Test]
public void ExplicitlyImplementedPropertiesShouldHaveExplicitlyImplementedAccessors() {
ITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsPropertyExplicitly));
var prop = type.Properties.Single();
Assert.IsTrue(prop.IsExplicitInterfaceImplementation);
Assert.IsTrue(prop.Getter.IsExplicitInterfaceImplementation);
Assert.IsTrue(prop.Setter.IsExplicitInterfaceImplementation);
}
[Test]
public void EventAccessorsShouldBeReportedAsImplementingInterfaceAccessors() {
@ -1057,7 +1086,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1057,7 +1086,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
[Test]
public void ExplicitlyImplementedEventsShouldBeReportedAsBeingImplemented() {
public void ExplicitlyImplementedEventsShouldBeReportedAsBeingImplemented()
{
ITypeDefinition type = GetTypeDefinition(typeof(ClassThatImplementsEventExplicitly));
var evt = type.Events.Single();
Assert.That(evt.ImplementedInterfaceMembers.Select(p => p.ReflectionName).ToList(), Is.EqualTo(new[] { "ICSharpCode.NRefactory.TypeSystem.TestCase.IHasEvent.Event" }));

1
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -136,6 +136,7 @@ @@ -136,6 +136,7 @@
<Compile Include="TypeSystem\Implementation\AbstractType.cs" />
<Compile Include="TypeSystem\Implementation\AbstractUnresolvedEntity.cs" />
<Compile Include="TypeSystem\Implementation\AbstractUnresolvedMember.cs" />
<Compile Include="TypeSystem\Implementation\AccessorOwnerMemberReference.cs" />
<Compile Include="TypeSystem\Implementation\BaseTypeCollector.cs" />
<Compile Include="TypeSystem\Implementation\DefaultAssemblyReference.cs" />
<Compile Include="TypeSystem\Implementation\DefaultMemberReference.cs" />

14
ICSharpCode.NRefactory/TypeSystem/AnonymousType.cs

@ -116,6 +116,20 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -116,6 +116,20 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
}
public override IEnumerable<IMethod> GetAccessors(Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
{
for (int i = 0; i < unresolvedProperties.Length; i++) {
if (unresolvedProperties[i].CanGet) {
if (filter == null || filter(unresolvedProperties[i].Getter))
yield return resolvedProperties[i].Getter;
}
if (unresolvedProperties[i].CanSet) {
if (filter == null || filter(unresolvedProperties[i].Setter))
yield return resolvedProperties[i].Setter;
}
}
}
public override int GetHashCode()
{
unchecked {

48
ICSharpCode.NRefactory/TypeSystem/ArrayType.cs

@ -96,36 +96,34 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -96,36 +96,34 @@ namespace ICSharpCode.NRefactory.TypeSystem
public override IEnumerable<IMethod> GetMethods(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
return compilation.FindType(KnownTypeCode.Array).GetMethods(filter, options);
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IMethod>.Instance;
else
return compilation.FindType(KnownTypeCode.Array).GetMethods(filter, options);
}
public override IEnumerable<IMethod> GetMethods(IList<IType> typeArguments, Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IMethod>.Instance;
else
return compilation.FindType(KnownTypeCode.Array).GetMethods(typeArguments, filter, options);
}
//static readonly DefaultUnresolvedParameter indexerParam = new DefaultUnresolvedParameter(KnownTypeReference.Int32, string.Empty);
public override IEnumerable<IMethod> GetAccessors(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IMethod>.Instance;
else
return compilation.FindType(KnownTypeCode.Array).GetAccessors(filter, options);
}
public override IEnumerable<IProperty> GetProperties(Predicate<IUnresolvedProperty> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
ITypeDefinition arrayDef = compilation.FindType(KnownTypeCode.Array) as ITypeDefinition;
if (arrayDef != null) {
if ((options & GetMemberOptions.IgnoreInheritedMembers) == 0) {
foreach (IProperty p in arrayDef.GetProperties(filter, options)) {
yield return p;
}
}
/*DefaultUnresolvedProperty indexer = new DefaultUnresolvedProperty(arrayDef, "Items") {
EntityType = EntityType.Indexer,
ReturnType = elementType,
Accessibility = Accessibility.Public,
Getter = DefaultAccessor.GetFromAccessibility(Accessibility.Public),
Setter = DefaultAccessor.GetFromAccessibility(Accessibility.Public),
IsSynthetic = true
};
for (int i = 0; i < dimensions; i++) {
indexer.Parameters.Add(indexerParam);
}
indexer.Freeze();
if (filter == null || filter(indexer)) {
yield return indexer.CreateResolved(context);
}*/
}
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IProperty>.Instance;
else
return compilation.FindType(KnownTypeCode.Array).GetProperties(filter, options);
}
// NestedTypes, Events, Fields: System.Array doesn't have any; so we can use the AbstractType default implementation

98
ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs

@ -89,15 +89,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -89,15 +89,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
this.InterningProvider = new SimpleInterningProvider();
}
void ReadExplicitInterfaceImplementation(DefaultUnresolvedMethod m, MethodDefinition method) {
if (method.Name.Contains(".") && method.HasOverrides) {
m.IsExplicitInterfaceImplementation = true;
foreach (var or in method.Overrides) {
m.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(EntityType.Method, ReadTypeReference(or.DeclaringType), or.Name, or.GenericParameters.Count, m.Parameters.Select(p => p.Type).ToList(), false));
}
}
}
#region Load From AssemblyDefinition
/// <summary>
/// Loads the assembly definition into a project content.
@ -1656,10 +1647,10 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1656,10 +1647,10 @@ namespace ICSharpCode.NRefactory.TypeSystem
[CLSCompliant(false)]
public IUnresolvedMethod ReadMethod(MethodDefinition method, IUnresolvedTypeDefinition parentType, EntityType methodType = EntityType.Method)
{
return ReadMethod(method, parentType, null, methodType);
return ReadMethod(method, parentType, methodType, null);
}
IUnresolvedMethod ReadMethod(MethodDefinition method, IUnresolvedTypeDefinition parentType, IUnresolvedMember accessorOwner, EntityType methodType = EntityType.Method, bool readExplicitInterfaceImplementation = true)
IUnresolvedMethod ReadMethod(MethodDefinition method, IUnresolvedTypeDefinition parentType, EntityType methodType, IUnresolvedMember accessorOwner)
{
if (method == null)
return null;
@ -1695,9 +1686,19 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1695,9 +1686,19 @@ namespace ICSharpCode.NRefactory.TypeSystem
m.IsExtensionMethod = true;
}
if (readExplicitInterfaceImplementation)
ReadExplicitInterfaceImplementation(m, method);
int lastDot = method.Name.LastIndexOf('.');
if (lastDot >= 0 && method.HasOverrides) {
// To be consistent with the parser-initialized type system, shorten the method name:
m.Name = method.Name.Substring(lastDot + 1);
m.IsExplicitInterfaceImplementation = true;
foreach (var or in method.Overrides) {
m.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
accessorOwner != null ? EntityType.Accessor : EntityType.Method,
ReadTypeReference(or.DeclaringType),
or.Name, or.GenericParameters.Count, m.Parameters.Select(p => p.Type).ToList()));
}
}
FinishReadMember(m, method);
return m;
}
@ -1895,8 +1896,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1895,8 +1896,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
TranslateModifiers(property.GetMethod ?? property.SetMethod, p);
p.ReturnType = ReadTypeReference(property.PropertyType, typeAttributes: property);
p.Getter = ReadMethod(property.GetMethod, parentType, p);
p.Setter = ReadMethod(property.SetMethod, parentType, p);
p.Getter = ReadMethod(property.GetMethod, parentType, EntityType.Accessor, p);
p.Setter = ReadMethod(property.SetMethod, parentType, EntityType.Accessor, p);
if (property.HasParameters) {
foreach (ParameterDefinition par in property.Parameters) {
@ -1905,31 +1906,15 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1905,31 +1906,15 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
AddAttributes(property, p);
int lastDot = property.Name.LastIndexOf('.');
if (lastDot >= 0) {
string name = property.Name.Substring(lastDot + 1);
if (p.Getter != null && p.Getter.IsExplicitInterfaceImplementation) {
p.IsExplicitInterfaceImplementation = true;
foreach (var x in p.Getter.ExplicitInterfaceImplementations) {
p.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(p.Parameters.Count == 0 ? EntityType.Property : EntityType.Indexer, x.DeclaringTypeReference, name, 0, p.Parameters.Select(y => y.Type).ToList()));
}
}
else if (p.Setter != null && p.Setter.IsExplicitInterfaceImplementation) {
p.IsExplicitInterfaceImplementation = true;
foreach (var x in p.Setter.ExplicitInterfaceImplementations) {
p.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(p.Parameters.Count == 0 ? EntityType.Property : EntityType.Indexer, x.DeclaringTypeReference, name, 0, p.Parameters.Select(y => y.Type).ToList()));
}
var accessor = p.Getter ?? p.Setter;
if (accessor != null && accessor.IsExplicitInterfaceImplementation) {
p.Name = property.Name.Substring(property.Name.LastIndexOf('.') + 1);
p.IsExplicitInterfaceImplementation = true;
foreach (var mr in accessor.ExplicitInterfaceImplementations) {
p.ExplicitInterfaceImplementations.Add(new AccessorOwnerMemberReference(mr));
}
}
// This is very hacky. Due to which code parts are taken later in the execution, we need to pretend that the accessors are not explicit interface implementations at this stage.
if (p.Getter != null && p.Getter.IsExplicitInterfaceImplementation) {
p.Getter = ReadMethod(property.GetMethod, parentType, p, readExplicitInterfaceImplementation: false);
}
if (p.Setter != null && p.Setter.IsExplicitInterfaceImplementation) {
p.Setter = ReadMethod(property.GetMethod, parentType, p, readExplicitInterfaceImplementation: false);
}
FinishReadMember(p, property);
return p;
}
@ -1948,38 +1933,19 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1948,38 +1933,19 @@ namespace ICSharpCode.NRefactory.TypeSystem
TranslateModifiers(ev.AddMethod, e);
e.ReturnType = ReadTypeReference(ev.EventType, typeAttributes: ev);
e.AddAccessor = ReadMethod(ev.AddMethod, parentType, e);
e.RemoveAccessor = ReadMethod(ev.RemoveMethod, parentType, e);
e.InvokeAccessor = ReadMethod(ev.InvokeMethod, parentType, e);
e.AddAccessor = ReadMethod(ev.AddMethod, parentType, EntityType.Accessor, e);
e.RemoveAccessor = ReadMethod(ev.RemoveMethod, parentType, EntityType.Accessor, e);
e.InvokeAccessor = ReadMethod(ev.InvokeMethod, parentType, EntityType.Accessor, e);
AddAttributes(ev, e);
int lastDot = ev.Name.LastIndexOf('.');
if (lastDot >= 0) {
string name = ev.Name.Substring(lastDot + 1);
if (e.AddAccessor != null && e.AddAccessor.IsExplicitInterfaceImplementation) {
e.IsExplicitInterfaceImplementation = true;
foreach (var x in e.AddAccessor.ExplicitInterfaceImplementations) {
e.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(EntityType.Event, x.DeclaringTypeReference, name));
}
var accessor = e.AddAccessor ?? e.RemoveAccessor ?? e.InvokeAccessor;
if (accessor != null && accessor.IsExplicitInterfaceImplementation) {
e.Name = ev.Name.Substring(ev.Name.LastIndexOf('.') + 1);
e.IsExplicitInterfaceImplementation = true;
foreach (var mr in accessor.ExplicitInterfaceImplementations) {
e.ExplicitInterfaceImplementations.Add(new AccessorOwnerMemberReference(mr));
}
else if (e.RemoveAccessor != null && e.RemoveAccessor.IsExplicitInterfaceImplementation) {
e.IsExplicitInterfaceImplementation = true;
foreach (var x in e.RemoveAccessor.ExplicitInterfaceImplementations) {
e.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(EntityType.Event, x.DeclaringTypeReference, name));
}
}
}
// This is very hacky. Due to which code parts are taken later in the execution, we need to pretend that the accessors are not explicit interface implementations at this stage.
if (e.AddAccessor != null && e.AddAccessor.IsExplicitInterfaceImplementation) {
e.AddAccessor = ReadMethod(ev.AddMethod, parentType, e, readExplicitInterfaceImplementation: false);
}
if (e.RemoveAccessor != null && e.RemoveAccessor.IsExplicitInterfaceImplementation) {
e.RemoveAccessor = ReadMethod(ev.RemoveMethod, parentType, e, readExplicitInterfaceImplementation: false);
}
if (e.InvokeAccessor != null && e.InvokeAccessor.IsExplicitInterfaceImplementation) {
e.InvokeAccessor = ReadMethod(ev.InvokeMethod, parentType, e, readExplicitInterfaceImplementation: false);
}
FinishReadMember(e, ev);

3
ICSharpCode.NRefactory/TypeSystem/EntityType.cs

@ -31,6 +31,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -31,6 +31,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
Method,
Operator,
Constructor,
Destructor
Destructor,
Accessor
}
}

15
ICSharpCode.NRefactory/TypeSystem/IType.cs

@ -194,7 +194,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -194,7 +194,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// <param name="options">Specified additional options for the GetMembers() operation.</param>
/// <remarks>
/// <para>
/// The result does not include constructors.
/// The result does not include constructors or accessors.
/// </para>
/// <para>
/// For methods on parameterized types, type substitution will be performed on the method signature,
@ -221,7 +221,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -221,7 +221,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// The filter is tested on the original method definitions (before specialization).</param>
/// <param name="options">Specified additional options for the GetMembers() operation.</param>
/// <remarks>
/// <para>The result does not include constructors.</para>
/// <para>The result does not include constructors or accessors.</para>
/// <para>
/// Type substitution will be performed on the method signature, creating a <see cref="Implementation.SpecializedMethod"/>
/// with the specified type arguments.
@ -288,6 +288,17 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -288,6 +288,17 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// </para>
/// </remarks>
IEnumerable<IMember> GetMembers(Predicate<IUnresolvedMember> filter = null, GetMemberOptions options = GetMemberOptions.None);
/// <summary>
/// Gets all accessors belonging to properties or events on this type.
/// </summary>
/// <param name="filter">The filter used to select which members to return.
/// The filter is tested on the original member definitions (before specialization).</param>
/// <param name="options">Specified additional options for the GetMembers() operation.</param>
/// <remarks>
/// Accessors are not returned by GetMembers() or GetMethods().
/// </remarks>
IEnumerable<IMethod> GetAccessors(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None);
}
[Flags]

8
ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs

@ -294,6 +294,14 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -294,6 +294,14 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return GetMembersHelper.GetMembers(this, FilterNonStatic(filter), options);
}
public IEnumerable<IMethod> GetAccessors(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers)
return EmptyList<IMethod>.Instance;
else
return GetMembersHelper.GetAccessors(this, FilterNonStatic(filter), options);
}
static Predicate<T> FilterNonStatic<T>(Predicate<T> filter) where T : class, IUnresolvedMember
{
if (filter == null)

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

@ -123,6 +123,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -123,6 +123,11 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
.Concat(GetEvents(filter, options));
}
public virtual IEnumerable<IMethod> GetAccessors(Predicate<IUnresolvedMethod> filter, GetMemberOptions options = GetMemberOptions.None)
{
return EmptyList<IMethod>.Instance;
}
public override sealed bool Equals(object obj)
{
return Equals(obj as IType);

51
ICSharpCode.NRefactory/TypeSystem/Implementation/AccessorOwnerMemberReference.cs

@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
/// <summary>
/// Given a reference to an accessor, returns the accessor's owner.
/// </summary>
[Serializable]
sealed class AccessorOwnerMemberReference : IMemberReference
{
readonly IMemberReference accessorReference;
public AccessorOwnerMemberReference(IMemberReference accessorReference)
{
if (accessorReference == null)
throw new ArgumentNullException("accessorReference");
this.accessorReference = accessorReference;
}
public ITypeReference DeclaringTypeReference {
get { return accessorReference.DeclaringTypeReference; }
}
public IMember Resolve(ITypeResolveContext context)
{
IMethod method = accessorReference.Resolve(context) as IMethod;
if (method != null)
return method.AccessorOwner;
else
return null;
}
}
}

12
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultMemberReference.cs

@ -38,9 +38,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -38,9 +38,8 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
string name;
int typeParameterCount;
IList<ITypeReference> parameterTypes;
bool isExplicitInterfaceImplementation;
public DefaultMemberReference(EntityType entityType, ITypeReference typeReference, string name, int typeParameterCount = 0, IList<ITypeReference> parameterTypes = null, bool isExplicitInterfaceImplementation = false)
public DefaultMemberReference(EntityType entityType, ITypeReference typeReference, string name, int typeParameterCount = 0, IList<ITypeReference> parameterTypes = null)
{
if (typeReference == null)
throw new ArgumentNullException("typeReference");
@ -53,7 +52,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -53,7 +52,6 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
this.name = name;
this.typeParameterCount = typeParameterCount;
this.parameterTypes = parameterTypes ?? EmptyList<ITypeReference>.Instance;
this.isExplicitInterfaceImplementation = isExplicitInterfaceImplementation;
}
public ITypeReference DeclaringTypeReference {
@ -64,14 +62,16 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -64,14 +62,16 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
{
IType type = typeReference.Resolve(context);
IEnumerable<IMember> members;
if (entityType == EntityType.Method) {
if (entityType == EntityType.Accessor) {
members = type.GetAccessors(m => m.Name == name && !m.IsExplicitInterfaceImplementation);
} else if (entityType == EntityType.Method) {
members = type.GetMethods(
m => m.Name == name && m.EntityType == EntityType.Method
&& m.TypeParameters.Count == typeParameterCount && m.IsExplicitInterfaceImplementation == isExplicitInterfaceImplementation,
&& m.TypeParameters.Count == typeParameterCount && !m.IsExplicitInterfaceImplementation,
GetMemberOptions.IgnoreInheritedMembers);
} else {
members = type.GetMembers(
m => m.Name == name && m.EntityType == entityType && m.IsExplicitInterfaceImplementation == isExplicitInterfaceImplementation,
m => m.Name == name && m.EntityType == entityType && !m.IsExplicitInterfaceImplementation,
GetMemberOptions.IgnoreInheritedMembers);
}
var resolvedParameterTypes = parameterTypes.Resolve(context);

32
ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs

@ -830,6 +830,38 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -830,6 +830,38 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
return GetMembersHelper.GetMembers(this, filter, options);
}
}
public virtual IEnumerable<IMethod> GetAccessors(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetFilteredAccessors(filter);
} else {
return GetMembersHelper.GetAccessors(this, filter, options);
}
}
IEnumerable<IMethod> GetFilteredAccessors(Predicate<IUnresolvedMethod> filter)
{
var members = GetMemberList();
for (int i = 0; i < members.unresolvedMembers.Length; i++) {
IUnresolvedMember unresolved = members.unresolvedMembers[i];
var unresolvedProperty = unresolved as IUnresolvedProperty;
var unresolvedEvent = unresolved as IUnresolvedEvent;
if (unresolvedProperty != null) {
if (unresolvedProperty.CanGet && (filter == null || filter(unresolvedProperty.Getter)))
yield return ((IProperty)members[i]).Getter;
if (unresolvedProperty.CanSet && (filter == null || filter(unresolvedProperty.Setter)))
yield return ((IProperty)members[i]).Setter;
} else if (unresolvedEvent != null) {
if (unresolvedEvent.CanAdd && (filter == null || filter(unresolvedEvent.AddAccessor)))
yield return ((IEvent)members[i]).AddAccessor;
if (unresolvedEvent.CanRemove && (filter == null || filter(unresolvedEvent.RemoveAccessor)))
yield return ((IEvent)members[i]).RemoveAccessor;
if (unresolvedEvent.CanInvoke && (filter == null || filter(unresolvedEvent.InvokeAccessor)))
yield return ((IEvent)members[i]).InvokeAccessor;
}
}
}
#endregion
public bool Equals(IType other)

14
ICSharpCode.NRefactory/TypeSystem/Implementation/ExplicitInterfaceImplementationMemberReference.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ICSharpCode.NRefactory.TypeSystem.Implementation
@ -58,9 +59,16 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -58,9 +59,16 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
IMember interfaceMember = interfaceMemberReference.Resolve(context.WithCurrentTypeDefinition(declaringType.GetDefinition()));
if (interfaceMember == null)
return null;
var members = declaringType.GetMembers(
m => m.EntityType == interfaceMember.EntityType && m.IsExplicitInterfaceImplementation,
GetMemberOptions.IgnoreInheritedMembers);
IEnumerable<IMember> members;
if (interfaceMember.EntityType == EntityType.Accessor) {
members = declaringType.GetAccessors(
m => m.IsExplicitInterfaceImplementation,
GetMemberOptions.IgnoreInheritedMembers);
} else {
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]));
}
}

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

@ -142,6 +142,22 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -142,6 +142,22 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
#endregion
#region GetAccessors
public static IEnumerable<IMethod> GetAccessors(IType type, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
{
if ((options & GetMemberOptions.IgnoreInheritedMembers) == GetMemberOptions.IgnoreInheritedMembers) {
return GetAccessorsImpl(type, filter, options);
} else {
return type.GetNonInterfaceBaseTypes().SelectMany(t => GetAccessorsImpl(t, filter, options));
}
}
static IEnumerable<IMethod> GetAccessorsImpl(IType baseType, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
{
return GetConstructorsOrAccessorsImpl(baseType, baseType.GetAccessors(filter, options | declaredMembers), filter, options);
}
#endregion
#region GetConstructors
public static IEnumerable<IMethod> GetConstructors(IType type, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
{
@ -154,17 +170,21 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation @@ -154,17 +170,21 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
static IEnumerable<IMethod> GetConstructorsImpl(IType baseType, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
{
IEnumerable<IMethod> declaredCtors = baseType.GetConstructors(filter, options | declaredMembers);
return GetConstructorsOrAccessorsImpl(baseType, baseType.GetConstructors(filter, options | declaredMembers), filter, options);
}
static IEnumerable<IMethod> GetConstructorsOrAccessorsImpl(IType baseType, IEnumerable<IMethod> declaredMembers, Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
{
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions) {
return declaredCtors;
return declaredMembers;
}
ParameterizedType pt = baseType as ParameterizedType;
if (pt != null) {
var substitution = pt.GetSubstitution();
return declaredCtors.Select(m => new SpecializedMethod(m, substitution) { DeclaringType = pt });
return declaredMembers.Select(m => new SpecializedMethod(m, substitution) { DeclaringType = pt });
} else {
return declaredCtors;
return declaredMembers;
}
}
#endregion

54
ICSharpCode.NRefactory/TypeSystem/InheritanceHelper.cs

@ -40,46 +40,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -40,46 +40,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
return GetBaseMembers(member, false).FirstOrDefault();
}
private static IEnumerable<IMember> GetBaseAccessors(IMethod accessor, bool includeImplementedInterfaces) {
IMember accessorOwner = accessor.AccessorOwner;
SpecializedMember specializedMember = accessor as SpecializedMember;
foreach (IMember baseOwner in GetBaseMembers(accessorOwner, includeImplementedInterfaces)) {
if (accessorOwner is IProperty && baseOwner is IProperty) {
var accessorProperty = (IProperty)accessorOwner;
var baseProperty = (IProperty)baseOwner;
if (accessor == accessorProperty.Getter && baseProperty.CanGet) {
if (specializedMember != null)
yield return SpecializedMember.Create(baseProperty.Getter, specializedMember.Substitution);
else
yield return baseProperty.Getter;
}
if (accessor == accessorProperty.Setter && baseProperty.CanSet) {
if (specializedMember != null)
yield return SpecializedMember.Create(baseProperty.Setter, specializedMember.Substitution);
else
yield return baseProperty.Setter;
}
}
else if (accessorOwner is IEvent && baseOwner is IEvent) {
var accessorEvent = (IEvent)accessorOwner;
var baseEvent = (IEvent)baseOwner;
if (accessor == accessorEvent.AddAccessor && baseEvent.CanAdd) {
if (specializedMember != null)
yield return SpecializedMember.Create(baseEvent.AddAccessor, specializedMember.Substitution);
else
yield return baseEvent.AddAccessor;
}
if (accessor == accessorEvent.RemoveAccessor && baseEvent.CanRemove) {
if (specializedMember != null)
yield return SpecializedMember.Create(baseEvent.RemoveAccessor, specializedMember.Substitution);
else
yield return baseEvent.RemoveAccessor;
}
}
}
}
/// <summary>
/// Gets all base members that have the same signature.
/// </summary>
@ -99,12 +59,6 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -99,12 +59,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
SpecializedMember specializedMember = member as SpecializedMember;
member = member.MemberDefinition;
if (member is IMethod && ((IMethod)member).IsAccessor) {
foreach (IMember m in GetBaseAccessors((IMethod)member, includeImplementedInterfaces))
yield return m;
yield break;
}
IEnumerable<IType> allBaseTypes;
if (includeImplementedInterfaces) {
@ -116,7 +70,13 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -116,7 +70,13 @@ namespace ICSharpCode.NRefactory.TypeSystem
if (baseType == member.DeclaringTypeDefinition)
continue;
foreach (IMember baseMember in baseType.GetMembers(m => m.Name == member.Name, GetMemberOptions.IgnoreInheritedMembers)) {
IEnumerable<IMember> baseMembers;
if (member.EntityType == EntityType.Accessor) {
baseMembers = baseType.GetAccessors(m => m.Name == member.Name && !m.IsExplicitInterfaceImplementation, GetMemberOptions.IgnoreInheritedMembers);
} else {
baseMembers = baseType.GetMembers(m => m.Name == member.Name && !m.IsExplicitInterfaceImplementation, GetMemberOptions.IgnoreInheritedMembers);
}
foreach (IMember baseMember in baseMembers) {
if (SignatureComparer.Ordinal.Equals(member, baseMember)) {
if (specializedMember != null)
yield return SpecializedMember.Create(baseMember, specializedMember.Substitution);

5
ICSharpCode.NRefactory/TypeSystem/IntersectionType.cs

@ -162,6 +162,11 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -162,6 +162,11 @@ namespace ICSharpCode.NRefactory.TypeSystem
return GetMembersHelper.GetMembers(this, FilterNonStatic(filter), options);
}
public override IEnumerable<IMethod> GetAccessors(Predicate<IUnresolvedMethod> filter, GetMemberOptions options)
{
return GetMembersHelper.GetAccessors(this, FilterNonStatic(filter), options);
}
static Predicate<T> FilterNonStatic<T>(Predicate<T> filter) where T : class, IUnresolvedMember
{
if (filter == null)

8
ICSharpCode.NRefactory/TypeSystem/ParameterizedType.cs

@ -259,6 +259,14 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -259,6 +259,14 @@ namespace ICSharpCode.NRefactory.TypeSystem
return GetMembersHelper.GetMembers(this, filter, options);
}
public IEnumerable<IMethod> GetAccessors(Predicate<IUnresolvedMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
if ((options & GetMemberOptions.ReturnMemberDefinitions) == GetMemberOptions.ReturnMemberDefinitions)
return genericType.GetAccessors(filter, options);
else
return GetMembersHelper.GetAccessors(this, filter, options);
}
public override bool Equals(object obj)
{
return Equals(obj as IType);

Loading…
Cancel
Save