From 5911b13497f64ceb4d4c10e11a6aaddc736cddad Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 28 Sep 2019 20:41:21 +0200 Subject: [PATCH] Fix modifiers on default interface methods. --- .../TestCases/Pretty/InterfaceTests.cs | 36 +++++++++++++++++++ .../CSharp/Syntax/TypeSystemAstBuilder.cs | 22 ++++++++---- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InterfaceTests.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InterfaceTests.cs index 3a539c9c1..d26c1fb68 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InterfaceTests.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/InterfaceTests.cs @@ -16,6 +16,9 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +// We can't test this because "error CS8701: Target runtime doesn't support default interface implementation." +#undef CS80 + using System; namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -37,9 +40,42 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty event EventHandler MyEvent; void Method(); + +#if CS80 + void DefaultMethod() + { + Method(); + PrivateMethod(); + } + + private void PrivateMethod() + { + Method(); + } + + internal void InternalMethod() + { + Method(); + } + + sealed void SealedMethod() + { + Method(); + } + + static void StaticMethod() + { + + } +#endif } public interface IA2 : IA { +#if CS80 + void IA.InternalMethod() + { + } +#endif } public interface IB { diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs index f39442bd8..64d677fb4 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs @@ -1741,8 +1741,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax bool NeedsAccessibility(IMember member) { var declaringType = member.DeclaringType; - if ((declaringType != null && declaringType.Kind == TypeKind.Interface) || member.IsExplicitInterfaceImplementation) + if (member.IsExplicitInterfaceImplementation) return false; + if (declaringType != null && declaringType.Kind == TypeKind.Interface) { + return member.Accessibility != Accessibility.Public; + } switch (member.SymbolKind) { case SymbolKind.Constructor: return !member.IsStatic; @@ -1764,13 +1767,18 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax m |= Modifiers.Static; } else { var declaringType = member.DeclaringType; - if (member.IsAbstract && declaringType != null && declaringType.Kind != TypeKind.Interface) - m |= Modifiers.Abstract; - if (member.IsOverride) + if (declaringType.Kind == TypeKind.Interface) { + if (!member.IsVirtual && !member.IsAbstract && !member.IsOverride && member.Accessibility != Accessibility.Private) + m |= Modifiers.Sealed; + } else { + if (member.IsAbstract) + m |= Modifiers.Abstract; + else if (member.IsVirtual && !member.IsOverride) + m |= Modifiers.Virtual; + } + if (member.IsOverride && !member.IsExplicitInterfaceImplementation) m |= Modifiers.Override; - if (member.IsVirtual && !member.IsAbstract && !member.IsOverride && declaringType.Kind != TypeKind.Interface) - m |= Modifiers.Virtual; - if (member.IsSealed) + if (member.IsSealed && !member.IsExplicitInterfaceImplementation) m |= Modifiers.Sealed; if (member is IMethod method && method.ThisIsRefReadOnly && method.DeclaringTypeDefinition?.IsReadOnly == false) m |= Modifiers.Readonly;