Browse Source

Rework C# decompiler options dialog.

pull/1471/head
Siegfried Pammer 6 years ago
parent
commit
e9370f057c
  1. 114
      ICSharpCode.Decompiler/DecompilerSettings.cs
  2. 45
      ILSpy/DecompilationOptions.cs
  3. 5
      ILSpy/ILSpy.csproj
  4. 1
      ILSpy/Languages/CSharpLanguage.cs
  5. 58
      ILSpy/Options/CSharpDecompilerSettingsPanel.xaml
  6. 195
      ILSpy/Options/CSharpDecompilerSettingsPanel.xaml.cs
  7. 2
      ILSpy/Options/DecompilerSettingsPanel.xaml
  8. 2
      ILSpy/Options/DisplaySettingsPanel.xaml.cs
  9. 2
      ILSpy/Options/MiscSettingsPanel.xaml.cs

114
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -129,6 +129,8 @@ namespace ICSharpCode.Decompiler @@ -129,6 +129,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile anonymous methods/lambdas.
/// </summary>
[Category("C# 2.0 / VS 2005")]
[Description("Decompile anonymous methods/lambdas")]
public bool AnonymousMethods {
get { return anonymousMethods; }
set {
@ -144,6 +146,8 @@ namespace ICSharpCode.Decompiler @@ -144,6 +146,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile anonymous types.
/// </summary>
[Category("C# 3.0 / VS 2008")]
[Description("Decompile anonymous types")]
public bool AnonymousTypes {
get { return anonymousTypes; }
set {
@ -159,6 +163,8 @@ namespace ICSharpCode.Decompiler @@ -159,6 +163,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Use C# 3 lambda syntax if possible.
/// </summary>
[Category("C# 3.0 / VS 2008")]
[Description("Use lambda syntax, if possible")]
public bool UseLambdaSyntax {
get { return useLambdaSyntax; }
set {
@ -174,6 +180,8 @@ namespace ICSharpCode.Decompiler @@ -174,6 +180,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile expression trees.
/// </summary>
[Category("C# 3.0 / VS 2008")]
[Description("Decompile expression trees")]
public bool ExpressionTrees {
get { return expressionTrees; }
set {
@ -189,6 +197,8 @@ namespace ICSharpCode.Decompiler @@ -189,6 +197,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile enumerators.
/// </summary>
[Category("C# 2.0 / VS 2005")]
[Description("Decompile enumerators")]
public bool YieldReturn {
get { return yieldReturn; }
set {
@ -204,6 +214,8 @@ namespace ICSharpCode.Decompiler @@ -204,6 +214,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile use of the 'dynamic' type.
/// </summary>
[Category("C# 4.0 / VS 2010")]
[Description("Decompile use of the 'dynamic' type")]
public bool Dynamic {
get { return dynamic; }
set {
@ -219,6 +231,8 @@ namespace ICSharpCode.Decompiler @@ -219,6 +231,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile async methods.
/// </summary>
[Category("C# 5.0 / VS 2012")]
[Description("Decompile async methods")]
public bool AsyncAwait {
get { return asyncAwait; }
set {
@ -235,6 +249,8 @@ namespace ICSharpCode.Decompiler @@ -235,6 +249,8 @@ namespace ICSharpCode.Decompiler
/// Decompile await in catch/finally blocks.
/// Only has an effect if <see cref="AsyncAwait"/> is enabled.
/// </summary>
[Category("C# 6.0 / VS 2015")]
[Description("Decompile await in catch/finally blocks")]
public bool AwaitInCatchFinally {
get { return awaitInCatchFinally; }
set {
@ -250,6 +266,7 @@ namespace ICSharpCode.Decompiler @@ -250,6 +266,7 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile [DecimalConstant(...)] as simple literal values.
/// </summary>
[Description("Decompile [DecimalConstant(...)] as simple literal values")]
public bool DecimalConstants {
get { return decimalConstants; }
set {
@ -265,6 +282,8 @@ namespace ICSharpCode.Decompiler @@ -265,6 +282,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile C# 1.0 'public unsafe fixed int arr[10];' members.
/// </summary>
[Category("C# 1.0 / VS .NET")]
[Description("Decompile C# 1.0 'public unsafe fixed int arr[10];' members")]
public bool FixedBuffers {
get { return fixedBuffers; }
set {
@ -280,6 +299,8 @@ namespace ICSharpCode.Decompiler @@ -280,6 +299,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Use lifted operators for nullables.
/// </summary>
[Category("C# 2.0 / VS 2005")]
[Description("Use lifted operators for nullables")]
public bool LiftNullables {
get { return liftNullables; }
set {
@ -295,6 +316,8 @@ namespace ICSharpCode.Decompiler @@ -295,6 +316,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile C# 6 ?. and ?[] operators.
/// </summary>
[Category("C# 6.0 / VS 2015")]
[Description("Decompile ?. and ?[] operators")]
public bool NullPropagation {
get { return nullPropagation; }
set {
@ -310,6 +333,8 @@ namespace ICSharpCode.Decompiler @@ -310,6 +333,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile automatic properties
/// </summary>
[Category("C# 3.0 / VS 2008")]
[Description("Decompile automatic properties")]
public bool AutomaticProperties {
get { return automaticProperties; }
set {
@ -325,6 +350,8 @@ namespace ICSharpCode.Decompiler @@ -325,6 +350,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile automatic events
/// </summary>
[Category("C# 1.0 / VS .NET")]
[Description("Decompile automatic events")]
public bool AutomaticEvents {
get { return automaticEvents; }
set {
@ -340,6 +367,8 @@ namespace ICSharpCode.Decompiler @@ -340,6 +367,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile using statements.
/// </summary>
[Category("C# 1.0 / VS .NET")]
[Description("Detect using statements")]
public bool UsingStatement {
get { return usingStatement; }
set {
@ -355,6 +384,9 @@ namespace ICSharpCode.Decompiler @@ -355,6 +384,9 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether to use braces for single-statement-blocks.
/// </summary>
[Category("Formatting")]
[Description("Always use braces")]
[Browsable(false)]
public bool AlwaysUseBraces {
get { return alwaysUseBraces; }
set {
@ -370,6 +402,8 @@ namespace ICSharpCode.Decompiler @@ -370,6 +402,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile foreach statements.
/// </summary>
[Category("C# 1.0 / VS .NET")]
[Description("Detect foreach statements")]
public bool ForEachStatement {
get { return forEachStatement; }
set {
@ -385,6 +419,8 @@ namespace ICSharpCode.Decompiler @@ -385,6 +419,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile lock statements.
/// </summary>
[Category("C# 1.0 / VS .NET")]
[Description("Detect lock statements")]
public bool LockStatement {
get { return lockStatement; }
set {
@ -397,6 +433,8 @@ namespace ICSharpCode.Decompiler @@ -397,6 +433,8 @@ namespace ICSharpCode.Decompiler
bool switchStatementOnString = true;
[Category("C# 1.0 / VS .NET")]
[Description("Detect switch on string")]
public bool SwitchStatementOnString {
get { return switchStatementOnString; }
set {
@ -409,6 +447,8 @@ namespace ICSharpCode.Decompiler @@ -409,6 +447,8 @@ namespace ICSharpCode.Decompiler
bool usingDeclarations = true;
[Category("C# 1.0 / VS .NET")]
[Browsable(false)]
public bool UsingDeclarations {
get { return usingDeclarations; }
set {
@ -421,6 +461,8 @@ namespace ICSharpCode.Decompiler @@ -421,6 +461,8 @@ namespace ICSharpCode.Decompiler
bool extensionMethods = true;
[Category("C# 3.0 / VS 2008")]
[Description("Use extension method syntax")]
public bool ExtensionMethods {
get { return extensionMethods; }
set {
@ -433,6 +475,8 @@ namespace ICSharpCode.Decompiler @@ -433,6 +475,8 @@ namespace ICSharpCode.Decompiler
bool queryExpressions = true;
[Category("C# 3.0 / VS 2008")]
[Description("Use LINQ expression syntax")]
public bool QueryExpressions {
get { return queryExpressions; }
set {
@ -450,6 +494,8 @@ namespace ICSharpCode.Decompiler @@ -450,6 +494,8 @@ namespace ICSharpCode.Decompiler
/// true: <c>EventHandler h = this.OnClick;</c>
/// false: <c>EventHandler h = new EventHandler(this.OnClick);</c>
/// </summary>
[Category("C# 2.0 / VS 2005")]
[Description("Use implicit method group conversions")]
public bool UseImplicitMethodGroupConversion {
get { return useImplicitMethodGroupConversion; }
set {
@ -468,6 +514,8 @@ namespace ICSharpCode.Decompiler @@ -468,6 +514,8 @@ namespace ICSharpCode.Decompiler
/// false: <c>pictureBox1.BeginInit();</c>
/// default: false
/// </summary>
[Category("Other")]
[Description("Always cast targets of explicit interface implementation calls")]
public bool AlwaysCastTargetsOfExplicitInterfaceImplementationCalls {
get { return alwaysCastTargetsOfExplicitInterfaceImplementationCalls; }
set {
@ -483,6 +531,9 @@ namespace ICSharpCode.Decompiler @@ -483,6 +531,9 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether to use variable names from debug symbols, if available.
/// </summary>
[Category("Other")]
[Description("Use variable names from debug symbols, if available")]
[Browsable(false)]
public bool UseDebugSymbols {
get { return useDebugSymbols; }
set {
@ -499,6 +550,8 @@ namespace ICSharpCode.Decompiler @@ -499,6 +550,8 @@ namespace ICSharpCode.Decompiler
/// Gets/Sets whether to use array initializers.
/// If set to false, might produce non-compilable code.
/// </summary>
[Category("C# 1.0 / VS .NET")]
[Description("Array initializer expressions")]
public bool ArrayInitializers
{
get { return arrayInitializers; }
@ -517,6 +570,8 @@ namespace ICSharpCode.Decompiler @@ -517,6 +570,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether to use C# 3.0 object/collection initializers.
/// </summary>
[Category("C# 3.0 / VS 2008")]
[Description("Object/collection initializer expressions")]
public bool ObjectOrCollectionInitializers {
get { return objectCollectionInitializers; }
set {
@ -533,6 +588,8 @@ namespace ICSharpCode.Decompiler @@ -533,6 +588,8 @@ namespace ICSharpCode.Decompiler
/// Gets/Sets whether to use C# 6.0 dictionary initializers.
/// Only has an effect if ObjectOrCollectionInitializers is enabled.
/// </summary>
[Category("C# 6.0 / VS 2015")]
[Description("Dictionary initializer expressions")]
public bool DictionaryInitializers {
get { return dictionaryInitializers; }
set {
@ -549,6 +606,8 @@ namespace ICSharpCode.Decompiler @@ -549,6 +606,8 @@ namespace ICSharpCode.Decompiler
/// Gets/Sets whether to use C# 6.0 Extension Add methods in collection initializers.
/// Only has an effect if ObjectOrCollectionInitializers is enabled.
/// </summary>
[Category("C# 6.0 / VS 2015")]
[Description("Allow extension 'Add' methods in collection initializer expressions")]
public bool ExtensionMethodsInCollectionInitializers {
get { return extensionMethodsInCollectionInitializers; }
set {
@ -564,6 +623,8 @@ namespace ICSharpCode.Decompiler @@ -564,6 +623,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether to use C# 6.0 string interpolation
/// </summary>
[Category("C# 6.0 / VS 2015")]
[Description("Use string interpolation")]
public bool StringInterpolation {
get { return stringInterpolation; }
set {
@ -579,6 +640,7 @@ namespace ICSharpCode.Decompiler @@ -579,6 +640,7 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether to include XML documentation comments in the decompiled code.
/// </summary>
[Browsable(false)]
public bool ShowXmlDocumentation {
get { return showXmlDocumentation; }
set {
@ -591,6 +653,7 @@ namespace ICSharpCode.Decompiler @@ -591,6 +653,7 @@ namespace ICSharpCode.Decompiler
bool foldBraces = false;
[Browsable(false)]
public bool FoldBraces {
get { return foldBraces; }
set {
@ -603,6 +666,7 @@ namespace ICSharpCode.Decompiler @@ -603,6 +666,7 @@ namespace ICSharpCode.Decompiler
bool expandMemberDefinitions = false;
[Browsable(false)]
public bool ExpandMemberDefinitions {
get { return expandMemberDefinitions; }
set {
@ -618,6 +682,8 @@ namespace ICSharpCode.Decompiler @@ -618,6 +682,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether member bodies should be decompiled.
/// </summary>
[Category("Other")]
[Browsable(false)]
public bool DecompileMemberBodies {
get { return decompileMemberBodies; }
set {
@ -633,6 +699,8 @@ namespace ICSharpCode.Decompiler @@ -633,6 +699,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether simple calculated getter-only property declarations should use expression body syntax.
/// </summary>
[Category("C# 6.0 / VS 2015")]
[Description("Use expression-bodied member syntax for get-only properties")]
public bool UseExpressionBodyForCalculatedGetterOnlyProperties {
get { return useExpressionBodyForCalculatedGetterOnlyProperties; }
set {
@ -648,6 +716,8 @@ namespace ICSharpCode.Decompiler @@ -648,6 +716,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether out variable declarations should be used when possible.
/// </summary>
[Category("C# 7.0 / VS 2017")]
[Description("Use out variable declarations")]
public bool OutVariables {
get { return outVariables; }
set {
@ -664,6 +734,8 @@ namespace ICSharpCode.Decompiler @@ -664,6 +734,8 @@ namespace ICSharpCode.Decompiler
/// Gets/Sets whether discards should be used when possible.
/// Only has an effect if <see cref="OutVariables"/> is enabled.
/// </summary>
[Category("C# 7.0 / VS 2017")]
[Description("Use discards")]
public bool Discards {
get { return discards; }
set {
@ -679,6 +751,8 @@ namespace ICSharpCode.Decompiler @@ -679,6 +751,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether IsByRefLikeAttribute should be replaced with 'ref' modifiers on structs.
/// </summary>
[Category("C# 7.2 / VS 2017.4")]
[Description("IsByRefLikeAttribute should be replaced with 'ref' modifiers on structs")]
public bool IntroduceRefModifiersOnStructs {
get { return introduceRefModifiersOnStructs; }
set {
@ -695,6 +769,8 @@ namespace ICSharpCode.Decompiler @@ -695,6 +769,8 @@ namespace ICSharpCode.Decompiler
/// Gets/Sets whether IsReadOnlyAttribute should be replaced with 'readonly' modifiers on structs
/// and with the 'in' modifier on parameters.
/// </summary>
[Category("C# 7.2 / VS 2017.4")]
[Description("IsReadOnlyAttribute should be replaced with 'readonly'/'in' modifiers on structs/parameters")]
public bool IntroduceReadonlyAndInModifiers {
get { return introduceReadonlyAndInModifiers; }
set {
@ -711,6 +787,8 @@ namespace ICSharpCode.Decompiler @@ -711,6 +787,8 @@ namespace ICSharpCode.Decompiler
/// If this option is active, [IsUnmanagedAttribute] on type parameters
/// is replaced with "T : unmanaged" constraints.
/// </summary>
[Category("C# 7.3 / VS 2017.7")]
[Description("IsUnmanagedAttribute on type parameters should be replaced with 'unmanaged' constraints")]
public bool IntroduceUnmanagedConstraint {
get { return introduceUnmanagedConstraint; }
set {
@ -726,6 +804,8 @@ namespace ICSharpCode.Decompiler @@ -726,6 +804,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether C# 7.3 stackalloc initializers should be used.
/// </summary>
[Category("C# 7.3 / VS 2017.7")]
[Description("Use stackalloc initializer syntax")]
public bool StackAllocInitializers {
get { return stackAllocInitializers; }
set {
@ -742,6 +822,8 @@ namespace ICSharpCode.Decompiler @@ -742,6 +822,8 @@ namespace ICSharpCode.Decompiler
/// Gets/Sets whether tuple type syntax <c>(int, string)</c>
/// should be used for <c>System.ValueTuple</c>.
/// </summary>
[Category("C# 7.0 / VS 2017")]
[Description("Use tuple type syntax")]
public bool TupleTypes {
get { return tupleTypes; }
set {
@ -758,6 +840,8 @@ namespace ICSharpCode.Decompiler @@ -758,6 +840,8 @@ namespace ICSharpCode.Decompiler
/// Gets/Sets whether implicit conversions between tuples
/// should be used in the decompiled output.
/// </summary>
[Category("C# 7.0 / VS 2017")]
[Description("Use implicit conversions between tuple types")]
public bool TupleConversions {
get { return tupleConversions; }
set {
@ -773,6 +857,8 @@ namespace ICSharpCode.Decompiler @@ -773,6 +857,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether tuple comparisons should be detected.
/// </summary>
[Category("C# 7.3 / VS 2017.7")]
[Description("Detect tuple comparisons")]
public bool TupleComparisons {
get { return tupleComparisons; }
set {
@ -788,6 +874,8 @@ namespace ICSharpCode.Decompiler @@ -788,6 +874,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether named arguments should be used.
/// </summary>
[Category("C# 4.0 / VS 2010")]
[Description("Use named arguments")]
public bool NamedArguments {
get { return namedArguments; }
set {
@ -803,6 +891,8 @@ namespace ICSharpCode.Decompiler @@ -803,6 +891,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether C# 7.2 non-trailing named arguments should be used.
/// </summary>
[Category("C# 7.2 / VS 2017.4")]
[Description("Use non-trailing named arguments")]
public bool NonTrailingNamedArguments {
get { return nonTrailingNamedArguments; }
set {
@ -818,6 +908,8 @@ namespace ICSharpCode.Decompiler @@ -818,6 +908,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether optional arguments should be removed, if possible.
/// </summary>
[Category("C# 4.0 / VS 2010")]
[Description("Remove optional arguments, if possible")]
public bool OptionalArguments {
get { return optionalArguments; }
set {
@ -834,6 +926,9 @@ namespace ICSharpCode.Decompiler @@ -834,6 +926,9 @@ namespace ICSharpCode.Decompiler
/// Gets/Sets whether C# 7.0 local functions should be used.
/// Note: this language feature is currently not implemented and this setting is always false.
/// </summary>
[Category("C# 7.0 / VS 2017")]
[Description("Introduce local functions (NOT IMPLEMENTED!)")]
[Browsable(false)]
public bool LocalFunctions {
get { return localFunctions; }
set {
@ -850,6 +945,8 @@ namespace ICSharpCode.Decompiler @@ -850,6 +945,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether C# 8.0 nullable reference types are enabled.
/// </summary>
[Category("C# 8.0 / VS 2019")]
[Description("Nullable reference types")]
public bool NullableReferenceTypes {
get { return nullableReferenceTypes; }
set {
@ -862,6 +959,9 @@ namespace ICSharpCode.Decompiler @@ -862,6 +959,9 @@ namespace ICSharpCode.Decompiler
bool showDebugInfo;
[Category("Other")]
[Description("Show info from debug symbols, if available")]
[Browsable(false)]
public bool ShowDebugInfo {
get { return showDebugInfo; }
set {
@ -878,6 +978,8 @@ namespace ICSharpCode.Decompiler @@ -878,6 +978,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether the decompiler can assume that 'ldlen; conv.i4.ovf' does not throw an overflow exception.
/// </summary>
[Category("VB-specific options")]
[Browsable(false)]
public bool AssumeArrayLengthFitsIntoInt32 {
get { return assumeArrayLengthFitsIntoInt32; }
set {
@ -893,6 +995,8 @@ namespace ICSharpCode.Decompiler @@ -893,6 +995,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether to use increment and decrement operators
/// </summary>
[Category("VB-specific options")]
[Browsable(false)]
public bool IntroduceIncrementAndDecrement {
get { return introduceIncrementAndDecrement; }
set {
@ -908,6 +1012,8 @@ namespace ICSharpCode.Decompiler @@ -908,6 +1012,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether to use assignment expressions such as in while ((count = Do()) != 0) ;
/// </summary>
[Category("VB-specific options")]
[Browsable(false)]
public bool MakeAssignmentExpressions {
get { return makeAssignmentExpressions; }
set {
@ -923,6 +1029,8 @@ namespace ICSharpCode.Decompiler @@ -923,6 +1029,8 @@ namespace ICSharpCode.Decompiler
#region Options to aid F# decompilation
bool removeDeadCode = false;
[Category("F#-specific options")]
[Browsable(false)]
public bool RemoveDeadCode {
get { return removeDeadCode; }
set {
@ -938,6 +1046,7 @@ namespace ICSharpCode.Decompiler @@ -938,6 +1046,7 @@ namespace ICSharpCode.Decompiler
bool loadInMemory = false;
[Browsable(false)]
public bool LoadInMemory {
get { return loadInMemory; }
set {
@ -950,6 +1059,7 @@ namespace ICSharpCode.Decompiler @@ -950,6 +1059,7 @@ namespace ICSharpCode.Decompiler
bool throwOnAssemblyResolveErrors = true;
[Browsable(false)]
public bool ThrowOnAssemblyResolveErrors {
get { return throwOnAssemblyResolveErrors; }
set {
@ -962,6 +1072,9 @@ namespace ICSharpCode.Decompiler @@ -962,6 +1072,9 @@ namespace ICSharpCode.Decompiler
bool applyWindowsRuntimeProjections = true;
[Category("Other")]
[Description("Apply Windows Runtime projections on loaded assemblies")]
[Browsable(false)]
public bool ApplyWindowsRuntimeProjections {
get { return applyWindowsRuntimeProjections; }
set {
@ -976,6 +1089,7 @@ namespace ICSharpCode.Decompiler @@ -976,6 +1089,7 @@ namespace ICSharpCode.Decompiler
CSharpFormattingOptions csharpFormattingOptions;
[Browsable(false)]
public CSharpFormattingOptions CSharpFormattingOptions {
get {
if (csharpFormattingOptions == null) {

45
ILSpy/DecompilationOptions.cs

@ -68,30 +68,43 @@ namespace ICSharpCode.ILSpy @@ -68,30 +68,43 @@ namespace ICSharpCode.ILSpy
internal bool IsDebug = false;
public DecompilationOptions()
: this(MainWindow.Instance.CurrentLanguageVersion, DecompilerSettingsPanel.CurrentDecompilerSettings, DisplaySettingsPanel.CurrentDisplaySettings)
: this(MainWindow.Instance.CurrentLanguageVersion, DecompilerSettingsPanel.CurrentDecompilerSettings, DisplaySettingsPanel.CurrentDisplaySettings, CSharpDecompilerSettingsPanel.CurrentCSharpSettings)
{
}
public DecompilationOptions(LanguageVersion version)
: this(version, DecompilerSettingsPanel.CurrentDecompilerSettings, DisplaySettingsPanel.CurrentDisplaySettings)
: this(version, DecompilerSettingsPanel.CurrentDecompilerSettings, DisplaySettingsPanel.CurrentDisplaySettings, CSharpDecompilerSettingsPanel.CurrentCSharpSettings)
{
}
public DecompilationOptions(LanguageVersion version, Options.DecompilerSettings settings, Options.DisplaySettings displaySettings)
public DecompilationOptions(LanguageVersion version, Options.DecompilerSettings settings, Options.DisplaySettings displaySettings, Decompiler.DecompilerSettings csharpSettings)
{
if (!Enum.TryParse(version.Version, out Decompiler.CSharp.LanguageVersion languageVersion))
languageVersion = Decompiler.CSharp.LanguageVersion.Latest;
this.DecompilerSettings = new Decompiler.DecompilerSettings(languageVersion) {
AlwaysUseBraces = settings.AlwaysUseBraces,
ExpandMemberDefinitions = displaySettings.ExpandMemberDefinitions,
FoldBraces = displaySettings.FoldBraces,
RemoveDeadCode = settings.RemoveDeadCode,
ShowDebugInfo = settings.ShowDebugInfo,
ShowXmlDocumentation = settings.ShowXmlDocumentation,
UseDebugSymbols = settings.UseDebugSymbols,
UsingDeclarations = settings.UsingDeclarations,
ApplyWindowsRuntimeProjections = settings.ApplyWindowsRuntimeProjections,
};
if (version.Version == "Custom") {
var newSettings = this.DecompilerSettings = csharpSettings.Clone();
newSettings.AlwaysUseBraces = settings.AlwaysUseBraces;
newSettings.ExpandMemberDefinitions = displaySettings.ExpandMemberDefinitions;
newSettings.FoldBraces = displaySettings.FoldBraces;
newSettings.RemoveDeadCode = settings.RemoveDeadCode;
newSettings.ShowDebugInfo = settings.ShowDebugInfo;
newSettings.ShowXmlDocumentation = settings.ShowXmlDocumentation;
newSettings.UseDebugSymbols = settings.UseDebugSymbols;
newSettings.UsingDeclarations = settings.UsingDeclarations;
newSettings.ApplyWindowsRuntimeProjections = settings.ApplyWindowsRuntimeProjections;
} else {
if (!Enum.TryParse(version.Version, out Decompiler.CSharp.LanguageVersion languageVersion))
languageVersion = Decompiler.CSharp.LanguageVersion.Latest;
this.DecompilerSettings = new Decompiler.DecompilerSettings(languageVersion) {
AlwaysUseBraces = settings.AlwaysUseBraces,
ExpandMemberDefinitions = displaySettings.ExpandMemberDefinitions,
FoldBraces = displaySettings.FoldBraces,
RemoveDeadCode = settings.RemoveDeadCode,
ShowDebugInfo = settings.ShowDebugInfo,
ShowXmlDocumentation = settings.ShowXmlDocumentation,
UseDebugSymbols = settings.UseDebugSymbols,
UsingDeclarations = settings.UsingDeclarations,
ApplyWindowsRuntimeProjections = settings.ApplyWindowsRuntimeProjections,
};
}
}
}
}

5
ILSpy/ILSpy.csproj

@ -158,6 +158,7 @@ @@ -158,6 +158,7 @@
<Compile Include="Languages\IResourceFileHandler.cs" />
<Compile Include="Languages\Language.cs" />
<Compile Include="Languages\Languages.cs" />
<Compile Include="Options\CSharpDecompilerSettingsPanel.xaml.cs" />
<Compile Include="Search\LiteralSearchStrategy.cs" />
<Compile Include="LoadedAssembly.cs" />
<Compile Include="LoadedAssemblyExtensions.cs" />
@ -316,6 +317,7 @@ @@ -316,6 +317,7 @@
<Page Include="OpenFromGacDialog.xaml" />
<Page Include="OpenListDialog.xaml" />
<Page Include="NugetPackageBrowserDialog.xaml" />
<Page Include="Options\CSharpDecompilerSettingsPanel.xaml" />
<Page Include="Options\DecompilerSettingsPanel.xaml" />
<Page Include="Options\DisplaySettingsPanel.xaml" />
<Page Include="Options\MiscSettingsPanel.xaml" />
@ -389,6 +391,9 @@ @@ -389,6 +391,9 @@
<ItemGroup>
<Page Update="@(Page)" SubType="Designer" Generator="MSBuild:Compile" />
<Page Update="Options\CSharpDecompilerSettingsPanel.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>

1
ILSpy/Languages/CSharpLanguage.cs

@ -102,6 +102,7 @@ namespace ICSharpCode.ILSpy @@ -102,6 +102,7 @@ namespace ICSharpCode.ILSpy
new LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp7_2.ToString(), "C# 7.2 / VS 2017.4"),
new LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp7_3.ToString(), "C# 7.3 / VS 2017.7"),
new LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp8_0.ToString(), "C# 8.0 / VS 2019"),
new LanguageVersion("Custom", "Custom"),
};
}
return versions;

58
ILSpy/Options/CSharpDecompilerSettingsPanel.xaml

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
<UserControl x:Class="ICSharpCode.ILSpy.Options.CSharpDecompilerSettingsPanel"
x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:options="clr-namespace:ICSharpCode.ILSpy.Options"
xmlns:controls="clr-namespace:ICSharpCode.ILSpy.Controls">
<UserControl.Resources>
<controls:BoolToVisibilityConverter x:Key="boolConv" />
<CollectionViewSource x:Key="SettingsCollection" Source="{Binding Settings}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Category" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Margin="3" Grid.ColumnSpan="3" TextWrapping="Wrap" Text="The settings selected below are applied to the 'Custom' setting in the language drop-down. Note that some settings implicitly depend on each other, e.g.: LINQ expressions cannot be introduced without first transforming static calls to extension method calls." />
<ListBox Grid.Row="1" ItemsSource="{Binding Source={StaticResource SettingsCollection}}">
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander Padding="0" BorderThickness="0" IsExpanded="True">
<Expander.Header>
<CheckBox Checked="OnGroupChecked" Unchecked="OnGroupUnchecked" Loaded="OnGroupLoaded" VerticalContentAlignment="Center"
FontSize="16" FontWeight="Bold" Content="{Binding Name}" />
</Expander.Header>
<ItemsPresenter/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListBox.GroupStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsEnabled}" Content="{Binding Description}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>

195
ILSpy/Options/CSharpDecompilerSettingsPanel.xaml.cs

@ -0,0 +1,195 @@ @@ -0,0 +1,195 @@
// Copyright (c) 2011 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.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Xml.Linq;
namespace ICSharpCode.ILSpy.Options
{
/// <summary>
/// Interaction logic for CSharpDecompilerSettingsPanel.xaml
/// </summary>
[ExportOptionPage(Title = "C# Decompiler", Order = 10)]
internal partial class CSharpDecompilerSettingsPanel : UserControl, IOptionPage
{
public CSharpDecompilerSettingsPanel()
{
InitializeComponent();
}
static Decompiler.DecompilerSettings currentCSharpSettings;
public static Decompiler.DecompilerSettings CurrentCSharpSettings {
get {
return currentCSharpSettings ?? (currentCSharpSettings = LoadDecompilerSettings(ILSpySettings.Load()));
}
}
public static Decompiler.DecompilerSettings LoadDecompilerSettings(ILSpySettings settings)
{
XElement e = settings["CustomCSharpDecompilerSettings"];
var newSettings = new Decompiler.DecompilerSettings();
var properties = typeof(Decompiler.DecompilerSettings).GetProperties()
.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false);
foreach (var p in properties) {
p.SetValue(newSettings, (bool?)e.Attribute(p.Name) ?? true);
}
return newSettings;
}
public void Load(ILSpySettings settings)
{
this.DataContext = new CSharpDecompilerSettings(LoadDecompilerSettings(settings));
}
public void Save(XElement root)
{
XElement section = new XElement("CustomCSharpDecompilerSettings");
var newSettings = ((CSharpDecompilerSettings)this.DataContext).ToDecompilerSettings();
var properties = typeof(Decompiler.DecompilerSettings).GetProperties()
.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false);
foreach (var p in properties) {
section.SetAttributeValue(p.Name, p.GetValue(newSettings));
}
XElement existingElement = root.Element("CustomCSharpDecompilerSettings");
if (existingElement != null)
existingElement.ReplaceWith(section);
else
root.Add(section);
currentCSharpSettings = newSettings;
}
private void OnGroupChecked(object sender, RoutedEventArgs e)
{
CheckGroup((CollectionViewGroup)((CheckBox)sender).DataContext, true);
}
private void OnGroupUnchecked(object sender, RoutedEventArgs e)
{
CheckGroup((CollectionViewGroup)((CheckBox)sender).DataContext, false);
}
void CheckGroup(CollectionViewGroup group, bool value)
{
foreach (var item in group.Items) {
switch (item) {
case CollectionViewGroup subGroup:
CheckGroup(subGroup, value);
break;
case CSharpDecompilerSetting setting:
setting.IsEnabled = value;
break;
}
}
}
bool IsGroupChecked(CollectionViewGroup group)
{
bool value = true;
foreach (var item in group.Items) {
switch (item) {
case CollectionViewGroup subGroup:
value = value && IsGroupChecked(subGroup);
break;
case CSharpDecompilerSetting setting:
value = value && setting.IsEnabled;
break;
}
}
return value;
}
private void OnGroupLoaded(object sender, RoutedEventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
checkBox.IsChecked = IsGroupChecked((CollectionViewGroup)checkBox.DataContext);
}
}
public class CSharpDecompilerSettings : INotifyPropertyChanged
{
public CSharpDecompilerSetting[] Settings { get; set; }
public CSharpDecompilerSettings(Decompiler.DecompilerSettings settings)
{
Settings = typeof(Decompiler.DecompilerSettings).GetProperties()
.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false)
.Select(p => new CSharpDecompilerSetting(p) { IsEnabled = (bool)p.GetValue(settings) })
.OrderBy(item => item.Category)
.ThenBy(item => item.Description)
.ToArray();
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public Decompiler.DecompilerSettings ToDecompilerSettings()
{
var settings = new Decompiler.DecompilerSettings();
foreach (var item in Settings) {
item.Property.SetValue(settings, item.IsEnabled);
}
return settings;
}
}
public class CSharpDecompilerSetting : INotifyPropertyChanged
{
bool isEnabled;
public CSharpDecompilerSetting(PropertyInfo p)
{
this.Property = p;
this.Category = p.GetCustomAttribute<CategoryAttribute>()?.Category ?? "Other";
this.Description = p.GetCustomAttribute<DescriptionAttribute>()?.Description ?? p.Name;
}
public PropertyInfo Property { get; }
public bool IsEnabled {
get => isEnabled;
set {
if (value != isEnabled) {
isEnabled = value;
OnPropertyChanged();
}
}
}
public string Description { get; set; }
public string Category { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

2
ILSpy/Options/DecompilerSettingsPanel.xaml

@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
<CheckBox IsChecked="{Binding UseDebugSymbols}">Use variable names from debug symbols, if available</CheckBox>
<CheckBox IsChecked="{Binding ShowDebugInfo}">Show info from debug symbols, if available</CheckBox>
<CheckBox IsChecked="{Binding ShowXmlDocumentation}">Show XML documentation in decompiled code</CheckBox>
<CheckBox IsChecked="{Binding RemoveDeadCode}">Remove dead and side effect free code</CheckBox>
<CheckBox IsChecked="{Binding RemoveDeadCode}">Remove dead and side effect free code (use with caution!)</CheckBox>
<CheckBox IsChecked="{Binding UsingDeclarations}">Insert using declarations</CheckBox>
<CheckBox IsChecked="{Binding AlwaysUseBraces}">Always use braces</CheckBox>
<CheckBox IsChecked="{Binding ApplyWindowsRuntimeProjections}">Apply Windows Runtime projections on loaded assemblies</CheckBox>

2
ILSpy/Options/DisplaySettingsPanel.xaml.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.ILSpy.Options @@ -31,7 +31,7 @@ namespace ICSharpCode.ILSpy.Options
/// <summary>
/// Interaction logic for DisplaySettingsPanel.xaml
/// </summary>
[ExportOptionPage(Title = "Display", Order = 1)]
[ExportOptionPage(Title = "Display", Order = 20)]
public partial class DisplaySettingsPanel : UserControl, IOptionPage
{
public DisplaySettingsPanel()

2
ILSpy/Options/MiscSettingsPanel.xaml.cs

@ -24,7 +24,7 @@ namespace ICSharpCode.ILSpy.Options @@ -24,7 +24,7 @@ namespace ICSharpCode.ILSpy.Options
/// <summary>
/// Interaction logic for MiscSettingsPanel.xaml
/// </summary>
[ExportOptionPage(Title = "Misc", Order = 2)]
[ExportOptionPage(Title = "Misc", Order = 30)]
public partial class MiscSettingsPanel : UserControl, IOptionPage
{
public MiscSettingsPanel()

Loading…
Cancel
Save