Browse Source

Support virtual modifier on static abstract interface members.

pull/3050/head
Siegfried Pammer 2 years ago
parent
commit
6172d63ff3
  1. 50
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/StaticAbstractInterfaceMembers.cs
  2. 10
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  3. 19
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs

50
ICSharpCode.Decompiler.Tests/TestCases/Pretty/StaticAbstractInterfaceMembers.cs

@ -2,16 +2,54 @@ @@ -2,16 +2,54 @@
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.StaticAbstractInterfaceMembers
{
public interface I
internal interface I<T> where T : I<T>
{
static abstract T P { get; set; }
static abstract event Action E;
static abstract void M();
static abstract T operator +(T l, T r);
static abstract bool operator ==(T l, T r);
static abstract bool operator !=(T l, T r);
static abstract implicit operator T(string s);
static abstract explicit operator string(T t);
}
public interface IAmSimple
{
static abstract int Capacity { get; }
static abstract int Count { get; set; }
static abstract int SetterOnly { set; }
static abstract event EventHandler E;
static abstract I CreateI();
static abstract IAmSimple CreateI();
}
internal interface IAmStatic<T> where T : IAmStatic<T>
{
static T P { get; set; }
static event Action E;
static void M()
{
}
static T operator +(IAmStatic<T> l, T r)
{
throw new NotImplementedException();
}
}
internal interface IAmVirtual<T> where T : IAmVirtual<T>
{
static virtual T P { get; set; }
static virtual event Action E;
static virtual void M()
{
}
static virtual T operator +(T l, T r)
{
throw new NotImplementedException();
}
}
public class X : I
public class X : IAmSimple
{
public static int Capacity { get; }
@ -24,13 +62,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.StaticAbstractInterfaceM @@ -24,13 +62,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.StaticAbstractInterfaceM
public static event EventHandler E;
public static I CreateI()
public static IAmSimple CreateI()
{
return new X();
}
}
public class X2 : I
public class X2 : IAmSimple
{
public static int Capacity {
get {
@ -61,7 +99,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.StaticAbstractInterfaceM @@ -61,7 +99,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.StaticAbstractInterfaceM
}
}
public static I CreateI()
public static IAmSimple CreateI()
{
throw new NotImplementedException();
}

10
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -2373,8 +2373,14 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -2373,8 +2373,14 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
{
m |= Modifiers.Sealed;
}
if (member.IsAbstract && member.IsStatic)
m |= Modifiers.Abstract;
if (member.IsStatic)
{
// modifiers of static members in interfaces:
if (member.IsAbstract)
m |= Modifiers.Abstract;
else if (member.IsVirtual && !member.IsOverride)
m |= Modifiers.Virtual;
}
}
else
{

19
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs

@ -576,8 +576,23 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -576,8 +576,23 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public bool IsStatic => (attributes & MethodAttributes.Static) != 0;
public bool IsAbstract => (attributes & MethodAttributes.Abstract) != 0;
public bool IsSealed => (attributes & (MethodAttributes.Abstract | MethodAttributes.Final | MethodAttributes.NewSlot | MethodAttributes.Static)) == MethodAttributes.Final;
public bool IsVirtual => (attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final)) == (MethodAttributes.Virtual | MethodAttributes.NewSlot);
public bool IsOverride => (attributes & (MethodAttributes.NewSlot | MethodAttributes.Virtual)) == MethodAttributes.Virtual;
public bool IsVirtual {
get {
if (IsStatic)
{
return (attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) == MethodAttributes.Virtual;
}
else
{
const MethodAttributes mask = MethodAttributes.Abstract | MethodAttributes.Virtual
| MethodAttributes.NewSlot | MethodAttributes.Final;
return (attributes & mask) == (MethodAttributes.Virtual | MethodAttributes.NewSlot);
}
}
}
public bool IsOverride => (attributes & (MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Static)) == MethodAttributes.Virtual;
public bool IsOverridable
=> (attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) != 0
&& (attributes & MethodAttributes.Final) == 0;

Loading…
Cancel
Save