From 96caa4ecb793c2e3215f44b7c05f1bd4d9ccf08e Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 22 Mar 2025 12:27:22 +0100 Subject: [PATCH] Fix: #3407 Add "private protected" feature for 7.2 decompiler options --- .../CSharp/CSharpDecompiler.cs | 1 + .../CSharp/OutputVisitor/CSharpAmbience.cs | 1 + .../CSharp/Syntax/TypeSystemAstBuilder.cs | 21 ++++++++++++------- ICSharpCode.Decompiler/DecompilerSettings.cs | 21 ++++++++++++++++++- ICSharpCode.Decompiler/Output/IAmbience.cs | 5 +++++ ILSpy/Properties/Resources.Designer.cs | 19 +++++++++++++++++ ILSpy/Properties/Resources.resx | 5 ++++- ILSpy/Properties/Resources.zh-Hans.resx | 3 +++ 8 files changed, 67 insertions(+), 9 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index b9559dba1..6c881715f 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -528,6 +528,7 @@ namespace ICSharpCode.Decompiler.CSharp { var typeSystemAstBuilder = new TypeSystemAstBuilder(); typeSystemAstBuilder.ShowAttributes = true; + typeSystemAstBuilder.UsePrivateProtectedAccessibility = settings.IntroducePrivateProtectedAccessibility; typeSystemAstBuilder.SortAttributes = settings.SortCustomAttributes; typeSystemAstBuilder.AlwaysUseShortTypeNames = true; typeSystemAstBuilder.AddResolveResultAnnotations = true; diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs index aa290cbd8..35036232e 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs @@ -236,6 +236,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor astBuilder.ShowTypeParametersForUnboundTypes = true; astBuilder.ShowModifiers = (ConversionFlags & ConversionFlags.ShowModifiers) == ConversionFlags.ShowModifiers; astBuilder.ShowAccessibility = (ConversionFlags & ConversionFlags.ShowAccessibility) == ConversionFlags.ShowAccessibility; + astBuilder.UsePrivateProtectedAccessibility = (ConversionFlags & ConversionFlags.UsePrivateProtectedAccessibility) == ConversionFlags.UsePrivateProtectedAccessibility; astBuilder.AlwaysUseShortTypeNames = (ConversionFlags & ConversionFlags.UseFullyQualifiedTypeNames) != ConversionFlags.UseFullyQualifiedTypeNames; astBuilder.ShowParameterNames = (ConversionFlags & ConversionFlags.ShowParameterNames) == ConversionFlags.ShowParameterNames; astBuilder.UseNullableSpecifierForValueTypes = (ConversionFlags & ConversionFlags.UseNullableSpecifierForValueTypes) != 0; diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs index 2e21d93c6..3583c6a44 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs @@ -70,6 +70,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax this.UseKeywordsForBuiltinTypes = true; this.UseNullableSpecifierForValueTypes = true; this.ShowAccessibility = true; + this.UsePrivateProtectedAccessibility = true; this.ShowModifiers = true; this.ShowBaseTypes = true; this.ShowTypeParameters = true; @@ -93,13 +94,19 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax public bool AddResolveResultAnnotations { get; set; } /// - /// Controls the accessibility modifiers are shown. + /// Controls whether accessibility modifiers are shown. /// The default value is . /// public bool ShowAccessibility { get; set; } /// - /// Controls the non-accessibility modifiers are shown. + /// Controls whether "private protected" accessibility modifiers are shown. + /// The default value is . + /// + public bool UsePrivateProtectedAccessibility { get; set; } + + /// + /// Controls whether non-accessibility modifiers are shown. /// The default value is . /// public bool ShowModifiers { get; set; } @@ -1805,7 +1812,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax Modifiers modifiers = Modifiers.None; if (this.ShowAccessibility) { - modifiers |= ModifierFromAccessibility(typeDefinition.Accessibility); + modifiers |= ModifierFromAccessibility(typeDefinition.Accessibility, UsePrivateProtectedAccessibility); } if (this.ShowModifiers) { @@ -2073,7 +2080,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } } if (this.ShowAccessibility && accessor.Accessibility != ownerAccessibility) - decl.Modifiers = ModifierFromAccessibility(accessor.Accessibility); + decl.Modifiers = ModifierFromAccessibility(accessor.Accessibility, UsePrivateProtectedAccessibility); if (this.ShowModifiers && accessor.HasReadonlyModifier()) decl.Modifiers |= Modifiers.Readonly; TokenRole keywordRole = kind switch { @@ -2342,7 +2349,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax #endregion #region Convert Modifiers - public static Modifiers ModifierFromAccessibility(Accessibility accessibility) + public static Modifiers ModifierFromAccessibility(Accessibility accessibility, bool usePrivateProtected) { switch (accessibility) { @@ -2357,7 +2364,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax case Accessibility.ProtectedOrInternal: return Modifiers.Protected | Modifiers.Internal; case Accessibility.ProtectedAndInternal: - return Modifiers.Private | Modifiers.Protected; + return usePrivateProtected ? Modifiers.Private | Modifiers.Protected : Modifiers.Protected; default: return Modifiers.None; } @@ -2388,7 +2395,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax Modifiers m = Modifiers.None; if (this.ShowAccessibility && NeedsAccessibility(member)) { - m |= ModifierFromAccessibility(member.Accessibility); + m |= ModifierFromAccessibility(member.Accessibility, UsePrivateProtectedAccessibility); } if (this.ShowModifiers) { diff --git a/ICSharpCode.Decompiler/DecompilerSettings.cs b/ICSharpCode.Decompiler/DecompilerSettings.cs index b2d7f75e2..f4fac4485 100644 --- a/ICSharpCode.Decompiler/DecompilerSettings.cs +++ b/ICSharpCode.Decompiler/DecompilerSettings.cs @@ -112,6 +112,7 @@ namespace ICSharpCode.Decompiler introduceRefModifiersOnStructs = false; nonTrailingNamedArguments = false; refExtensionMethods = false; + introducePrivateProtectedAccessibilty = false; } if (languageVersion < CSharp.LanguageVersion.CSharp7_3) { @@ -185,7 +186,7 @@ namespace ICSharpCode.Decompiler || patternBasedFixedStatement) return CSharp.LanguageVersion.CSharp7_3; if (introduceRefModifiersOnStructs || introduceReadonlyAndInModifiers - || nonTrailingNamedArguments || refExtensionMethods) + || nonTrailingNamedArguments || refExtensionMethods || introducePrivateProtectedAccessibilty) return CSharp.LanguageVersion.CSharp7_2; // C# 7.1 missing if (outVariables || throwExpressions || tupleTypes || tupleConversions @@ -1418,6 +1419,24 @@ namespace ICSharpCode.Decompiler } } + bool introducePrivateProtectedAccessibilty = true; + + /// + /// Gets/Sets whether "private protected" should be used. + /// + [Category("C# 7.2 / VS 2017.4")] + [Description("DecompilerSettings.IntroducePrivateProtectedAccessibility")] + public bool IntroducePrivateProtectedAccessibility { + get { return introducePrivateProtectedAccessibilty; } + set { + if (introducePrivateProtectedAccessibilty != value) + { + introducePrivateProtectedAccessibilty = value; + OnPropertyChanged(); + } + } + } + bool readOnlyMethods = true; [Category("C# 8.0 / VS 2019")] diff --git a/ICSharpCode.Decompiler/Output/IAmbience.cs b/ICSharpCode.Decompiler/Output/IAmbience.cs index 6518313a4..6099678e0 100644 --- a/ICSharpCode.Decompiler/Output/IAmbience.cs +++ b/ICSharpCode.Decompiler/Output/IAmbience.cs @@ -117,9 +117,14 @@ namespace ICSharpCode.Decompiler.Output /// Support C# 11 operator checked. /// SupportOperatorChecked = 0x100000, + /// + /// Support C# 7.2 private protected. + /// + UsePrivateProtectedAccessibility = 0x200000, StandardConversionFlags = ShowParameterNames | ShowAccessibility | + UsePrivateProtectedAccessibility | ShowParameterList | ShowParameterModifiers | ShowParameterDefaultValues | diff --git a/ILSpy/Properties/Resources.Designer.cs b/ILSpy/Properties/Resources.Designer.cs index ce6597717..c2982ddda 100644 --- a/ILSpy/Properties/Resources.Designer.cs +++ b/ILSpy/Properties/Resources.Designer.cs @@ -1080,6 +1080,15 @@ namespace ICSharpCode.ILSpy.Properties { } } + /// + /// Looks up a localized string similar to Introduce 'private protected' accessibility. + /// + public static string DecompilerSettings_IntroducePrivateProtectedAccessibility { + get { + return ResourceManager.GetString("DecompilerSettings.IntroducePrivateProtectedAccessibility", resourceCulture); + } + } + /// /// Looks up a localized string similar to Introduce static local functions. /// @@ -1118,6 +1127,16 @@ namespace ICSharpCode.ILSpy.Properties { } } + /// + /// Looks up a localized resource of type System.Object. + /// + public static object DecompilerSettings_LifetimeAnnotations { + get { + object obj = ResourceManager.GetObject("DecompilerSettings.LifetimeAnnotations", resourceCulture); + return ((object)(obj)); + } + } + /// /// Looks up a localized string similar to Use nint/nuint types. /// diff --git a/ILSpy/Properties/Resources.resx b/ILSpy/Properties/Resources.resx index dd575638a..8b6e4ce23 100644 --- a/ILSpy/Properties/Resources.resx +++ b/ILSpy/Properties/Resources.resx @@ -595,7 +595,7 @@ Are you sure you want to continue? Enable folding on all blocks in braces - Enable smooth scrolling + Enable smooth scrolling Enable word wrap @@ -1108,4 +1108,7 @@ Do you want to continue? _Window + + Introduce 'private protected' accessibility + \ No newline at end of file diff --git a/ILSpy/Properties/Resources.zh-Hans.resx b/ILSpy/Properties/Resources.zh-Hans.resx index 472ac2503..0c6decb07 100644 --- a/ILSpy/Properties/Resources.zh-Hans.resx +++ b/ILSpy/Properties/Resources.zh-Hans.resx @@ -369,6 +369,9 @@ 引入局部函数(local functions) + + + 引入静态局部函数(static local functions)