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.

2213 lines
56 KiB

3 years ago
5 years ago
  1. // Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4. // software and associated documentation files (the "Software"), to deal in the Software
  5. // without restriction, including without limitation the rights to use, copy, modify, merge,
  6. // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7. // to whom the Software is furnished to do so, subject to the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be included in all copies or
  10. // substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  13. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  14. // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  15. // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  17. // DEALINGS IN THE SOFTWARE.
  18. using System;
  19. using System.ComponentModel;
  20. using System.Runtime.CompilerServices;
  21. using ICSharpCode.Decompiler.CSharp.OutputVisitor;
  22. namespace ICSharpCode.Decompiler
  23. {
  24. /// <summary>
  25. /// Settings for the decompiler.
  26. /// </summary>
  27. public class DecompilerSettings : INotifyPropertyChanged
  28. {
  29. /// <summary>
  30. /// Equivalent to <c>new DecompilerSettings(LanguageVersion.Latest)</c>
  31. /// </summary>
  32. public DecompilerSettings()
  33. {
  34. }
  35. /// <summary>
  36. /// Creates a new DecompilerSettings instance with initial settings
  37. /// appropriate for the specified language version.
  38. /// </summary>
  39. /// <remarks>
  40. /// This does not imply that the resulting code strictly uses only language features from
  41. /// that version. Language constructs like generics or ref locals cannot be removed from
  42. /// the compiled code.
  43. /// </remarks>
  44. public DecompilerSettings(CSharp.LanguageVersion languageVersion)
  45. {
  46. SetLanguageVersion(languageVersion);
  47. }
  48. /// <summary>
  49. /// Deactivates all language features from versions newer than <paramref name="languageVersion"/>.
  50. /// </summary>
  51. public void SetLanguageVersion(CSharp.LanguageVersion languageVersion)
  52. {
  53. // By default, all decompiler features are enabled.
  54. // Disable some of them based on language version:
  55. if (languageVersion < CSharp.LanguageVersion.CSharp2)
  56. {
  57. anonymousMethods = false;
  58. liftNullables = false;
  59. yieldReturn = false;
  60. useImplicitMethodGroupConversion = false;
  61. }
  62. if (languageVersion < CSharp.LanguageVersion.CSharp3)
  63. {
  64. anonymousTypes = false;
  65. useLambdaSyntax = false;
  66. objectCollectionInitializers = false;
  67. automaticProperties = false;
  68. extensionMethods = false;
  69. queryExpressions = false;
  70. expressionTrees = false;
  71. }
  72. if (languageVersion < CSharp.LanguageVersion.CSharp4)
  73. {
  74. dynamic = false;
  75. namedArguments = false;
  76. optionalArguments = false;
  77. }
  78. if (languageVersion < CSharp.LanguageVersion.CSharp5)
  79. {
  80. asyncAwait = false;
  81. }
  82. if (languageVersion < CSharp.LanguageVersion.CSharp6)
  83. {
  84. awaitInCatchFinally = false;
  85. useExpressionBodyForCalculatedGetterOnlyProperties = false;
  86. nullPropagation = false;
  87. stringInterpolation = false;
  88. dictionaryInitializers = false;
  89. extensionMethodsInCollectionInitializers = false;
  90. useRefLocalsForAccurateOrderOfEvaluation = false;
  91. getterOnlyAutomaticProperties = false;
  92. }
  93. if (languageVersion < CSharp.LanguageVersion.CSharp7)
  94. {
  95. outVariables = false;
  96. throwExpressions = false;
  97. tupleTypes = false;
  98. tupleConversions = false;
  99. discards = false;
  100. localFunctions = false;
  101. deconstruction = false;
  102. patternMatching = false;
  103. }
  104. if (languageVersion < CSharp.LanguageVersion.CSharp7_2)
  105. {
  106. introduceReadonlyAndInModifiers = false;
  107. introduceRefModifiersOnStructs = false;
  108. nonTrailingNamedArguments = false;
  109. refExtensionMethods = false;
  110. }
  111. if (languageVersion < CSharp.LanguageVersion.CSharp7_3)
  112. {
  113. introduceUnmanagedConstraint = false;
  114. stackAllocInitializers = false;
  115. tupleComparisons = false;
  116. patternBasedFixedStatement = false;
  117. }
  118. if (languageVersion < CSharp.LanguageVersion.CSharp8_0)
  119. {
  120. nullableReferenceTypes = false;
  121. readOnlyMethods = false;
  122. asyncUsingAndForEachStatement = false;
  123. asyncEnumerator = false;
  124. useEnhancedUsing = false;
  125. staticLocalFunctions = false;
  126. ranges = false;
  127. switchExpressions = false;
  128. recursivePatternMatching = false;
  129. }
  130. if (languageVersion < CSharp.LanguageVersion.CSharp9_0)
  131. {
  132. nativeIntegers = false;
  133. initAccessors = false;
  134. functionPointers = false;
  135. forEachWithGetEnumeratorExtension = false;
  136. recordClasses = false;
  137. withExpressions = false;
  138. usePrimaryConstructorSyntax = false;
  139. covariantReturns = false;
  140. relationalPatterns = false;
  141. patternCombinators = false;
  142. }
  143. if (languageVersion < CSharp.LanguageVersion.CSharp10_0)
  144. {
  145. fileScopedNamespaces = false;
  146. recordStructs = false;
  147. }
  148. if (languageVersion < CSharp.LanguageVersion.CSharp11_0)
  149. {
  150. scopedRef = false;
  151. requiredMembers = false;
  152. numericIntPtr = false;
  153. utf8StringLiterals = false;
  154. unsignedRightShift = false;
  155. checkedOperators = false;
  156. }
  157. if (languageVersion < CSharp.LanguageVersion.CSharp12_0)
  158. {
  159. refReadOnlyParameters = false;
  160. usePrimaryConstructorSyntaxForNonRecordTypes = false;
  161. }
  162. }
  163. public CSharp.LanguageVersion GetMinimumRequiredVersion()
  164. {
  165. if (refReadOnlyParameters || usePrimaryConstructorSyntaxForNonRecordTypes)
  166. return CSharp.LanguageVersion.CSharp12_0;
  167. if (scopedRef || requiredMembers || numericIntPtr || utf8StringLiterals || unsignedRightShift || checkedOperators)
  168. return CSharp.LanguageVersion.CSharp11_0;
  169. if (fileScopedNamespaces || recordStructs)
  170. return CSharp.LanguageVersion.CSharp10_0;
  171. if (nativeIntegers || initAccessors || functionPointers || forEachWithGetEnumeratorExtension
  172. || recordClasses || withExpressions || usePrimaryConstructorSyntax || covariantReturns
  173. || relationalPatterns || patternCombinators)
  174. return CSharp.LanguageVersion.CSharp9_0;
  175. if (nullableReferenceTypes || readOnlyMethods || asyncEnumerator || asyncUsingAndForEachStatement
  176. || staticLocalFunctions || ranges || switchExpressions || recursivePatternMatching)
  177. return CSharp.LanguageVersion.CSharp8_0;
  178. if (introduceUnmanagedConstraint || tupleComparisons || stackAllocInitializers
  179. || patternBasedFixedStatement)
  180. return CSharp.LanguageVersion.CSharp7_3;
  181. if (introduceRefModifiersOnStructs || introduceReadonlyAndInModifiers
  182. || nonTrailingNamedArguments || refExtensionMethods)
  183. return CSharp.LanguageVersion.CSharp7_2;
  184. // C# 7.1 missing
  185. if (outVariables || throwExpressions || tupleTypes || tupleConversions
  186. || discards || localFunctions || deconstruction || patternMatching)
  187. return CSharp.LanguageVersion.CSharp7;
  188. if (awaitInCatchFinally || useExpressionBodyForCalculatedGetterOnlyProperties || nullPropagation
  189. || stringInterpolation || dictionaryInitializers || extensionMethodsInCollectionInitializers
  190. || useRefLocalsForAccurateOrderOfEvaluation || getterOnlyAutomaticProperties)
  191. return CSharp.LanguageVersion.CSharp6;
  192. if (asyncAwait)
  193. return CSharp.LanguageVersion.CSharp5;
  194. if (dynamic || namedArguments || optionalArguments)
  195. return CSharp.LanguageVersion.CSharp4;
  196. if (anonymousTypes || objectCollectionInitializers || automaticProperties
  197. || queryExpressions || expressionTrees)
  198. return CSharp.LanguageVersion.CSharp3;
  199. if (anonymousMethods || liftNullables || yieldReturn || useImplicitMethodGroupConversion)
  200. return CSharp.LanguageVersion.CSharp2;
  201. return CSharp.LanguageVersion.CSharp1;
  202. }
  203. bool nativeIntegers = true;
  204. /// <summary>
  205. /// Use C# 9 <c>nint</c>/<c>nuint</c> types.
  206. /// </summary>
  207. [Category("C# 9.0 / VS 2019.8")]
  208. [Description("DecompilerSettings.NativeIntegers")]
  209. public bool NativeIntegers {
  210. get { return nativeIntegers; }
  211. set {
  212. if (nativeIntegers != value)
  213. {
  214. nativeIntegers = value;
  215. OnPropertyChanged();
  216. }
  217. }
  218. }
  219. bool numericIntPtr = true;
  220. /// <summary>
  221. /// Treat <c>IntPtr</c>/<c>UIntPtr</c> as <c>nint</c>/<c>nuint</c>.
  222. /// </summary>
  223. [Category("C# 11.0 / VS 2022.4")]
  224. [Description("DecompilerSettings.NumericIntPtr")]
  225. public bool NumericIntPtr {
  226. get { return numericIntPtr; }
  227. set {
  228. if (numericIntPtr != value)
  229. {
  230. numericIntPtr = value;
  231. OnPropertyChanged();
  232. }
  233. }
  234. }
  235. bool covariantReturns = true;
  236. /// <summary>
  237. /// Decompile C# 9 covariant return types.
  238. /// </summary>
  239. [Category("C# 9.0 / VS 2019.8")]
  240. [Description("DecompilerSettings.CovariantReturns")]
  241. public bool CovariantReturns {
  242. get { return covariantReturns; }
  243. set {
  244. if (covariantReturns != value)
  245. {
  246. covariantReturns = value;
  247. OnPropertyChanged();
  248. }
  249. }
  250. }
  251. bool initAccessors = true;
  252. /// <summary>
  253. /// Use C# 9 <c>init;</c> property accessors.
  254. /// </summary>
  255. [Category("C# 9.0 / VS 2019.8")]
  256. [Description("DecompilerSettings.InitAccessors")]
  257. public bool InitAccessors {
  258. get { return initAccessors; }
  259. set {
  260. if (initAccessors != value)
  261. {
  262. initAccessors = value;
  263. OnPropertyChanged();
  264. }
  265. }
  266. }
  267. bool recordClasses = true;
  268. /// <summary>
  269. /// Use C# 9 <c>record</c> classes.
  270. /// </summary>
  271. [Category("C# 9.0 / VS 2019.8")]
  272. [Description("DecompilerSettings.RecordClasses")]
  273. public bool RecordClasses {
  274. get { return recordClasses; }
  275. set {
  276. if (recordClasses != value)
  277. {
  278. recordClasses = value;
  279. OnPropertyChanged();
  280. }
  281. }
  282. }
  283. bool recordStructs = true;
  284. /// <summary>
  285. /// Use C# 10 <c>record</c> structs.
  286. /// </summary>
  287. [Category("C# 10.0 / VS 2022")]
  288. [Description("DecompilerSettings.RecordStructs")]
  289. public bool RecordStructs {
  290. get { return recordStructs; }
  291. set {
  292. if (recordStructs != value)
  293. {
  294. recordStructs = value;
  295. OnPropertyChanged();
  296. }
  297. }
  298. }
  299. bool withExpressions = true;
  300. /// <summary>
  301. /// Use C# 9 <c>with</c> initializer expressions.
  302. /// </summary>
  303. [Category("C# 9.0 / VS 2019.8")]
  304. [Description("DecompilerSettings.WithExpressions")]
  305. public bool WithExpressions {
  306. get { return withExpressions; }
  307. set {
  308. if (withExpressions != value)
  309. {
  310. withExpressions = value;
  311. OnPropertyChanged();
  312. }
  313. }
  314. }
  315. bool usePrimaryConstructorSyntax = true;
  316. /// <summary>
  317. /// Use primary constructor syntax with records.
  318. /// </summary>
  319. [Category("C# 9.0 / VS 2019.8")]
  320. [Description("DecompilerSettings.UsePrimaryConstructorSyntax")]
  321. public bool UsePrimaryConstructorSyntax {
  322. get { return usePrimaryConstructorSyntax; }
  323. set {
  324. if (usePrimaryConstructorSyntax != value)
  325. {
  326. usePrimaryConstructorSyntax = value;
  327. OnPropertyChanged();
  328. }
  329. }
  330. }
  331. bool functionPointers = true;
  332. /// <summary>
  333. /// Use C# 9 <c>delegate* unmanaged</c> types.
  334. /// If this option is disabled, function pointers will instead be decompiled with type `IntPtr`.
  335. /// </summary>
  336. [Category("C# 9.0 / VS 2019.8")]
  337. [Description("DecompilerSettings.FunctionPointers")]
  338. public bool FunctionPointers {
  339. get { return functionPointers; }
  340. set {
  341. if (functionPointers != value)
  342. {
  343. functionPointers = value;
  344. OnPropertyChanged();
  345. }
  346. }
  347. }
  348. bool scopedRef = true;
  349. /// <summary>
  350. /// Use C# 11 <c>scoped</c> modifier.
  351. /// </summary>
  352. [Category("C# 11.0 / VS 2022.4")]
  353. [Description("DecompilerSettings.ScopedRef")]
  354. public bool ScopedRef {
  355. get { return scopedRef; }
  356. set {
  357. if (scopedRef != value)
  358. {
  359. scopedRef = value;
  360. OnPropertyChanged();
  361. }
  362. }
  363. }
  364. [Obsolete("Renamed to ScopedRef. This property will be removed in a future version of the decompiler.")]
  365. [Browsable(false)]
  366. public bool LifetimeAnnotations {
  367. get { return ScopedRef; }
  368. set { ScopedRef = value; }
  369. }
  370. bool requiredMembers = true;
  371. /// <summary>
  372. /// Use C# 11 <c>required</c> modifier.
  373. /// </summary>
  374. [Category("C# 11.0 / VS 2022.4")]
  375. [Description("DecompilerSettings.RequiredMembers")]
  376. public bool RequiredMembers {
  377. get { return requiredMembers; }
  378. set {
  379. if (requiredMembers != value)
  380. {
  381. requiredMembers = value;
  382. OnPropertyChanged();
  383. }
  384. }
  385. }
  386. bool switchExpressions = true;
  387. /// <summary>
  388. /// Use C# 8 switch expressions.
  389. /// </summary>
  390. [Category("C# 8.0 / VS 2019")]
  391. [Description("DecompilerSettings.SwitchExpressions")]
  392. public bool SwitchExpressions {
  393. get { return switchExpressions; }
  394. set {
  395. if (switchExpressions != value)
  396. {
  397. switchExpressions = value;
  398. OnPropertyChanged();
  399. }
  400. }
  401. }
  402. bool fileScopedNamespaces = true;
  403. /// <summary>
  404. /// Use C# 10 file-scoped namespaces.
  405. /// </summary>
  406. [Category("C# 10.0 / VS 2022")]
  407. [Description("DecompilerSettings.FileScopedNamespaces")]
  408. public bool FileScopedNamespaces {
  409. get { return fileScopedNamespaces; }
  410. set {
  411. if (fileScopedNamespaces != value)
  412. {
  413. fileScopedNamespaces = value;
  414. OnPropertyChanged();
  415. }
  416. }
  417. }
  418. bool anonymousMethods = true;
  419. /// <summary>
  420. /// Decompile anonymous methods/lambdas.
  421. /// </summary>
  422. [Category("C# 2.0 / VS 2005")]
  423. [Description("DecompilerSettings.DecompileAnonymousMethodsLambdas")]
  424. public bool AnonymousMethods {
  425. get { return anonymousMethods; }
  426. set {
  427. if (anonymousMethods != value)
  428. {
  429. anonymousMethods = value;
  430. OnPropertyChanged();
  431. }
  432. }
  433. }
  434. bool anonymousTypes = true;
  435. /// <summary>
  436. /// Decompile anonymous types.
  437. /// </summary>
  438. [Category("C# 3.0 / VS 2008")]
  439. [Description("DecompilerSettings.DecompileAnonymousTypes")]
  440. public bool AnonymousTypes {
  441. get { return anonymousTypes; }
  442. set {
  443. if (anonymousTypes != value)
  444. {
  445. anonymousTypes = value;
  446. OnPropertyChanged();
  447. }
  448. }
  449. }
  450. bool useLambdaSyntax = true;
  451. /// <summary>
  452. /// Use C# 3 lambda syntax if possible.
  453. /// </summary>
  454. [Category("C# 3.0 / VS 2008")]
  455. [Description("DecompilerSettings.UseLambdaSyntaxIfPossible")]
  456. public bool UseLambdaSyntax {
  457. get { return useLambdaSyntax; }
  458. set {
  459. if (useLambdaSyntax != value)
  460. {
  461. useLambdaSyntax = value;
  462. OnPropertyChanged();
  463. }
  464. }
  465. }
  466. bool expressionTrees = true;
  467. /// <summary>
  468. /// Decompile expression trees.
  469. /// </summary>
  470. [Category("C# 3.0 / VS 2008")]
  471. [Description("DecompilerSettings.DecompileExpressionTrees")]
  472. public bool ExpressionTrees {
  473. get { return expressionTrees; }
  474. set {
  475. if (expressionTrees != value)
  476. {
  477. expressionTrees = value;
  478. OnPropertyChanged();
  479. }
  480. }
  481. }
  482. bool yieldReturn = true;
  483. /// <summary>
  484. /// Decompile enumerators.
  485. /// </summary>
  486. [Category("C# 2.0 / VS 2005")]
  487. [Description("DecompilerSettings.DecompileEnumeratorsYieldReturn")]
  488. public bool YieldReturn {
  489. get { return yieldReturn; }
  490. set {
  491. if (yieldReturn != value)
  492. {
  493. yieldReturn = value;
  494. OnPropertyChanged();
  495. }
  496. }
  497. }
  498. bool dynamic = true;
  499. /// <summary>
  500. /// Decompile use of the 'dynamic' type.
  501. /// </summary>
  502. [Category("C# 4.0 / VS 2010")]
  503. [Description("DecompilerSettings.DecompileUseOfTheDynamicType")]
  504. public bool Dynamic {
  505. get { return dynamic; }
  506. set {
  507. if (dynamic != value)
  508. {
  509. dynamic = value;
  510. OnPropertyChanged();
  511. }
  512. }
  513. }
  514. bool asyncAwait = true;
  515. /// <summary>
  516. /// Decompile async methods.
  517. /// </summary>
  518. [Category("C# 5.0 / VS 2012")]
  519. [Description("DecompilerSettings.DecompileAsyncMethods")]
  520. public bool AsyncAwait {
  521. get { return asyncAwait; }
  522. set {
  523. if (asyncAwait != value)
  524. {
  525. asyncAwait = value;
  526. OnPropertyChanged();
  527. }
  528. }
  529. }
  530. bool awaitInCatchFinally = true;
  531. /// <summary>
  532. /// Decompile await in catch/finally blocks.
  533. /// Only has an effect if <see cref="AsyncAwait"/> is enabled.
  534. /// </summary>
  535. [Category("C# 6.0 / VS 2015")]
  536. [Description("DecompilerSettings.DecompileAwaitInCatchFinallyBlocks")]
  537. public bool AwaitInCatchFinally {
  538. get { return awaitInCatchFinally; }
  539. set {
  540. if (awaitInCatchFinally != value)
  541. {
  542. awaitInCatchFinally = value;
  543. OnPropertyChanged();
  544. }
  545. }
  546. }
  547. bool asyncEnumerator = true;
  548. /// <summary>
  549. /// Decompile IAsyncEnumerator/IAsyncEnumerable.
  550. /// Only has an effect if <see cref="AsyncAwait"/> is enabled.
  551. /// </summary>
  552. [Category("C# 8.0 / VS 2019")]
  553. [Description("DecompilerSettings.AsyncEnumerator")]
  554. public bool AsyncEnumerator {
  555. get { return asyncEnumerator; }
  556. set {
  557. if (asyncEnumerator != value)
  558. {
  559. asyncEnumerator = value;
  560. OnPropertyChanged();
  561. }
  562. }
  563. }
  564. bool decimalConstants = true;
  565. /// <summary>
  566. /// Decompile [DecimalConstant(...)] as simple literal values.
  567. /// </summary>
  568. [Category("C# 1.0 / VS .NET")]
  569. [Description("DecompilerSettings.DecompileDecimalConstantAsSimpleLiteralValues")]
  570. public bool DecimalConstants {
  571. get { return decimalConstants; }
  572. set {
  573. if (decimalConstants != value)
  574. {
  575. decimalConstants = value;
  576. OnPropertyChanged();
  577. }
  578. }
  579. }
  580. bool fixedBuffers = true;
  581. /// <summary>
  582. /// Decompile C# 1.0 'public unsafe fixed int arr[10];' members.
  583. /// </summary>
  584. [Category("C# 1.0 / VS .NET")]
  585. [Description("DecompilerSettings.DecompileC10PublicUnsafeFixedIntArr10Members")]
  586. public bool FixedBuffers {
  587. get { return fixedBuffers; }
  588. set {
  589. if (fixedBuffers != value)
  590. {
  591. fixedBuffers = value;
  592. OnPropertyChanged();
  593. }
  594. }
  595. }
  596. bool stringConcat = true;
  597. /// <summary>
  598. /// Decompile 'string.Concat(a, b)' calls into 'a + b'.
  599. /// </summary>
  600. [Category("C# 1.0 / VS .NET")]
  601. [Description("DecompilerSettings.StringConcat")]
  602. public bool StringConcat {
  603. get { return stringConcat; }
  604. set {
  605. if (stringConcat != value)
  606. {
  607. stringConcat = value;
  608. OnPropertyChanged();
  609. }
  610. }
  611. }
  612. bool liftNullables = true;
  613. /// <summary>
  614. /// Use lifted operators for nullables.
  615. /// </summary>
  616. [Category("C# 2.0 / VS 2005")]
  617. [Description("DecompilerSettings.UseLiftedOperatorsForNullables")]
  618. public bool LiftNullables {
  619. get { return liftNullables; }
  620. set {
  621. if (liftNullables != value)
  622. {
  623. liftNullables = value;
  624. OnPropertyChanged();
  625. }
  626. }
  627. }
  628. bool nullPropagation = true;
  629. /// <summary>
  630. /// Decompile C# 6 ?. and ?[] operators.
  631. /// </summary>
  632. [Category("C# 6.0 / VS 2015")]
  633. [Description("DecompilerSettings.NullPropagation")]
  634. public bool NullPropagation {
  635. get { return nullPropagation; }
  636. set {
  637. if (nullPropagation != value)
  638. {
  639. nullPropagation = value;
  640. OnPropertyChanged();
  641. }
  642. }
  643. }
  644. bool automaticProperties = true;
  645. /// <summary>
  646. /// Decompile automatic properties
  647. /// </summary>
  648. [Category("C# 3.0 / VS 2008")]
  649. [Description("DecompilerSettings.DecompileAutomaticProperties")]
  650. public bool AutomaticProperties {
  651. get { return automaticProperties; }
  652. set {
  653. if (automaticProperties != value)
  654. {
  655. automaticProperties = value;
  656. OnPropertyChanged();
  657. }
  658. }
  659. }
  660. bool getterOnlyAutomaticProperties = true;
  661. /// <summary>
  662. /// Decompile getter-only automatic properties
  663. /// </summary>
  664. [Category("C# 6.0 / VS 2015")]
  665. [Description("DecompilerSettings.GetterOnlyAutomaticProperties")]
  666. public bool GetterOnlyAutomaticProperties {
  667. get { return getterOnlyAutomaticProperties; }
  668. set {
  669. if (getterOnlyAutomaticProperties != value)
  670. {
  671. getterOnlyAutomaticProperties = value;
  672. OnPropertyChanged();
  673. }
  674. }
  675. }
  676. bool automaticEvents = true;
  677. /// <summary>
  678. /// Decompile automatic events
  679. /// </summary>
  680. [Category("C# 1.0 / VS .NET")]
  681. [Description("DecompilerSettings.DecompileAutomaticEvents")]
  682. public bool AutomaticEvents {
  683. get { return automaticEvents; }
  684. set {
  685. if (automaticEvents != value)
  686. {
  687. automaticEvents = value;
  688. OnPropertyChanged();
  689. }
  690. }
  691. }
  692. bool usingStatement = true;
  693. /// <summary>
  694. /// Decompile using statements.
  695. /// </summary>
  696. [Category("C# 1.0 / VS .NET")]
  697. [Description("DecompilerSettings.DetectUsingStatements")]
  698. public bool UsingStatement {
  699. get { return usingStatement; }
  700. set {
  701. if (usingStatement != value)
  702. {
  703. usingStatement = value;
  704. OnPropertyChanged();
  705. }
  706. }
  707. }
  708. bool useEnhancedUsing = true;
  709. /// <summary>
  710. /// Use enhanced using statements.
  711. /// </summary>
  712. [Category("C# 8.0 / VS 2019")]
  713. [Description("DecompilerSettings.UseEnhancedUsing")]
  714. public bool UseEnhancedUsing {
  715. get { return useEnhancedUsing; }
  716. set {
  717. if (useEnhancedUsing != value)
  718. {
  719. useEnhancedUsing = value;
  720. OnPropertyChanged();
  721. }
  722. }
  723. }
  724. bool alwaysUseBraces = true;
  725. /// <summary>
  726. /// Gets/Sets whether to use braces for single-statement-blocks.
  727. /// </summary>
  728. [Category("DecompilerSettings.Other")]
  729. [Description("DecompilerSettings.AlwaysUseBraces")]
  730. public bool AlwaysUseBraces {
  731. get { return alwaysUseBraces; }
  732. set {
  733. if (alwaysUseBraces != value)
  734. {
  735. alwaysUseBraces = value;
  736. OnPropertyChanged();
  737. }
  738. }
  739. }
  740. bool forEachStatement = true;
  741. /// <summary>
  742. /// Decompile foreach statements.
  743. /// </summary>
  744. [Category("C# 1.0 / VS .NET")]
  745. [Description("DecompilerSettings.DetectForeachStatements")]
  746. public bool ForEachStatement {
  747. get { return forEachStatement; }
  748. set {
  749. if (forEachStatement != value)
  750. {
  751. forEachStatement = value;
  752. OnPropertyChanged();
  753. }
  754. }
  755. }
  756. bool forEachWithGetEnumeratorExtension = true;
  757. /// <summary>
  758. /// Support GetEnumerator extension methods in foreach.
  759. /// </summary>
  760. [Category("C# 9.0 / VS 2019.8")]
  761. [Description("DecompilerSettings.DecompileForEachWithGetEnumeratorExtension")]
  762. public bool ForEachWithGetEnumeratorExtension {
  763. get { return forEachWithGetEnumeratorExtension; }
  764. set {
  765. if (forEachWithGetEnumeratorExtension != value)
  766. {
  767. forEachWithGetEnumeratorExtension = value;
  768. OnPropertyChanged();
  769. }
  770. }
  771. }
  772. bool lockStatement = true;
  773. /// <summary>
  774. /// Decompile lock statements.
  775. /// </summary>
  776. [Category("C# 1.0 / VS .NET")]
  777. [Description("DecompilerSettings.DetectLockStatements")]
  778. public bool LockStatement {
  779. get { return lockStatement; }
  780. set {
  781. if (lockStatement != value)
  782. {
  783. lockStatement = value;
  784. OnPropertyChanged();
  785. }
  786. }
  787. }
  788. bool switchStatementOnString = true;
  789. [Category("C# 1.0 / VS .NET")]
  790. [Description("DecompilerSettings.DetectSwitchOnString")]
  791. public bool SwitchStatementOnString {
  792. get { return switchStatementOnString; }
  793. set {
  794. if (switchStatementOnString != value)
  795. {
  796. switchStatementOnString = value;
  797. OnPropertyChanged();
  798. }
  799. }
  800. }
  801. bool sparseIntegerSwitch = true;
  802. [Category("C# 1.0 / VS .NET")]
  803. [Description("DecompilerSettings.SparseIntegerSwitch")]
  804. public bool SparseIntegerSwitch {
  805. get { return sparseIntegerSwitch; }
  806. set {
  807. if (sparseIntegerSwitch != value)
  808. {
  809. sparseIntegerSwitch = value;
  810. OnPropertyChanged();
  811. }
  812. }
  813. }
  814. bool usingDeclarations = true;
  815. [Category("C# 1.0 / VS .NET")]
  816. [Description("DecompilerSettings.InsertUsingDeclarations")]
  817. public bool UsingDeclarations {
  818. get { return usingDeclarations; }
  819. set {
  820. if (usingDeclarations != value)
  821. {
  822. usingDeclarations = value;
  823. OnPropertyChanged();
  824. }
  825. }
  826. }
  827. bool extensionMethods = true;
  828. [Category("C# 3.0 / VS 2008")]
  829. [Description("DecompilerSettings.UseExtensionMethodSyntax")]
  830. public bool ExtensionMethods {
  831. get { return extensionMethods; }
  832. set {
  833. if (extensionMethods != value)
  834. {
  835. extensionMethods = value;
  836. OnPropertyChanged();
  837. }
  838. }
  839. }
  840. bool queryExpressions = true;
  841. [Category("C# 3.0 / VS 2008")]
  842. [Description("DecompilerSettings.UseLINQExpressionSyntax")]
  843. public bool QueryExpressions {
  844. get { return queryExpressions; }
  845. set {
  846. if (queryExpressions != value)
  847. {
  848. queryExpressions = value;
  849. OnPropertyChanged();
  850. }
  851. }
  852. }
  853. bool useImplicitMethodGroupConversion = true;
  854. /// <summary>
  855. /// Gets/Sets whether to use C# 2.0 method group conversions.
  856. /// true: <c>EventHandler h = this.OnClick;</c>
  857. /// false: <c>EventHandler h = new EventHandler(this.OnClick);</c>
  858. /// </summary>
  859. [Category("C# 2.0 / VS 2005")]
  860. [Description("DecompilerSettings.UseImplicitMethodGroupConversions")]
  861. public bool UseImplicitMethodGroupConversion {
  862. get { return useImplicitMethodGroupConversion; }
  863. set {
  864. if (useImplicitMethodGroupConversion != value)
  865. {
  866. useImplicitMethodGroupConversion = value;
  867. OnPropertyChanged();
  868. }
  869. }
  870. }
  871. bool alwaysCastTargetsOfExplicitInterfaceImplementationCalls = false;
  872. /// <summary>
  873. /// Gets/Sets whether to always cast targets to explicitly implemented methods.
  874. /// true: <c>((ISupportInitialize)pictureBox1).BeginInit();</c>
  875. /// false: <c>pictureBox1.BeginInit();</c>
  876. /// default: false
  877. /// </summary>
  878. [Category("Other")]
  879. [Description("DecompilerSettings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls")]
  880. public bool AlwaysCastTargetsOfExplicitInterfaceImplementationCalls {
  881. get { return alwaysCastTargetsOfExplicitInterfaceImplementationCalls; }
  882. set {
  883. if (alwaysCastTargetsOfExplicitInterfaceImplementationCalls != value)
  884. {
  885. alwaysCastTargetsOfExplicitInterfaceImplementationCalls = value;
  886. OnPropertyChanged();
  887. }
  888. }
  889. }
  890. bool alwaysQualifyMemberReferences = false;
  891. /// <summary>
  892. /// Gets/Sets whether to always qualify member references.
  893. /// true: <c>this.DoSomething();</c>
  894. /// false: <c>DoSomething();</c>
  895. /// default: false
  896. /// </summary>
  897. [Category("Other")]
  898. [Description("DecompilerSettings.AlwaysQualifyMemberReferences")]
  899. public bool AlwaysQualifyMemberReferences {
  900. get { return alwaysQualifyMemberReferences; }
  901. set {
  902. if (alwaysQualifyMemberReferences != value)
  903. {
  904. alwaysQualifyMemberReferences = value;
  905. OnPropertyChanged();
  906. }
  907. }
  908. }
  909. bool alwaysShowEnumMemberValues = false;
  910. /// <summary>
  911. /// Gets/Sets whether to always show enum member values.
  912. /// true: <c>enum Kind { A = 0, B = 1, C = 5 }</c>
  913. /// false: <c>enum Kind { A, B, C = 5 }</c>
  914. /// default: false
  915. /// </summary>
  916. [Category("Other")]
  917. [Description("DecompilerSettings.AlwaysShowEnumMemberValues")]
  918. public bool AlwaysShowEnumMemberValues {
  919. get { return alwaysShowEnumMemberValues; }
  920. set {
  921. if (alwaysShowEnumMemberValues != value)
  922. {
  923. alwaysShowEnumMemberValues = value;
  924. OnPropertyChanged();
  925. }
  926. }
  927. }
  928. bool useDebugSymbols = true;
  929. /// <summary>
  930. /// Gets/Sets whether to use variable names from debug symbols, if available.
  931. /// </summary>
  932. [Category("Other")]
  933. [Description("DecompilerSettings.UseVariableNamesFromDebugSymbolsIfAvailable")]
  934. public bool UseDebugSymbols {
  935. get { return useDebugSymbols; }
  936. set {
  937. if (useDebugSymbols != value)
  938. {
  939. useDebugSymbols = value;
  940. OnPropertyChanged();
  941. }
  942. }
  943. }
  944. bool arrayInitializers = true;
  945. /// <summary>
  946. /// Gets/Sets whether to use array initializers.
  947. /// If set to false, might produce non-compilable code.
  948. /// </summary>
  949. [Category("C# 1.0 / VS .NET")]
  950. [Description("DecompilerSettings.ArrayInitializerExpressions")]
  951. public bool ArrayInitializers {
  952. get { return arrayInitializers; }
  953. set {
  954. if (arrayInitializers != value)
  955. {
  956. arrayInitializers = value;
  957. OnPropertyChanged();
  958. }
  959. }
  960. }
  961. bool objectCollectionInitializers = true;
  962. /// <summary>
  963. /// Gets/Sets whether to use C# 3.0 object/collection initializers.
  964. /// </summary>
  965. [Category("C# 3.0 / VS 2008")]
  966. [Description("DecompilerSettings.ObjectCollectionInitializerExpressions")]
  967. public bool ObjectOrCollectionInitializers {
  968. get { return objectCollectionInitializers; }
  969. set {
  970. if (objectCollectionInitializers != value)
  971. {
  972. objectCollectionInitializers = value;
  973. OnPropertyChanged();
  974. }
  975. }
  976. }
  977. bool dictionaryInitializers = true;
  978. /// <summary>
  979. /// Gets/Sets whether to use C# 6.0 dictionary initializers.
  980. /// Only has an effect if ObjectOrCollectionInitializers is enabled.
  981. /// </summary>
  982. [Category("C# 6.0 / VS 2015")]
  983. [Description("DecompilerSettings.DictionaryInitializerExpressions")]
  984. public bool DictionaryInitializers {
  985. get { return dictionaryInitializers; }
  986. set {
  987. if (dictionaryInitializers != value)
  988. {
  989. dictionaryInitializers = value;
  990. OnPropertyChanged();
  991. }
  992. }
  993. }
  994. bool extensionMethodsInCollectionInitializers = true;
  995. /// <summary>
  996. /// Gets/Sets whether to use C# 6.0 Extension Add methods in collection initializers.
  997. /// Only has an effect if ObjectOrCollectionInitializers is enabled.
  998. /// </summary>
  999. [Category("C# 6.0 / VS 2015")]
  1000. [Description("DecompilerSettings.AllowExtensionAddMethodsInCollectionInitializerExpressions")]
  1001. public bool ExtensionMethodsInCollectionInitializers {
  1002. get { return extensionMethodsInCollectionInitializers; }
  1003. set {
  1004. if (extensionMethodsInCollectionInitializers != value)
  1005. {
  1006. extensionMethodsInCollectionInitializers = value;
  1007. OnPropertyChanged();
  1008. }
  1009. }
  1010. }
  1011. bool useRefLocalsForAccurateOrderOfEvaluation = true;
  1012. /// <summary>
  1013. /// Gets/Sets whether to use local ref variables in cases where this is necessary
  1014. /// for re-compilation with a modern C# compiler to reproduce the same behavior
  1015. /// as the original assembly produced with an old C# compiler that used an incorrect
  1016. /// order of evaluation.
  1017. /// See https://github.com/icsharpcode/ILSpy/issues/2050
  1018. /// </summary>
  1019. [Category("C# 6.0 / VS 2015")]
  1020. [Description("DecompilerSettings.UseRefLocalsForAccurateOrderOfEvaluation")]
  1021. public bool UseRefLocalsForAccurateOrderOfEvaluation {
  1022. get { return useRefLocalsForAccurateOrderOfEvaluation; }
  1023. set {
  1024. if (useRefLocalsForAccurateOrderOfEvaluation != value)
  1025. {
  1026. useRefLocalsForAccurateOrderOfEvaluation = value;
  1027. OnPropertyChanged();
  1028. }
  1029. }
  1030. }
  1031. bool refExtensionMethods = true;
  1032. /// <summary>
  1033. /// Gets/Sets whether to use C# 7.2 'ref' extension methods.
  1034. /// </summary>
  1035. [Category("C# 7.2 / VS 2017.4")]
  1036. [Description("DecompilerSettings.AllowExtensionMethodSyntaxOnRef")]
  1037. public bool RefExtensionMethods {
  1038. get { return refExtensionMethods; }
  1039. set {
  1040. if (refExtensionMethods != value)
  1041. {
  1042. refExtensionMethods = value;
  1043. OnPropertyChanged();
  1044. }
  1045. }
  1046. }
  1047. bool stringInterpolation = true;
  1048. /// <summary>
  1049. /// Gets/Sets whether to use C# 6.0 string interpolation
  1050. /// </summary>
  1051. [Category("C# 6.0 / VS 2015")]
  1052. [Description("DecompilerSettings.UseStringInterpolation")]
  1053. public bool StringInterpolation {
  1054. get { return stringInterpolation; }
  1055. set {
  1056. if (stringInterpolation != value)
  1057. {
  1058. stringInterpolation = value;
  1059. OnPropertyChanged();
  1060. }
  1061. }
  1062. }
  1063. bool utf8StringLiterals = true;
  1064. /// <summary>
  1065. /// Gets/Sets whether to use C# 11.0 UTF-8 string literals
  1066. /// </summary>
  1067. [Category("C# 11.0 / VS 2022.4")]
  1068. [Description("DecompilerSettings.Utf8StringLiterals")]
  1069. public bool Utf8StringLiterals {
  1070. get { return utf8StringLiterals; }
  1071. set {
  1072. if (utf8StringLiterals != value)
  1073. {
  1074. utf8StringLiterals = value;
  1075. OnPropertyChanged();
  1076. }
  1077. }
  1078. }
  1079. bool switchOnReadOnlySpanChar = true;
  1080. /// <summary>
  1081. /// Gets/Sets whether to use C# 11.0 switch on (ReadOnly)Span&lt;char&gt;
  1082. /// </summary>
  1083. [Category("C# 11.0 / VS 2022.4")]
  1084. [Description("DecompilerSettings.SwitchOnReadOnlySpanChar")]
  1085. public bool SwitchOnReadOnlySpanChar {
  1086. get { return switchOnReadOnlySpanChar; }
  1087. set {
  1088. if (switchOnReadOnlySpanChar != value)
  1089. {
  1090. switchOnReadOnlySpanChar = value;
  1091. OnPropertyChanged();
  1092. }
  1093. }
  1094. }
  1095. bool unsignedRightShift = true;
  1096. /// <summary>
  1097. /// Gets/Sets whether to use C# 11.0 unsigned right shift operator.
  1098. /// </summary>
  1099. [Category("C# 11.0 / VS 2022.4")]
  1100. [Description("DecompilerSettings.UnsignedRightShift")]
  1101. public bool UnsignedRightShift {
  1102. get { return unsignedRightShift; }
  1103. set {
  1104. if (unsignedRightShift != value)
  1105. {
  1106. unsignedRightShift = value;
  1107. OnPropertyChanged();
  1108. }
  1109. }
  1110. }
  1111. bool checkedOperators = true;
  1112. /// <summary>
  1113. /// Gets/Sets whether to use C# 11.0 user-defined checked operators.
  1114. /// </summary>
  1115. [Category("C# 11.0 / VS 2022.4")]
  1116. [Description("DecompilerSettings.CheckedOperators")]
  1117. public bool CheckedOperators {
  1118. get { return checkedOperators; }
  1119. set {
  1120. if (checkedOperators != value)
  1121. {
  1122. checkedOperators = value;
  1123. OnPropertyChanged();
  1124. }
  1125. }
  1126. }
  1127. bool showXmlDocumentation = true;
  1128. /// <summary>
  1129. /// Gets/Sets whether to include XML documentation comments in the decompiled code.
  1130. /// </summary>
  1131. [Category("DecompilerSettings.Other")]
  1132. [Description("DecompilerSettings.IncludeXMLDocumentationCommentsInTheDecompiledCode")]
  1133. public bool ShowXmlDocumentation {
  1134. get { return showXmlDocumentation; }
  1135. set {
  1136. if (showXmlDocumentation != value)
  1137. {
  1138. showXmlDocumentation = value;
  1139. OnPropertyChanged();
  1140. }
  1141. }
  1142. }
  1143. bool foldBraces = false;
  1144. [Browsable(false)]
  1145. public bool FoldBraces {
  1146. get { return foldBraces; }
  1147. set {
  1148. if (foldBraces != value)
  1149. {
  1150. foldBraces = value;
  1151. OnPropertyChanged();
  1152. }
  1153. }
  1154. }
  1155. bool expandMemberDefinitions = false;
  1156. [Browsable(false)]
  1157. public bool ExpandMemberDefinitions {
  1158. get { return expandMemberDefinitions; }
  1159. set {
  1160. if (expandMemberDefinitions != value)
  1161. {
  1162. expandMemberDefinitions = value;
  1163. OnPropertyChanged();
  1164. }
  1165. }
  1166. }
  1167. bool expandUsingDeclarations = false;
  1168. [Browsable(false)]
  1169. public bool ExpandUsingDeclarations {
  1170. get { return expandUsingDeclarations; }
  1171. set {
  1172. if (expandUsingDeclarations != value)
  1173. {
  1174. expandUsingDeclarations = value;
  1175. OnPropertyChanged();
  1176. }
  1177. }
  1178. }
  1179. bool decompileMemberBodies = true;
  1180. /// <summary>
  1181. /// Gets/Sets whether member bodies should be decompiled.
  1182. /// </summary>
  1183. [Category("DecompilerSettings.Other")]
  1184. [Browsable(false)]
  1185. public bool DecompileMemberBodies {
  1186. get { return decompileMemberBodies; }
  1187. set {
  1188. if (decompileMemberBodies != value)
  1189. {
  1190. decompileMemberBodies = value;
  1191. OnPropertyChanged();
  1192. }
  1193. }
  1194. }
  1195. bool useExpressionBodyForCalculatedGetterOnlyProperties = true;
  1196. /// <summary>
  1197. /// Gets/Sets whether simple calculated getter-only property declarations
  1198. /// should use expression body syntax.
  1199. /// </summary>
  1200. [Category("C# 6.0 / VS 2015")]
  1201. [Description("DecompilerSettings.UseExpressionBodiedMemberSyntaxForGetOnlyProperties")]
  1202. public bool UseExpressionBodyForCalculatedGetterOnlyProperties {
  1203. get { return useExpressionBodyForCalculatedGetterOnlyProperties; }
  1204. set {
  1205. if (useExpressionBodyForCalculatedGetterOnlyProperties != value)
  1206. {
  1207. useExpressionBodyForCalculatedGetterOnlyProperties = value;
  1208. OnPropertyChanged();
  1209. }
  1210. }
  1211. }
  1212. bool outVariables = true;
  1213. /// <summary>
  1214. /// Gets/Sets whether out variable declarations should be used when possible.
  1215. /// </summary>
  1216. [Category("C# 7.0 / VS 2017")]
  1217. [Description("DecompilerSettings.UseOutVariableDeclarations")]
  1218. public bool OutVariables {
  1219. get { return outVariables; }
  1220. set {
  1221. if (outVariables != value)
  1222. {
  1223. outVariables = value;
  1224. OnPropertyChanged();
  1225. }
  1226. }
  1227. }
  1228. bool discards = true;
  1229. /// <summary>
  1230. /// Gets/Sets whether discards should be used when possible.
  1231. /// Only has an effect if <see cref="OutVariables"/> is enabled.
  1232. /// </summary>
  1233. [Category("C# 7.0 / VS 2017")]
  1234. [Description("DecompilerSettings.UseDiscards")]
  1235. public bool Discards {
  1236. get { return discards; }
  1237. set {
  1238. if (discards != value)
  1239. {
  1240. discards = value;
  1241. OnPropertyChanged();
  1242. }
  1243. }
  1244. }
  1245. bool introduceRefModifiersOnStructs = true;
  1246. /// <summary>
  1247. /// Gets/Sets whether IsByRefLikeAttribute should be replaced with 'ref' modifiers on structs.
  1248. /// </summary>
  1249. [Category("C# 7.2 / VS 2017.4")]
  1250. [Description("DecompilerSettings.IsByRefLikeAttributeShouldBeReplacedWithRefModifiersOnStructs")]
  1251. public bool IntroduceRefModifiersOnStructs {
  1252. get { return introduceRefModifiersOnStructs; }
  1253. set {
  1254. if (introduceRefModifiersOnStructs != value)
  1255. {
  1256. introduceRefModifiersOnStructs = value;
  1257. OnPropertyChanged();
  1258. }
  1259. }
  1260. }
  1261. bool introduceReadonlyAndInModifiers = true;
  1262. /// <summary>
  1263. /// Gets/Sets whether IsReadOnlyAttribute should be replaced with 'readonly' modifiers on structs
  1264. /// and with the 'in' modifier on parameters.
  1265. /// </summary>
  1266. [Category("C# 7.2 / VS 2017.4")]
  1267. [Description("DecompilerSettings." +
  1268. "IsReadOnlyAttributeShouldBeReplacedWithReadonlyInModifiersOnStructsParameters")]
  1269. public bool IntroduceReadonlyAndInModifiers {
  1270. get { return introduceReadonlyAndInModifiers; }
  1271. set {
  1272. if (introduceReadonlyAndInModifiers != value)
  1273. {
  1274. introduceReadonlyAndInModifiers = value;
  1275. OnPropertyChanged();
  1276. }
  1277. }
  1278. }
  1279. bool readOnlyMethods = true;
  1280. [Category("C# 8.0 / VS 2019")]
  1281. [Description("DecompilerSettings.ReadOnlyMethods")]
  1282. public bool ReadOnlyMethods {
  1283. get { return readOnlyMethods; }
  1284. set {
  1285. if (readOnlyMethods != value)
  1286. {
  1287. readOnlyMethods = value;
  1288. OnPropertyChanged();
  1289. }
  1290. }
  1291. }
  1292. bool asyncUsingAndForEachStatement = true;
  1293. [Category("C# 8.0 / VS 2019")]
  1294. [Description("DecompilerSettings.DetectAsyncUsingAndForeachStatements")]
  1295. public bool AsyncUsingAndForEachStatement {
  1296. get { return asyncUsingAndForEachStatement; }
  1297. set {
  1298. if (asyncUsingAndForEachStatement != value)
  1299. {
  1300. asyncUsingAndForEachStatement = value;
  1301. OnPropertyChanged();
  1302. }
  1303. }
  1304. }
  1305. bool introduceUnmanagedConstraint = true;
  1306. /// <summary>
  1307. /// If this option is active, [IsUnmanagedAttribute] on type parameters
  1308. /// is replaced with "T : unmanaged" constraints.
  1309. /// </summary>
  1310. [Category("C# 7.3 / VS 2017.7")]
  1311. [Description("DecompilerSettings." +
  1312. "IsUnmanagedAttributeOnTypeParametersShouldBeReplacedWithUnmanagedConstraints")]
  1313. public bool IntroduceUnmanagedConstraint {
  1314. get { return introduceUnmanagedConstraint; }
  1315. set {
  1316. if (introduceUnmanagedConstraint != value)
  1317. {
  1318. introduceUnmanagedConstraint = value;
  1319. OnPropertyChanged();
  1320. }
  1321. }
  1322. }
  1323. bool stackAllocInitializers = true;
  1324. /// <summary>
  1325. /// Gets/Sets whether C# 7.3 stackalloc initializers should be used.
  1326. /// </summary>
  1327. [Category("C# 7.3 / VS 2017.7")]
  1328. [Description("DecompilerSettings.UseStackallocInitializerSyntax")]
  1329. public bool StackAllocInitializers {
  1330. get { return stackAllocInitializers; }
  1331. set {
  1332. if (stackAllocInitializers != value)
  1333. {
  1334. stackAllocInitializers = value;
  1335. OnPropertyChanged();
  1336. }
  1337. }
  1338. }
  1339. bool patternBasedFixedStatement = true;
  1340. /// <summary>
  1341. /// Gets/Sets whether C# 7.3 pattern based fixed statement should be used.
  1342. /// </summary>
  1343. [Category("C# 7.3 / VS 2017.7")]
  1344. [Description("DecompilerSettings.UsePatternBasedFixedStatement")]
  1345. public bool PatternBasedFixedStatement {
  1346. get { return patternBasedFixedStatement; }
  1347. set {
  1348. if (patternBasedFixedStatement != value)
  1349. {
  1350. patternBasedFixedStatement = value;
  1351. OnPropertyChanged();
  1352. }
  1353. }
  1354. }
  1355. bool tupleTypes = true;
  1356. /// <summary>
  1357. /// Gets/Sets whether tuple type syntax <c>(int, string)</c>
  1358. /// should be used for <c>System.ValueTuple</c>.
  1359. /// </summary>
  1360. [Category("C# 7.0 / VS 2017")]
  1361. [Description("DecompilerSettings.UseTupleTypeSyntax")]
  1362. public bool TupleTypes {
  1363. get { return tupleTypes; }
  1364. set {
  1365. if (tupleTypes != value)
  1366. {
  1367. tupleTypes = value;
  1368. OnPropertyChanged();
  1369. }
  1370. }
  1371. }
  1372. bool throwExpressions = true;
  1373. /// <summary>
  1374. /// Gets/Sets whether throw expressions should be used.
  1375. /// </summary>
  1376. [Category("C# 7.0 / VS 2017")]
  1377. [Description("DecompilerSettings.UseThrowExpressions")]
  1378. public bool ThrowExpressions {
  1379. get { return throwExpressions; }
  1380. set {
  1381. if (throwExpressions != value)
  1382. {
  1383. throwExpressions = value;
  1384. OnPropertyChanged();
  1385. }
  1386. }
  1387. }
  1388. bool tupleConversions = true;
  1389. /// <summary>
  1390. /// Gets/Sets whether implicit conversions between tuples
  1391. /// should be used in the decompiled output.
  1392. /// </summary>
  1393. [Category("C# 7.0 / VS 2017")]
  1394. [Description("DecompilerSettings.UseImplicitConversionsBetweenTupleTypes")]
  1395. public bool TupleConversions {
  1396. get { return tupleConversions; }
  1397. set {
  1398. if (tupleConversions != value)
  1399. {
  1400. tupleConversions = value;
  1401. OnPropertyChanged();
  1402. }
  1403. }
  1404. }
  1405. bool tupleComparisons = true;
  1406. /// <summary>
  1407. /// Gets/Sets whether tuple comparisons should be detected.
  1408. /// </summary>
  1409. [Category("C# 7.3 / VS 2017.7")]
  1410. [Description("DecompilerSettings.DetectTupleComparisons")]
  1411. public bool TupleComparisons {
  1412. get { return tupleComparisons; }
  1413. set {
  1414. if (tupleComparisons != value)
  1415. {
  1416. tupleComparisons = value;
  1417. OnPropertyChanged();
  1418. }
  1419. }
  1420. }
  1421. bool namedArguments = true;
  1422. /// <summary>
  1423. /// Gets/Sets whether named arguments should be used.
  1424. /// </summary>
  1425. [Category("C# 4.0 / VS 2010")]
  1426. [Description("DecompilerSettings.UseNamedArguments")]
  1427. public bool NamedArguments {
  1428. get { return namedArguments; }
  1429. set {
  1430. if (namedArguments != value)
  1431. {
  1432. namedArguments = value;
  1433. OnPropertyChanged();
  1434. }
  1435. }
  1436. }
  1437. bool nonTrailingNamedArguments = true;
  1438. /// <summary>
  1439. /// Gets/Sets whether C# 7.2 non-trailing named arguments should be used.
  1440. /// </summary>
  1441. [Category("C# 7.2 / VS 2017.4")]
  1442. [Description("DecompilerSettings.UseNonTrailingNamedArguments")]
  1443. public bool NonTrailingNamedArguments {
  1444. get { return nonTrailingNamedArguments; }
  1445. set {
  1446. if (nonTrailingNamedArguments != value)
  1447. {
  1448. nonTrailingNamedArguments = value;
  1449. OnPropertyChanged();
  1450. }
  1451. }
  1452. }
  1453. bool optionalArguments = true;
  1454. /// <summary>
  1455. /// Gets/Sets whether optional arguments should be removed, if possible.
  1456. /// </summary>
  1457. [Category("C# 4.0 / VS 2010")]
  1458. [Description("DecompilerSettings.RemoveOptionalArgumentsIfPossible")]
  1459. public bool OptionalArguments {
  1460. get { return optionalArguments; }
  1461. set {
  1462. if (optionalArguments != value)
  1463. {
  1464. optionalArguments = value;
  1465. OnPropertyChanged();
  1466. }
  1467. }
  1468. }
  1469. bool localFunctions = true;
  1470. /// <summary>
  1471. /// Gets/Sets whether C# 7.0 local functions should be transformed.
  1472. /// </summary>
  1473. [Category("C# 7.0 / VS 2017")]
  1474. [Description("DecompilerSettings.IntroduceLocalFunctions")]
  1475. public bool LocalFunctions {
  1476. get { return localFunctions; }
  1477. set {
  1478. if (localFunctions != value)
  1479. {
  1480. localFunctions = value;
  1481. OnPropertyChanged();
  1482. }
  1483. }
  1484. }
  1485. bool deconstruction = true;
  1486. /// <summary>
  1487. /// Gets/Sets whether C# 7.0 deconstruction should be detected.
  1488. /// </summary>
  1489. [Category("C# 7.0 / VS 2017")]
  1490. [Description("DecompilerSettings.Deconstruction")]
  1491. public bool Deconstruction {
  1492. get { return deconstruction; }
  1493. set {
  1494. if (deconstruction != value)
  1495. {
  1496. deconstruction = value;
  1497. OnPropertyChanged();
  1498. }
  1499. }
  1500. }
  1501. bool patternMatching = true;
  1502. /// <summary>
  1503. /// Gets/Sets whether C# 7.0 pattern matching should be detected.
  1504. /// </summary>
  1505. [Category("C# 7.0 / VS 2017")]
  1506. [Description("DecompilerSettings.PatternMatching")]
  1507. public bool PatternMatching {
  1508. get { return patternMatching; }
  1509. set {
  1510. if (patternMatching != value)
  1511. {
  1512. patternMatching = value;
  1513. OnPropertyChanged();
  1514. }
  1515. }
  1516. }
  1517. bool recursivePatternMatching = true;
  1518. /// <summary>
  1519. /// Gets/Sets whether C# 8.0 recursive patterns should be detected.
  1520. /// </summary>
  1521. [Category("C# 8.0 / VS 2019")]
  1522. [Description("DecompilerSettings.RecursivePatternMatching")]
  1523. public bool RecursivePatternMatching {
  1524. get { return recursivePatternMatching; }
  1525. set {
  1526. if (recursivePatternMatching != value)
  1527. {
  1528. recursivePatternMatching = value;
  1529. OnPropertyChanged();
  1530. }
  1531. }
  1532. }
  1533. bool patternCombinators = true;
  1534. /// <summary>
  1535. /// Gets/Sets whether C# 9.0 and, or, not patterns should be detected.
  1536. /// </summary>
  1537. [Category("C# 9.0 / VS 2019.8")]
  1538. [Description("DecompilerSettings.PatternCombinators")]
  1539. public bool PatternCombinators {
  1540. get { return patternCombinators; }
  1541. set {
  1542. if (patternCombinators != value)
  1543. {
  1544. patternCombinators = value;
  1545. OnPropertyChanged();
  1546. }
  1547. }
  1548. }
  1549. bool relationalPatterns = true;
  1550. /// <summary>
  1551. /// Gets/Sets whether C# 9.0 relational patterns should be detected.
  1552. /// </summary>
  1553. [Category("C# 9.0 / VS 2019.8")]
  1554. [Description("DecompilerSettings.RelationalPatterns")]
  1555. public bool RelationalPatterns {
  1556. get { return relationalPatterns; }
  1557. set {
  1558. if (relationalPatterns != value)
  1559. {
  1560. relationalPatterns = value;
  1561. OnPropertyChanged();
  1562. }
  1563. }
  1564. }
  1565. bool staticLocalFunctions = true;
  1566. /// <summary>
  1567. /// Gets/Sets whether C# 8.0 static local functions should be transformed.
  1568. /// </summary>
  1569. [Category("C# 8.0 / VS 2019")]
  1570. [Description("DecompilerSettings.IntroduceStaticLocalFunctions")]
  1571. public bool StaticLocalFunctions {
  1572. get { return staticLocalFunctions; }
  1573. set {
  1574. if (staticLocalFunctions != value)
  1575. {
  1576. staticLocalFunctions = value;
  1577. OnPropertyChanged();
  1578. }
  1579. }
  1580. }
  1581. bool ranges = true;
  1582. /// <summary>
  1583. /// Gets/Sets whether C# 8.0 index and range syntax should be used.
  1584. /// </summary>
  1585. [Category("C# 8.0 / VS 2019")]
  1586. [Description("DecompilerSettings.Ranges")]
  1587. public bool Ranges {
  1588. get { return ranges; }
  1589. set {
  1590. if (ranges != value)
  1591. {
  1592. ranges = value;
  1593. OnPropertyChanged();
  1594. }
  1595. }
  1596. }
  1597. bool nullableReferenceTypes = true;
  1598. /// <summary>
  1599. /// Gets/Sets whether C# 8.0 nullable reference types are enabled.
  1600. /// </summary>
  1601. [Category("C# 8.0 / VS 2019")]
  1602. [Description("DecompilerSettings.NullableReferenceTypes")]
  1603. public bool NullableReferenceTypes {
  1604. get { return nullableReferenceTypes; }
  1605. set {
  1606. if (nullableReferenceTypes != value)
  1607. {
  1608. nullableReferenceTypes = value;
  1609. OnPropertyChanged();
  1610. }
  1611. }
  1612. }
  1613. bool showDebugInfo;
  1614. [Category("DecompilerSettings.Other")]
  1615. [Description("DecompilerSettings.ShowInfoFromDebugSymbolsIfAvailable")]
  1616. [Browsable(false)]
  1617. public bool ShowDebugInfo {
  1618. get { return showDebugInfo; }
  1619. set {
  1620. if (showDebugInfo != value)
  1621. {
  1622. showDebugInfo = value;
  1623. OnPropertyChanged();
  1624. }
  1625. }
  1626. }
  1627. #region Options to aid VB decompilation
  1628. bool assumeArrayLengthFitsIntoInt32 = true;
  1629. /// <summary>
  1630. /// Gets/Sets whether the decompiler can assume that 'ldlen; conv.i4.ovf'
  1631. /// does not throw an overflow exception.
  1632. /// </summary>
  1633. [Category("DecompilerSettings.VBSpecificOptions")]
  1634. [Browsable(false)]
  1635. public bool AssumeArrayLengthFitsIntoInt32 {
  1636. get { return assumeArrayLengthFitsIntoInt32; }
  1637. set {
  1638. if (assumeArrayLengthFitsIntoInt32 != value)
  1639. {
  1640. assumeArrayLengthFitsIntoInt32 = value;
  1641. OnPropertyChanged();
  1642. }
  1643. }
  1644. }
  1645. bool introduceIncrementAndDecrement = true;
  1646. /// <summary>
  1647. /// Gets/Sets whether to use increment and decrement operators
  1648. /// </summary>
  1649. [Category("DecompilerSettings.VBSpecificOptions")]
  1650. [Browsable(false)]
  1651. public bool IntroduceIncrementAndDecrement {
  1652. get { return introduceIncrementAndDecrement; }
  1653. set {
  1654. if (introduceIncrementAndDecrement != value)
  1655. {
  1656. introduceIncrementAndDecrement = value;
  1657. OnPropertyChanged();
  1658. }
  1659. }
  1660. }
  1661. bool makeAssignmentExpressions = true;
  1662. /// <summary>
  1663. /// Gets/Sets whether to use assignment expressions such as in while ((count = Do()) != 0) ;
  1664. /// </summary>
  1665. [Category("DecompilerSettings.VBSpecificOptions")]
  1666. [Browsable(false)]
  1667. public bool MakeAssignmentExpressions {
  1668. get { return makeAssignmentExpressions; }
  1669. set {
  1670. if (makeAssignmentExpressions != value)
  1671. {
  1672. makeAssignmentExpressions = value;
  1673. OnPropertyChanged();
  1674. }
  1675. }
  1676. }
  1677. #endregion
  1678. #region Options to aid F# decompilation
  1679. bool removeDeadCode = false;
  1680. [Category("DecompilerSettings.FSpecificOptions")]
  1681. [Description("DecompilerSettings.RemoveDeadAndSideEffectFreeCodeUseWithCaution")]
  1682. public bool RemoveDeadCode {
  1683. get { return removeDeadCode; }
  1684. set {
  1685. if (removeDeadCode != value)
  1686. {
  1687. removeDeadCode = value;
  1688. OnPropertyChanged();
  1689. }
  1690. }
  1691. }
  1692. bool removeDeadStores = false;
  1693. [Category("DecompilerSettings.FSpecificOptions")]
  1694. [Description("DecompilerSettings.RemoveDeadStores")]
  1695. public bool RemoveDeadStores {
  1696. get { return removeDeadStores; }
  1697. set {
  1698. if (removeDeadStores != value)
  1699. {
  1700. removeDeadStores = value;
  1701. OnPropertyChanged();
  1702. }
  1703. }
  1704. }
  1705. #endregion
  1706. #region Assembly Load and Resolve options
  1707. bool loadInMemory = false;
  1708. [Browsable(false)]
  1709. public bool LoadInMemory {
  1710. get { return loadInMemory; }
  1711. set {
  1712. if (loadInMemory != value)
  1713. {
  1714. loadInMemory = value;
  1715. OnPropertyChanged();
  1716. }
  1717. }
  1718. }
  1719. bool throwOnAssemblyResolveErrors = true;
  1720. [Browsable(false)]
  1721. public bool ThrowOnAssemblyResolveErrors {
  1722. get { return throwOnAssemblyResolveErrors; }
  1723. set {
  1724. if (throwOnAssemblyResolveErrors != value)
  1725. {
  1726. throwOnAssemblyResolveErrors = value;
  1727. OnPropertyChanged();
  1728. }
  1729. }
  1730. }
  1731. bool applyWindowsRuntimeProjections = true;
  1732. [Category("DecompilerSettings.Other")]
  1733. [Description("DecompilerSettings.ApplyWindowsRuntimeProjectionsOnLoadedAssemblies")]
  1734. public bool ApplyWindowsRuntimeProjections {
  1735. get { return applyWindowsRuntimeProjections; }
  1736. set {
  1737. if (applyWindowsRuntimeProjections != value)
  1738. {
  1739. applyWindowsRuntimeProjections = value;
  1740. OnPropertyChanged();
  1741. }
  1742. }
  1743. }
  1744. bool autoLoadAssemblyReferences = true;
  1745. [Category("DecompilerSettings.Other")]
  1746. [Description("DecompilerSettings.AutoLoadAssemblyReferences")]
  1747. public bool AutoLoadAssemblyReferences {
  1748. get { return autoLoadAssemblyReferences; }
  1749. set {
  1750. if (autoLoadAssemblyReferences != value)
  1751. {
  1752. autoLoadAssemblyReferences = value;
  1753. OnPropertyChanged();
  1754. }
  1755. }
  1756. }
  1757. #endregion
  1758. bool forStatement = true;
  1759. /// <summary>
  1760. /// Gets/sets whether the decompiler should produce for loops.
  1761. /// </summary>
  1762. [Category("C# 1.0 / VS .NET")]
  1763. [Description("DecompilerSettings.ForStatement")]
  1764. public bool ForStatement {
  1765. get { return forStatement; }
  1766. set {
  1767. if (forStatement != value)
  1768. {
  1769. forStatement = value;
  1770. OnPropertyChanged();
  1771. }
  1772. }
  1773. }
  1774. bool doWhileStatement = true;
  1775. /// <summary>
  1776. /// Gets/sets whether the decompiler should produce do-while loops.
  1777. /// </summary>
  1778. [Category("C# 1.0 / VS .NET")]
  1779. [Description("DecompilerSettings.DoWhileStatement")]
  1780. public bool DoWhileStatement {
  1781. get { return doWhileStatement; }
  1782. set {
  1783. if (doWhileStatement != value)
  1784. {
  1785. doWhileStatement = value;
  1786. OnPropertyChanged();
  1787. }
  1788. }
  1789. }
  1790. bool refReadOnlyParameters = true;
  1791. /// <summary>
  1792. /// Gets/sets whether RequiresLocationAttribute on parameters should be replaced with 'ref readonly' modifiers.
  1793. /// </summary>
  1794. [Category("C# 12.0 / VS 2022.8")]
  1795. [Description("DecompilerSettings.RefReadOnlyParameters")]
  1796. public bool RefReadOnlyParameters {
  1797. get { return refReadOnlyParameters; }
  1798. set {
  1799. if (refReadOnlyParameters != value)
  1800. {
  1801. refReadOnlyParameters = value;
  1802. OnPropertyChanged();
  1803. }
  1804. }
  1805. }
  1806. bool usePrimaryConstructorSyntaxForNonRecordTypes = true;
  1807. /// <summary>
  1808. /// Use primary constructor syntax with classes and structs.
  1809. /// </summary>
  1810. [Category("C# 12.0 / VS 2022.8")]
  1811. [Description("DecompilerSettings.UsePrimaryConstructorSyntaxForNonRecordTypes")]
  1812. public bool UsePrimaryConstructorSyntaxForNonRecordTypes {
  1813. get { return usePrimaryConstructorSyntaxForNonRecordTypes; }
  1814. set {
  1815. if (usePrimaryConstructorSyntaxForNonRecordTypes != value)
  1816. {
  1817. usePrimaryConstructorSyntaxForNonRecordTypes = value;
  1818. OnPropertyChanged();
  1819. }
  1820. }
  1821. }
  1822. bool separateLocalVariableDeclarations = false;
  1823. /// <summary>
  1824. /// Gets/sets whether the decompiler should separate local variable declarations
  1825. /// from their initialization.
  1826. /// </summary>
  1827. [Category("DecompilerSettings.Other")]
  1828. [Description("DecompilerSettings.SeparateLocalVariableDeclarations")]
  1829. public bool SeparateLocalVariableDeclarations {
  1830. get { return separateLocalVariableDeclarations; }
  1831. set {
  1832. if (separateLocalVariableDeclarations != value)
  1833. {
  1834. separateLocalVariableDeclarations = value;
  1835. OnPropertyChanged();
  1836. }
  1837. }
  1838. }
  1839. bool useSdkStyleProjectFormat = true;
  1840. /// <summary>
  1841. /// Gets or sets a value indicating whether the new SDK style format
  1842. /// shall be used for the generated project files.
  1843. /// </summary>
  1844. [Category("DecompilerSettings.ProjectExport")]
  1845. [Description("DecompilerSettings.UseSdkStyleProjectFormat")]
  1846. public bool UseSdkStyleProjectFormat {
  1847. get { return useSdkStyleProjectFormat; }
  1848. set {
  1849. if (useSdkStyleProjectFormat != value)
  1850. {
  1851. useSdkStyleProjectFormat = value;
  1852. OnPropertyChanged();
  1853. }
  1854. }
  1855. }
  1856. bool useNestedDirectoriesForNamespaces;
  1857. /// <summary>
  1858. /// Gets/sets whether namespaces and namespace-like identifiers should be split at '.'
  1859. /// and each part should produce a new level of nesting in the output directory structure.
  1860. /// </summary>
  1861. [Category("DecompilerSettings.ProjectExport")]
  1862. [Description("DecompilerSettings.UseNestedDirectoriesForNamespaces")]
  1863. public bool UseNestedDirectoriesForNamespaces {
  1864. get { return useNestedDirectoriesForNamespaces; }
  1865. set {
  1866. if (useNestedDirectoriesForNamespaces != value)
  1867. {
  1868. useNestedDirectoriesForNamespaces = value;
  1869. OnPropertyChanged();
  1870. }
  1871. }
  1872. }
  1873. bool aggressiveScalarReplacementOfAggregates = false;
  1874. [Category("DecompilerSettings.Other")]
  1875. [Description("DecompilerSettings.AggressiveScalarReplacementOfAggregates")]
  1876. // TODO : Remove once https://github.com/icsharpcode/ILSpy/issues/2032 is fixed.
  1877. #if !DEBUG
  1878. [Browsable(false)]
  1879. #endif
  1880. public bool AggressiveScalarReplacementOfAggregates {
  1881. get { return aggressiveScalarReplacementOfAggregates; }
  1882. set {
  1883. if (aggressiveScalarReplacementOfAggregates != value)
  1884. {
  1885. aggressiveScalarReplacementOfAggregates = value;
  1886. OnPropertyChanged();
  1887. }
  1888. }
  1889. }
  1890. bool aggressiveInlining = false;
  1891. /// <summary>
  1892. /// If set to false (the default), the decompiler will inline local variables only when they occur
  1893. /// in a context where the C# compiler is known to emit compiler-generated locals.
  1894. /// If set to true, the decompiler will inline local variables whenever possible.
  1895. /// </summary>
  1896. [Category("DecompilerSettings.Other")]
  1897. [Description("DecompilerSettings.AggressiveInlining")]
  1898. public bool AggressiveInlining {
  1899. get { return aggressiveInlining; }
  1900. set {
  1901. if (aggressiveInlining != value)
  1902. {
  1903. aggressiveInlining = value;
  1904. OnPropertyChanged();
  1905. }
  1906. }
  1907. }
  1908. bool alwaysUseGlobal = false;
  1909. /// <summary>
  1910. /// Always fully qualify namespaces using the "global::" prefix.
  1911. /// </summary>
  1912. [Category("DecompilerSettings.Other")]
  1913. [Description("DecompilerSettings.AlwaysUseGlobal")]
  1914. public bool AlwaysUseGlobal {
  1915. get { return alwaysUseGlobal; }
  1916. set {
  1917. if (alwaysUseGlobal != value)
  1918. {
  1919. alwaysUseGlobal = value;
  1920. OnPropertyChanged();
  1921. }
  1922. }
  1923. }
  1924. bool sortCustomAttributes = false;
  1925. /// <summary>
  1926. /// Sort custom attributes.
  1927. /// </summary>
  1928. [Category("DecompilerSettings.Other")]
  1929. [Description("DecompilerSettings.SortCustomAttributes")]
  1930. public bool SortCustomAttributes {
  1931. get { return sortCustomAttributes; }
  1932. set {
  1933. if (sortCustomAttributes != value)
  1934. {
  1935. sortCustomAttributes = value;
  1936. OnPropertyChanged();
  1937. }
  1938. }
  1939. }
  1940. CSharpFormattingOptions csharpFormattingOptions;
  1941. [Browsable(false)]
  1942. public CSharpFormattingOptions CSharpFormattingOptions {
  1943. get {
  1944. if (csharpFormattingOptions == null)
  1945. {
  1946. csharpFormattingOptions = FormattingOptionsFactory.CreateAllman();
  1947. csharpFormattingOptions.IndentSwitchBody = false;
  1948. csharpFormattingOptions.ArrayInitializerWrapping = Wrapping.WrapIfTooLong;
  1949. csharpFormattingOptions.AutoPropertyFormatting = PropertyFormatting.SingleLine;
  1950. }
  1951. return csharpFormattingOptions;
  1952. }
  1953. set {
  1954. if (value == null)
  1955. throw new ArgumentNullException();
  1956. if (csharpFormattingOptions != value)
  1957. {
  1958. csharpFormattingOptions = value;
  1959. OnPropertyChanged();
  1960. }
  1961. }
  1962. }
  1963. public event PropertyChangedEventHandler PropertyChanged;
  1964. protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  1965. {
  1966. if (PropertyChanged != null)
  1967. {
  1968. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  1969. }
  1970. }
  1971. public DecompilerSettings Clone()
  1972. {
  1973. DecompilerSettings settings = (DecompilerSettings)MemberwiseClone();
  1974. if (csharpFormattingOptions != null)
  1975. settings.csharpFormattingOptions = csharpFormattingOptions.Clone();
  1976. settings.PropertyChanged = null;
  1977. return settings;
  1978. }
  1979. }
  1980. }