.NET Decompiler with support for PDB generation, ReadyToRun, Metadata (&more) - cross-platform!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1151 lines
30 KiB

// 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;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
namespace ICSharpCode.Decompiler
{
/// <summary>
/// Settings for the decompiler.
/// </summary>
public class DecompilerSettings : INotifyPropertyChanged
{
/// <summary>
/// Equivalent to <c>new DecompilerSettings(LanguageVersion.Latest)</c>
/// </summary>
public DecompilerSettings()
{
}
/// <summary>
/// Creates a new DecompilerSettings instance with initial settings
/// appropriate for the specified language version.
/// </summary>
/// <remarks>
/// This does not imply that the resulting code strictly uses only language features from that version.
/// Language constructs like generics or ref locals cannot be removed from the compiled code.
/// </remarks>
public DecompilerSettings(CSharp.LanguageVersion languageVersion)
{
SetLanguageVersion(languageVersion);
}
/// <summary>
/// Deactivates all language features from versions newer than <paramref name="languageVersion"/>.
/// </summary>
public void SetLanguageVersion(CSharp.LanguageVersion languageVersion)
{
// By default, all decompiler features are enabled.
// Disable some of them based on language version:
if (languageVersion < CSharp.LanguageVersion.CSharp2) {
anonymousMethods = false;
liftNullables = false;
yieldReturn = false;
useImplicitMethodGroupConversion = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp3) {
anonymousTypes = false;
useLambdaSyntax = false;
objectCollectionInitializers = false;
automaticProperties = false;
extensionMethods = false;
queryExpressions = false;
expressionTrees = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp4) {
dynamic = false;
namedArguments = false;
optionalArguments = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp5) {
asyncAwait = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp6) {
awaitInCatchFinally = false;
useExpressionBodyForCalculatedGetterOnlyProperties = false;
nullPropagation = false;
stringInterpolation = false;
dictionaryInitializers = false;
extensionMethodsInCollectionInitializers = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp7) {
outVariables = false;
tupleTypes = false;
tupleConversions = false;
discards = false;
localFunctions = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp7_2) {
introduceReadonlyAndInModifiers = false;
introduceRefModifiersOnStructs = false;
nonTrailingNamedArguments = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp7_3) {
introduceUnmanagedConstraint = false;
stackAllocInitializers = false;
tupleComparisons = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp8_0) {
nullableReferenceTypes = false;
}
}
public CSharp.LanguageVersion GetMinimumRequiredVersion()
{
if (nullableReferenceTypes)
return CSharp.LanguageVersion.CSharp8_0;
if (introduceUnmanagedConstraint || tupleComparisons || stackAllocInitializers)
return CSharp.LanguageVersion.CSharp7_3;
if (introduceRefModifiersOnStructs || introduceReadonlyAndInModifiers || nonTrailingNamedArguments)
return CSharp.LanguageVersion.CSharp7_2;
// C# 7.1 missing
if (outVariables || tupleTypes || tupleConversions || discards || localFunctions)
return CSharp.LanguageVersion.CSharp7;
if (awaitInCatchFinally || useExpressionBodyForCalculatedGetterOnlyProperties || nullPropagation
|| stringInterpolation || dictionaryInitializers || extensionMethodsInCollectionInitializers)
return CSharp.LanguageVersion.CSharp6;
if (asyncAwait)
return CSharp.LanguageVersion.CSharp5;
if (dynamic || namedArguments || optionalArguments)
return CSharp.LanguageVersion.CSharp4;
if (anonymousTypes || objectCollectionInitializers || automaticProperties || queryExpressions || expressionTrees)
return CSharp.LanguageVersion.CSharp3;
if (anonymousMethods || liftNullables || yieldReturn || useImplicitMethodGroupConversion)
return CSharp.LanguageVersion.CSharp2;
return CSharp.LanguageVersion.CSharp1;
}
bool anonymousMethods = true;
/// <summary>
/// Decompile anonymous methods/lambdas.
/// </summary>
[Category("C# 2.0 / VS 2005")]
[Description("Decompile anonymous methods/lambdas")]
public bool AnonymousMethods {
get { return anonymousMethods; }
set {
if (anonymousMethods != value) {
anonymousMethods = value;
OnPropertyChanged();
}
}
}
bool anonymousTypes = true;
/// <summary>
/// Decompile anonymous types.
/// </summary>
[Category("C# 3.0 / VS 2008")]
[Description("Decompile anonymous types")]
public bool AnonymousTypes {
get { return anonymousTypes; }
set {
if (anonymousTypes != value) {
anonymousTypes = value;
OnPropertyChanged();
}
}
}
bool useLambdaSyntax = true;
/// <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 {
if (useLambdaSyntax != value) {
useLambdaSyntax = value;
OnPropertyChanged();
}
}
}
bool expressionTrees = true;
/// <summary>
/// Decompile expression trees.
/// </summary>
[Category("C# 3.0 / VS 2008")]
[Description("Decompile expression trees")]
public bool ExpressionTrees {
get { return expressionTrees; }
set {
if (expressionTrees != value) {
expressionTrees = value;
OnPropertyChanged();
}
}
}
bool yieldReturn = true;
/// <summary>
/// Decompile enumerators.
/// </summary>
[Category("C# 2.0 / VS 2005")]
[Description("Decompile enumerators (yield return)")]
public bool YieldReturn {
get { return yieldReturn; }
set {
if (yieldReturn != value) {
yieldReturn = value;
OnPropertyChanged();
}
}
}
bool dynamic = true;
/// <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 {
if (dynamic != value) {
dynamic = value;
OnPropertyChanged();
}
}
}
bool asyncAwait = true;
/// <summary>
/// Decompile async methods.
/// </summary>
[Category("C# 5.0 / VS 2012")]
[Description("Decompile async methods")]
public bool AsyncAwait {
get { return asyncAwait; }
set {
if (asyncAwait != value) {
asyncAwait = value;
OnPropertyChanged();
}
}
}
bool awaitInCatchFinally = true;
/// <summary>
/// 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 {
if (awaitInCatchFinally != value) {
awaitInCatchFinally = value;
OnPropertyChanged();
}
}
}
bool decimalConstants = true;
/// <summary>
/// Decompile [DecimalConstant(...)] as simple literal values.
/// </summary>
[Category("C# 1.0 / VS .NET")]
[Description("Decompile [DecimalConstant(...)] as simple literal values")]
public bool DecimalConstants {
get { return decimalConstants; }
set {
if (decimalConstants != value) {
decimalConstants = value;
OnPropertyChanged();
}
}
}
bool fixedBuffers = true;
/// <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 {
if (fixedBuffers != value) {
fixedBuffers = value;
OnPropertyChanged();
}
}
}
bool liftNullables = true;
/// <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 {
if (liftNullables != value) {
liftNullables = value;
OnPropertyChanged();
}
}
}
bool nullPropagation = true;
/// <summary>
/// Decompile C# 6 ?. and ?[] operators.
/// </summary>
[Category("C# 6.0 / VS 2015")]
[Description("Decompile ?. and ?[] operators")]
public bool NullPropagation {
get { return nullPropagation; }
set {
if (nullPropagation != value) {
nullPropagation = value;
OnPropertyChanged();
}
}
}
bool automaticProperties = true;
/// <summary>
/// Decompile automatic properties
/// </summary>
[Category("C# 3.0 / VS 2008")]
[Description("Decompile automatic properties")]
public bool AutomaticProperties {
get { return automaticProperties; }
set {
if (automaticProperties != value) {
automaticProperties = value;
OnPropertyChanged();
}
}
}
bool automaticEvents = true;
/// <summary>
/// Decompile automatic events
/// </summary>
[Category("C# 1.0 / VS .NET")]
[Description("Decompile automatic events")]
public bool AutomaticEvents {
get { return automaticEvents; }
set {
if (automaticEvents != value) {
automaticEvents = value;
OnPropertyChanged();
}
}
}
bool usingStatement = true;
/// <summary>
/// Decompile using statements.
/// </summary>
[Category("C# 1.0 / VS .NET")]
[Description("Detect using statements")]
public bool UsingStatement {
get { return usingStatement; }
set {
if (usingStatement != value) {
usingStatement = value;
OnPropertyChanged();
}
}
}
bool alwaysUseBraces = true;
/// <summary>
/// Gets/Sets whether to use braces for single-statement-blocks.
/// </summary>
[Category("Other")]
[Description("Always use braces")]
public bool AlwaysUseBraces {
get { return alwaysUseBraces; }
set {
if (alwaysUseBraces != value) {
alwaysUseBraces = value;
OnPropertyChanged();
}
}
}
bool forEachStatement = true;
/// <summary>
/// Decompile foreach statements.
/// </summary>
[Category("C# 1.0 / VS .NET")]
[Description("Detect foreach statements")]
public bool ForEachStatement {
get { return forEachStatement; }
set {
if (forEachStatement != value) {
forEachStatement = value;
OnPropertyChanged();
}
}
}
bool lockStatement = true;
/// <summary>
/// Decompile lock statements.
/// </summary>
[Category("C# 1.0 / VS .NET")]
[Description("Detect lock statements")]
public bool LockStatement {
get { return lockStatement; }
set {
if (lockStatement != value) {
lockStatement = value;
OnPropertyChanged();
}
}
}
bool switchStatementOnString = true;
[Category("C# 1.0 / VS .NET")]
[Description("Detect switch on string")]
public bool SwitchStatementOnString {
get { return switchStatementOnString; }
set {
if (switchStatementOnString != value) {
switchStatementOnString = value;
OnPropertyChanged();
}
}
}
bool usingDeclarations = true;
[Category("C# 1.0 / VS .NET")]
[Description("Insert using declarations")]
public bool UsingDeclarations {
get { return usingDeclarations; }
set {
if (usingDeclarations != value) {
usingDeclarations = value;
OnPropertyChanged();
}
}
}
bool extensionMethods = true;
[Category("C# 3.0 / VS 2008")]
[Description("Use extension method syntax")]
public bool ExtensionMethods {
get { return extensionMethods; }
set {
if (extensionMethods != value) {
extensionMethods = value;
OnPropertyChanged();
}
}
}
bool queryExpressions = true;
[Category("C# 3.0 / VS 2008")]
[Description("Use LINQ expression syntax")]
public bool QueryExpressions {
get { return queryExpressions; }
set {
if (queryExpressions != value) {
queryExpressions = value;
OnPropertyChanged();
}
}
}
bool useImplicitMethodGroupConversion = true;
/// <summary>
/// Gets/Sets whether to use C# 2.0 method group conversions.
/// 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 {
if (useImplicitMethodGroupConversion != value) {
useImplicitMethodGroupConversion = value;
OnPropertyChanged();
}
}
}
bool alwaysCastTargetsOfExplicitInterfaceImplementationCalls = false;
/// <summary>
/// Gets/Sets whether to always cast targets to explicitly implemented methods.
/// true: <c>((ISupportInitialize)pictureBox1).BeginInit();</c>
/// 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 {
if (alwaysCastTargetsOfExplicitInterfaceImplementationCalls != value) {
alwaysCastTargetsOfExplicitInterfaceImplementationCalls = value;
OnPropertyChanged();
}
}
}
bool useDebugSymbols = true;
/// <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")]
public bool UseDebugSymbols {
get { return useDebugSymbols; }
set {
if (useDebugSymbols != value) {
useDebugSymbols = value;
OnPropertyChanged();
}
}
}
bool arrayInitializers = true;
/// <summary>
/// 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; }
set
{
if (arrayInitializers != value)
{
arrayInitializers = value;
OnPropertyChanged();
}
}
}
bool objectCollectionInitializers = true;
/// <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 {
if (objectCollectionInitializers != value) {
objectCollectionInitializers = value;
OnPropertyChanged();
}
}
}
bool dictionaryInitializers = true;
/// <summary>
/// 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 {
if (dictionaryInitializers != value) {
dictionaryInitializers = value;
OnPropertyChanged();
}
}
}
bool extensionMethodsInCollectionInitializers = true;
/// <summary>
/// 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 {
if (extensionMethodsInCollectionInitializers != value) {
extensionMethodsInCollectionInitializers = value;
OnPropertyChanged();
}
}
}
bool stringInterpolation = true;
/// <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 {
if (stringInterpolation != value) {
stringInterpolation = value;
OnPropertyChanged();
}
}
}
bool showXmlDocumentation = true;
/// <summary>
/// Gets/Sets whether to include XML documentation comments in the decompiled code.
/// </summary>
[Category("Other")]
[Description("Include XML documentation comments in the decompiled code")]
public bool ShowXmlDocumentation {
get { return showXmlDocumentation; }
set {
if (showXmlDocumentation != value) {
showXmlDocumentation = value;
OnPropertyChanged();
}
}
}
bool foldBraces = false;
[Browsable(false)]
public bool FoldBraces {
get { return foldBraces; }
set {
if (foldBraces != value) {
foldBraces = value;
OnPropertyChanged();
}
}
}
bool expandMemberDefinitions = false;
[Browsable(false)]
public bool ExpandMemberDefinitions {
get { return expandMemberDefinitions; }
set {
if (expandMemberDefinitions != value) {
expandMemberDefinitions = value;
OnPropertyChanged();
}
}
}
bool expandUsingDeclarations = false;
[Browsable(false)]
public bool ExpandUsingDeclarations {
get { return expandUsingDeclarations; }
set {
if (expandUsingDeclarations != value) {
expandUsingDeclarations = value;
OnPropertyChanged();
}
}
}
bool decompileMemberBodies = true;
/// <summary>
/// Gets/Sets whether member bodies should be decompiled.
/// </summary>
[Category("Other")]
[Browsable(false)]
public bool DecompileMemberBodies {
get { return decompileMemberBodies; }
set {
if (decompileMemberBodies != value) {
decompileMemberBodies = value;
OnPropertyChanged();
}
}
}
bool useExpressionBodyForCalculatedGetterOnlyProperties = true;
/// <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 {
if (useExpressionBodyForCalculatedGetterOnlyProperties != value) {
useExpressionBodyForCalculatedGetterOnlyProperties = value;
OnPropertyChanged();
}
}
}
bool outVariables = true;
/// <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 {
if (outVariables != value) {
outVariables = value;
OnPropertyChanged();
}
}
}
bool discards = true;
/// <summary>
/// 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 {
if (discards != value) {
discards = value;
OnPropertyChanged();
}
}
}
bool introduceRefModifiersOnStructs = true;
/// <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 {
if (introduceRefModifiersOnStructs != value) {
introduceRefModifiersOnStructs = value;
OnPropertyChanged();
}
}
}
bool introduceReadonlyAndInModifiers = true;
/// <summary>
/// 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 {
if (introduceReadonlyAndInModifiers != value) {
introduceReadonlyAndInModifiers = value;
OnPropertyChanged();
}
}
}
bool introduceUnmanagedConstraint = true;
/// <summary>
/// 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 {
if (introduceUnmanagedConstraint != value) {
introduceUnmanagedConstraint = value;
OnPropertyChanged();
}
}
}
bool stackAllocInitializers = true;
/// <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 {
if (stackAllocInitializers != value) {
stackAllocInitializers = value;
OnPropertyChanged();
}
}
}
bool tupleTypes = true;
/// <summary>
/// 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 {
if (tupleTypes != value) {
tupleTypes = value;
OnPropertyChanged();
}
}
}
bool tupleConversions = true;
/// <summary>
/// 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 {
if (tupleConversions != value) {
tupleConversions = value;
OnPropertyChanged();
}
}
}
bool tupleComparisons = true;
/// <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 {
if (tupleComparisons != value) {
tupleComparisons = value;
OnPropertyChanged();
}
}
}
bool namedArguments = true;
/// <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 {
if (namedArguments != value) {
namedArguments = value;
OnPropertyChanged();
}
}
}
bool nonTrailingNamedArguments = true;
/// <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 {
if (nonTrailingNamedArguments != value) {
nonTrailingNamedArguments = value;
OnPropertyChanged();
}
}
}
bool optionalArguments = true;
/// <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 {
if (optionalArguments != value) {
optionalArguments = value;
OnPropertyChanged();
}
}
}
bool localFunctions = false;
/// <summary>
/// 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 {
if (localFunctions != value) {
throw new NotImplementedException("C# 7.0 local functions are not implemented!");
//localFunctions = value;
//OnPropertyChanged();
}
}
}
bool nullableReferenceTypes = true;
/// <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 {
if (nullableReferenceTypes != value) {
nullableReferenceTypes = value;
OnPropertyChanged();
}
}
}
bool showDebugInfo;
[Category("Other")]
[Description("Show info from debug symbols, if available")]
[Browsable(false)]
public bool ShowDebugInfo {
get { return showDebugInfo; }
set {
if (showDebugInfo != value) {
showDebugInfo = value;
OnPropertyChanged();
}
}
}
#region Options to aid VB decompilation
bool assumeArrayLengthFitsIntoInt32 = true;
/// <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 {
if (assumeArrayLengthFitsIntoInt32 != value) {
assumeArrayLengthFitsIntoInt32 = value;
OnPropertyChanged();
}
}
}
bool introduceIncrementAndDecrement = true;
/// <summary>
/// Gets/Sets whether to use increment and decrement operators
/// </summary>
[Category("VB-specific options")]
[Browsable(false)]
public bool IntroduceIncrementAndDecrement {
get { return introduceIncrementAndDecrement; }
set {
if (introduceIncrementAndDecrement != value) {
introduceIncrementAndDecrement = value;
OnPropertyChanged();
}
}
}
bool makeAssignmentExpressions = true;
/// <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 {
if (makeAssignmentExpressions != value) {
makeAssignmentExpressions = value;
OnPropertyChanged();
}
}
}
#endregion
#region Options to aid F# decompilation
bool removeDeadCode = false;
[Category("F#-specific options")]
[Description("Remove dead and side effect free code (use with caution!)")]
public bool RemoveDeadCode {
get { return removeDeadCode; }
set {
if (removeDeadCode != value) {
removeDeadCode = value;
OnPropertyChanged();
}
}
}
#endregion
#region Assembly Load and Resolve options
bool loadInMemory = false;
[Browsable(false)]
public bool LoadInMemory {
get { return loadInMemory; }
set {
if (loadInMemory != value) {
loadInMemory = value;
OnPropertyChanged();
}
}
}
bool throwOnAssemblyResolveErrors = true;
[Browsable(false)]
public bool ThrowOnAssemblyResolveErrors {
get { return throwOnAssemblyResolveErrors; }
set {
if (throwOnAssemblyResolveErrors != value) {
throwOnAssemblyResolveErrors = value;
OnPropertyChanged();
}
}
}
bool applyWindowsRuntimeProjections = true;
[Category("Other")]
[Description("Apply Windows Runtime projections on loaded assemblies")]
public bool ApplyWindowsRuntimeProjections {
get { return applyWindowsRuntimeProjections; }
set {
if (applyWindowsRuntimeProjections != value) {
applyWindowsRuntimeProjections = value;
OnPropertyChanged();
}
}
}
#endregion
CSharpFormattingOptions csharpFormattingOptions;
[Browsable(false)]
public CSharpFormattingOptions CSharpFormattingOptions {
get {
if (csharpFormattingOptions == null) {
csharpFormattingOptions = FormattingOptionsFactory.CreateAllman();
csharpFormattingOptions.IndentSwitchBody = false;
csharpFormattingOptions.ArrayInitializerWrapping = Wrapping.WrapAlways;
}
return csharpFormattingOptions;
}
set {
if (value == null)
throw new ArgumentNullException();
if (csharpFormattingOptions != value) {
csharpFormattingOptions = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public DecompilerSettings Clone()
{
DecompilerSettings settings = (DecompilerSettings)MemberwiseClone();
if (csharpFormattingOptions != null)
settings.csharpFormattingOptions = csharpFormattingOptions.Clone();
settings.PropertyChanged = null;
return settings;
}
}
}