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 @@
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.StaticAbstractInterfaceMembers 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 Capacity { get; }
static abstract int Count { get; set; } static abstract int Count { get; set; }
static abstract int SetterOnly { set; } static abstract int SetterOnly { set; }
static abstract event EventHandler E; 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; } public static int Capacity { get; }
@ -24,13 +62,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.StaticAbstractInterfaceM
public static event EventHandler E; public static event EventHandler E;
public static I CreateI() public static IAmSimple CreateI()
{ {
return new X(); return new X();
} }
} }
public class X2 : I public class X2 : IAmSimple
{ {
public static int Capacity { public static int Capacity {
get { get {
@ -61,7 +99,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.StaticAbstractInterfaceM
} }
} }
public static I CreateI() public static IAmSimple CreateI()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

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

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

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

@ -576,8 +576,23 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public bool IsStatic => (attributes & MethodAttributes.Static) != 0; public bool IsStatic => (attributes & MethodAttributes.Static) != 0;
public bool IsAbstract => (attributes & MethodAttributes.Abstract) != 0; public bool IsAbstract => (attributes & MethodAttributes.Abstract) != 0;
public bool IsSealed => (attributes & (MethodAttributes.Abstract | MethodAttributes.Final | MethodAttributes.NewSlot | MethodAttributes.Static)) == MethodAttributes.Final; 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 public bool IsOverridable
=> (attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) != 0 => (attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) != 0
&& (attributes & MethodAttributes.Final) == 0; && (attributes & MethodAttributes.Final) == 0;

Loading…
Cancel
Save