// 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 { /// /// Settings for the decompiler. /// public class DecompilerSettings : INotifyPropertyChanged { /// /// Equivalent to new DecompilerSettings(LanguageVersion.Latest) /// public DecompilerSettings() { } /// /// Creates a new DecompilerSettings instance with initial settings /// appropriate for the specified language version. /// /// /// 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. /// public DecompilerSettings(CSharp.LanguageVersion languageVersion) { SetLanguageVersion(languageVersion); } /// /// Deactivates all language features from versions newer than . /// 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; /// /// Decompile anonymous methods/lambdas. /// [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; /// /// Decompile anonymous types. /// [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; /// /// Use C# 3 lambda syntax if possible. /// [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; /// /// Decompile expression trees. /// [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; /// /// Decompile enumerators. /// [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; /// /// Decompile use of the 'dynamic' type. /// [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; /// /// Decompile async methods. /// [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; /// /// Decompile await in catch/finally blocks. /// Only has an effect if is enabled. /// [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; /// /// Decompile [DecimalConstant(...)] as simple literal values. /// [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; /// /// Decompile C# 1.0 'public unsafe fixed int arr[10];' members. /// [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; /// /// Use lifted operators for nullables. /// [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; /// /// Decompile C# 6 ?. and ?[] operators. /// [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; /// /// Decompile automatic properties /// [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; /// /// Decompile automatic events /// [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; /// /// Decompile using statements. /// [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; /// /// Gets/Sets whether to use braces for single-statement-blocks. /// [Category("Other")] [Description("Always use braces")] public bool AlwaysUseBraces { get { return alwaysUseBraces; } set { if (alwaysUseBraces != value) { alwaysUseBraces = value; OnPropertyChanged(); } } } bool forEachStatement = true; /// /// Decompile foreach statements. /// [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; /// /// Decompile lock statements. /// [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; /// /// Gets/Sets whether to use C# 2.0 method group conversions. /// true: EventHandler h = this.OnClick; /// false: EventHandler h = new EventHandler(this.OnClick); /// [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; /// /// Gets/Sets whether to always cast targets to explicitly implemented methods. /// true: ((ISupportInitialize)pictureBox1).BeginInit(); /// false: pictureBox1.BeginInit(); /// default: false /// [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; /// /// Gets/Sets whether to use variable names from debug symbols, if available. /// [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; /// /// Gets/Sets whether to use array initializers. /// If set to false, might produce non-compilable code. /// [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; /// /// Gets/Sets whether to use C# 3.0 object/collection initializers. /// [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; /// /// Gets/Sets whether to use C# 6.0 dictionary initializers. /// Only has an effect if ObjectOrCollectionInitializers is enabled. /// [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; /// /// Gets/Sets whether to use C# 6.0 Extension Add methods in collection initializers. /// Only has an effect if ObjectOrCollectionInitializers is enabled. /// [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; /// /// Gets/Sets whether to use C# 6.0 string interpolation /// [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; /// /// Gets/Sets whether to include XML documentation comments in the decompiled code. /// [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; /// /// Gets/Sets whether member bodies should be decompiled. /// [Category("Other")] [Browsable(false)] public bool DecompileMemberBodies { get { return decompileMemberBodies; } set { if (decompileMemberBodies != value) { decompileMemberBodies = value; OnPropertyChanged(); } } } bool useExpressionBodyForCalculatedGetterOnlyProperties = true; /// /// Gets/Sets whether simple calculated getter-only property declarations should use expression body syntax. /// [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; /// /// Gets/Sets whether out variable declarations should be used when possible. /// [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; /// /// Gets/Sets whether discards should be used when possible. /// Only has an effect if is enabled. /// [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; /// /// Gets/Sets whether IsByRefLikeAttribute should be replaced with 'ref' modifiers on structs. /// [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; /// /// Gets/Sets whether IsReadOnlyAttribute should be replaced with 'readonly' modifiers on structs /// and with the 'in' modifier on parameters. /// [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; /// /// If this option is active, [IsUnmanagedAttribute] on type parameters /// is replaced with "T : unmanaged" constraints. /// [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; /// /// Gets/Sets whether C# 7.3 stackalloc initializers should be used. /// [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; /// /// Gets/Sets whether tuple type syntax (int, string) /// should be used for System.ValueTuple. /// [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; /// /// Gets/Sets whether implicit conversions between tuples /// should be used in the decompiled output. /// [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; /// /// Gets/Sets whether tuple comparisons should be detected. /// [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; /// /// Gets/Sets whether named arguments should be used. /// [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; /// /// Gets/Sets whether C# 7.2 non-trailing named arguments should be used. /// [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; /// /// Gets/Sets whether optional arguments should be removed, if possible. /// [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; /// /// 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. /// [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; /// /// Gets/Sets whether C# 8.0 nullable reference types are enabled. /// [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; /// /// Gets/Sets whether the decompiler can assume that 'ldlen; conv.i4.ovf' does not throw an overflow exception. /// [Category("VB-specific options")] [Browsable(false)] public bool AssumeArrayLengthFitsIntoInt32 { get { return assumeArrayLengthFitsIntoInt32; } set { if (assumeArrayLengthFitsIntoInt32 != value) { assumeArrayLengthFitsIntoInt32 = value; OnPropertyChanged(); } } } bool introduceIncrementAndDecrement = true; /// /// Gets/Sets whether to use increment and decrement operators /// [Category("VB-specific options")] [Browsable(false)] public bool IntroduceIncrementAndDecrement { get { return introduceIncrementAndDecrement; } set { if (introduceIncrementAndDecrement != value) { introduceIncrementAndDecrement = value; OnPropertyChanged(); } } } bool makeAssignmentExpressions = true; /// /// Gets/Sets whether to use assignment expressions such as in while ((count = Do()) != 0) ; /// [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; } } }